/*
 *   Reads and writes preferences to a file.
 */
#import <defaults/defaults.h>
#import "TVPrint.h"
#import <appkit/Window.h>
#import "PageView.h"
#import "ComScroll.h"
#import <appkit/Text.h>
#import <appkit/Font.h>
/*
 *   These are the variables we save.
 */
extern PageView *myPageView ;
extern real defhsize, defvsize, defhmarg, defvmarg ;
extern Boolean generatefonts, mocked ;
extern int debugon, paranoia ;
extern real userdpi[] ;
extern char defaultfont[] ;
extern char LastFormat[], CustomFormat[] ;
extern real possibmag[] ;
extern int strcmp() ;
extern long atol() ;
extern void upmock() ;
extern int getuid() ;
extern char *strcpy(), *strcat() ;
extern struct printVals printVals ;
struct windowStatus {
   NXRect r ;
   integer onscreen ;
} ;
static struct windowStatus windowRect =
    { { { -10.0, -10.0 }, { -10.0, -10.0 }}, 1} ;
static struct windowStatus consoleRect =
    { { { -10.0, -10.0 }, { -10.0, -10.0 }}, 0} ;
static struct windowStatus texRect =
    { { { -10.0, -10.0 }, { -10.0, -10.0 }}, 0} ;
static struct windowStatus commandRect =
    { { { -10.0, -10.0 }, { -10.0, -10.0 }}, 1} ;
struct prefs {
   char *keyword ;
   char *type ;
   void *addr ;
} prefs[] = {
   { "hsize", "real", &defhsize } ,
   { "vsize", "real", &defvsize } ,
   { "hmarg", "real", &defhmarg } ,
   { "vmarg", "real", &defvmarg } ,
   { "generatefonts", "boolean", &generatefonts } ,
   { "mocked", "boolean", &mocked } ,
   { "unzoomres", "real", userdpi } ,
   { "zoomres", "real", userdpi + 1 } ,
   { "customdpi", "integer", &printVals.customdpi } ,
   { "reversed", "boolean", &printVals.reversed },
   { "compressed", "boolean", &printVals.compressed },
   { "sync", "boolean", &printVals.sync },
   { "windowposition", "window", &(windowRect) },
   { "consoleposition", "window", &(consoleRect) },
   { "texposition", "window", &(texRect) },
   { "commandposition", "window", &(commandRect) },
   { "defaultfont", "string", defaultfont },
   { "defaultformat", "string", LastFormat },
   { "customformat", "string", CustomFormat },
   { "usecustom", "boolean", &printVals.customchosen },
   { NULL, NULL, NULL }
} ;

static NXDefaultsVector myDefaults = {
   { "hsize", "8.5" },
   { "vsize", "11" },
   { "hmarg", "1" },
   { "vmarg", "1" },
   { "generatefonts", "false" },
   { "mocked", "false" },
   { "unzoomres", "91.287102" },
   { "zoomres", "120" },
   { "customdpi", "1270" },
   { "reversed", "true" },
   { "compressed", "false" },
   { "sync", "true" },
   { "windowposition", "" },
   { "consoleposition", "" },
   { "texposition", "" },
   { "commandposition", "" },
   { "defaultfont", "" },
   { "defaultformat", "tex" },
   { "customformat", "amstex" },
   { "usecustom", "false" },
   { NULL, NULL }
} ;

extern void *error() ;
extern char temperrorbuf[] ;

