/*

  these are how I used to do the config files..  they're much quicker now...


*/

V_ERROR  __asm __saveds LIBHBBS_LoadConfig(register __a0 struct CfgFileData *cfgfile, register __a1 UBYTE *filename)
{
  BPTR FH;
  struct FileInfoBlock *FIB=NULL;
  V_ERROR error=ERR_NO_ERROR;
  LONG nr; //num bytes read!

  if (!(FH=Open(filename,MODE_OLDFILE)))
  {
    error=LIBHBBS_LogError(BBSGlobal->ErrorLogFile,ERR_ERROR_OPENING,filename,TYPE_FATAL);
  }
  else // opened ok.
  {
    if (FIB=(struct FileInfoBlock *)AllocVec(sizeof(struct FileInfoBlock),MEMF_PUBLIC))
    {
      ExamineFH(FH,FIB);
      cfgfile->Length=FIB->fib_Size;
      if (cfgfile->Data=AllocVec(cfgfile->Length,MEMF_PUBLIC))
      {
        if ((nr=Read(FH,cfgfile->Data,cfgfile->Length))!=cfgfile->Length)
        {
          FreeVec(cfgfile->Data);
          cfgfile->Data=NULL;
          cfgfile->Length=0;
          error=LIBHBBS_LogError(BBSGlobal->ErrorLogFile,ERR_ERROR_READING,filename,TYPE_CRITICAL);
        }
      }

      FreeVec(FIB);
    } else error=TYPE_MEMORY;
    Close(FH);
  }
  return(error);
}

void  __asm __saveds  LIBHBBS_FlushConfig(register __a0 struct CfgFileData *cfgfile)
{
  if (cfgfile->Data) // just a smidgin of error checking... :-)
  {
    FreeMem(cfgfile->Data,cfgfile->Length);
    cfgfile->Data=NULL;
  }
  cfgfile->Length=0;
}

V_SMALLNUM  __asm __saveds LIBHBBS_GetSetting(register __a0 struct CfgFileData *cfgfile,register __a1 void **result,register __d0 V_FLAGS optiontype,register __a2 V_STRING optionstr,register __d1 V_BOOL multi)
{

  // Now this is a beauty of a routine!

  V_BIGNUM linenum=0;
  V_BOOL done,nearlydone;
  V_SMALLNUM found=0;
  LONG filepos=0,bufferpos;
  V_STRING buffer;
  V_STRING ItemName;
  V_STRING Params;
  V_STRING CompareStr;
  struct Node *node;

  if (buffer=AllocMem(BIG_STR,MEMF_PUBLIC))
  {
    if (ItemName=AllocMem(BIG_STR,MEMF_PUBLIC))
    {
      if (Params=AllocMem(BIG_STR,MEMF_PUBLIC))
      {
        if (CompareStr=AllocMem(BIG_STR,MEMF_PUBLIC))
        {
          do
          {
            bufferpos=0;
            done=FALSE;
            nearlydone=FALSE; // :-) love those variable names! :-)
            do
            {
              if (cfgfile->Data[filepos]=='\r' || cfgfile->Data[filepos]=='\n')
              {
                nearlydone=TRUE;
                filepos++;
              }
              else
              {
                if (nearlydone)
                {
                  done=TRUE;
                }
                else
                {
                  buffer[bufferpos]=cfgfile->Data[filepos];
                  filepos++;
                  bufferpos++;
                }
              }
            } while (filepos<cfgfile->Length && !done && bufferpos<BIG_STR-2); // 1 for null and 1 more cos we still have to add the null
            buffer[bufferpos]=0;

            linenum++;

            LIBStripComments(buffer);
            LIBStripSpaces(buffer);
            LIBGetItem(ItemName,buffer);
            LIBGetParams(Params,buffer);
            if (ItemName[0])
            {
              if (multi==OPT_MULTI)
              {
                sprintf(CompareStr,"%s_%d",optionstr,found+1);
              }
              else strcpy(CompareStr,optionstr);


              if (stricmp(CompareStr,ItemName)==0)
              {
                switch(optiontype)
                {
                  case VTYPE_STRING:
                    if (*result!=NULL) LIBFreeStr(*result);
                    *result=(V_STRING *)LIBDupStr(Params);
                    found++;
                    break;
                  case VTYPE_BOOL:
                    *result=(V_BOOL *)LIBCheckBoolean(Params);
                    found++;
                    break;
                  case VTYPE_BIGNUM:
                    *result=(V_BIGNUM *)atoi(Params);
                    found++;
                    break;
                  case VTYPE_SMALLNUM:
                    *result=(V_SMALLNUM *)atoi(Params);
                    found++;
                    break;
                  case VTYPE_STRINGLIST:
                    // free existing stringlist if present

                    if ((found==0) && (*result))
                    {
                      LIBFreeStrList((V_STRINGLIST)*result);
                    }
                    if (!(*result))
                    {
                      if(*result=AllocMem(sizeof (struct List),MEMF_PUBLIC))
                      {
                        NewList((struct List*)*result);
                      }
                    }
                    if (*result) // allocated new list ok ?
                    {
                      if (node=AllocMem(sizeof(struct Node),MEMF_PUBLIC))
                      {
                        if (!(node->ln_Name=LIBDupStr(Params)))
                        {
                          FreeMem(node,sizeof(struct Node));
                        }
                        else
                        {
                          AddTail((struct List *)*result,node);
                          found++;
                        }
                      }
                    }
                }
              }
            }
          } while (filepos<cfgfile->Length && ((multi==OPT_SINGLE && !found) || (multi==OPT_MULTI)));
          FreeMem(CompareStr,BIG_STR);
        }
        FreeMem(Params,BIG_STR);
      }
      FreeMem(ItemName,BIG_STR);
    }
    FreeMem(buffer,BIG_STR);
  }
  return(found);
}
