/* xytocross.c
:w | !gcc % -o %< -lgd -Wfatal-errors
:w | !gcc % -o %< -lgd && ./%<  && display damesjadis-X.jpg
*/

#include "cross-stitch.h"

int main(int argc, char *argv[]) 
{
   
   char *name = argc == 1 ? "damesjadis" : argv[1];

   int n;
   if(argc == 2 && (sscanf(argv[2], "%d", &n) == 1)) N = n;

   W = 2*N*step*scale + 2*pad;
   H = 26*step + 2*pad;

   // Allocate image pointer
   im = gdImageCreate(W, H);
   // colors
   for(int i=0; i<palette_size; i++) {
      fg[i] = gdImageColorAllocate(im, 
	 palette[i][0], palette[i][1], palette[i][2]);
      c[i] = gdImageColorAllocate(im, 
	 color[i][0], color[i][1], color[i][2]);
   }

   width = W - 2*pad;
   height = H - 2*pad;

   aida();

   score(name);

   save(name); // save the cross stitch

   for(int i=0; i<palette_size; i++) {
      gdImageColorDeallocate(im, fg[i]);
      gdImageColorDeallocate(im, c[i]);
   }

   gdImageDestroy(im);

   return 0;
}

void aida()
{
   // draw yarns tile: w × h
   const int w = step - hole, h = step + hole;
   gdImageSetThickness(im, 1);
   for(int v = 0, i = 0; v < H; v += step, i++) {
      // tiles
      if(i%2) box(0, v + hole, h, w - 1, fg[2]);
      for(int u = 0; u < W; u += w + h) {
	 x = u + step*(i%2);
	 y = v;
	 // vertical tile
	 box(x, y, w, h, fg[2]); // tile
	 rect(x, y, w, h, fg[3]); // border
	 box(x + 1, y + 1, w - 3, 2, fg[1]); // shadow
	 // horizontal tile
	 x += w; y += hole; 
	 box(x, y, h, w, fg[2]); // tile
	 rect(x, y, h, w, fg[3]); // border
	 box(x + 1, y + 1, 2, w - 3, fg[1]); // shadow
	 
      }
      // horizontal tiles
   }
   
   // frame
   gdImageSetThickness(im, 3); // 5 ; 2 ; 7 ; 12
   gdImageRectangle(im, 1, 1, W - 1, H - 1, fg[4]); 
   gdImageRectangle(im, 4, 4, W - 4, H - 4, fg[5]); 
   gdImageRectangle(im, 7, 7, W - 7, H - 7, fg[4]); 
   gdImageSetThickness(im, 1);
   // lights
   line(40, 4, 320, 4, fg[1]); 
   line(60, H - 4, 140, H - 4, fg[1]); line(280, H - 4, 340, H - 4, fg[1]);
   line(4, 50, 4, 180, fg[1]); line(W - 4, 60, W - 4, 190, fg[1]);
   
}

void score(char * name)
{
   FILE *fp = fopen(name, "r");

   int d, p, x = 0; // duration, pitch, cross abscissa
   int page = 0;
   printf("width: %d ; height: %d\n", width, height) ; 
   do {
      fscanf(fp, "%d %d", &d, &p); // read duration from file
      
      if(x + d*scale >= width/step) {
	 x = 0;
	 ++page % palette_size;
      }
      
      for(int dx=0; dx<scale*d - 1; dx++) {
	 if(p != NaN)
	    cross(x + dx, p, c[page]); // draw  d - 1 crosses
      }
      x += d*scale; // go forward
   } while(!feof(fp)); // && page < 16);
 
   fclose(fp);
}
// make a cross
void cross(int x, int y, int color)
{
   int X = 2*pad + x*step;
   int Y = H - pad - y*step + 2;
   gdImageSetThickness(im, 5);
   line(X , Y, X + step - 2, Y - step - 1 , color);
   line(X, Y - step - 1, X + step - 2, Y, color);
}
// draw a rest
void rest(int x, int y, int color)
{
   int X = 2*pad + x*step;
   int Y = H - pad - y*step + 2;
   gdImageSetThickness(im, 5);
   line(X , Y, X + step - 2, Y, color);
}

void save(char * name)
{
   char dest[1024]; // output file name 
   strcpy(dest, name);
   strcat(dest, "-X.jpg");
   printf("Writing %s\n", dest); // msg
   jpeg = fopen(dest, "w");
   gdImageJpeg(im, jpeg, -1); // saved as jpeg file
   fclose(jpeg);
}

void line(int x1, int y1, int x2, int y2, int c) 
{
   gdImageLine(im, x1, y1, x2, y2, c);
   _x = x2; _y = y2;
}

void box(int x, int y, int w, int h, int c)
{
   gdImageFilledRectangle(im, x, y, x + w, y + h, c);
}

void rect(int x, int y, int w, int h, int c)
{
   gdImageRectangle(im, x, y, x + w, y + h, c);
}
