#include "billingkom.h"

char *groupsfile = GROUPSFILE;
char *stringsfile = STRINGSFILE;
char *commandsfile = COMMANDSFILE;

extern char *defaulthasselected,*defaulthascomment,*defaulthastext,*defaulthasgroup,*defaulttime;

/************************* Config ************************************/

int cfg_Width;
int cfg_Lines;

struct flag flags[] = { { &strings[STR_CFGSUBJECTLINE], "BillingKom.SubjectLine", FALSE },
                        { &strings[STR_CFGCLEARSCREEN], "BillingKom.ClearScreen", FALSE },
                        { &strings[STR_CFGHIDEORG],     "BillingKom.HideOrganization", FALSE },
                        { &strings[STR_CFGHIDEDISTR],   "BillingKom.HideDistribution", FALSE },
                        { &strings[STR_CFGHILIGHTQUOTE],"BillingKom.HighlightQuote", FALSE },
                        { &strings[STR_CFGTEXTSTYLES],  "BillingKom.TextStyles", FALSE },
                        { &strings[STR_CFGREADOWN],     "BillingKom.ReadOwn", FALSE },
                        { &strings[STR_CFGSIGNALTOYOU], "BillingKom.SignalToYou", FALSE },
                        { &strings[STR_CFGESPERANTO],   "BillingKom.Esperanto", FALSE },
                        { NULL, NULL, FALSE } };

/************************* Variables *********************************/

int linesonscreen;

bool brk;
bool carrierlost;
bool exitkom;

char currentgroup[100];
char currentfolder[100];

long readarray[READARRAYSIZE];
long backarray[BACKARRAYSIZE];

int readarraynum;
int backarraynum;

int backpos;
long lastread;

char loginusername[100];
char loginpassword[100];
char realname[100];

FILE *ownstdout;

long currentwidth;

bool arg_local;

void prompt(char *s,long len)
{
   char def[100];
   long new,sel;

   sel=countselected();
   new=countnewgroup(currentgroup,currentfolder);

   def[0]=0;

   if(sel && defaulthasselected)
      sprintf(def,"%s (%lu %s)",
         defaulthasselected,
         sel,
         sel==1?strings[STR_SELECTEDTEXTPROMPT]:strings[STR_SELECTEDTEXTSPROMPT]);

   else if(readarraynum != 0 && defaulthascomment)
      sprintf(def,"%s (%lu %s)",
         defaulthascomment,
         new,
         new==1?strings[STR_UNREADTEXT]:strings[STR_UNREADTEXTS]);

   else if(new && defaulthastext)
      sprintf(def,"%s (%lu %s)",
         defaulthastext,
         new,
         new==1?strings[STR_UNREADTEXT]:strings[STR_UNREADTEXTS]);

   else if(findnextgroup() && defaulthasgroup)
      strcpy(def,defaulthasgroup);

   else if(defaulttime)
      strcpy(def,defaulttime);

   printf("\n%s --> ",def);
   fflush(stdout);
   osreadline(s,len);

   if(s[0]==0)
      mystrncpy(s,def,len);

   printf("\n");
}