void loadconfig() {
   register struct prefs *p ;
   register int i, j ;
   register real r, b, off, boff ;
   const char *val ;
   struct windowStatus *w ;

   NXRegisterDefaults("TeXview", myDefaults) ;
   for (p=prefs; p->keyword; p++) {
      val = NXGetDefaultValue("TeXview", p->keyword) ;
      if (val)
         switch (p->type[0]) {
case 'r':
            *(real *)(p->addr) = atof(val) ;
            break ;
case 'b':
            if (*val == 't' || *val == 'T' || *val == '1')
               *(Boolean *)(p->addr) = 1 ;
            else
               *(Boolean *)(p->addr) = 0 ;
            break ;
case 's':
            strcpy((char *)p->addr, val); 
            break ;
case 'i':
            *(integer *)(p->addr) = atol(val) ;
            break ;
case 'w':
            w = (struct windowStatus *)(p->addr) ;
            if (sscanf(val, "%f:%f:%f:%f:%ld", &(w->r.origin.x),
    &(w->r.origin.y), &(w->r.size.width), &(w->r.size.height),
    &(w->onscreen)) < 4)
               w->r.size.width = -10 ;
            break ;
         }
   }
   if (val=NXGetDefaultValue("TeXview", "debug"))
      debugon = *val - '0' ;
/* if (val=NXGetDefaultValue("TeXview", "paranoia"))
      paranoia = *val - '0' ; */
/*
 *   Now we check userdpi[] values for validity.
 */
   for (i=0; i<2; i++) {
      r = userdpi[i] ;
      if (r < 69.0)
         r = 69.0 ;
      else if (r > 1000.0)
         r = 189.0 ;
      b = 100.0 ;
      boff = 99.9 ;
      for (j = 17; j < 31; j++) {
         off = possibmag[j] - r ;
         if (off < 0)
            off = - off ;
         if (off < boff) {
            b = possibmag[j] ;
            boff = off ;
         }
      }
      userdpi[i] = b ;
   }
/*
 *   We load up the system defaults, if such exist.  We only
 *   are concerned with Printer and PrinterResolution.
 *
 *   Actually, we let the PrintPanel code do this.
 */
/* if (val = NXGetDefaultValue("System", "Printer"))
      strcpy(printVals.printername, val) ;
   if (val = NXGetDefaultValue("System", "PrinterResolution")) {
      if (strcmp(val, "400")==0) {
         printVals.seldpi = 1 ;
      } else if (strcmp(val, "300")==0) {
         printVals.seldpi = 0 ;
      } else {
         printVals.seldpi = 2 ;
         printVals.customdpi = atol(val) ;
      }
   } */
   upmock() ;
}

void configure() {
   static virgin = 1 ;
   if (virgin) {
      loadconfig() ;
      virgin = 0 ;
   }
}

static int lastwason ;
NXRect *initsizewindow(int which) {
   static char gotitonce[4] = { 0, 0, 0, 0 } ;
   struct windowStatus *w = &windowRect ;

   switch (which) {
      case 0: w = &windowRect ; break ;
      case 1: w = &consoleRect ; break ;
      case 2: w = &texRect ; break ;
      case 3: w = &commandRect ; break ;
      default: which = 0 ; break ;
   }
   configure() ;
   if (w->r.size.width > 10.0 && gotitonce[which] == 0) {
      gotitonce[which] = 1 ;
      lastwason = w->onscreen ;
      return &(w->r) ;
   }
   return 0 ;
}

int initWasOnScreen(void) {
   return lastwason ;
}

void saveconfig() {
   register struct prefs *p ;
   int i ;
   char val[1000] ;
   struct windowStatus *w ;
   id tw = [myPageView getTeX] ;

   [[myPageView window] getFrame:&windowRect.r] ;
   windowRect.onscreen = [[myPageView window] isVisible] ;
   [[(ComScroll *)[myPageView getConsole] window] getFrame:&consoleRect.r] ;
   consoleRect.onscreen = [[[myPageView getConsole] window] isVisible] ;
   [[tw window] getFrame:&texRect.r] ;
   texRect.onscreen = [[tw window] isVisible] ;
   [(Window *)[myPageView getCommand] getFrame:&commandRect.r] ;
   commandRect.onscreen = [[myPageView getCommand] isVisible] ;
   [[(ComScroll *)[myPageView getTeX] window] getFrame:&texRect.r] ;
   sprintf(defaultfont, "%s:%g",
                     [[[tw text] font] name], [[[tw text] font] pointSize]) ;
   for (p = prefs, i=0; p->keyword; p++, i++) {
      switch (p->type[0]) {
case 'r' : sprintf(val, "%g", *(real *)p->addr) ; break ;
case 'b' : sprintf(val, "%s", (*(Boolean *)(p->addr) ? "true" : "false")) ; break ;
case 's' : if (*(char *)(p->addr))
                    strcpy(val, (char *)p->addr) ; else val[0] = 0 ; break ;
case 'i' : sprintf(val, "%ld", *(integer *)p->addr) ; break ;
case 'w' : w = (struct windowStatus *)(p->addr) ;
           sprintf(val, "%g:%g:%g:%g:%ld", w->r.origin.x, w->r.origin.y, 
       w->r.size.width, w->r.size.height, w->onscreen) ;
           break ;
      }
/*
 *   Only keep non-default defaults around.
 */
      if (strcmp(val, myDefaults[i].value) == 0)
         NXRemoveDefault("TeXview", p->keyword) ;
      else
         NXWriteDefault("TeXview", p->keyword, val) ;
   }
}
