#include "billingkom.h"

void mystrncpy(char *dest,char *src,long len)
{
   strncpy(dest,src,(size_t)len-1);
   dest[len-1]=0;
}

void ownprintf(char *fmt,...)
{
   va_list args;
   long c;

   va_start(args, fmt);
   vfprintf(ownstdout,fmt,args);
   va_end(args);

   for(c=0;fmt[c];c++)
      if(fmt[c]=='\n') linesonscreen++;

   if(linesonscreen >= cfg_Lines-2 && ownstdout == stdout)
   {
      ospause(strings[STR_PRESSRETURN]);
      linesonscreen=0;
   }
}

void ownprintfscr(char *fmt,...)
{
   va_list args;
   long c;

   va_start(args, fmt);
   vprintf(fmt,args);
   va_end(args);

   for(c=0;fmt[c];c++)
      if(fmt[c]=='\n') linesonscreen++;

   if(linesonscreen >= cfg_Lines-2)
   {
      ospause(strings[STR_PRESSRETURN]);
      linesonscreen=0;
   }
}

char *ownstristr(char *string,char *find)
{
   int c;

   for(c=0;string[c];c++)
      if(strnicmp(&string[c],find,strlen(find))==0) return(&string[c]);

   return(FALSE);
}

bool isnum(char *s)
{
   int c;

   for(c=0;s[c];c++)
      if(s[c]<'0' || s[c]>'9') return(FALSE);

   return(TRUE);
}

void rawmakegroup(char *dest,char *group,char *folder)
{
   if(group && group[0])
   {
      strcpy(dest,group);
   }
   else
   {
      if(folder && folder[0])
         sprintf(dest,"%s, %s",strings[STR_MAILBOX],folder);

      else
         strcpy(dest,strings[STR_MAILBOX]);
   }
}

/*********************************************************************/

void makegroup(char *dest,char *group,char *folder)
{
   struct group *gr;
   char *sfolder,*sgroup;

   sgroup=group;
   sfolder=folder;

   if(!sgroup) sgroup="";
   if(!sfolder) sfolder="";

   for(gr=firstgroup;gr;gr=gr->next)
      if(stricmp(sgroup,gr->umsgroup)==0 && stricmp(sfolder,gr->umsfolder)==0)
      {
         strcpy(dest,gr->komname);
         return;
      }

   rawmakegroup(dest,group,folder);
}

void makename(char *dest,char *name,char *addr)
{
   if(name)
   {
      strcpy(dest,name);

      if(addr && addr[0])
      {
         strcat(dest," <");
         strcat(dest,addr);
         strcat(dest,">");
      }
   }
   else if(addr)
   {
      strcpy(dest,addr);
   }
}

/* 

   Poängsättning i match:

   Match: 1000 poäng
   Exakt match: 100 poäng
   Rätt längd: 10 poäng

*/

int match(char *input,char *string,char **arg)
{
   int c,d;
   int score;
   bool hasword;

   c=0;
   d=0;
   score=0;
   hasword=FALSE;

   if(arg)
      *arg=NULL;

   for(;;)
   {
      if(input[c]=='(')
      {
         /* Skippa ord inom paranteser i input */
         while(input[c]!=')' && input[c]!=0) c++;
         if(input[c]==')') c++;
         while(input[c]==' ') c++;
      }

      if(string[d]=='(')
      {
         /* Skippa ord inom paranteser i string */
         while(string[d]!=')' && string[d]!=0) d++;
         if(string[d]==')') d++;
         while(string[d]==' ') d++;
      }

      if(input[c]==' ' || input[c]==0)
      {
         /* Slut på ord i input */

         if(hasword)
         {
            score+=1000;
            if(string[d]==' ' || string[d]==0) score+=100; /* Matches exactly */
         }

         hasword=FALSE;

         /* Tugga fram till nästa ord i input */
         while(input[c]==' ' && input[c]!=0) c++;

         /* Tugga fram till nästa ord i string */
         while(string[d]!=' ' && string[d]!=0) d++;
         while(string[d]==' ' && string[d]!=0) d++;

            if(string[d]=='(')
         {
            /* Skippa ord inom paranteser i string */
            while(string[d]!=')' && string[d]!=0) d++;
            if(string[d]==')') d++;
            while(string[d]==' ') d++;
         }

         if(string[d]==0 || string[d]==' ')
            score+=10;

         if(input[c]==0)
            return(score);
      }
      else if(string[d]==0)
      {
         if(arg)
         {
            *arg = &input[c];
            return(score);
         }

         return(0);
      }
      else
      {
         /* Det finns ett tecken att jämföra */

         if(ostoupper((unsigned char)input[c]) == ostoupper((unsigned char)string[d]))
            hasword=TRUE;

         else
            return(0);

         c++;
         d++;
      }
   }
}