main(int argc, char **argv)
{
   char s[100];
   long res,c,d;
   char *realnameptr,*cfg;
   char *server="default";
   bool hasuser,haspassword;
   FILE *outfp;
   bool err;

   /* Parse arg */

   if(argc == 2 && strcmp(argv[1],"?")==0)
   {
      printf("Usage: BillingKom [-s <server>] [-c <commands] [-g <groups>] [-t <texts>]\n"
             "       [-local] [<user>] [<password>]\n");

      exit(0);
   }

   loginusername[0]=0;
   loginpassword[0]=0;

   hasuser=FALSE;
   haspassword=FALSE;

   arg_local=FALSE;

   for(c=1;c<argc;c++)
   {
      if(stricmp(argv[c],"-s")==0)
      {
         if(c+1 == argc)
         {
            printf("Missing argument for %s\n",argv[c]);
            exit(10);
         }

         server=argv[++c];
      }
      else if(stricmp(argv[c],"-t")==0)
      {
         if(c+1 == argc)
         {
            printf("Missing argument for %s\n",argv[c]);
            exit(10);
         }

         stringsfile=argv[++c];
      }
      else if(stricmp(argv[c],"-c")==0)
      {
         if(c+1 == argc)
         {
            printf("Missing argument for %s\n",argv[c]);
            exit(10);
         }

         commandsfile=argv[++c];
      }
      else if(stricmp(argv[c],"-g")==0)
      {
         if(c+1 == argc)
         {
            printf("Missing argument for %s\n",argv[c]);
            exit(10);
         }

         groupsfile=argv[++c];
      }
      else if(stricmp(argv[c],"-local")==0)
      {
         arg_local=TRUE;
      }
      else
      {
         if(!hasuser)
         {
            mystrncpy(loginusername,argv[c],200);
            hasuser=TRUE;
         }
         else if(!haspassword)
         {
            mystrncpy(loginpassword,argv[c],200);
            haspassword=TRUE;
         }
         else
         {
            printf("Too many arguments.\n");
            exit(10);
         }
      }
   }

   if(!readstrings())
   {
      freestrings();
      exit(10);
   }

   if(!readgroups())
   {
      freestrings();
      freegroups();
      exit(10);
   }

   if(!readcommands())
   {
      freestrings();
      freegroups();
      freecommands();
      exit(10);
   }

   if(!osinit())
   {
      freestrings();
      freegroups();
      freecommands();
      exit(10);
   }

   printf("\n");
   printf(strings[STR_STARTCOPYRIGHT],BASENAME,VERSION,COPYRIGHT);
   printf("\n");

   /* Login */

   while(!login)
   {
      printf("%s ",strings[STR_NAME]);
      fflush(stdout);

      if(hasuser)
         printf("%s\n",loginusername);

      else
         osreadline(loginusername,200);

      if(brk || carrierlost)
      {
         if(brk)
         {
            printf("\n");
            printf(strings[STR_BREAK]);
         }

         osclose();
         freestrings();
         freegroups();
         freecommands();
         exit(0);
      }

      if(!haspassword)
      {
         printf("%s ",strings[STR_PASSWORD]);
         fflush(stdout);
         osreadlineinvisible(loginpassword,200);
      }

      if(brk || carrierlost)
      {
         if(brk)
         {
            printf("\n");
            printf(strings[STR_BREAK]);
         }

         osclose();
         freestrings();
         freegroups();
         freecommands();
         exit(0);
      }

      if(!(login=UMSRLogin(server,loginusername,loginpassword)))
      {
         printf("\n");
         printf(strings[STR_LOGINFAILED]);
         printf("\n");
         loginusername[0]=0;
         loginpassword[0]=0;
         hasuser=FALSE;
         haspassword=FALSE;
      }
   }

   printf("\n");
   printf(strings[STR_LOGGEDIN],BASENAME);
   printf("\n");

   getgroupflags();

   /* Read config items */

   if((realnameptr=UMSReadConfigTags(login,UMSTAG_CfgUserName,loginusername,TAG_DONE)))
   {
      mystrncpy(realname,realnameptr,100);
      UMSFreeConfig(login,realnameptr);
   }

   if(cfg=UMSReadConfigTags(login,UMSTAG_CfgName,BASENAME".ScreenLength",TAG_DONE))
   {
      cfg_Lines = atoi(cfg);
      UMSFreeConfig(login,cfg);
   }

   if(cfg_Lines < 10 || cfg_Lines > 200)
      cfg_Lines=23;

   if(cfg=UMSReadConfigTags(login,UMSTAG_CfgName,BASENAME".LineWidth",TAG_DONE))
   {
      cfg_Width = atoi(cfg);
      UMSFreeConfig(login,cfg);
   }

   if(cfg_Width < 50 || cfg_Width > 200)
      cfg_Width=78;

   for(c=0;flags[c].name;c++)
      if(cfg=UMSReadConfigTags(login,UMSTAG_CfgName,flags[c].umsname,TAG_DONE))
      {
         if(stricmp(cfg,"on")==0) flags[c].set=TRUE;
         UMSFreeConfig(login,cfg);
      }

   if(arg_local)
   {
      if(osgetwindowsize(&cfg_Lines,&cfg_Width))
         printf(strings[STR_AUTODETECTWIN],cfg_Lines,cfg_Width);

      else
         printf(strings[STR_AUTODETECTWINFAIL]);

      printf("\n");
   }

   ownstdout=stdout;

   umsflag_clearsearch();

   /* Check for postponed messages */

   res=UMSSelectTags(login,UMSTAG_SelMask,       UMSUSTATF_PostPoned,
                           UMSTAG_SelMatch,      UMSUSTATF_PostPoned,
                           UMSTAG_SelUnset,      UMSUSTATF_Old | UMSUSTATF_PostPoned,
                           TAG_DONE);

   if(res)
   {
      if(res == 1)
         printf(strings[STR_POSTPONEDUNREAD],res);

      else
         printf(strings[STR_POSTPONEDUNREADS],res);

      printf("\n");
   }

   /* Check for parked message */

   umsflag_clear();
   res=umsflag_selectparked();

   if(res)
   {
      if(res == 1)
         printf(strings[STR_HASPARKED],res);

      else
         printf(strings[STR_HASPARKEDS],res);

      printf("\n");
      kom_listparked(NULL,NULL);
      printf("\n");
   }

   /* Start */

   mystrncpy(currentgroup,firstgroup->umsgroup,sizeof(currentgroup));
   mystrncpy(currentfolder,firstgroup->umsfolder,sizeof(currentfolder));

   kom_where(NULL,NULL);

   exitkom=FALSE;
   while(!exitkom && !carrierlost)
   {
      findnextgroup_cache=NULL;
      prompt(s,100);
      linesonscreen=0;

      if(!carrierlost)
      {
         if(isnum(s))
         {
            currentwidth=cfg_Width;
            kom_readmessage(s,NULL);
         }
         else
         {
            struct command *matchcmd;
            char *arg;

            matchcmd=expandcommand(s,&arg,firstcommand);

            if(matchcmd)
            {
               currentwidth=cfg_Width;
               outfp=NULL;
               err=FALSE;

               if(arg)
               {
                  for(c=strlen(arg);c!=0;c--)
                     if(arg[c]=='>') break;

                  while(arg[c-1]=='>' && c>0)
                     c--;

                  if(arg[c]=='>')
                  {
                     if(arg_local)
                     {
                        char *mode;

                        mode="w";

                        arg[c]=0;

                        for(d=c;d!=0 && arg[d-1]==' ';d--);
                        arg[d]=0;

                        c++;

                        if(arg[c] == '>')
                        {
                           mode="a";
                           c++;
                        }

                        if(!(outfp=fopen(&arg[c],mode)))
                        {
                           printf(strings[STR_FAILEDOPEN],&arg[c]);
                           err=TRUE;
                        }
                        else
                        {
                           currentwidth=79;
                           ownstdout=outfp;
                        }
                     }
                     else
                     {
                        printf(strings[STR_NOREDIRECT]);
                        err=TRUE;
                     }
                  }
               }

               if(!err)
                  (*matchcmd->func)(arg,matchcmd->data);

               if(outfp)
               {
                  fclose(outfp);
                  ownstdout=stdout;
               }
            }
         }
      }
   }

   UMSLogout(login);
   osclose();
   freestrings();
   freegroups();
   freecommands();
   exit(0);
}


