#define Uses_TSortedListBox
#define Uses_TStringCollection
#define Uses_TEvent
#define Uses_TKeys
#include <tv.h>

#include <string.h>
#include <ctype.h>
#include "tnocastc.h"

#define shiftKeys (char)(event.keyDown.shiftState & 0xFF)

void *TNoCaseStringCollection::readItem( ipstream& is )
{
 char buffer[256];
 is.readString(buffer,256);
 return (void *)strdup(buffer);
}

void TNoCaseStringCollection::writeItem( void *obj, opstream& os )
{
 os.writeString((char *)obj);
}

const char * const TNoCaseStringCollection::name="TNoCaseStringCollection";

void TSOSSortedListBox::getText(char *dest, ccIndex item, short maxChars)
{
 TNoCaseSOSStringCollection *i=(TNoCaseSOSStringCollection *)list();

 if ( i != 0 )
   {
    strncpy( dest, (const char *)(i->atStr(item)), maxChars );
    dest[maxChars] = '\0';
   }
 else
   *dest = EOS;
}

int TNoCaseSOSStringCollection::compare(void *s1,void *s2)
{
 return strcasecmp(GetString(s1),GetString(s2));
}

char *TNoCaseSOSStringCollection::GetString( void *h )
{
 return stkL->GetStrOf((stkHandler)h);
}

Boolean TNoCaseSOSStringCollection::Search( char *key, ccIndex& index )
{
 ccIndex l = 0;
 ccIndex h = count - 1;
 Boolean res = False;
 while( l <= h )
     {
     ccIndex i = (l +  h) >> 1;
     int c = strcasecmp( GetString(items[i]), key );
     if( c < 0 )
         l = i + 1;
     else
         {
         h = i - 1;
         if( c == 0 )
             {
             res = True;
             if( !duplicates )
                 l = i;
             }
         }
     }
 index = l;
 return res;
}


void TSOSSortedListBox::handleEvent(TEvent& event)
{
 char curString[256], newString[256];
 int value, oldPos, oldValue;

 oldValue = focused;
 TListBox::handleEvent( event );
 if( oldValue != focused )
     SearchPos = USHRT_MAX;
 if( event.what == evKeyDown )
     {
     if( event.keyDown.charScan.charCode != 0 )
         {
         value = focused;
         if( value < range )
             getText( curString, value, 255 );
         else
             *curString = EOS;
         oldPos = SearchPos;
         if( event.keyDown.keyCode == kbBack )
             {
             if( SearchPos == USHRT_MAX )
                 return;
             SearchPos--;
             if( SearchPos == USHRT_MAX )
                 ShiftState = shiftKeys;
             curString[SearchPos] = EOS;
             }
         else if( (event.keyDown.charScan.charCode == '.') )
             {
             char *loc = strchr( curString, '.' );
             if( loc == 0 )
                 SearchPos = USHRT_MAX;
             else
                 SearchPos = ushort(loc - curString);
             }
         else
             {
             SearchPos++;
             if( SearchPos == 0 )
                 ShiftState = shiftKeys;
             curString[SearchPos] = event.keyDown.charScan.charCode;
             curString[SearchPos+1] = EOS;
             }
         ((TNoCaseSOSStringCollection *)list())->Search( curString, value );
         if( value < range )
             {
             getText( newString, value, 255 );
             if( strncasecmp( curString, newString, SearchPos+1 )==0 )
                 {
                 if( value != oldValue )
                     {
                     focusItem(value);
                     setCursor( cursor.x+SearchPos, cursor.y );
                     }
                 else
                     setCursor(cursor.x+(SearchPos-oldPos), cursor.y );
                 }
             else
                 SearchPos = oldPos;
             }
         else
             SearchPos = oldPos;
         if( SearchPos != oldPos ||
             isalpha( event.keyDown.charScan.charCode )
           )
             clearEvent(event);
         }
     }
}

