/* Copyright (C) 1996,1997,1998,1999 by Salvador E. Tropea (SET),
   see copyrigh file for details */
/* This file is an adaptation of idespecs.cc from Robert Hoehne to make the editor */
/* more coherent with RHIDE and more easy to configure (?)                         */

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <pathtool.h>

typedef unsigned short ushort;

static char *default_variables[] =
{
/* No longer used, now if the user doesn't make it I simply report it as an error and
   point to the readme.1st file.
#ifdef __DJGPP__
 // In DOS is common to have C:
 "SET_FILES",
 "c:/etc",
#else
 // For UNIX the right place to put these files is the etc dir
 "SET_FILES",
 "/etc",
#endif*/
 "SET_CONFQUIT","0",
 "SET_CREATE_DST","1",
 0,
 0
};

static char **vars;
static int var_count = 0;

static
void add_variable(char *variable,char *contents)
{
 var_count++;
 vars = (char **)realloc(vars,var_count*2*sizeof(char *));
 vars[var_count*2-2]=strdup(variable);
 vars[var_count*2-1]=strdup(contents);
}

void InsertEnviromentVar(char *variable,char *contents)
{
 int i;
 for (i=0;i<var_count;i++)
 {
   if (strcmp(vars[i*2],variable) == 0)
   {
     free(vars[2*i+1]);
     vars[2*i+1]=strdup(contents);
     return;
   }
 }
 add_variable(variable,contents);
}


//static
const char * GetVariable(const char *variable)
{
 int i;
 for (i=0;i<var_count;i++)
    {
     if (strcmp(variable,vars[i*2]) == 0)
        return vars[i*2+1];
    }
 return getenv(variable);
}

static char Signature[]="SET's editor enviroment\x1A";

static
void fGetStr(char *s, FILE *f)
{
 ushort len;
 fread(&len,sizeof(ushort),1,f);
 if (!feof(f))
   {
    fread(s,len,1,f);
    s[len]=0;
   }
 else
    *s=0;
}

static
void ReadEnviromentFile(void)
{
 char *s=ExpandFileNameToUserHome("setenvir.dat");

 if (s)
   {
    char Name[PATH_MAX];
    char Val[PATH_MAX];
    FILE *f=fopen(s,"rb");
    if (f)
      {
       fread(Name,sizeof(Signature),1,f);
       if (strcmp(Name,Signature)==0)
         {
          do
            {
             fGetStr(Name,f);
             fGetStr(Val,f);
             if (!feof(f))
                InsertEnviromentVar(Name,Val);
            }
          while (!feof(f));
         }
       fclose(f);
      }
   }
}

static
void fPutVar(char *var,FILE *f)
{
 char *c=(char *)GetVariable(var);
 if (c)
   {
    int len=strlen(var);
    fwrite(&len,sizeof(ushort),1,f);
    fwrite(var,len,1,f);
    len=strlen(c);
    fwrite(&len,sizeof(ushort),1,f);
    fwrite(c,len,1,f);
   }
}

void SaveEnviromentFile(void)
{
 char *s=ExpandFileNameToUserHome("setenvir.dat");
 if (s)
   {
    FILE *f=fopen(s,"wb");
    if (f)
      {
       fwrite(Signature,sizeof(Signature),1,f);
       fPutVar("SET_CONFQUIT",f);
       fPutVar("SET_VERUSED",f);
       fPutVar("SET_CREATE_DST",f);
       fPutVar("SET_TIP_INFO",f);
       fPutVar("SET_README_SHOWN",f);
       fPutVar("SET_TIPS1",f);
       fclose(f);
      }
   }
}

extern char **environ;

//static __attribute__ ((__constructor__))
void InitEnvirVariables(void)
{
 char *variable,*contents;
 int i=0;
 // The lower priority is the one of the hardcoded
 while (default_variables[i])
   {
    variable = default_variables[i];
    contents = default_variables[i+1];
    add_variable(variable,contents);
    i += 2;
   }
 // Now read the binary enviroment file
 ReadEnviromentFile();
 // Now check the env for any SET_ variable (higher priority)
 for (i=0;environ[i];i++)
    {
     if (strncmp(environ[i],"SET_",4)==0)
       {
        contents = strchr(environ[i],'=');
        if (!contents) continue;
        contents++;
        char var[256];
        memcpy(var,environ[i],(int)(contents-environ[i])-1);
        var[(int)(contents-environ[i])-1] = 0;
        InsertEnviromentVar(var,contents);
       }
    }
}

// Is ever good to have a way to destroy all the allocated memory and helps to
// find leaks.
void DeInitEnvirVariables(void)
{
 int i;
 for (i=0;i<var_count;i++)
    {
     free(vars[i*2]);
     free(vars[i*2+1]);
    }
 free(vars);
 vars=0;
 var_count=0;
}
