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

#include "tboxlibs/flex.h"
#include "os.h"
#include "swis.h"

#include "mystring.h"
#include "fs.h"
#include "options.h"
#include "msgtrans.h"

#include "debug.h"

#define CMOS_LOC_DESKTOP 28
#define CMOS_NO_FILERACTION  4
#define CMOS_DRAGASPRITE     2

#define CMOS_LOC_FLAGS 0xc6
#define CMOS_FORCE   (1<<4)
#define CMOS_CONFIRM (1<<5)
#define CMOS_VERBOSE (1<<6)
#define CMOS_NEWER   (1<<7)

typedef enum {
  __OPTUP_NOUPDATE,
  __OPTUP_UPDATE,
  __OPTUP_NOFILE
} __optup;

static __optup __options_update_pending=__OPTUP_UPDATE;
static int __options_state=0;

unsigned int options_get(void)
{
  int loc,value;
  _kernel_oserror *e;
  
  // get fileraction state and the dragasprite state from CMOS
  loc=CMOS_LOC_DESKTOP;
  value=0;
  os_byte(161,&loc,&value);
  __options_state=(__options_state & ~__OPTIONS_DRAGASPRITE) | (__OPTIONS_DRAGASPRITE * ((value&CMOS_DRAGASPRITE)!=0));
  __options_state=(__options_state & ~__OPTIONS_FILERACTION) | (__OPTIONS_FILERACTION * ((value&CMOS_NO_FILERACTION)==0));

  // do we need to update from the FlrSetup file?
  if (__options_update_pending==__OPTUP_UPDATE) {
    // is there a FlrSetup file at all?
    int type,length;
    e=_swix(OS_File,_INR(0,1)|_OUT(0)|_OUT(4),5,"Choices:Boot.Tasks.FlrSetup",&type,&length);
    if (e || type!=1) {
      // no - read CMOS instead
      __options_update_pending=__OPTUP_NOFILE;
    } else {
      // yes - see if we can load and parse it
      char *filedata,*ptr;
      if (flex_alloc((flex_ptr)&filedata,length+1)) {
        // +1 so we can zero terminate the file
        _swix(OS_File,_INR(0,3),255,"Choices:Boot.Tasks.FlrSetup",filedata,0);
        *(filedata+length)=0;

        // all off to start with
        __options_state=__options_state & ~(__OPTIONS_CONFIRMCOPY | __OPTIONS_CONFIRMDELETE | __OPTIONS_FORCE | __OPTIONS_VERBOSE | __OPTIONS_NEWER | __OPTIONS_FASTER);

        for (ptr=filedata;ptr<filedata+length;ptr++) {
          *ptr=toupper(*ptr);
        }

        // is there the correct command...?
        if ((ptr=strstr(filedata,"FILER_OPTIONS"))!=0) {
          // find the end of the command
          char *end;
          for (end=ptr;*end>=32;end++); // we already null terminated it
          *end=0; // truncate to the endpoint
          // look for the options now
          if (strstr(ptr,"-CONFIRMALL")) __options_state|=__OPTIONS_CONFIRMCOPY | __OPTIONS_CONFIRMDELETE;
          if (strstr(ptr,"-CONFIRMDELETES")) __options_state|=__OPTIONS_CONFIRMDELETE;
          if (strstr(ptr,"-VERBOSE")) __options_state|=__OPTIONS_VERBOSE;
          if (strstr(ptr,"-NEWER")) __options_state|=__OPTIONS_NEWER;
          if (strstr(ptr,"-FORCE")) __options_state|=__OPTIONS_FORCE;
          if (strstr(ptr,"-FASTER")) __options_state|=__OPTIONS_FASTER;
        } else {
          // no options present, so assume all off
        }
        flex_free((flex_ptr)&filedata);
        __options_update_pending=__OPTUP_NOUPDATE;
      } else {
        // can't load, try CMOS instead
        msgtrans_report_error("OptsMem");
        __options_update_pending=__OPTUP_NOFILE;
      }
    }
  }

  if (__options_update_pending==__OPTUP_NOFILE) {
    // read CMOS instead
    loc=CMOS_LOC_FLAGS;
    value=0;
    os_byte(161,&loc,&value);

    __options_state=(__options_state & ~__OPTIONS_CONFIRMCOPY) | (__OPTIONS_CONFIRMCOPY * ((value&CMOS_CONFIRM)!=0));
    __options_state=(__options_state & ~__OPTIONS_CONFIRMDELETE) | (__OPTIONS_CONFIRMDELETE * ((value&CMOS_CONFIRM)!=0));
    __options_state=(__options_state & ~__OPTIONS_FORCE) | (__OPTIONS_FORCE * ((value&CMOS_FORCE)!=0));
    __options_state=(__options_state & ~__OPTIONS_VERBOSE) | (__OPTIONS_VERBOSE * ((value&CMOS_VERBOSE)!=0));
    __options_state=(__options_state & ~__OPTIONS_NEWER) | (__OPTIONS_NEWER * ((value&CMOS_NEWER)!=0));
    // faster remains off
    __options_state=(__options_state & ~__OPTIONS_FASTER);
  }
  
  return __options_state;
}

void options_test_flrsetup(char *fs,char *path)
{
  char *canon_name;
  // test path to see if it matches the choices for flrsetup
  if (!fs_canon("Choices:Boot.Tasks.FlrSetup",&canon_name)) return;

  if (strncasecmp(canon_name,fs,strlen(fs))!=0) {
    // FS is different
    flex_free((flex_ptr)&canon_name);
    return;
  }

  if (*(canon_name+strlen(fs))!=':') {
    // FS different
    flex_free((flex_ptr)&canon_name);
    return;
  }

  if (strcasecmp(canon_name+strlen(fs)+1,path)==0) {
    // a match!
    __options_update_pending=__OPTUP_UPDATE;
  }
  
  flex_free((flex_ptr)&canon_name);

}
