
#include <stdio.h>
#include <exec/types.h>
#include <libraries/locale.h>
#include <exec/memory.h>
#include <dos/dosextens.h>
#include <intuition/screens.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <diskfont/diskfont.h>
#include <utility/utility.h>
#include <graphics/gfxbase.h>
#include <devices/console.h>
#include <workbench/workbench.h>
#include <graphics/scale.h>
#include <clib/locale_protos.h>
#include <clib/exec_protos.h>
#include <clib/wb_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/utility_protos.h>
#include <string.h>
#include <clib/diskfont_protos.h>

#include <dos/dos.h>
#include <dos/dostags.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <libraries/reqtools.h>

#include <clib/alib_protos.h>
#include <clib/dos_protos.h>
#include <clib/reqtools_protos.h>

#include "NodeGUI.h"

extern struct ReqToolsBase *ReqToolsBase;
extern ULONG InfoWinActive;
extern ULONG *rttags;

#include <hbbs/ANSI_Codes.h>
#include <hbbs/types.h>
#include <hbbs/access.h>
#include <hbbs/errors.h>
#include <hbbs/defines.h>
#include <hbbs/structures.h>
#include <hbbs/strings.h>
#include <hbbs/files.h>

//#include "Node_Console_Protos.h"
#include "Node_Serial_Protos.h"
#include "Node_Main_Protos.h"
#include "Node_Misc_Protos.h"
#include "Node_Input_Protos.h"

#include <HBBS/Hbbscommon_protos.h>
#ifdef __SASC
#include <HBBS/hbbscommon_pragmas_sas.h>
#else
#include <HBBS/hbbscommon_pragmas_stc.h>
#endif

#include <HBBS/Hbbsnode_protos.h>
#ifdef __SASC
#include <HBBS/Hbbsnode_pragmas_sas.h>
#else
#include <HBBS/Hbbsnode_pragmas_stc.h>
#endif

extern int N_NodeNum;
extern struct BBSGlobalData *BBSGlobal;
extern struct NodeData *N_ND;
extern struct Library *HBBSCommonBase;
extern struct Library *HBBSNodeBase;

#include "/Shared/shared_protos.h"


short fposition(char *substr,char *str,ULONG startpos)
{
  // returns an character offset of a substring in a string
  // this version is CASE SENSITIVE
  // returns -1 if substring not found in the string

  char *whstr;
  return((short)((whstr=strstr(str+startpos,substr)) ? (short)((LONG)whstr-(LONG)str) : -1));
}

/*
void strftcpy(char *dest,char *source,int from,int topos)
{
  int loop=from,pos=0;
  if (from<=strlen(source)-1)
  {
    while (source[loop] && loop<=topos)
    {
      dest[pos]=source[loop];
      loop++;
      pos++;
    }
  }
  dest[pos]=0;
}
*/

void PausePrompt(char *promptstr,ULONG Timeout)
{
  char prompt[BIG_STR];

  if (N_ND->OnlineStatus == OS_ONLINE || N_ND->RunningAwait)
  {
    if ((promptstr && promptstr[0]==0) || (!promptstr))
    {
      MenuPrompt(N_ND->BBSStrings->PausePrompt,' ');
    }
    else
    {
      strcpy(prompt,promptstr);
      HBBS_ModifyString(prompt);
      PutText(prompt);
    }

    Get_Line(GL_IMMEDIATE,'\0',1,Timeout,NULL);
    PutText("\n\r");
  }
}

