/*

 CheckTags
 =========

 if option is "LOGIN_CHECK" then
 begin

   "You still have these tagged files from your last call"
   (and list tagged files)
   "Do you want to keep them [Y/N]"

   if "Nope" then clear all tags, continue otherwise

 else

   ran door without options ?

   begin

     repeat

       Display tagged files

       ask whether to clear all or add/remove single tags.

     until user quits door

   else

     perform required options (Tag, Clear,List,Help)

   end
 end

 History
 =======

 Date       Modification
 ---------  ------------
 ?????????  Wrote Door
 24-OCT-95  Re-Wrote most of the door
            Fixed Loads Of Bugs
            Optimized
            Added Help



*/
#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/alib_protos.h>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>


#ifdef __SASC
int CXBRK(void) { return(0); }
int _CXBRK(void) { return(0); }
void chkabort(void) {}
#endif

#include <HBBS/ANSI_Codes.h>
#include <HBBS/Defines.h>
#include <HBBS/types.h>
#include <HBBS/structures.h>
#include <HBBS/hbbscommon_protos.h>
#include <HBBS/hbbscommon_pragmas.h>
#include <HBBS/Hbbsnode_protos.h>
#include <HBBS/Hbbsnode_pragmas.h>
#include <HBBS/release.h>
char *versionstr="$VER: CheckTags "RELEASE_STR;

struct Library *HBBSCommonBase=NULL;
struct Library *HBBSNodeBase=NULL;

struct BBSGlobalData *BBSGlobal=NULL;
struct NodeData *N_ND=NULL;
int N_NodeNum=-1;
char outstr[1024];
BOOL interactive=TRUE;

static VOID cleanup(ULONG num)
{
  if (HBBSNodeBase)
  {
    HBBS_CleanUpDoor();
    CloseLibrary (HBBSNodeBase);
  }

  if (HBBSCommonBase)
  {
    HBBS_CleanUpCommon();
    CloseLibrary (HBBSCommonBase);
  }

  if (num) printf("Door Error = %d\n",num);

  exit(0);
}

static VOID init(char *name)
{
  if(!(HBBSCommonBase = OpenLibrary("HBBSCommon.library",0)))
  {
    cleanup(1);
  }

  if (!(HBBS_InitCommon()))
  {
    cleanup(2);
  }

  if(!(HBBSNodeBase = OpenLibrary("HBBSNode.library",0)))
  {
    cleanup(3);
  }

  if (!(HBBS_InitDoor(N_NodeNum,name)))
  {
    cleanup(4);
  }
  SetProgramName(name);
}

void DisplayTaggedFiles( void )
{
  struct TaggedFile *Tag;
  int loop=0;

  DOOR_DisplaySpecialScreen("Banner_TOP");
  for (Tag = (struct TaggedFile *)N_ND->TaggedFileList->lh_Head ; Tag->node.ln_Succ ; Tag =(struct TaggedFile*)Tag->node.ln_Succ)
  {
    loop++;
    if (Tag->WarezFile)
    {
      sprintf(outstr,ANSI_FG_CYAN "    %3d" ANSI_FG_WHITE ") \"" ANSI_FG_GREEN "%-12s" ANSI_FG_WHITE "\" %9.0lf " ANSI_FG_PURPLE "%s%s\r\n",loop,FilePart(Tag->node.ln_Name),Tag->FileSize,HBBS_ListName(BBSGlobal->ConfList,Tag->ConferenceNum-1), Tag->Flags & TF_FREEDOWNLOAD ? " "ANSI_FG_YELLOW" FREE D/L!" : ""); //-1 cos HBBS_ListName starts at 0.. conf numbers start at 1
    }
    else
    {
      sprintf(outstr,ANSI_FG_CYAN "    %3d" ANSI_FG_WHITE ") " ANSI_FG_YELLOW "%s\r\n",loop,Tag->node.ln_Name);
    }

    DOOR_WriteText(outstr);
  }
  if (loop==0)  DOOR_WriteText(ANSI_FG_CYAN "No Tagged Files!\r\n" ANSI_RESET);
  DOOR_DisplaySpecialScreen("Banner_BOT");

  DOOR_WriteText(ANSI_FG_WHITE);
}

#define TAG_ADD 1
#define TAG_CLEAR 2

