#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <mem.h>
#include "types.h"
#include "develop.h"
#include "wndo_lib.h"
#include "keyboard.h"
#include "text_lib.h"
#include "mnu_inpt.h"

DrawHelpString( char * helpstring );

/*
===================
=
= GetTime
=
===================
*/

int32 GetTime( void )
   {
   int32 time;

   time = clock();
   time = (time * 1000) / CLOCKS_PER_SEC;
   return time;
   }


//******************************************************************************
//
// DrawCursor()
//
//******************************************************************************

static void DrawCursor (int32 windowhandle, int32 x, int32 y)
   {
   int32 ch;
   int32 foreground;
   int32 background;

   GetWindowCharacter
      (
      windowhandle,
      x,
      y,
      &ch,
      &foreground,
      &background
      );

   foreground ^= 14;
   background ^= 14;

   DrawWindowCharacter
      (
      windowhandle,
      x,
      y,
      ch,
      foreground,
      background
      );
   }



//******************************************************************************
//
// InputString()
//
///******************************************************************************

#define INPUTWINDOWHEIGHT (4)
#define MAXSTRING (80)
#define STRINGBACKGROUNDCOLOR COLOR_BLACK

boolean InputString
   (
   char * buf,
   char * header,
   boolean escok,
   int32 maxwidth
   )
   {
   boolean  redraw,
            cursorvis,
            done,
            result;
   char     s[MAXSTRING];
   int32    cursor;
   int32    lasttime;

   int32    windowhandle;
   int32    windowwidth;
   char     footer[MAXSTRING];
   int32    x,y;
   int32    keypress;

   KB_FlushKeyboardQueue();
   KB_ClearKeysDown();
   KB_TurnKeypadOn();

   strcpy (footer,"Escape to abort  Enter to end");

   windowwidth = maxwidth + 4;

   if ( strlen(header)-1 > windowwidth )
      {
      windowwidth = strlen(header)-1;
      }

   if ( strlen(footer)-1 > windowwidth )
      {
      windowwidth = strlen(footer)-1;
      }
   windowhandle = OpenCenteredWindow(
               windowwidth,
               INPUTWINDOWHEIGHT,
               COLOR_LIGHTCYAN,
               COLOR_BLUE);

   DrawWindowCenteredString
       (
       windowhandle,
       0,
       header,
       WindowForegroundColor( windowhandle ),
       WindowBackgroundColor( windowhandle )
       );
   DrawWindowDivider( windowhandle, 1 );

   DrawWindowCenteredString
       (
       windowhandle,
       INPUTWINDOWHEIGHT,
       footer,
       WindowForegroundColor( windowhandle ),
       WindowBackgroundColor( windowhandle )
       );
   DrawWindowDivider( windowhandle, INPUTWINDOWHEIGHT-1 );

   x = (WindowWidth( windowhandle ) - maxwidth) >> 1;
   y = 2;

   memset (footer,' ',sizeof(s));
   footer[maxwidth]='\0';
   DrawWindowString
       (
       windowhandle,
       x,
       y,
       footer,
       WindowForegroundColor( windowhandle ),
       STRINGBACKGROUNDCOLOR
       );

   memset (s,0,MAXSTRING);
   strcpy (s, buf);

   cursor      = strlen (s);
   redraw = true;
   cursorvis   = done   = false;

   lasttime  = GetTime();

   while (done==false)
      {
      if (cursorvis==true)
         {
         DrawCursor (windowhandle, x+cursor, y);
         cursorvis = false;
         }

      if (KB_KeyWaiting() == true)
         {
         redraw = true;
         keypress = KB_Getch();
         if (keypress == 0)
            {
            // Must be a scan code
            keypress = KB_Getch();
            switch (keypress)
               {
               case sc_LeftArrow:
                  if (cursor > 0)
                     {
                     cursor--;
                     redraw = true;
                     }
                  break;
               case sc_RightArrow:
                  if ( (cursor < (maxwidth-1) ) && s[cursor])
                     {
                     cursor++;
                     redraw = true;
                     }
                  break;

               case sc_Home:
                  if (cursor > 0)
                     {
                     cursor = 0;
                     redraw = true;
                     }
                  break;

               case sc_End:
                  if (cursor != strlen (s))
                     {
                     cursor = strlen (s);
                     redraw = true;
                     }
                  break;

               case sc_Delete:
                  if (s[cursor])
                     {
                     strcpy (s + cursor,s + cursor + 1);
                     redraw = true;
                     }
                  break;
               }
            }
         else
            {
            switch (keypress)
               {
               case asc_Tab:
               case asc_Enter:
                  strcpy (buf,s);
                  done    = true;
                  result  = true;
                  redraw  = true;
                  break;

               case asc_Escape:
                  if (escok==true)
                     {
                     done = true;
                     result = false;
                     }
                  break;

               case asc_BackSpace:
                  if (cursor>0)
                     {
                     strcpy (s + cursor - 1,s + cursor);
                     cursor--;
                     redraw = true;
                     }
                  break;
               default:
                  {
                  int32 length;

                  length = strlen (s);
                  if (
                        isprint( keypress ) &&
                        ( length < maxwidth-1 )
                     )
                     {
                     int32 i;

                     for (i = length + 1;i > cursor;i--)
                        s[i] = s[i - 1];
                     s[cursor++] = keypress;
                     redraw = true;
                     }
                  }
                  break;
               }
            }
         }
      if (redraw == true)
         {
         DrawWindowString
             (
             windowhandle,
             x,
             y,
             footer,
             WindowForegroundColor( windowhandle ),
             STRINGBACKGROUNDCOLOR
             );

         DrawWindowString
            (
            windowhandle,
            x,
            y,
            s,
            WindowForegroundColor( windowhandle ),
            STRINGBACKGROUNDCOLOR
            );
         redraw = false;
         cursorvis   = false;
         lasttime    = GetTime() - 1000;
         }

      if ( (GetTime() - lasttime) > 500 )
         {
         lasttime   = GetTime();
         cursorvis ^= true;
         }
      }

   CloseWindow( windowhandle );

   KB_FlushKeyboardQueue();
   KB_ClearKeysDown();
   KB_TurnKeypadOff();

   return (result);
   }

