#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc,char *argv[])
{
  int  n,nmax,irs,nn,m,dn[2],k,kmax,kk,kkmax,mode;
  FILE *fp,*fpt;
  char fname[128],st[64][8],pos1[64][128],pos2[64][128],pos2s[64][128],buf[512],*ret,mod[16],mod2[4],com[64][512],com2[64][512];

  if(argc != 3){
    fprintf(stderr,"Usage: %s exposure_list OBS_MODE(CBS BS or BS+)\n",argv[0]);
    exit(0);
  }

  if(strcmp(argv[2],"BS")==0) mode=0;
  else if(strcmp(argv[2],"BS+")==0) mode=1;
  else if(strcmp(argv[2],"CBS")==0) mode=2;
  else{
    fprintf(stderr,"OBS_MODE must be 'CBS' 'BS' or 'BS+' (%s).\n",argv[2]);
    fprintf(stderr,"BS+: Normsl Beam Switch mode for bright object\n");
    exit(0);
  }
  if(strncmp(argv[1],"irs1",4)==0) irs=0;
  else if(strncmp(argv[1],"irs2",4)==0) irs=1;
  else{
    fprintf(stderr,"The name of exposure_list should be start from 'irs1' or 'irs2' (%s).\n",argv[1]);
    exit(1);
  }

  if((fp = fopen(argv[1],"r")) == NULL){
    fprintf(stderr,"Cannot open %s\n",argv[1]);
    exit(1);
  }

  n=0;
  while(!feof(fp)){
    if(fgets(buf,sizeof(buf),fp)==NULL) break;
    if(strncmp(buf,"#",1)==0) continue;
    strcpy(pos2s[n],"");
    if(sscanf(buf,"%s %s %s %s",st[n],pos1[n],pos2[n],pos2s[n]) < 3){
      fprintf(stderr,"Wrong format: %s",buf);
      exit(1);
    }
    if(strlen(pos2s[n]) == 0){
      if((ret = strrchr(pos2[n], '/')) != NULL) sprintf(buf,"%ssub.fits",ret+1);
      else sprintf(buf,"%ssub.fits",pos2[n]);
      //fprintf(stderr,"%s\n",buf);
      if((fpt=fopen(buf,"rb"))!=NULL){
	sprintf(pos2s[n],"%s",buf);
	if((ret = strrchr(pos2s[n], '.')) != NULL) *(ret)='\0';
	fclose(fpt);
      }    
    }
    n++;
  }
  fclose(fp);
  nmax=n;

  sscanf(argv[1],"%s",fname);
  ret = strrchr(fname, '_');
  strcpy(mod,ret);
  if(strncmp(mod,"_lr",3)==0) strcpy(mod2,"s");else strcpy(mod2,"");
  *(ret)='\0';
  if((ret = strrchr(mod, '.')) != NULL) *(ret)='\0';

  k=0;kk=0;
  for(n=0;n<nmax;n++){
    if(strcmp(pos1[n],"NONE")==0 && strcmp(pos2[n],"NONE")==0) continue;

    nn=0;
    for(m=0;nn<2;m++){
      if(m==nmax*2){
	if(nn) dn[nn]=999;
	else{
	  fprintf(stderr,"At least one image is required for pos.B\n");
	  exit(1);
	}
      }else{
	dn[nn]=(1-m%2*2)*((m+1)/2);
	if(n+dn[nn]<0 || n+dn[nn]>=nmax) continue;
	if(strcmp(pos2[n+dn[nn]],"NONE")==0) continue;
      }
      nn++;
    }
    if(strcmp(pos1[n],"NONE")!=0){
      if(dn[1]!=999){
	if(strlen(pos2s[n+dn[1]]) > 0) sprintf(com[k++],"!../subtract %s.fits %s.fits %s%s%+d%s.fits %s.fits\n",pos1[n],pos2[n+dn[1]],fname,st[n],dn[1],mod,pos2s[n+dn[1]]);
	else sprintf(com[k++],"!../subtract %s.fits %s.fits %s%s%+d%s.fits\n",pos1[n],pos2[n+dn[1]],fname,st[n],dn[1],mod);
      }
      if(dn[0]==0){
	if(strlen(pos2s[n]) > 0) sprintf(com[k++],"!../subtract %s.fits %s.fits %s%s%s.fits %s.fits\n",pos1[n],pos2[n],fname,st[n],mod,pos2s[n]);
	else sprintf(com[k++],"!../subtract %s.fits %s.fits %s%s%s.fits\n",pos1[n],pos2[n],fname,st[n],mod);
      }else{
	if(strlen(pos2s[n+dn[0]]) > 0)sprintf(com[k++],"!../subtract %s.fits %s.fits %s%s%+d%s.fits %s.fits\n",pos1[n],pos2[n+dn[0]],fname,st[n],dn[0],mod,pos2s[n+dn[0]]);
	else sprintf(com[k++],"!../subtract %s.fits %s.fits %s%s%+d%s.fits\n",pos1[n],pos2[n+dn[0]],fname,st[n],dn[0],mod);
      }
      if(dn[1]==999){
	if(dn[0]==0){
	  if(mode==2){
	    sprintf(com2[kk++],"imdel %s%s1%s.fits\n",fname,st[n],mod); 
	    sprintf(com2[kk++],"imcopy %s%s%s.fits %s%s1%s.fits\n",fname,st[n],mod,fname,st[n],mod);
	  }
	}else{
	  sprintf(com2[kk++],"imdel %s%s%s.fits\n",fname,st[n],mod); 
	  sprintf(com2[kk++],"imcopy %s%s%+d%s.fits %s%s%s.fits\n",fname,st[n],dn[0],mod,fname,st[n],mod);
	}
      }else{
	if(dn[0]==0){
	  if(mode==2){
	    sprintf(com2[kk++],"!../skysub %s%s%s.fits %s%s%+d%s.fits %s%s1%s.fits\n",fname,st[n],mod,fname,st[n],dn[1],mod,fname,st[n],mod);
	  }else{
	    sprintf(com2[kk++],"!../skysub %s%s%s.fits %s%s%+d%s.fits %s%s%s.fits\n",fname,st[n],mod,fname,st[n],dn[1],mod,fname,st[n],mod);
	  }
	}
	else{
	  sprintf(com2[kk++],"!../skysub %s%s%+d%s.fits %s%s%+d%s.fits %s%s%s.fits\n",fname,st[n],dn[0],mod,fname,st[n],dn[1],mod,fname,st[n],mod);
	}
      }
    }
    
    if(mode==2){
    nn=0;
    for(m=0;nn<2;m++){
      if(m==nmax*2){
        if(nn) dn[nn]=999;
        else{
          fprintf(stderr,"At least one image is required for pos.A\n");
          exit(1);
        }
      }else{
        dn[nn]=(m%2*2-1)*((m+1)/2);
        if(n+dn[nn]<0 || n+dn[nn]>=nmax) continue;
	if(strcmp(pos1[n+dn[nn]],"NONE")==0) continue;
      }
      nn++;
    }
    if(strcmp(pos2[n],"NONE")!=0){
      if(dn[1]!=999){
	if(strlen(pos2s[n]) > 0) sprintf(com[k++],"!../subtract %s.fits %s.fits %s%s%+d%s.fits %s.fits\n",pos1[n+dn[1]],pos2[n],fname,st[n+dn[1]],-dn[1],mod,pos2s[n]);
	else sprintf(com[k++],"!../subtract %s.fits %s.fits %s%s%+d%s.fits\n",pos1[n+dn[1]],pos2[n],fname,st[n+dn[1]],-dn[1],mod);
      }
      if(dn[0]==0){
	if(strlen(pos2s[n]) > 0) sprintf(com[k++],"!../subtract %s.fits %s.fits %s%s%s.fits %s.fits\n",pos1[n],pos2[n],fname,st[n],mod,pos2s[n]);
	else sprintf(com[k++],"!../subtract %s.fits %s.fits %s%s%s.fits\n",pos1[n],pos2[n],fname,st[n],mod);
      }else{
	if(strlen(pos2s[n]) > 0) sprintf(com[k++],"!../subtract %s.fits %s.fits %s%s%+d%s.fits %s.fits\n",pos1[n+dn[0]],pos2[n],fname,st[n+dn[0]],-dn[0],mod,pos2[n]);
	else sprintf(com[k++],"!../subtract %s.fits %s.fits %s%s%+d%s.fits\n",pos1[n+dn[0]],pos2[n],fname,st[n+dn[0]],-dn[0],mod);
      }
      if(dn[1]==999){
	if(dn[0]==0){
          sprintf(com2[kk++],"imdel %s%s2%s.fits\n",fname,st[n],mod);
	  sprintf(com2[kk++],"imcopy %s%s%s.fits %s%s2%s.fits\n",fname,st[n+dn[0]],mod,fname,st[n],mod);
	}else{
          sprintf(com2[kk++],"imdel %s%s%s.fits\n",fname,st[n],mod);
	  sprintf(com2[kk++],"imcopy %s%s%+d%s.fits %s%s%s.fits\n",fname,st[n+dn[0]],-dn[0],mod,fname,st[n],mod);
	}
      }else{
	if(dn[0]==0){
	  sprintf(com2[kk++],"!../skysub %s%s%s.fits %s%s%+d%s.fits %s%s2%s.fits\n",fname,st[n],mod,fname,st[n+dn[1]],-dn[1],mod,fname,st[n],mod);
	}
	else{
	  sprintf(com2[kk++],"!../skysub %s%s%+d%s.fits %s%s%+d%s.fits %s%s%s.fits\n",fname,st[n+dn[0]],-dn[0],mod,fname,st[n+dn[1]],-dn[1],mod,fname,st[n],mod);
	}
      }
    }
    }
  }

  fprintf(stderr,"Write mkscr.cl ... ");
  if((fp = fopen("mkscr.cl","w")) == NULL){
    fprintf(stderr,"Cannot open mkscr.cl\n");
    exit(1);
  }
  kmax=k;kkmax=kk;
  for(k=0;k<kmax;k++){
    nn=1;
    for(n=k+1;n<kmax;n++){
      if(strcmp(com[k],com[n])==0) nn=0;
    }
    if(nn) fprintf(fp,"%s",com[k]);
  }
  for(kk=0;kk<kkmax;kk++) fprintf(fp,"%s",com2[kk]);
  fclose(fp);
  fprintf(stderr,"OK\n");

  for(n=0;n<nmax;n++){
    printf("#Set '%s'\n",st[n]);
    if(strcmp(pos1[n],"NONE")==0 && strcmp(pos2[n],"NONE")==0) continue;
    if(strcmp(pos1[n],"NONE")==0 && mode!=2) continue;
    if(strcmp(pos1[n],"NONE")==0 || strcmp(pos2[n],"NONE")==0 || mode!=2){
      printf("#First Step (Bad pix Correction and Transformation)\n");
      if(irs) printf("!sed -e 's/FMSAfileno/%s%s%s/g' ../redscr1%s_ | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' > tmpscr\n",fname,st[n],mod,mod2,mod+1);
      else    printf("!sed -e 's/FMSAfileno/%s%s%s/g' ../redscr1%s | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' > tmpscr\n",fname,st[n],mod,mod2,mod+1);
      printf("#cl < tmpscr\n");
      printf("#Residual Sky Subtraction and Rearrangement\n");
      printf("imarith %s%s_mask.fits * 1. %s%s%s_mask.fits\n",fname,mod,fname,st[n],mod);
      if(mode==1){
	if(irs) printf("!sed -e 's/FMSAfileno/%s%s%s/g' ../redscr2%s | sed -e 's/irs1/irs2/g' | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' | sed -e 's/high_r=2 low_r=2/high_r=1.5 low_r=3/g' > tmpscr\n",fname,st[n],mod,mod2,mod+1);
	else    printf("!sed -e 's/FMSAfileno/%s%s%s/g' ../redscr2%s | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' | sed -e 's/high_r=2 low_r=2/high_r=1.5 low_r=3/g' > tmpscr\n",fname,st[n],mod,mod2,mod+1);
      }else{
	if(irs) printf("!sed -e 's/FMSAfileno/%s%s%s/g' ../redscr2%s | sed -e 's/irs1/irs2/g' | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' > tmpscr\n",fname,st[n],mod,mod2,mod+1);
	else    printf("!sed -e 's/FMSAfileno/%s%s%s/g' ../redscr2%s | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' > tmpscr\n",fname,st[n],mod,mod2,mod+1);
      }
      printf("cl < tmpscr\n");
      printf("#Secondary Bad pix Correction\n");
      printf("!sed -e 's/FMSAfileno/%s%s%sxp/g' ../redscrb > tmpscr\n",fname,st[n],mod);
      printf("cl < tmpscr\n");
    }else{
      printf("#First Step (Bad pix Correction and Transformation)\n");
      if(irs){
	printf("!sed -e 's/FMSAfileno/%s%s1%s/g' ../redscr1%s_ | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' > tmpscr\n",fname,st[n],mod,mod2,mod+1);
	printf("!sed -e 's/FMSAfileno/%s%s2%s/g' ../redscr1%s_ | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' >> tmpscr\n",fname,st[n],mod,mod2,mod+1);
      }
      else{
	printf("!sed -e 's/FMSAfileno/%s%s1%s/g' ../redscr1%s | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' > tmpscr\n",fname,st[n],mod,mod2,mod+1);
	printf("!sed -e 's/FMSAfileno/%s%s2%s/g' ../redscr1%s | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' >> tmpscr\n",fname,st[n],mod,mod2,mod+1);
      }
      printf("#cl < tmpscr\n");
      printf("#Residual Sky Subtraction and Rearrangement\n");
      printf("imarith %s%s_mask.fits * 1. %s%s1%s_mask.fits\n",fname,mod,fname,st[n],mod);
      printf("imarith %s%s_mask.fits * 1. %s%s2%s_mask.fits\n",fname,mod,fname,st[n],mod);
      if(mode==1){
	if(irs){
	  printf("#!sed -e 's/FMSAfileno/%s%s1%s/g' ../redscr2%s | sed -e 's/irs1/irs2/g' | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' | sed -e 's/high_r=2 low_r=2/high_r=1.5 low_r=3/g' > tmpscr\n",fname,st[n],mod,mod2,mod+1);
	  printf("#!sed -e 's/FMSAfileno/%s%s2%s/g' ../redscr2%s | sed -e 's/irs1/irs2/g' | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' | sed -e 's/high_r=2 low_r=2/high_r=1.5 low_r=3/g' >> tmpscr\n",fname,st[n],mod,mod2,mod+1);
	}
	else{
	  printf("#!sed -e 's/FMSAfileno/%s%s1%s/g' ../redscr2%s | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' | sed -e 's/high_r=2 low_r=2/high_r=1.5 low_r=3/g' > tmpscr\n",fname,st[n],mod,mod2,mod+1);
	  printf("#!sed -e 's/FMSAfileno/%s%s2%s/g' ../redscr2%s | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' | sed -e 's/high_r=2 low_r=2/high_r=1.5 low_r=3/g' >> tmpscr\n",fname,st[n],mod,mod2,mod+1);
	}
      }else{
	if(irs){
	  printf("!sed -e 's/FMSAfileno/%s%s1%s/g' ../redscr2%s | sed -e 's/irs1/irs2/g' | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' > tmpscr\n",fname,st[n],mod,mod2,mod+1);
	  printf("!sed -e 's/FMSAfileno/%s%s2%s/g' ../redscr2%s | sed -e 's/irs1/irs2/g' | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' >> tmpscr\n",fname,st[n],mod,mod2,mod+1);
	}
	else{
	  printf("!sed -e 's/FMSAfileno/%s%s1%s/g' ../redscr2%s | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' > tmpscr\n",fname,st[n],mod,mod2,mod+1);
	  printf("!sed -e 's/FMSAfileno/%s%s2%s/g' ../redscr2%s | sed -e 's/BAND/%s/g' | sed -e 's/SHIFT/0/g' >> tmpscr\n",fname,st[n],mod,mod2,mod+1);
	}
      }
      printf("cl < tmpscr\n");
      printf("#Secondary Bad pix Correction\n");
      printf("!sed -e 's/FMSAfileno/%s%s1%sxp/g' ../redscrb > tmpscr\n",fname,st[n],mod);
      printf("!sed -e 's/FMSAfileno/%s%s2%sxp/g' ../redscrb >> tmpscr\n",fname,st[n],mod);
      printf("cl < tmpscr\n");
      printf("!../mergepair %s%s1%sxpb.fits %s%s2%sxpb.fits %s_pair.tbl %s%s%sxpb.fits\n",fname,st[n],mod,fname,st[n],mod,fname,fname,st[n],mod);
      printf("!../mergepair %s%s1%sxp_bpm.fits %s%s2%sxp_bpm.fits %s_pair.tbl %s%s%sxp_bpm.fits\n",fname,st[n],mod,fname,st[n],mod,fname,fname,st[n],mod);
      printf("displ %s%s%sxpb 1\n",fname,st[n],mod);
    }
  }
  return(0);
}
