/*  
    Copyright (C) 2003 Johan Borg

    This file is part of xmerge.

    xmerge is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
                
    xmerge is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
                          
    You should have received a copy of the GNU General Public License
    along with xmerge; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/


#include "xmerge.h"

extern double LCOL_r,LCOL_g,LCOL_b;

IMG * read_ppm(char *name) {
 int fd,d,e,xd=0,yd=0,ds;
 unsigned char c;
 unsigned char buf[80];
 IMG * img;
 fd=open(name,O_RDONLY);
 if (fd<0) {
  fprintf(stderr,"unable to open file %s, exiting\n",name);
  exit(-1);
 } 
  
 d=c=0;
 while ((c!=10) && (d<80)) { read(fd,&c,1); buf[d++]=c; }
 buf[--d]=0;

 if (memcmp(buf,"P6",2)) {
  fprintf(stderr,"error: not a ppm file (%s)\n",name);
  exit(-1);
 } 

 e=0;
 
l1:
 read(fd,&c,1);
 while (c=='#') { while (c!=10)  read(fd,&c,1);  read(fd,&c,1); }
  
 buf[0]=c;
 d=1; 

 while ((c!=10) && (c!=32) && (d<80)) { read(fd,&c,1); buf[d++]=c; } 
 if (d==1) goto l1;
 
 e++;
 switch(e) {
  case 1:
   xd=atoi(buf);
   goto l1;
  case 2:
   yd=atoi(buf);
   goto l1;
 } 
 

   
 printf("xd: %d yd: %d\n",xd,yd);
 ds=xd*yd*3;
 img=(IMG *)malloc(sizeof(IMG)+ds);
 read(fd,img->pix,ds);
 img->sx=xd;
 img->sy=yd;
 img->sd=ds;
 img->Gr=img->Gg=img->Gb=1;
 img->Grn=img->Ggn=img->Gbn=0; 
 img->name=malloc(strlen(name)+1);
 strcpy(img->name,name);

 close(fd);
 return img;
}


void write_ppm(IMG *img,char *name) {
 int fd;
 char buf[32];
 fd=open(name,O_WRONLY|O_CREAT|O_TRUNC,0777);
 sprintf(buf,"P6\n%d %d\n255\n",img->sx,img->sy);
 write(fd,buf,strlen(buf));
 write(fd,img->pix,img->sd);
 close(fd);
}

void writed_ppm(unsigned char * data,int dx,int dy,char *name) {
 int fd;
 char buf[32];
 fd=open(name,O_WRONLY|O_CREAT|O_TRUNC,0777);
 sprintf(buf,"P6\n%d %d\n255\n",dx,dy);
 write(fd,buf,strlen(buf));
 write(fd,data,dx*dy*3);
 close(fd);
}


extern int Dxm1,Dym1,Dxm,Dym;

extern int writing_list;

void write_list(char *name) {
 FILE *F;
 int a,b,si,di;
 edget *edge;
 writing_list=1;
 F=fopen(name,"w+");
 fprintf(F,"XMF\n");

 b=0;
 for(a=0;a<MAXLINKS;a++) if (rlink[a].stat&2) b++;
 
 
 fprintf(F,"%d %d %d %d %d %d %d %d\n",Ot,b,Dxm1,Dym1,Ml0,Mt0,Mr0,Mb0);
 
 fprintf(F,"c %d %d %d %d\n",Ml,Mt,Mr,Mb);
 
 for(a=0;a<Ot;a++) {
  fprintf(F,"f %d %d %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %d %.3f %d %.3f %d %s\n",simg[a]->Tx,simg[a]->Ty,
                 simg[a]->dx1,simg[a]->dy1,simg[a]->dx2,simg[a]->dy2,simg[a]->dx3,simg[a]->dy3,simg[a]->dx4,simg[a]->dy4,
                 simg[a]->Gr,simg[a]->Grn,simg[a]->Gg,simg[a]->Ggn,simg[a]->Gb,simg[a]->Gbn,
                 simg[a]->name);
  edge=simg[a]->edge;
  fprintf(F,"e %d",simg[a]->edgen);
  while(edge) {
   fprintf(F," %d %d",edge->x,edge->y);  
   edge=edge->next;
  }
  fprintf(F,"\n");
 } 
 
 for(a=0;a<MAXLINKS;a++) {
  if (rlink[a].stat&2) {
   for(b=0;b<Ot;b++) if (rlink[a].si==simg[b]) break;
   si=b;
   for(b=0;b<Ot;b++) if (rlink[a].di==simg[b]) break;
   di=b;
   
   switch(rlink[a].type) {
    case 0:
     fprintf(F,"l %d %d %.3f %.3f %.3f %.3f %.3f %.3f\n",si,di,rlink[a].sx1,rlink[a].sy1,rlink[a].sx2,rlink[a].sy2,rlink[a].dx,rlink[a].dy);
     break;
    case 1:
     fprintf(F,"d %d %d %.3f %.3f %.3f %.3f %.3f\n",si,di,rlink[a].sx1,rlink[a].sy1,rlink[a].dx,rlink[a].dy,rlink[a].angle);     
     break;
   } 
  } 
 } 
 writing_list=0; 
 fclose(F);
}

extern double opt_lscale;

int read_list(char *name) {
 FILE *F;
 int a,b,Tx,Ty,csi,csl,si,di,Grn,Ggn,Gbn;
 double sx1,sy1,sx2,sy2,dx,dy,dx1,dy1,dx2,dy2,dx3,dy3,dx4,dy4,angle,Gr,Gg,Gb;
 char buf[256];
 edget *edge;

 F=fopen(name,"r");
 if (!F) {
  printf("unable to open file %s, exiting\n",name);
  exit(-1);
 }
 fgets(buf,256,F);
 
 if (strcmp(buf,"XMF\n")) {
  printf("error loading xmerge list file, aborting\n");
  exit(-1);
 } 
// printf("reading xmerge list file\n");
 
 if ((a=fscanf(F,"%d %d %d %d %d %d %d %d\n",&Ot,&b,&Dxm1,&Dym1,&Ml0,&Mt0,&Mr0,&Mb0))!=8) {
  printf("invalid format, aborting %d\n",a);
  exit(-1);
 }
 
 Ml0*=opt_lscale; Mt0*=opt_lscale; Mr0*=opt_lscale; Mb0*=opt_lscale;    
 
 Dxm=Dxm1;
 Dym=Dym1;
  
 simg=malloc(sizeof(IMG *)*Ot);
 printf("Ot: %d b: %d\n",Ot,b);

 if (b>=MAXLINKS) {
  printf("too many links listed in file, aborting\n");
  exit(-1);
 }


 csi=-1;
 csl=-1;
 edge=0;
 
 
// Gr=Gg=Gb=1;
// Grn=Ggn=Gbn=0;
 
 
 while(!feof(F)) {
  switch(fgetc(F)) {
   case 'f':
    if (fscanf(F," %d %d %lf %lf %lf %lf %lf %lf %lf %lf %lf %d %lf %d %lf %d %255s\n",&Tx,&Ty,&dx1,&dy1,&dx2,&dy2,&dx3,&dy3,&dx4,&dy4,&Gr,&Grn,&Gg,&Ggn,&Gb,&Gbn,buf)!=17) {
//    if (fscanf(F," %d %d %lf %lf %lf %lf %lf %lf %lf %lf %255s\n",&Tx,&Ty,&dx1,&dy1,&dx2,&dy2,&dx3,&dy3,&dx4,&dy4,buf)!=11) {
     printf("invalid format, aborting\n");
     exit(-1);
    }
    
    csi++;
    if (csi==Ot) {
     printf("invalid format, aborting\n");
     exit(-1);
    }
    simg[csi]=read_ppm(buf);
//    simg[csi]=malloc(20000);
//    simg[csi]->name=malloc(strlen(buf)+1);
//    strcpy(simg[csi]->name,buf);

    dx1*=opt_lscale; dy1*=opt_lscale; dx2*=opt_lscale; dy2*=opt_lscale; 
    dx3*=opt_lscale; dy3*=opt_lscale; dx4*=opt_lscale; dy4*=opt_lscale; 

    simg[csi]->Tx=Tx;  simg[csi]->Ty=Ty;
    simg[csi]->dx1=dx1; simg[csi]->dy1=dy1; simg[csi]->dx2=dx2; simg[csi]->dy2=dy2;
    simg[csi]->dx3=dx3; simg[csi]->dy3=dy3; simg[csi]->dx4=dx4; simg[csi]->dy4=dy4;    
    simg[csi]->Gr=Gr*LCOL_r; simg[csi]->Grn=Grn; 
    simg[csi]->Gg=Gg*LCOL_g; simg[csi]->Ggn=Ggn;
    simg[csi]->Gb=Gb*LCOL_b; simg[csi]->Gbn=Gbn;
    
    
    edge=0;
    printf("name: %s\n",buf);

    break;
    
   case 'e':
    if (csi==-1) {
     printf("invalid format, aborting\n");
     exit(-1);
    }
    
    if (fscanf(F," %d",&a)!=1) {
     printf("invalid format, aborting\n");
     exit(-1);
    } 
    
    for(b=0;b<a-1;b++) {
     if (fscanf(F," %d %d",&Tx,&Ty)!=2) {
      printf("invalid format, aborting\n");
      exit(-1);
     } 
     edge=edge_add(simg[csi],edge,Tx,Ty);
    }
    
    if (fscanf(F," %d %d\n",&Tx,&Ty)!=2) {
     printf("invalid format, aborting\n");
     exit(-1);
    }  
    edge=edge_add(simg[csi],edge,Tx,Ty);
    break;
    
   case 'c':
    if (fscanf(F," %d %d %d %d\n",&Ml,&Mt,&Mr,&Mb)!=4) {
     printf("invalid format, aborting\n");
     exit(-1);
    } 
    Ml*=opt_lscale; Mt*=opt_lscale; Mr*=opt_lscale; Mb*=opt_lscale;    
    break;
    
    
   case 'l':
    if (fscanf(F," %d %d %lf %lf %lf %lf %lf %lf\n",&si,&di,&sx1,&sy1,&sx2,&sy2,&dx,&dy)!=8) {
     printf("invalid format, aborting\n");
     exit(-1);
    }    
    
    csl++;
    if (csl==MAXLINKS) {
     printf("too many links listed in file, aborting\n");
     exit(-1);
    }

    if ((si>csi) || (di>csi)) {
     printf("link listed before refered image, aborting\n");
     exit(-1);
    }
    
    rlink[csl].si=simg[si]; rlink[csl].di=simg[di];
    rlink[csl].sx1=sx1; rlink[csl].sy1=sy1;
    rlink[csl].sx2=sx2; rlink[csl].sy2=sy2;
    rlink[csl].dx=dx;   rlink[csl].dy=dy;
    rlink[csl].type=0;
    rlink[csl].stat=3;
    
    break;
    
   case 'd':
    if (fscanf(F," %d %d %lf %lf %lf %lf %lf\n",&si,&di,&sx1,&sy1,&dx,&dy,&angle)!=7) {
     printf("invalid format, aborting\n");
     exit(-1);
    }
   
    csl++;
    if (csl==MAXLINKS) {
     printf("too many links listed in file, aborting\n");
     exit(-1);
    }
    
    rlink[csl].si=simg[si]; rlink[csl].di=simg[di];
    rlink[csl].sx1=sx1; rlink[csl].sy1=sy1;
    rlink[csl].dx=dx;   rlink[csl].dy=dy;
    rlink[csl].angle=angle;
    rlink[csl].type=1;
    rlink[csl].stat=3;    
    break;
    
  
  
  }

 }

 printf("boo\n"); 
 fclose(F);
 return 1;
}



void read_files(char ** argv,int argc) {
 int a,b,c,d,x,y;
 int *xmax,*ymax;
 edget *edge;


 b=0;
 c=1;
 Ox=Oy=0;


 for(a=0;a<argc;a++) {
  if (!strcmp(argv[a],"/")) {
   c++;
   b=0;
 
  } else if (argv[a][0]==0) {
   b++;
  } else {
   Ot++;
   b++;
   if (b>Ox) Ox=b;
   if (c>Oy) Oy=c;
  }
 }

 printf("cols: %d  rows: %d\n",Ox,Oy);

 simg=malloc(sizeof(IMG *)*Ot);
 xmax=malloc(sizeof(int)*Ox);
 ymax=malloc(sizeof(int)*Oy); 
 bzero(xmax,sizeof(int)*Ox);
 bzero(ymax,sizeof(int)*Oy);
 
 b=c=0;
 d=0;
 for(a=0;a<argc;a++) {
  if (!strcmp(argv[a],"/")) {
   c++;
   b=0;
  } else if (argv[a][0]==0) {
   b++;
  } else {
 
   simg[d]=read_ppm(argv[a]);
   if (xmax[b]<simg[d]->sx) xmax[b]=simg[d]->sx;
   if (ymax[c]<simg[d]->sy) ymax[c]=simg[d]->sy;
   printf("b: %d c: %d\n",b,c);
   b++;   
   d++;
  }
 }
 
 

 x=y=20;
 
 d=0;
 b=c=0;
 for(a=0;a<argc;a++) {
  if (!strcmp(argv[a],"/")) {
   b=0;
   x=20;
   y+=20+ymax[c];
   c++;
  } else if (argv[a][0]==0) {
   b++;
   x+=20+xmax[c];
  } else {
   simg[d]->Tx=x;
   simg[d]->Ty=y;
   
   simg[d]->dx1=simg[d]->dx3=x;
   simg[d]->dy1=simg[d]->dy2=y;
   simg[d]->dx2=simg[d]->dx4=x+simg[d]->sx;
   simg[d]->dy3=simg[d]->dy4=y+simg[d]->sy;
   simg[d]->edgen=0;
    
  
   edge=edge_add(simg[d],0,0,0);
   edge=edge_add(simg[d],edge,simg[d]->sx,0);
   edge=edge_add(simg[d],edge,simg[d]->sx,simg[d]->sy);  
   edge=edge_add(simg[d],edge,0,simg[d]->sy);   
   x+=20+xmax[b];
   b++;   
   d++;
  }
 }
 
 Dxm=Dym=20;
 for(a=0;a<Ox;a++) Dxm+=xmax[a]+20;
 for(a=0;a<Oy;a++) Dym+=ymax[a]+20;
 
 Dxm1=Dxm;
 Dym1=Dym;
 
 free(xmax);
 free(ymax);




 Ml0=Ml=15;
 Mt0=Mt=15;
 Mr0=Mr=Dxm-15;
 Mb0=Mb=Dym-15;






}