//******************************************************************************
//
// MenuInputString()
//
///******************************************************************************


boolean MenuInputString
   (
   char * buf,
   char * nameofstring,
   boolean escok,
   int32 maxwidth
   )
   {
   DrawHelpString( "Enter text for the given string\0" );

   return InputString
      (
      buf,
      nameofstring,
      escok,
      maxwidth
      );
   }

//******************************************************************************
//
// MenuInputValue()
//
///******************************************************************************

boolean MenuInputValue
   (
   int32 * value,
   char * nameofvalue,
   boolean escok,
   boolean hexadecimal,
   int32 minvalue,
   int32 maxvalue
   )
   {
   char string[80];
   char temp[16];
   char header[80];
   int32 maxwidth;
   int32 base;
   boolean done;
   boolean result;

   if (value == NULL)
      return false;

   strcpy (header,"Enter a value to ");
   strcat (header,nameofvalue);

   if (hexadecimal == true)
      {
      base = 16;
      strcat (header," in hexadecimal.");
      }
   else
      {
      base = 10;
      strcat (header," in decimal.");
      }

   strcpy (string,"Enter a value between ");
   ltoa (minvalue,temp,base);
   strcat (string,temp);
   strcat (string," and ");
   ltoa (maxvalue,temp,base);
   strcat (string,temp);
   DrawHelpString( string );

   ltoa (maxvalue,string,base);
   maxwidth = strlen(string)+1;
   if (*value != -1)
      {
      ltoa (*value,string,base);
      }
   else
      {
      memset(string,0,sizeof(string));
      }

   done = false;
   while (done == false)
      {
      if ( InputString ( string, header, escok, maxwidth ) == true )
         {
         int32 tempvalue;

         if (strlen(string)>0)
            {
            if (hexadecimal == true)
               {
               sscanf(string,"%lx",&tempvalue);
               }
            else
               {
               sscanf(string,"%ld",&tempvalue);
               }
            if ((tempvalue >= minvalue) && (tempvalue <= maxvalue))
               {
               done = true;
               *value = tempvalue;
               result = true;
               }
            }
         else
            {
            done = true;
            *value = -1;
            result = true;
            }
         }
      else
         {
         done = true;
         result = false;
         }
      }

   return (result);
   }

//******************************************************************************
//
// DrawSlider()
//
///******************************************************************************

void DrawSlider
   (
   int32 windowhandle,
   int32 x,
   int32 y,
   int32 position,
   int32 length,
   boolean vertical
   )
   {
   char slider[MAXSTRING];

   memset (slider,'°',sizeof(slider));
   slider[length+2]='\0';
   slider[position+1]='Û';
   if (vertical)
      {
      int32 i;

      slider[0]='';
      slider[length+1]='';
      for (i=0;i<strlen(slider);i++)
         {
         DrawWindowCharacter
            (
            windowhandle,
            x,
            y+i,
            slider[i],
            WindowForegroundColor( windowhandle ),
            STRINGBACKGROUNDCOLOR
            );
         }
      }
   else
      {
      slider[0]='';
      slider[length+1]='';
      DrawWindowString
          (
          windowhandle,
          x,
          y,
          slider,
          WindowForegroundColor( windowhandle ),
          STRINGBACKGROUNDCOLOR
          );
      }
   }

