/* input-output functions for SSS */
/* Tue,30 Jul 1991 */
/* Copyright C.T.Stretch 1991 */

#include "ssshdr.h"

BOOL io_save(char *fn,void *part)
{ int x,y,nc,nr;
  int x0=0,x1=ncols,y0=0,y1=nrows;
  entry *cb;
  FILE *out=fopen(fn,"w");
  if(!out) return FALSE;
  if(part)
  { x0=sx0;x1=sx1+1;y0=sy0;y1=sy1+1;
  }
  nc=x1-x0;nr=y1-y0;
  fwrite(&nc,4,1,out);
  fwrite(&nr,4,1,out);
  fwrite(width+x0,4,nc,out);
  for(y=y0;y<y1;y++) for(x=x0;x<x1;x++)
  { cb=sheet[x+NCOLS*y];
    if(cb)
    { fputs(&(cb->c),out);putc('\n',out);
      fwrite(cb,4,1,out);
    }
    else putc(0,out);
  }
  fclose(out);
  sprintf(buf,"settype %s %X",fn,SSSTYPE);
  system(buf);
  strcpy(fname,fn);
  return TRUE;
}


static void readentries(int nc,int nr,int xx,int y,FILE *file)
{ int x,c,f;
  for(;nr>0;nr--,y++) for(x=xx;x<xx+nc;x++)
  if((c=getc(file))!=0)
  { ungetc(c,file);
    fgets(buf,BUFLEN,file);
    buf[strlen(buf)-1]=0;
    fread(&f,4,1,file);
    if((x<ncols)&&(y<nrows)) sheet_getentry(x,y,f);
  }
}

void io_merge()
{ FILE *file;
  int nc,nr,w[NCOLS],x;
  char *fn;
  int ftype=xferrecv_checkinsert(&fn);
  if(ftype!=SSSTYPE) return;
  file=fopen(fn,"r");
  if(!file) return;
  fread(&nc,4,1,file);
  fread(&nr,4,1,file);
  if(nc>=NCOLS) nc=NCOLS;
  fread(w,4,nc,file);
  for(x=0;x<nc;x++)
  { if(x+ex0>=ncols) break;
    if(w[x]>width[ex0+x]) width[ex0+x]=w[x];
  }
  readentries(nc,nr,ex0,ey0,file);
  xferrecv_insertfileok();
  fclose(file);
  if(autox) sheet_change();
}


void io_load(char* fn)
{ FILE *file;
  int nr;
  file=fopen(fn,"r");
  if(!file) return;
  fread(&ncols,4,1,file);
  fread(&nr,4,1,file);
  if(ncols>=NCOLS) werr(1,"Bad file");
  sheet_clear(nr);
  fread(width,4,ncols,file);
  readentries(ncols,nr,0,0,file);
  fclose(file);
  strcpy(fname,fn);
  if(autox) sheet_change();
}


static int form()
{ switch(buf[0])
  { case '+':case '-':case '.':goto number;
    default:if(isdigit(buf[0])) goto number;
  }
  return FSTRING;
  number:if(strpbrk(buf,"eE")) return FEXP;
  if(strchr(buf,'.')) return F2DP;
  return FINT;
}

static void readtext(char *fn)
{ FILE *file;
  int c,nr,nc=10,x=0,y=0;
  int p=0;
  file=fopen(fn,"r");
  if(!file) return;
  for(nr=1;(c=fgetc(file))!=EOF;) if(c=='\n') nr++;
  sheet_clear(nr);
  rewind(file);
  for(;;) switch(c=fgetc(file))
  { case '\n':x=0;y++;
    case ' ':case ',':case '\r':case '\t':
             if(p)
             { if((x<NCOLS)&&(y<nrows))
               { buf[p]=0;
                 sheet_getentry(x++,y,form());
               if(x>nc) nc=x;
               }
               p=0;
             }
             break;
     case EOF:goto eof;
    default:buf[p++]=c;if(p>=BUFLEN) p=0;break;
  }
  eof:xferrecv_insertfileok();
  fclose(file);
  strcpy(fname,"Import");
  ncols=nc;
  if(autox) sheet_change();
}

BOOL io_read(BOOL text)
{ FILE *file;
  char *fn;
  int nc,nr;
  int ftype=xferrecv_checkinsert(&fn);
  if(ftype==0xFFF) if(text) {readtext(fn);return TRUE;} else return FALSE;
  if(ftype!=SSSTYPE) return FALSE;
  file=fopen(fn,"r");
  if(!file) return FALSE;
  fread(&nc,4,1,file);
  fread(&nr,4,1,file);
  if(nc>=NCOLS) nc=NCOLS;
  sheet_clear(nr);
  ncols=nc;
  fread(width,4,nc,file);
  readentries(nc,nr,0,0,file);
  xferrecv_insertfileok();
  fclose(file);
  strcpy(fname,fn);
  if(autox) sheet_change();
  return TRUE;
}

static void prcell(FILE *file,int x,int y)
{ entry *ce=sheet[x+y*NCOLS];
  int n=width[x]-1;
  char num[32];
  if(ce)
  { if(ce->p) fprintf(file,"%-*.*s",n,n,"P???????");
    else
    { if(ce->a) fprintf(file,"%-*.*s",n,n,"A!!!!!!!");
      else switch(ce->t)
      { case FSTRING:
        case FLONG:fprintf(file,"%-*.*s",n,n,&(ce->c));break;
        case FINT:sprintf(num,"%.0f",ce->v);
                  fprintf(file,"%-*.*s",n,n,num);break;
        case F2DP:sprintf(num,"%.2f",ce->v);
                  fprintf(file,"%-*.*s",n,n,num);break;
        case F4DP:sprintf(num,"%.4f",ce->v);
                  fprintf(file,"%-*.*s",n,n,num);break;
        case FEXP:sprintf(num,"%.4e",ce->v);
                  fprintf(file,"%-*.*s",n,n,num);break;
      }
    }
  }
  else fprintf(file,"%*.*s",n,n,"");
}

BOOL io_pr(char *fn,void *v)
{ FILE *file;
  int x,xx=0,y,pw,s,n=strlen(sep);
  int x0=sx0;
  BOOL rep;
  v=v;
  while(!width[x0]) x0++;
  if(x0>sx1) return FALSE;
  file=fopen(fn,"w");
  if(!file) return FALSE;
  rep=repfirst&x0<sx1;
  pw=(rep)?prwidth-width[x0]-n+1:prwidth;
  x=x0;if(rep)x++;
  while(x<=sx1)
  { for(y=sy0;y<=sy1;y++)
    { xx=x;
      if(rep){ prcell(file,x0,y);fputs(sep,file);}
      while(!width[xx]) xx++;if(xx>sx1)break;
      s=pw+width[xx]-1;prcell(file,xx++,y);
      while(!width[xx]) xx++;
      while(xx<=sx1&&s>width[xx]+n-1)
      { fputs(sep,file);
        s-=width[xx]+n-1;
        prcell(file,xx++,y);
        while(!width[xx]) xx++;
      }
      fputc('\n',file);
    }
    x=xx;
    fputc('\n',file);
  }
  fclose(file);
  return TRUE;
}