/*

användartips:
ha ett guestkonto där man kan ansöka om ett konto
skriva ut textfil innan och efter: kör det i ett script
snyggare listakommando med SHOWFILE

*/

/*

   sen 0.1:

   - kommentarsläsning funkar perfa nu
   - konfigurerarbara texter i programmet
   - lista möten
   - riktig nästa möte + möteslista
   - lista parkerade
   - söker efter parkerade och postponade vid startup

   sen 0.2:

   - billingkom.text -> billingkom.texts
   - bättre parsning av kommandorad vid uppstart
   - osynlig inmatning av lösenord
   - fixade bugg i UNREAD när man skulle sätta till 0 blev alla olästa
   - bredden på subjectfältet i LISTSUBJECTS och LISTPARKED styrs ny av radbredden
   - brevlådor heter inte brevlådan/folder utan brevlådan, folder
   - LISTSUBJECTS markerar med en '*' om en text är en kommentar till en text av dig
   - LISTUNREAD markerar med en '*' om gruppen innehåller texter som är kommentarer
     till texter av dig.
   - ändrat (och förhoppningsvis förbättrat :-)) utseendet av headern när man läser post
   - kallar mötesnamn för 'Mottagare' när man läser post p.s.s. som andra KOM-system
   - kan du redirecta outputen till en fil med > eller >>. Redirectningen måste stå
     sist på kommandoraden. Denna var enklare en att göra ett separat kommando för
     att spara till en text, och det kan säkert vara bra på andra sätt också. För
     att man ska få lov att göra detta måste -local vara angiven. Vid redirecting är
     alltid radbredden 79 tecken.
   - förbättrat parsern lite

   sen 0.3:

   - visar rader lästa och totalt vid Press return när man läser en text
   - quote highlight
   - detectar skärmstorlek själv om -local
   - textstilar
   - %c, %l i editorkommando
   - en stor billingkom.subscribed istället för en för varje grupp
   - läser Attributes, Organization, Dist, ReplyTo, FupTo
   - PARK/UNPARK
   - REPLY/FOLLOWUP/MAILMESSAGE/POSTMESSAGE med tillhörande editmeny funkar
   - kan signalera om en text till dig
   - även %c och %l i EXECUTE-strängen

   sen 0.4

   - EDITMESSAGE-kommando
   - FORWARDMAIL/FORWARDPOST
   - SELECT/LISTSELECTED/NEXTSELECTED
   - BillingKom.Reflow & \reflow
   - HELP-kommando

*/