//******************************************************************************
//
// MenuInputSlider()
//
///******************************************************************************

#define SLIDERWIDTH (26)
#define SLIDERBARWIDTH (SLIDERWIDTH + 2)
#define TOTALSLIDERBARWIDTH (SLIDERWIDTH + 2 + 6)

void MenuInputSlider
   (
   int32 * value,
   char * header,
   int32 minimum,
   int32 maximum
   )
   {
   boolean  redraw,
            abort,
            done;

   char footer[MAXSTRING];

   int32    windowhandle;
   int32    windowwidth;
   int32    x,y;
   int32    position;
   int32    increment;
   int32    keypress;
   int32    original;


   original = *value;
   abort = false;
   KB_FlushKeyboardQueue();
   KB_ClearKeysDown();

   DrawHelpString( "Use the arrow keys, home and end to adjust the value\0" );
   strcpy (footer," Move Slider  Enter Accepts  Escape Aborts");

   windowwidth = TOTALSLIDERBARWIDTH;

   if ( strlen(header)-1 > windowwidth )
      {
      windowwidth = strlen(header)-1;
      }

   if ( strlen(footer)-1 > windowwidth )
      {
      windowwidth = strlen(footer)-1;
      }
   windowhandle = OpenCenteredWindow(
               windowwidth,
               INPUTWINDOWHEIGHT,
               COLOR_LIGHTCYAN,
               COLOR_BLUE);

   DrawWindowCenteredString
       (
       windowhandle,
       0,
       header,
       WindowForegroundColor( windowhandle ),
       WindowBackgroundColor( windowhandle )
       );
   DrawWindowDivider( windowhandle, 1 );

   DrawWindowCenteredString
       (
       windowhandle,
       INPUTWINDOWHEIGHT,
       footer,
       WindowForegroundColor( windowhandle ),
       WindowBackgroundColor( windowhandle )
       );
   DrawWindowDivider( windowhandle, INPUTWINDOWHEIGHT-1 );

   increment = (maximum-minimum)/SLIDERWIDTH;

   if (increment<1)
      {
      increment = 1;
      }

   x = (WindowWidth( windowhandle ) - TOTALSLIDERBARWIDTH) >> 1;
   y = 2;

   redraw = true;
   done = false;

   while (done==false)
      {
      if (KB_KeyWaiting() == true)
         {
         redraw = true;
         keypress = KB_Getch();
         if (keypress == 0)
            {
            // Must be a scan code
            keypress = KB_Getch();
            switch (keypress)
               {
               case sc_LeftArrow:
               case sc_kpad_4:
                  *value -= increment;
                  if (*value < minimum)
                     {
                     *value = minimum;
                     }
                  break;
               case sc_RightArrow:
               case sc_kpad_6:
                  *value += increment;
                  if (*value > maximum)
                     {
                     *value = maximum;
                     }
                  break;
               case sc_Home:
               case sc_kpad_7:
                  *value = minimum;
                  break;
               case sc_End:
               case sc_kpad_1:
                  *value = maximum;
                  break;
               }
            }
         else
            {
            switch (keypress)
               {
               case asc_Escape:
                  abort = true;
               case asc_Enter:
                  done = true;
                  break;
               }
            }
         }
      if (redraw == true)
         {
         char number[20];

         position = (((*value) - minimum)*SLIDERWIDTH)/(maximum-minimum);
         if (position >= SLIDERWIDTH)
            position--;
         DrawSlider (windowhandle, x, y, position, SLIDERWIDTH, false );
         strcpy (footer,"(\0");
         itoa( *value, number, 10 );
         strcat (footer,number);
         strcat (footer,")\0");
         if (strlen(footer)<8)
            {
            int32 len;

            len = strlen(footer);
            for (;len<=8;len++)
               footer[len]=' ';
            footer[9]='\0';
            }
         DrawWindowString
             (
             windowhandle,
             x+SLIDERBARWIDTH+1,
             y,
             footer,
             WindowForegroundColor( windowhandle ),
             WindowBackgroundColor( windowhandle )
             );
         redraw = false;
         }
      }

   CloseWindow( windowhandle );

   KB_FlushKeyboardQueue();
   KB_ClearKeysDown();

   if (abort)
      *value = original;

   return;
   }

