/*************************************************************************
                FORMS version 1.0 written by Joseph Hodge.
                ------------------------------------------

 This AmiExpress Interface allows you to provide templates as text files
 which will allow users to fill the templates out via a FullScreen
 editing capability.
**************************************************************************/

#include <exec/exec.h>
#include <stdio.h>
#include <stdlib.h>
#include "dh1:source/doors/romconf/doorheader.h"
#define ACCESS_WRITE -1

/****** AmiExpress now will return arrow key information as the following
        codes, these codes are stored as the first character in any
        getuserstring function
 ******/


#define RIGHTARROW 2
#define LEFTARROW 3
#define UPARROW 4
#define DOWNARROW 5

#define gu getuserstring

char cmd[100]; /* misc storage throughout program */
char im[200][82]; /* storage for text user types and also the 15 line forms */           

int x,y,line; /* holds current cursor coordinates & max number of lines */

void end(); /** Required for any interface for AmiExpress. **/
void showstat(int line,int x,int y); /** Places cursor in appropriate 
                                         location **/

void InitArray(); /* Initializes im[][] to spaces */
void SaveAs(); /* saves finished form on drive */
void showarg(char *str[]); /* This will show all of the command line
                              arguments used to invoke this interface
                           */

void makearg(char *str); /* parses the commandline and stores the arg
                            pointers in argment[]
                         */

void sr(char *str); /* removes trailing ascii codes < 33 from any string */

void LoadForm(char *str); /* loads the desired Form Template */

void Goto(int x,int y); /* Used to position cursor at specific locations
                           on the screen
                        */
int node; /* contains the node number from where this interface was invoked */

void LoadFormsPath(char *str);
int UserFound(void);
void UserSave(void);

#define sm sendmessage
#define cm sendchar
#define pu putuserstring
#define co ConOnly
#define fk Fhotkey
BOOL FORM=FALSE; /* set to true if there is a form for the editor */

char *argment[50];              /** Pointers to commandline arguments **/

int argcount=0;                 /** Total number of commandline arguments **/

struct FORMS                    /** Holds location & response for enteries **/
{
  short x,y;
  char content[80];
} Fm[100];

int LastForm=0; /* contains total number of entries allowed on the form
                   based on '[' in template */