V_BOOL ContinuePrompt(char *promptstr,V_BIGNUM Flags,ULONG Timeout)
{
  V_BOOL retval=FALSE;
  char defaultchar='N';

  if (promptstr)
  {
    if (Flags & DCP_COLOURIZE)
    {
      MenuPrompt(promptstr,' ');
    }
    else
    {
      PutText(promptstr);
    }
  }
  else
  {
    PutText(ANSI_RESET "Continue ");

  }
  if (Flags & DCP_ADDYN)
  {
    if (Flags & DEFAULT_YES) defaultchar='Y';
    // add to end of string
    MenuPrompt("[Y]es, [N]o:",defaultchar);
  }

  strcpy(N_ND->CharsAllowed,"YyNn");

  Get_Line(GL_IMMEDIATE |
           GL_NORETURN |
           ((Flags & DEFAULT_NONE) ? GL_USECHARS : 0) |
           ((Flags & DCP_NOOLM) ? GL_NOOLM : 0) |
           ((Flags & DCP_COUNTDOWN) ? GL_COUNTDOWN : 0),
           '\0',1,Timeout,NULL);

  if (N_ND->OnlineStatus==OS_ONLINE) // losing carrier returns false!
  {
    if (N_ND->CurrentLine[0])
    {
      if (toupper(N_ND->CurrentLine[0]) == 'Y')
      {
        retval=TRUE;
      }
      else // user pressed another key..
      {
        if (toupper(N_ND->CurrentLine[0]) != 'N') // if user pressed N, then return FALSE, otherwise use default
        {
          if (Flags & DEFAULT_YES) retval=TRUE; // retval is set to false by default so we don't check
        }
      }
    }
    else
    {
      if (Flags & DEFAULT_YES) retval=TRUE; // retval is set to false by default so we don't check
    }

    if (!(Flags & DCP_NODISPLAY))
    {
      if (retval)
      {
        PutText("Y");
      }
      else
      {
        PutText("N");
      }
    }

/*
    if (((N_ND->CurrentLine[0]=='\0') && (Flags & DEFAULT_YES)) || (toupper(N_ND->CurrentLine[0])=='Y'))
    {
      if (!(Flags & DCP_NODISPLAY)) PutText("Y");
      retval=TRUE;
    }
    else
    {
      if (!(Flags & DCP_NODISPLAY)) PutText("N");
      retval=FALSE;
    }
*/
    if (Flags & DCP_CLEAR)
    {
      PutText("\r\033[K\r");
    }
    else
    {
      PutText("\r\n");
    }
  }

  return(retval);
}

/* old method

void CoolText(char *str)
{
  int loop,loop2;
  int len,clipstart;
  char tmpstr[BIG_STR],cmovestr[10];

  len=strlen(str);
  clipstart=len / 2;

  for (loop=1;loop<=len;loop++)
  {
    for (loop2=0;loop2<clipstart;loop2++) tmpstr[loop2]=' ';
    tmpstr[loop2]=0;
    strNcpy(tmpstr+strlen(tmpstr),str+clipstart,loop);
    PutText(tmpstr);


    if (loop<len)
    {
      sprintf(cmovestr,"\033[%dD",strlen(tmpstr));
      PutText(cmovestr);
    }
    if (loop % 2) clipstart --;
  }
}

*/

void CoolText(char *str)
{
  int loop,len,hl,c1,c2;
  char tmpstr[10];

  len=strlen(str);

  if (len<=3)
  {
    PutText(str);
  }
  else
  {

    hl=len/2;

    sprintf(tmpstr,"\033[%dC",hl);
    PutText(tmpstr);

    for (loop=0;loop<hl;loop++)
    {
      c1=(hl)-(loop+1);
      c2=(hl)+(loop);

      sprintf(tmpstr,"\033[%dD%c",loop+loop+1,str[c1]);
      PutText(tmpstr);

      if (loop>0)
      {
        sprintf(tmpstr,"\033[%dC",loop+loop);
        PutText(tmpstr);
      }

      sprintf(tmpstr,"%c",str[c2]);
      PutText(tmpstr);
    }
    if (len % 2 == 1) // odd number of chars ?
    {
      sprintf(tmpstr,"%c",str[len-1]);
      PutText(tmpstr);
    }
  }

}