struct group *findnextgroup_cache;

struct group *findnextgroup(void)
{
   struct group *group,*origgroup;
   long res,c;
   char *thing="|/-\\";

   if(findnextgroup_cache)
      return(findnextgroup_cache);

   umsflag_clear();
   umsflag_selectnew();

   for(group=firstgroup;group;group=group->next)
      if(stricmp(currentgroup,group->umsgroup)==0 && stricmp(currentfolder,group->umsfolder)==0) break;

   origgroup=group;
   group=group->next;
   if(!group) group=firstgroup;

   c=0;

   while(group != origgroup)
   {
      res=0;

      if(group->subscribed && group->access)
      {
         printf("%lc",thing[c]);
         fflush(stdout);
         c++;
         if(c==4) c=0;

         if(groupunread(group->umsgroup,group->umsfolder))
         {
            findnextgroup_cache=group;
            printf("\x08" " " "\x08");
            fflush(stdout);
            return(group);
         }

         printf("\x08");
         fflush(stdout);
      }

      group=group->next;
      if(!group) group=firstgroup;
   }

   printf(" " "\x08");
   return(NULL);
}

void makemailname(char *dest,char *name,char *addr)
{
   char *b;
   char rec[100];

   strcpy(rec,dest);

   name[0]=0;
   addr[0]=0;

   if(b=strrchr(rec,','))
   {
      *b=0;
      mystrncpy(name,rec,100);
      mystrncpy(addr,&b[1],100);
   }
   else
   {
      if(b=strchr(rec,'@'))
      {
         mystrncpy(addr,rec,100);
         *b=0;
         mystrncpy(name,rec,100);
      }
      else
      {
         mystrncpy(name,rec,100);
      }
   }
}

void strip(char *str)
{
   int c;
   for(c=strlen(str)-1;str[c] == 32 && c>=0;c--) str[c]=0;
}

struct command *expandcommand(char *input,char **arg,struct command *firstcmd)
{
   struct command *command,*matchcommand;
   int tempscore,highscore,matches;
   char *temparg;

   highscore=0;
   matches=0;

   matchcommand=NULL;

   for(command=firstcmd;command;command=command->next)
   {
      if((tempscore=match(input,command->command,&temparg)))
      {
         if(tempscore > highscore)
         {
            matches=0;
            highscore=tempscore;
         }

         if(tempscore == highscore)
         {
            matchcommand=command;
            matches++;
            *arg=temparg;
         }
      }
   }

   if(matches == 1)
   {
      return(matchcommand);
   }

   if(matches == 0)
   {
      printf(strings[STR_UNKNOWNCOMMAND]);
      return(NULL);
   }

   linesonscreen=0;
   brk=FALSE;

   ownprintfscr(strings[STR_AMBIGOUSCOMMAND]);
   ownprintfscr("\n");

   brk=FALSE;

   for(command=firstcmd;command && !brk;command=command->next)
   {
      if(match(input,command->command,&temparg)==highscore)
      {
         ownprintfscr("%s\n",command->command);
      }
   }

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

   return(NULL);
}

struct group *expandgroup(char *input)
{
   char s[100],i[100];
   struct group *group,*matchgroup;
   int tempscore,highscore,matches,c;
   bool leave;

   mystrncpy(s,input,100);