int CurrForm=0; /* contains the current entry the user is editing. */
char FORMPATH[200];
BOOL APPEND;
BOOL UNIQUE;
BOOL NODEPREFIX;
long lock=0L; 
main(int argc,char *argv[])
{
  char hmd;
  char temp[10];
  int t=0;
  BOOL stop=FALSE; /* provides a loop for the editor */
  int tline=0,i;   /* tline holds current line the user it on */
  x=y=line=0;

  if(argc!=2)
  {
     printf("Forms v1.0 written by Joseph Hodge\n");
     printf("This is an XIM for AmiExpress v2.0+\n");
     printf("\n");
     exit(0);
  }
  Register(argv[1][0]-'0'); /** Initiliaze communication between BBS
                                and program
                             **/

  node = argv[1][0]-'0'; /** store current node the user is on **/
  pu("",RAWARROW); /** Turns off arrowkey filter, allowing us to
                         intercept them and do what we wish with it
                      **/
  InitArray();

  
 
  gu(cmd,BB_MAINLINE); /* determine commandline used to invoke the FORMS */
  makearg(cmd); /* parse the commandline */
  
if(argcount==1)
    LoadForm(argment[0]);
 else LoadForm(NULL);
  Goto(Fm[CurrForm].x,Fm[CurrForm].y); x=Fm[CurrForm].x;
  y=Fm[CurrForm].y;

  /** loop until the user presses '/' on the begining of any line **/
  do
  {
     hotkey("",temp);hmd=temp[0];
     //hmd=Fhotkey();
     switch(hmd)
     {
       case RIGHTARROW:
            if(FORM)
            {
               if(x-1>=0)
               {
                 if(im[y][x-1]=='[')
                 {
                   CurrForm -=1; if(CurrForm<0) CurrForm=LastForm-1;
                   y=Fm[CurrForm].y;x=Fm[CurrForm].x;Goto(x,y);
                 }
                 else
                 {
                   x -=1; if(x<0) x=0; else sm("[D",0);
                
                 }

               }
             }
             else
             {
                x -=1; if(x<0) x=0; else sm("[D",0);
                
             }
             break;
       case LEFTARROW:
            if(FORM)
            {
               if(x+1<=79)
               {
                 if(im[y][x+1]==']')
                 {
                   CurrForm +=1; if(CurrForm>=LastForm) CurrForm=0;
                   y=Fm[CurrForm].y;x=Fm[CurrForm].x;Goto(x,y);
                 }
                 else 
                 {
                     x +=1; if(x>79) x=79; else sm("[C",0); 
                 }
               }
             }
             else
             {
              x +=1; if(x>78) x=78; else sm("[C",0); 
             }
             break;
       case UPARROW:
            if(FORM)
            {
                       CurrForm -=1; if(CurrForm<0) CurrForm=LastForm-1;
                       y=Fm[CurrForm].y;x=Fm[CurrForm].x; Goto(x,y); 
            }else
            {
              y -=1; if(y<0) y=0; else { sm("[A",0); tline--; }
            }
            break;
       case DOWNARROW:
            if(FORM)
            {
              CurrForm +=1; if(CurrForm>=LastForm) CurrForm=0;
                       y=Fm[CurrForm].y;x=Fm[CurrForm].x; Goto(x,y);  
            }else
            {         
              y +=1; if(y>16) y=16; else{ sm("[B",0); tline++;
                   if(tline>line) line++;} 
            }
            break;
       case 12:
       case 13:
            if(FORM)
            {
                CurrForm +=1; if(CurrForm>=LastForm) CurrForm=0;
                y=Fm[CurrForm].y; x=Fm[CurrForm].x; Goto(x,y);
            }
            else
            {
                y +=1; x=0; if(y>16) y=16; else { tline++;if(tline>line)line++;}
               
            }
            break;
       case '\b':
            if(FORM)
            {
               if(x-1>=0)
               {
                 if(im[y][x-1]=='[')
                 {
                   CurrForm -=1; if(CurrForm<0) CurrForm=LastForm-1;
                   y=Fm[CurrForm].y;x=Fm[CurrForm].x;Goto(x,y);
                 }
                 else
                 {
                   x -=1; if(x<0) x=0; else sm("\b \b",0);
                
                 }

               }
             }
             else {
            x = x-1; if(x<0) x=0; else sm("\b \b",0);} break;
       case '\t':
              CurrForm +=1; if(CurrForm>=LastForm) CurrForm=0;
                y=Fm[CurrForm].y; x=Fm[CurrForm].x; Goto(x,y);
              break;
       default: if((hmd=='S' || hmd=='A' || hmd=='a' || hmd=='s')&& CurrForm==LastForm-1) { stop=TRUE; break;} 
            cm(hmd,0); im[y][x]=hmd; 
            if(FORM)
            {
              if(x+1<=79)
               {
                 if(im[y][x+1]==']')
                 {
                   CurrForm +=1; if(CurrForm>=LastForm) CurrForm=0;
                   y=Fm[CurrForm].y;x=Fm[CurrForm].x;Goto(x,y);
                 }
                 else 
                 {
                     x +=1; if(x>79) x=79; //else sm("[C",0); 
                 }
               }
            }
            else { x +=1; if(x>78)
                 {
                   if(y+1<=16)
                   {
                     x=78; while(x>=0 && im[y][x]!=' ') x--;
                      x++; t=x; x=0; while(t<=78)
                     {
                       im[y+1][x]=im[y][t];im[y][t]=' ';
                       Goto(t,y);cm(im[y][t],0);Goto(x,y+1);cm(im[y+1][x],0); 
                       x++; t++;
                     }
                     y++;
                   }
                   else x=78;
                 }
                }
     }
   //  co("[0 p",0);showstat(line,x,y); co("[ p",0);
  }while(!stop);
  
  if(hmd=='S' || hmd=='s')SaveAs();
  sm("",0);
  sm("",1);
  sm("[33mExiting FullEdit[0m",1);
  sm("",1);
  ShutDown();
  end();
}
void InitArray()
{
  register int i,j;
  for(i=0;i<200;i++)
  {
    for(j=0;j<79;j++)
     im[i][j]=' '; im[i][j]='\0';
  }
}
void showstat(int line,int x,int y)
{
  char str[200];
/*    sm("[34m",0);
    sm("[2;1H",0);


sprintf(str,"--[33m%3d[34m--[33m%2d[34m--[33m%2d[34m--------------------------------------------------------------",line,x,y);
    sm(str,1);
*/
    sprintf(str,"[%d;%dH[36m",y+3,x+1);
    sm(str,0);
}
void SaveAs()
{
  FILE *fi;
  char FileName[200];
  register int i;
  sprintf(FileName,"%s%s.frm",FORMPATH,(STRPTR)argment[0]);
  while(!(lock=Lock(FileName,ACCESS_WRITE)));
  
  sprintf(FileName,"%s%s.dat",FORMPATH,(STRPTR)argment[0]);
  fi=fopen(FileName,"a");
  if(fi==NULL)
  {
    sm("[31mError, cannot locate node(x)/work",1);
    UnLock(lock);
    return;
  }
  i=0;
  while(i<line)
  {
    fprintf(fi,"%s\n",im[i]);
    i++;
  }
  fclose(fi);
  UnLock(lock);
  if(UNIQUE)
  {
    UserSave();
  }
}
void end()
{
  exit(0);
}
void showarg(char *str[])
{
  register int i=0;
  while(str[i][0]!=NULL)
  {
    strcpy(cmd,str[i]);
    sm(cmd,1);
    i++;
  }
}
void makearg(char *str)
{
  static int i=0;
  static int j=0;
  argcount=0;
while(1)
{
  argment[j]=str+i; j++; argment[j]=NULL; argcount++;
  if(*(str+i)=='\0') { argment[j]=NULL; return; }
  while(*(str+i)>32)
  {
    i++;
  }
  if(*(str+i)=='\0') return;
  *(str+i)='\0';i++;
 }
}