#define SCROLL_FROMRIGHT 1
#define SCROLL_FROMLEFT 2

void ScrollAnsi(int ScrollDirection,char *str)
{
  int loop;
  int len;
  char tmpstr[BIG_STR],clipstr[BIG_STR];

  len=strlen(str);

  if (ScrollDirection == SCROLL_FROMRIGHT)
  {
    for (loop=1;loop<=len;loop++)
    {
      strNcpy(clipstr,str,loop);
      sprintf(tmpstr,"\033[%dD%s",loop,clipstr);
      PutText(tmpstr);
    }
  }

  if (ScrollDirection == SCROLL_FROMLEFT)
  {
    for (loop=1;loop<=len;loop++)
    {
      strNcpy(clipstr,str+len-loop,loop);
      PutText(clipstr);

      if (loop<len)
      {
        sprintf(tmpstr,"\033[%dD",loop);
        PutText(tmpstr);
      }
    }
  }
}

void DisplayBuffer(UBYTE *LineBuffer, BOOL CheckSequences, char *AbsolutePath) // LINEBUFFER MUST BE BIG_STR or larger!!
{
  char *errorstr="<ERROR>";
  UBYTE *tmpstr,checkstr[BIG_STR],mystr[BIG_STR],formatstr[20],outstr[BIG_STR],doorname[BIG_STR],dooroptions[BIG_STR];
  BOOL Done,found;
  short startpos,endpos;
  long PauseDelay;

  tmpstr=mystr;
  if (CheckSequences)
  {
    Done=FALSE;
    strcpy(tmpstr,LineBuffer);
    LineBuffer[0]=0;

    while (!Done)
    {
      Done=TRUE;

      // is there a sequence introducer in the buffer ?

      if ((startpos=position("@^",tmpstr))>=0)
      {
        // yup, but is it followed by a sequence terminator ?
        if ((endpos=fposition("@",tmpstr,startpos+2))>=0)
//        if ((endpos=position("@",tmpstr+startpos+2))>=0)
        {
          // yes it is. so make sure we check for more sequences when we've done this one
          Done=FALSE;

          // get the sequence from the buffer.. missing off the introducer
          // and the terminator, i.e. the bit between the @^ and the @


          // this should be replaced with...
          strftcpy(checkstr,tmpstr,startpos+2,endpos-1);

          // copy the normal text to the output buffer.
          if (startpos) strncat(LineBuffer,tmpstr,startpos);

          // modify our temporary buffer..

//          strfcpy(tmpstr,tmpstr,endpos+1);
          tmpstr=tmpstr+endpos+1;

          if (endpos-1 > startpos+2) // skip @^@'s
          {


            formatstr[0] = 0;
            if ((startpos = position("^",checkstr))>=0)
            {
              strNcpy(formatstr,checkstr,startpos);
              //strftcpy(formatstr,checkstr,0,startpos-1);
              strfcpy(checkstr,checkstr,startpos+1);
            }

            StripSpaces(checkstr);
            if ((startpos=position(" ",checkstr))>=0)
            {
              strNcpy(doorname,checkstr,startpos);
              strftcpy(dooroptions,checkstr,startpos+1,strlen(checkstr)-1);
            }
            else
            {
              strcpy(doorname,checkstr);
              dooroptions[0]=0;
            }

            if (stricmp(formatstr,"CLS")==0) PutText(ANSI_CLS); else
            if (stricmp(formatstr,"PAUSE")==0) PausePrompt(checkstr,0); else
            if (stricmp(formatstr,"SCREEN")==0) DisplayScreen(checkstr); else
            if (stricmp(formatstr,"SSCREEN")==0) DisplaySpecialScreen(checkstr,DSS_NONE); else
            if (stricmp(formatstr,"SYSDOOR")==0) GoSystemDoor(doorname,dooroptions); else
            if (stricmp(formatstr,"SCROLLFROMLEFT")==0)
            {
              PutText(LineBuffer);
              LineBuffer[0]=0;
              ScrollAnsi(SCROLL_FROMLEFT,checkstr);
            }
            else
            if (stricmp(formatstr,"SCROLLFROMRIGHT")==0)
            {
              PutText(LineBuffer);
              LineBuffer[0]=0;
              ScrollAnsi(SCROLL_FROMRIGHT,checkstr);
            }
            else
            if (stricmp(formatstr,"COOLTEXT")==0)
            {
              PutText(LineBuffer);
              LineBuffer[0]=0;
              CoolText(checkstr);
            }
            else
            if (stricmp(formatstr,"TPAUSE")==0)
            {
              PauseDelay=atol(checkstr);
              PausePrompt(NULL,PauseDelay >0 ? PauseDelay : 10);
            }
            else
            if (stricmp(formatstr,"USERDOOR")==0) GoUserDoor(doorname,dooroptions); else
            {

              // check checkstr against table and store result in same variable.

              // this looks shite, but is actually quite fast compared to checking for all occurences!

              found=TRUE;
              switch(toupper(checkstr[0]))
              {
                case 'B':
                  if (stricmp("BBSName",checkstr)==0) strcpy(checkstr,BBSGlobal->BBSName); else
                  if (stricmp("BBSLocation",checkstr)==0) strcpy(checkstr,BBSGlobal->BBSLocation); else
                  if (stricmp("BBSCountry",checkstr)==0) strcpy(checkstr,BBSGlobal->BBSCountry); else
                  if (stricmp("BBSSerial",checkstr)==0) sprintf(checkstr,"%d",BBSGlobal->BBSSerial); else
                  if (stricmp("BBSNodes",checkstr)==0) sprintf(checkstr,"%d",BBSGlobal->BBSNodes); else
                    found=FALSE;
                  break;
                case 'C':
                  if (stricmp("Conferences",checkstr)==0) sprintf(checkstr,"%d",BBSGlobal->Conferences); else
                  if (stricmp("ConfName",checkstr)==0)
                  {
                    if (N_ND->CurrentConf) sprintf(checkstr,"%s",N_ND->CurrentConf->node.ln_Name);
                  }
                  else
                  if (stricmp("CallsToday",checkstr)==0) sprintf(checkstr,"%d",BBSGlobal->CallsToday); else
                  if (stricmp("CallsThisWeek",checkstr)==0) sprintf(checkstr,"%d",BBSGlobal->CallsThisWeek); else
                  if (stricmp("CallsNodeToday",checkstr)==0) sprintf(checkstr,"%d",N_ND->CallsToday); else
                    found=FALSE;
                  break;
                case 'D':
                  if (stricmp("Date",checkstr)==0) HBBS_GetDate(checkstr); else
                    found=FALSE;
                  break;
                case 'F':
                    if (stricmp("File",checkstr)==0) strNcpy(checkstr,FilePart(AbsolutePath),BIG_STR-1); else
                    found=FALSE;
                  break;
                case 'P':
                    if (stricmp("Path",checkstr)==0) strNcpy(checkstr,AbsolutePath, (PathPart(AbsolutePath)+1) - AbsolutePath); else
                    found=FALSE;
                  break;
                case 'S':
                  if (stricmp("Sysop",checkstr)==0) strcpy(checkstr,BBSGlobal->SysopAccount); else
                    found=FALSE;
                  break;
                case 'T':
                  if (stricmp("TotalUsers",checkstr)==0) sprintf(checkstr,"%d",BBSGlobal->TotalUsers); else
                  if (stricmp("Time",checkstr)==0) HBBS_GetTime(checkstr); else
                    found=FALSE;
                  break;
                default:
                  found=FALSE;
              }

              if ((!found) && (N_ND->User->Valid))
              {
                found=TRUE;

                // Check the first character of the string to speed up finding replacement strings.

                switch(toupper(checkstr[0]))
                {
                  case 'A':
                    if (stricmp("AccessName",checkstr)==0) strcpy(checkstr,HBBS_AccessName(N_ND->User->CallData->Access)); else
                    if (stricmp("Access",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->Access); else
                    if (stricmp("A_UploadBytes",checkstr)==0) sprintf(checkstr,"%1.0lf",N_ND->User->CallData->ActualUploadBytes); else
                    if (stricmp("A_DownloadBytes",checkstr)==0) sprintf(checkstr,"%1.0lf",N_ND->User->CallData->ActualDownloadBytes); else
                    if (stricmp("A_UploadFiles",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->ActualUploadFiles); else
                    if (stricmp("A_DownloadFiles",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->ActualDownloadFiles); else
                      found=FALSE;
                    break;
                  case 'B':
                    if (stricmp("BestCPSUp",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->BestCPSUp); else
                    if (stricmp("BestCPSDown",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->BestCPSDown); else
                    if (stricmp("BRatio",checkstr)==0)
                    {
                      if ((N_ND->User->CallData->BytesRatio==0) || (HBBS_CheckAccess(ACS_UNLIMBYTES)))
                      {
                        strcpy(checkstr,"Disabled!");
                      }
                      else sprintf(checkstr,"%d",N_ND->User->CallData->BytesRatio);
                    }
                    else
                    if (stricmp("BytesUsed",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->BytesUsed); else
                    if (stricmp("BytesAllowed",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->BytesAllowed); else
                      found=FALSE;
                    break;
                  case 'C':
                    if (stricmp("ComputerType",checkstr)==0) strcpy(checkstr,N_ND->User->CallData->ComputerType); else
                    if (stricmp("Country",checkstr)==0) strcpy(checkstr,N_ND->User->CallData->Country); else
                    if (stricmp("CallsMade",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->CallsMade); else
                    if (stricmp("ChatAllowed",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->ChatAllowed); else
                    if (stricmp("CallsAllowed",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->CallsAllowed); else
                    if (stricmp("ChatUsed",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->ChatUsed); else
                    if (stricmp("CallsUsed",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->CallsUsed); else
                      found=FALSE;
                    break;
                  case 'D':
                    if (stricmp("DownloadBytes",checkstr)==0) sprintf(checkstr,"%1.0lf",N_ND->User->CallData->DownloadBytes); else
                    if (stricmp("DownloadFiles",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->DownloadFiles); else
                      found=FALSE;
                    break;
                  case 'F':
                    if (stricmp("FRatio",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->FilesRatio); else
                      found=FALSE;
                    break;
                  case 'G':
                    if (stricmp("Group",checkstr)==0) strcpy(checkstr,N_ND->User->CallData->Group); else
                    if (stricmp("GeoLocation",checkstr)==0) strcpy(checkstr,N_ND->User->CallData->GeoLocation); else
                      found=FALSE;
                    break;
                  case 'H':
                    if (stricmp("Handle",checkstr)==0) strcpy(checkstr,N_ND->User->CallData->Handle); else
                      found=FALSE;
                    break;
                  case 'L':
                    if (stricmp("LastConf",checkstr)==0) strcpy(checkstr,HBBS_ListName(BBSGlobal->ConfList,N_ND->User->CallData->LastConf-1)); else
                    if (stricmp("LastConfNum",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->LastConf); else
                    if (stricmp("LinesPerScreen",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->LinesPerScreen); else
                      found=FALSE;
                    break;
                  case 'M':
                    if (stricmp("MessagesWritten",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->MessagesWritten); else
                      found=FALSE;
                    break;
                  case 'P':
                    if (stricmp("PagesMade",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->PagesMade); else
                    if (stricmp("PhoneNumber",checkstr)==0) strcpy(checkstr,N_ND->User->CallData->PhoneNumber); else
                    if (stricmp("Password",checkstr)==0) strcpy(checkstr,N_ND->User->CallData->Password); else
                    if (stricmp("PreferredConfNum",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->PreferredConf); else
                    if (stricmp("PreferredConf",checkstr)==0) strcpy(checkstr,HBBS_ListName(BBSGlobal->ConfList,N_ND->User->CallData->PreferredConf)); else
                      found=FALSE;
                    break;
                  case 'R':
                    if (stricmp("RealName",checkstr)==0) strcpy(checkstr,N_ND->User->CallData->RealName); else
                      found=FALSE;
                    break;
                  case 'S':
                    if (stricmp("Status",checkstr)==0) sprintf(checkstr,"%c",N_ND->User->CallData->Status); else
                      found=FALSE;
                    break;
                  case 'T':
                    if (stricmp("TimeAllowed",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->TimeAllowed); else
                    if (stricmp("TimeUsed",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->TimeUsed+HBBS_TimeOnline()); else
                    if (stricmp("TimeLeft",checkstr)==0) sprintf(checkstr,"%d",HBBS_TimeLeft()); else
                    if (stricmp("TimeOnline",checkstr)==0) sprintf(checkstr,"%d",HBBS_TimeOnline()); else
                      found=FALSE;
                    break;
                  case 'U':
                    if (stricmp("UserID",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->UserID); else
                    if (stricmp("UserType",checkstr)==0) sprintf(checkstr,"%c",N_ND->User->CallData->UserType); else
                    if (stricmp("UploadBytes",checkstr)==0) sprintf(checkstr,"%1.0lf",N_ND->User->CallData->UploadBytes); else
                    if (stricmp("UploadFiles",checkstr)==0) sprintf(checkstr,"%d",N_ND->User->CallData->UploadFiles); else
                      found=FALSE;
                    break;

// *** Copy Me! ***
//                  case '':
//                      found=FALSE;
//                    break;

                  default:
                    found=FALSE;
                }
              }

              if (!found)
              {
                strcpy(checkstr,errorstr);
              }
              sprintf(outstr,"%%%ss",formatstr);
              sprintf(LineBuffer+strlen(LineBuffer),outstr,checkstr);
            }
          }
        }
      }

      // Check to see if the user has lost carrier.
      if (!N_ND->RunningAwait)
      {
        if (N_ND->OnlineStatus==OS_OFFLINE || CarrierLost())
        {
          Done=TRUE;
        }
      }
    }
    strcat(LineBuffer,tmpstr);  // and copy what's left..
  }



  if (N_ND->OnlineStatus==OS_ONLINE || N_ND->RunningAwait)
  {
    PutText(LineBuffer);
    PutText("\r\n");
  }
}

V_BOOL DisplayScreen(char *ScreenName)
{
  BPTR FH,FL;
  struct FileInfoBlock FIB;
  UBYTE buffer[BIG_STR];
  BOOL retval=FALSE,checkcodes=FALSE;
  char actualname[1024]="";

  // if we are online or the activedoor is "Awaiting Connect"  // *C* Document this! vvvvvv
  // AND file exists then continue..

  if ((N_ND->OnlineStatus==OS_ONLINE || N_ND->RunningAwait) &&
      (AssignOK(ScreenName)) &&
      (FL=Lock(ScreenName,ACCESS_READ)))
  {

    NameFromLock(FL,actualname,1023);

    if (Examine(FL,&FIB))
    {
      if (FIB.fib_Size)
      {
        if (FH=OpenFromLock(FL))
        {
          PutText(ANSI_RESET);

          retval=TRUE;

          if (FGets(FH,buffer,BIG_STR)) // check the first line for a @^@
          {
            if (strncmp(buffer,"@^@",3)==0) checkcodes=TRUE;
            stripcr(buffer);
            DisplayBuffer(buffer,checkcodes,actualname);
          }

          while (FGets(FH,buffer,BIG_STR) &&
                 (N_ND->OnlineStatus==OS_ONLINE || N_ND->RunningAwait))
          {
            stripcr(buffer);
            DisplayBuffer(buffer,checkcodes,actualname);
          }
          Close(FH);
          FL=NULL;

          PutText(ANSI_RESET);
        }
      }
    }
    if (FL) UnLock(FL);
  }

  return(retval);
}

/*
void MenuPrompt(char *promptstr,char promptdefault)
{
  char tmpstr[1024];
  char matchstr[4];
  char replacestr[1024];

  strcpy(tmpstr,promptstr);

  if (promptdefault!=' ')
  {
    sprintf(matchstr,"[%c]",promptdefault);
    sprintf(replacestr,"["ANSI_BOLD"%c"ANSI_RESET"]",promptdefault);

    replace(tmpstr,tmpstr,matchstr,replacestr);
  }

  if (tmpstr[0]=='[')
  {
    strcpy(replacestr,ANSI_FG_BLUE "[" ANSI_FG_YELLOW);
    strcat(replacestr,&tmpstr[1]);
    strcpy(tmpstr,replacestr);
  }

  replace(tmpstr,tmpstr," ["," "ANSI_FG_BLUE "[" ANSI_FG_YELLOW);
  replace(tmpstr,tmpstr,"]",ANSI_FG_BLUE "]" ANSI_FG_WHITE);

  PutText(ANSI_RESET);
  PutText(tmpstr);
}

  V_STRING MenuTextANSI;            // default: " [0;37m"    "white"
  V_STRING MenuOpenBracket;         // default: " [0;34m["   "blue["
  V_STRING MenuCloseBracket;        // default: " [0;34m]"   "blue]"
  V_STRING MenuHighlightANSI;       // default: " [0;33m"    "yellow"
  V_STRING MenuDefaultOptANSI;      // default: " [1;37m"    "boldwhite"
  V_STRING MenuPromptANSI;          // default: "  [0;34m: " " blue: "
  V_STRING MenuDefaultOptTextANSI;  // default: " [0;33m "   "yellow"

*/

void MenuPrompt(char *promptstr,char promptdefault)
{
  char tmpstr[1024];
  char matchstr[4];
  char replacestr[1024];
  short l;
  strcpy(tmpstr,promptstr);

  if (promptdefault!=' ')
  {
    sprintf(matchstr,"[%c]",promptdefault);
    sprintf(replacestr,"%s%s%c%s%s",N_ND->BBSCols->MenuOpenBracket,N_ND->BBSCols->MenuDefaultOptANSI,promptdefault,N_ND->BBSCols->MenuCloseBracket,N_ND->BBSCols->MenuDefaultOptTextANSI);

    replace(tmpstr,tmpstr,matchstr,replacestr);
  }

  if (tmpstr[0]=='[')
  {
    strcpy(replacestr,N_ND->BBSCols->MenuOpenBracket);
    strcat(replacestr,N_ND->BBSCols->MenuHighlightANSI);
    strcat(replacestr,&tmpstr[1]);
    strcpy(tmpstr,replacestr);
  }

  replacestr[0]=' ';
  replacestr[1]=0;
  strcat(replacestr,N_ND->BBSCols->MenuOpenBracket);
  strcat(replacestr,N_ND->BBSCols->MenuHighlightANSI);
  replace(tmpstr,tmpstr," [",replacestr);

  strcpy(replacestr,N_ND->BBSCols->MenuCloseBracket);
  strcat(replacestr,N_ND->BBSCols->MenuTextANSI);
  replace(tmpstr,tmpstr,"]",replacestr);

  PutText(ANSI_RESET);

  l=strlen(tmpstr);

  if (tmpstr[--l] == ':')
  {
    tmpstr[l] = 0;
    strcat(tmpstr+l,N_ND->BBSCols->MenuPromptANSI);
  }
  PutText(tmpstr);
  PutText(ANSI_RESET);
}