   for(;;)
   {
      highscore=0;
      matches=0;

      matchgroup=NULL;

      for(group=firstgroup;group;group=group->next)
      {
         if(group->access)
         {
            if((tempscore=match(s,group->komname,NULL)))
            {
               if(tempscore > highscore)
               {
                  matches=0;
                  highscore=tempscore;
               }

               if(tempscore == highscore)
               {
                  matchgroup=group;
                  matches++;
               }
            }
         }
      }

      if(matches == 1)
      {
         return(matchgroup);
      }

      if(matches == 0)
      {
         printf(strings[STR_UNKNOWNGROUP]);
         return(NULL);
      }

      linesonscreen=0;
      brk=FALSE;

      ownprintfscr(strings[STR_AMBIGOUSGROUP]);
      ownprintfscr("\n");

      c=0;
      brk=FALSE;

      for(group=firstgroup;group && !brk;group=group->next)
      {
         if(group->access && match(s,group->komname,NULL)==highscore)
         {
            c++;
            ownprintfscr("%ld: %s\n",c,group->komname);
         }
      }

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

      leave=FALSE;

      while(!leave)
      {
         printf("\n");
         printf("%s ",strings[STR_ENTERNRGROUP]);
         fflush(stdout);
         osreadline(i,100);
         printf("\n");

         if(i[0]==0)
         {
            return(NULL);
         }
         else if(isnum(i))
         {
            if(atoi(i) >= 1 && atoi(i) <= matches)
            {
               c=0;

               for(group=firstgroup;group;group=group->next)
               {
                  if(group->access && match(s,group->komname,NULL)==highscore)
                  {
                     c++;

                     if(c == atoi(i))
                        return(group);
                  }
               }
            }
            else
            {
               printf(strings[STR_NROUTOFRANGE],1,matches);
            }
         }
         else
         {
            leave=TRUE;
         }

         strcpy(s,i);
      }
   }
}

struct flag *expandflag(char *input)
{
   struct flag *matchflag;
   int tempscore,highscore,matches,c;

   highscore=0;
   matches=0;

   matchflag=NULL;

   for(c=0;flags[c].name;c++)
   {
      if((tempscore=match(input,*(flags[c].name),NULL)))
      {
         if(tempscore > highscore)
         {
            matches=0;
            highscore=tempscore;
         }

         if(tempscore == highscore)
         {
            matchflag = &flags[c];
               matches++;
         }
      }
   }

   if(matches == 1)
   {
      return(matchflag);
   }

   if(matches == 0)
   {
      printf(strings[STR_UNKNOWNFLAG]);
      return(NULL);
   }

   linesonscreen=0;
   brk=FALSE;

   ownprintfscr(strings[STR_AMBIGOUSFLAG]);
   ownprintfscr("\n");

   c=0;
   brk=FALSE;

   for(c=0;flags[c].name;c++)
   {
      if(match(input,*(flags[c].name),NULL)==highscore)
         ownprintfscr("%s\n",*(flags[c].name));
   }

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

   return(NULL);
}

struct receiver *expandreceiver(char *input,struct receiver *firstreceiver)
{
   struct receiver *receiver,*matchreceiver;
   int tempscore,highscore,matches;

   highscore=0;
   matches=0;

   matchreceiver=NULL;

   for(receiver=firstreceiver;receiver;receiver=receiver->next)
   {
      if((tempscore=match(input,receiver->name,NULL)))
      {
         if(tempscore > highscore)
         {
            matches=0;
            highscore=tempscore;
         }

         if(tempscore == highscore)
         {
            matchreceiver=receiver;
            matches++;
         }
      }
   }

   if(matches == 1)
   {
      return(matchreceiver);
   }

   if(matches == 0)
   {
      printf(strings[STR_UNKNOWNRECEIVER]);
      return(NULL);
   }

   linesonscreen=0;
   brk=FALSE;

   ownprintfscr(strings[STR_AMBIGOUSRECEIVER]);
   ownprintfscr("\n");

   brk=FALSE;

   for(receiver=firstreceiver;receiver && !brk;receiver=receiver->next)
   {
      if(match(input,receiver->name,NULL)==highscore)
      {
         ownprintfscr("%s\n",receiver->name);
      }
   }

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

   return(NULL);
}

bool getargorlast(char *arg,long *num)
{
   if(!arg)
   {
      if(lastread == 0)
      {
         printf(strings[STR_NOTREADTEXTS]);
         return(FALSE);
      }
      else
      {
         *num=lastread;
         return(TRUE);
      }
   }
   else
   {
      if(!isnum(arg))
      {
         printf(strings[STR_NEEDSNUMARG]);
         return(FALSE);
      }
      else
      {
         *num=atoi(arg);
         return(TRUE);
      }
   }
}