void LoadForm(char *str)
{
  FILE *fi;
  char local[100];
  char FileName[100];
  char showname[200];
  char cmd[200];
  register int i=0,j;
  if(str!=NULL)
  {
    strcpy(FileName,str);
    LoadFormsPath(str);
    sprintf(FileName,"%s%s.frm",FORMPATH,str);
    sprintf(showname,"%s%s",FORMPATH,str);
    if(UserFound()) 
    {
      //sm("[32mRecords indicate you have already filled out a form[0m",1);
      ShutDown();
      end();
    }
// co("[0 p",0); /* turn console cursor off */
//  showstat(line,x,y); /* move cursor to correct place */
//  co("[ p",0);  /* turn console cursor back on */

  sm("",0);/* clears the screen */

  sm("[33mFORMS version 1.0 [35m written by Joseph Hodge[0m",1);
sm("------------------------------------------------------------------------------",1);

  sm("[20;1H",0);
  sm("[34m",0);

sm("------------------------------------------------------------------------------",1);
sm("[31mPress S)ave A)bort [ ].",1);
sm("[34m------------------------------------------------------------------------------",0);

    fi=fopen(FileName,"r");
    if(fi==NULL) return;FORM=TRUE;
    while(fgets(cmd,80,fi)!=NULL && i<15)
   {
   
    j=0; 
    sprintf(local,"[%d;%dH[36m",i+3,1);
    sm(local,0);
    sr(cmd);
    while(cmd[j]!='\0' && j<79)
    {
      im[i][j]=cmd[j]; if(cmd[j]=='[') { Fm[LastForm].x=j+1;
                                         Fm[LastForm].y=i; LastForm++; }
      j++;
    }
    //sm(cmd,0);
    i++; line++;
  }
  }
  Goto(1,0);
  if(str==NULL)
  {
    Fm[LastForm].x=0 ;
    Fm[LastForm].y=0 ;
    LastForm++;
  }
  Fm[LastForm].x=20;
  Fm[LastForm].y=18;
  im[18][19]='[';
  im[18][21]=']';
  LastForm++;
  
  
  if(fi!=NULL){fclose(fi); showgfile(showname);}
}

void sr(char *str)
{
  register int i;
  i=strlen(str)-1;
  while(i>-1)
  {
    if(*(str+i)<=32) *(str+i)='\0'; else break;
    i--;
  }
}

void Goto(int x,int y)
{
  char local[20];
  sprintf(local,"[%d;%dH[36m",y+3,x+1);
  sm(local,0);
}
void LoadFormsPath(char *str)
{
  FILE *fi;
  char cmd[200];
  APPEND=FALSE;
  UNIQUE=FALSE;
  NODEPREFIX=FALSE;
  strcpy(FORMPATH,"DOORS:FormEdit/Forms/");
  sprintf(cmd,"%s%s.cfg",FORMPATH,(STRPTR)argment[0]);
  fi=fopen(cmd,"r");
  if(fi==NULL) return;
  while(fgets(cmd,80,fi)!=NULL)
  {
    sr(cmd);strupr(cmd);
    if(!strcmp(cmd,"NODE PREFIX"))
    {
      NODEPREFIX=TRUE;
    }
    if(!strcmp(cmd,"UNIQUE RECORD"))
    {
      UNIQUE=TRUE;
    }
    if(!strnicmp(cmd,"PATH",4))
    {
      strcpy(FORMPATH,&cmd[5]);
    }
    if(!strcmp(cmd,"APPEND"))
    {
      APPEND=TRUE;
    }
    
  }
  fclose(fi);
}
int UserFound(void)
{
  FILE *fi;
  char Name[200];
  char FileName[200];
  gu(Name,DT_NAME);
  sprintf(FileName,"%s%s.db",FORMPATH,argment[0]);
  strupr(Name);
  if(!UNIQUE) return(0);
  fi=fopen(FileName,"r");
  if(fi==NULL)
  {
    return(0);
  }
  while(fgets(FileName,80,fi)!=NULL)
  {
    sr(FileName); 
    if(!strcmp(Name,FileName))
    {
     fclose(fi);return(1);
    }
  }
  fclose(fi);
  return(0);
}
void UserSave(void)
{
  FILE *fi;
  char Name[200];
  char FileName[200];
  gu(Name,DT_NAME);
  sprintf(FileName,"%s%s.frm",FORMPATH,argment[0]);
  while(!(lock=Lock(FileName,ACCESS_WRITE)));
  sprintf(FileName,"%s%s.db",FORMPATH,argment[0]);
  strupr(Name);
  if(!UNIQUE) return;
  fi=fopen(FileName,"a");
  if(fi==NULL)
  {
    UnLock(lock);
    return;
  }
  fprintf(fi,"%s\n",Name);
  fclose(fi);
  UnLock(lock);
}

int strnicmp(char *str1,char *str2,int len)
{
  register int i;
  strupr(str1);
  strupr(str2);
  i=0;
  while(i<len)
  {
    if(*(str1+i)!=*(str2+i)) return(1);
    i++;
  }
  return(0);
}
void LastCommand(void)
{
}