int ClearSingleTag( char *filename)
{
  char matchstr[512];
  struct TaggedFile *Tag,*TTag;
  int Cleared=0;

  ParsePatternNoCase(filename,matchstr,512);

  for (Tag = (struct TaggedFile *)N_ND->TaggedFileList->lh_Head ; Tag->node.ln_Succ ; Tag =(struct TaggedFile*)Tag->node.ln_Succ)
  {


    if (MatchPatternNoCase(matchstr,FilePart(Tag->node.ln_Name)))
    {
      // croikey, the file IS tagged, better do what the user wants and untag it then..

      DOOR_WriteText((Tag->WarezFile) ? (char *)FilePart(Tag->node.ln_Name) : (char *)Tag->node.ln_Name);
      DOOR_WriteText(" ");

      TTag=(struct TaggedFile*)Tag->node.ln_Pred; // store point to previous tag

      FreeStr(Tag->node.ln_Name);
      Remove((struct Node*)Tag);
      FreeVec(Tag);
      N_ND->TaggedFiles--;
      Cleared++;

      Tag = TTag; // skip back one in the list, so the nfor/next loop skips forward to the right node..
    }
  }
  return(Cleared);
}

void ClearTags( char*filenames)
{
  char singlename[512];
  int where,cleared=0;

  DOOR_WriteText(ANSI_FG_YELLOW "Clearing Tags "ANSI_FG_BLUE": " ANSI_FG_WHITE);

  while (filenames[0]) // any chars left ?
  {
    while ((filenames[0]==' ') && (filenames[0])) filenames++; //skip spaces..

    if (filenames[0])
    {
      if ((where=position(" ",filenames))>=0)
      {
        strNcpy(singlename,filenames,where);
        filenames+=where;
      }
      else
      {
        strcpy(singlename,filenames);
        filenames+=strlen(singlename);
      }

      cleared+=ClearSingleTag(singlename);
    }
  }
  if (!cleared) DOOR_WriteText( ANSI_FG_CYAN "\r\nNo File tags were cleared!");
  DOOR_WriteText(ANSI_RESET "\r\n");
}

V_BIGNUM TagFiles(char *filenames)
{
  char filename[512],tmpstr[1024];
  int where;
  V_BIGNUM tempnum=0;

  tmpstr[0]=0;
  while (filenames[0]) // any chars left ?
  {
    while ((filenames[0]==' ') && (filenames[0])) filenames++; //skip spaces..

    if (filenames[0])
    {
      if ((where=position(" ",filenames))>=0)
      {
        strNcpy(filename,filenames,where);
        filenames+=where;
      }
      else
      {
        strcpy(filename,filenames);
        filenames+=strlen(filename);
      }
      sprintf(tmpstr+strlen(tmpstr),"C=%d,N=%s ",N_ND->CurrentConf ? N_ND->CurrentConf->ConfNum : 0,filename);
    }
  }
  DOOR_SystemDoor("TAG_FILE",tmpstr);
  sscanf(N_ND->DoorReturn,"%ld",&tempnum);
  return(tempnum);
}

void Help( void )
{
  DOOR_WriteText(ANSI_RESET ANSI_FG_CYAN
                 "This door adds and removes files to/from your list of tagged files\r\n"
                 "if you run this door with no parameters you will get a prompt, at that\r\n"
                 "prompt you have the following options\r\n"
                 " A - Adds tags\r\n"
                 " C - Clears tags  (Supports #?, ? and * wildcards)\r\n"
                 " * - Clears ALL tags\r\n"
                 " L - Lists your currently tagged files\r\n"
                 "If you specify A or C and type in some file names the appropriate action\r\n"
                 "be taken, if you don't specify any file names for A or C then you will be\r\n"
                 "prompted for some filenames.\r\n"
                 "\r\n"
                 "You can also use all these options direct from the bbs prompt, here's a\r\n"
                 "few examples that show you how\r\n"
                 "\r\n"
                 "A *                   -> Clears all tags\r\n"
                 "A BANANA.LHA F123.DMS -> Adds BANANA.LHA and F123.DMS to your list of tags\r\n"
                 "A L                   -> Lists your currently tagged files\r\n"
                 "A C #?ANA#?           -> Clears any files tagged that have ANA in the middle\r\n"
                 "\r\n");
}


