/*
 * config.c   V1.3
 *
 * configuration file handling
 *
 * (c) 1991 by Stefan Becker
 *
 */
#include "ToolManager.h"

/* Keywords in the configuration file, must end with a ':'!! */
static char IconKey[]="ICON:";
static char CLIKey[]="CLI:";
static char WBKey[]="WB:";

/* miscellaneous */
extern char *ConfigName;
extern char SCButtonText[];  /* file requester title */

/* Set the name of the config file */
void SetConfigFileName(char *s)
{
 if (ConfigName) free(ConfigName);
 ConfigName=strdup(s);
}

/* Build one config line */
void BuildConfigLine(struct ToolNode *tn, char *buf)
{
 if (tn->tn_CLI) strcpy(buf,CLIKey); /* Copy tool type */
 else strcpy(buf,WBKey);

 strcat(buf,tn->tn_Node.ln_Name);    /* Append menu entry name */
 if (tn->tn_RealName)                /* Exists a real name? */
  {
   strcat(buf,";");                  /* Yes, append it */
   strcat(buf,tn->tn_RealName);
  }
}

/* Scan one config line */
BOOL ScanConfigLine(char *buf, BPTR fl)
{
 char *cp1,*cp2;
 BOOL cli,rc=FALSE;

 if ((cli=!strnicmp(buf,CLIKey,sizeof(CLIKey)-1)) ||
     !strnicmp(buf,WBKey,sizeof(WBKey)-1))
  {
   cp1=strchr(buf,':')+1;

   if (cp2=strchr(cp1,';'))              /* Scan config line for ';' */
    {
     *cp2='\0';                          /* Menu entry ; real program name */
     rc=AddToolNode(fl,cp1,++cp2,cli);
    }
   else rc=AddToolNode(fl,cp1,NULL,cli); /* Menu entry == real program name */
  }

 return(rc);
}

/* Read configuration file */
void ReadConfigFile(BPTR fl)
{
 FILE *fh;                /* Filehandle for config file */
 char ConfigLine[BUFLEN]; /* Buffer for one config file line */

 if (fh=fopen(ConfigName,"r")) /* Scan config file */
  {
   while (!feof(fh)) /* if not end of file, read one line into buffer */
    if (fgets(ConfigLine,BUFLEN,fh) && (strlen(ConfigLine)>1))
     {
      ConfigLine[strlen(ConfigLine)-1]='\0'; /* Strip newline */
      if (!strnicmp(ConfigLine,IconKey,sizeof(IconKey)-1))
       {
        char *cp;

        IconXPos=strtol(ConfigLine+sizeof(IconKey)-1,&cp,10);
        IconYPos=strtol(cp+1,&cp,10);
       }
      else ScanConfigLine(ConfigLine,fl);
     }
   fclose(fh);  /* close config file */
  }
}

/* Tiny long to string conversion routine */
static void ltoa(char *s, long n)
{
 long i=1000000000;     /* Divisor */
 BOOL inumber=FALSE;    /* Flag */

 if (n==-2147483648)    /* Handle special case 2^31*/
  {
   strcpy(s,"-2147483648");
   return;
  }

 if (n<0)               /* Handle negativ numbers */
  {
   n=-n;
   *s++='-';
  }

 if (n==0) *s++='0';    /* Zero is a special case */
 else while (i)         /* Every other numer goes here */
       {
        *s=n/i+'0';     /* Retrieve leading digit */
        if (*s!='0') inumber=TRUE; /* Suppress leading zero's */
        if (inumber) s++;
        n%=i;           /* Remove digit from number */
        i/=10;          /* next divisor */
       }

 *s='\0';               /* Append string terminator */
}

/* Write configuration file */
BOOL WriteConfigFile(struct Window *w)
{
 struct FileRequester *req;
 BOOL rc=FALSE;
 char dir[NAMELEN],file[NAMELEN],*cp;

 /* Split file name */
 cp=FilePart(ConfigName);
 if (cp!=ConfigName) strncpy(dir,ConfigName,cp-ConfigName);
 dir[cp-ConfigName]='\0';
 strncpy(file,cp,NAMELEN);

 /* Alloc file requester structure */
 if (!(req=AllocAslRequestTags(ASL_FileRequest,ASL_Hail,SCButtonText,
                                               ASL_Window,w,
                                               ASL_LeftEdge,w->LeftEdge,
                                               ASL_TopEdge,w->TopEdge,
                                               ASL_Dir,dir,
                                               ASL_File,file,
                                               ASL_FuncFlags,FILF_SAVE,
                                               TAG_DONE)))
  return(TRUE);

 /* Open file requester */
 if (AslRequest(req,NULL))
  if (*req->rf_File)                   /* Valid file name? */
   {
    FILE *fh;
    struct ToolNode *tn;

    strncpy(dir,req->rf_Dir,NAMELEN);  /* Build complete name */
    AddPart(dir,req->rf_File,NAMELEN);
    SetConfigFileName(dir);

    if (fh=fopen(ConfigName,"w"))      /* Open config file */
     {
      /* Write icon position line */
      fputs(IconKey,fh);
      ltoa(dir,IconXPos);
      fputs(dir,fh);
      fputc(',',fh);
      ltoa(dir,IconYPos);
      fputs(dir,fh);
      fputc('\n',fh);

      for (tn=GetHead(&ToolList); tn; tn=GetSucc(tn))
       {
        if (tn->tn_CLI) fputs(CLIKey,fh); /* Write tool type */
        else fputs(WBKey,fh);

        fputs(tn->tn_Node.ln_Name,fh); /* Write menu entry name */
        if (tn->tn_RealName)           /* Exists a real name? */
         {
          fputc(';',fh);               /* Yes, append it */
          if (tn->tn_CLI) fputs(tn->tn_RealName,fh);
          else
           if (!NameFromLock(tn->tn_DirLock,dir,NAMELEN) ||
                !AddPart(dir,tn->tn_RealName,NAMELEN))
            fputs(tn->tn_RealName,fh);
           else fputs(dir,fh);
         }
        fputc('\n',fh);                /* Append a new line */
       }
      fclose(fh);                      /* Close the config file */
     }
    else rc=TRUE;                      /* Could not open config file! */
   }
  else rc=TRUE;                        /* No valid file name */

 FreeAslRequest(req);
 return(rc);
}