BOOL ParseString( char *str)
{
  BOOL Done=FALSE;
  short mode=0,len;
  char tmpstr[20];

  while (str[0] && str[0]==' ') str++; //skip spaces


  if (len=strlen(str))
  {
    while (str[len-1]==' ')
    {
      len--;
      str[len]=0;
    }

    if ( ((len>2) && (str[1]==' ')) || (len==1))
    {
      switch (toupper(str[0]))
      {
        case 'A':
          mode=TAG_ADD;
          break;
        case 'C':
          mode=TAG_CLEAR;
          break;
        case '*':
          FreeFileTags(N_ND);
          DOOR_WriteText(ANSI_FG_RED "All Tags Cleared!\r\n" ANSI_FG_WHITE);
          break;
        case 'L':
          DisplayTaggedFiles();
          break;
        case '?':
          Help();
          break;
        default:
          TagFiles(str);
          break;
      }
      if (mode)
      {
        if ((len==1) && (interactive))
        {
          DOOR_WriteText(ANSI_FG_YELLOW "Filenames "ANSI_FG_BLUE"> "ANSI_FG_WHITE);
          if (DOOR_GetLine(GL_EDIT|GL_DISPLAY,'\0',0,0,NULL)==IN_LOSSCARRIER)
          {
            Done=TRUE;
          }
          else
          {
            RemoveSpaces(N_ND->CurrentLine);
            if (N_ND->CurrentLine[0])
            {
              if (mode==TAG_ADD)
              {
                TagFiles(N_ND->CurrentLine);
              } else ClearTags(N_ND->CurrentLine);
            }
          }
        }
        else
        {
          if (mode==TAG_ADD)
          {
            sprintf(tmpstr,"%ld",TagFiles(str+2));
            DOOR_Return(tmpstr); //*C* what's this for ?
          }
          else ClearTags(str+2);
        }
      }
    } else TagFiles(str);
  }
  else Done=TRUE;

  return(Done);
}

void promptuser( void )
{
  BOOL Done=FALSE;


  DisplayTaggedFiles();

  do
  {
//    DOOR_WriteText(ANSI_RESET ANSI_FG_YELLOW "["ANSI_FG_WHITE"C"ANSI_FG_YELLOW"]"ANSI_FG_WHITE"lear, "ANSI_FG_YELLOW"["ANSI_FG_WHITE"A"ANSI_FG_YELLOW"]"ANSI_FG_WHITE"dd, "ANSI_FG_YELLOW"["ANSI_FG_WHITE"*"ANSI_FG_YELLOW"]"ANSI_FG_WHITE"Clear All Tags, "ANSI_FG_YELLOW"["ANSI_FG_WHITE"L"ANSI_FG_YELLOW"]"ANSI_FG_WHITE"ist Tags > " ANSI_FG_CYAN);
    DOOR_MenuPrompt("[C]lear, [A]dd, [*] Clear All Tags, [L]ist Tags : ",' ');
    DOOR_GetLine(GL_EDIT|GL_DISPLAY,'\0',0,0,NULL);
    if (N_ND->OnlineStatus!=OS_ONLINE)
    {
      Done=TRUE;
    }
    else
    {
      Done=ParseString(N_ND->CurrentLine);
    }
  } while (!Done);

}

void DoorMain(int argc,char *argv[])
{
  short loop;
  char params[512];

//  DOOR_WriteText("\r\n[0;36m-=[ [37;44m [0;3;37;44mHydra TagCheck V1.0[0;37;44m [36;40m ]=-[35m ========== [36m-=[ [37;44m [0;3;37;44m(C) 1995 Deluxe Software Ltd[0;37;44m [36;40m ]=-\r\n\r\n");

  // door has three modes, the first is a login check, the second is a system add/remove tag
  // and the third is the normal use interactive mode..

  if (stricmp(N_ND->ActiveDoor->SystemOptions,"LOGIN_CHECK")==0)
  {

    if (N_ND->TaggedFiles>0)
    {
      DOOR_WriteText(ANSI_RESET "You still have these files tagged from your last visit on ");
      HBBS_GetDateString(outstr,N_ND->User->CallData->LastCalledDate);
      DOOR_WriteText(outstr);
      DOOR_WriteText("\n\r\n");
      DisplayTaggedFiles();
      if (!(DOOR_ContinuePrompt("\r\nDo you still want to keep them tagged ",DEFAULT_YES | DCP_ADDYN)))
      {
        if (N_ND->OnlineStatus == OS_ONLINE) // don't clear the flags if the user drops carrier
        {
          FreeFileTags(N_ND);
          DOOR_WriteText(ANSI_RESET ANSI_FG_YELLOW "All tags have been cleared!\r\n" ANSI_RESET);
        }
      }
    }
  }
  else
  {
    if (stricmp(N_ND->ActiveDoor->SystemOptions,"NOUSER")==0)
    {
      interactive=FALSE;
    }

    if (argc>2)
    {
      params[0]=0; //null terminate string.

      for(loop=2;loop<argc;loop++)
      {
        if (loop>2) strcat(params," ");
        strcat(params,argv[loop]);
      }
      ParseString(params);
    }
    else
    {
      if (interactive) promptuser();
    }
  }
}

int main(int argc,char *argv[])
{
  if (sscanf(argv[1],"%d",&N_NodeNum)==0)
  {
    printf("Invalid/No Paramaters for door!\n");
    exit (20);
  }

  init("CheckTags");

  if (BBSGlobal=HBBS_GimmeBBS())
  {
    if (N_ND=HBBS_NodeDataPtr(N_NodeNum)) // this should not fail in normal circumstances..
    {
      DoorMain(argc,argv);
    }
  }
  cleanup(0);
}
