/*
	$Id: console_chewing.c,v 1.3 2001/07/09 11:41:14 kpchen Exp $
	a testing program for console input & output
	is not needed for xcin
*/
#include<assert.h>
#include<curses.h>
#include<stdio.h>
#include<string.h>
#include<time.h>
#include"chewingio.h"
#include"global.h"
#include"console_chewing.h"
#include"char.h"
#include"dict.h"
#include"zuin.h"
#include"hash.h"

// global data
FILE *fpout;
#ifdef DEBUG
FILE *fp_g ;
#endif

extern int lifetime;

void Live()
{
  static time_t nowtime, lasttime = 0 ;

  nowtime = time(NULL) ;
  if(lasttime != 0)
    lifetime += (nowtime - lasttime) ;
  lasttime = nowtime ;
}


//----------------------------------------------------
// io 

void IO_Init(void) 
{ 
  initscr() ; 
  cbreak() ; 
  noecho() ; 
  nonl(); 
  intrflush(stdscr, FALSE); 
  keypad(stdscr, TRUE); 
 
} 
 
void IO_End(void) 
{ 
  endwin(); 
} 

int GetKey(void)
{
  return getch();
}

void Clrscr(void)
{
  clear();
}

void ClrEol(void)
{
  clrtoeol();
}

void Gotoxy(int col,int row)
{
  move(row,col);
}

void PutText(const char *buf)
{
  printw("%s",buf);
}
//----------------------------------------------------

void ShowText(wch_t buf[],int len,wch_t zuinBuf[],int cursor)
{
  char out_buf[100];
  int i;

  memset( out_buf, 0 ,sizeof(out_buf));

  // modified by kpchen 99.8.24
  for(i=0;i<cursor;i++) 
    strcat( out_buf, buf[i].s ) ;
  
  for(i=0;i<ZUIN_SIZE;i++) {
    // assume zuinBuf terminated in '\0'
    strcat( out_buf, zuinBuf[i].s);
  }
  for(i=cursor; i<len; i++) 
    strcat( out_buf, buf[i].s);

  Gotoxy(0,0);
  ClrEol();
  PutText(out_buf);
}

void ShowInterval(wch_t buf[],int bufLen,IntervalType arrInter[],int nInter)
{
  char out_buf[100];
  int i,count ;
  int arrPos[MAX_PHONE_SEQ_LEN];

  count = 0;
  for(i=0;i<bufLen;i++) {
    arrPos[i] = count;
    count += strlen( (buf[i]).s);
  }
  arrPos[i] = count;

  memset( out_buf, ' ', count*(sizeof(char)) );
  out_buf[count] = '\0';

  for(i=0;i<nInter;i++) {
    out_buf[ arrPos[ arrInter[i].from]]  =  '[';
    out_buf[ arrPos[ arrInter[i].to] -1]    =  ']';
    memset( &out_buf[ arrPos[ arrInter[i].from] + 1],'-', 
	    arrPos[ arrInter[i].to] - arrPos[ arrInter[i].from] - 2);
  }

  Gotoxy(0,1);
  ClrEol();
  PutText(out_buf);
}

void ShowChoose(ChoiceInfo* pci, ChewingOutput *pgo)
{
  // 1.XXXX 2.XXXX 3.XXXX  XX/XX
  int i,no;
  char out_buf[100];
  char tempStr[] = "1.";

  if(pci->nPage == 0) {
    Gotoxy(0, 2) ;
    ClrEol() ;
    return ;  // kpchen 99.8.24
  }

  out_buf[0] = '\0';
  
  no = pci->pageNo * pci->nChoicePerPage;
  for(i=0;i<pci->nChoicePerPage; no++,i++) {
    if( no >= pci->nTotalChoice )
      break;

    tempStr[0] = pgo->selKey[i] ;
    
    strcat( out_buf, tempStr);
    strcat( out_buf, pci->totalChoiceStr[no]);
    strcat( out_buf, " ");
  }
  sprintf( &out_buf[strlen(out_buf)],"%d/%d",pci->pageNo+1, pci->nPage);


  Gotoxy(0,2);
  ClrEol();
  PutText( out_buf);
}

void SetCursor(wch_t buf[],int cursor)
{
  int i,count;

  for(count=0,i=0;i<cursor;i++) {
    count += strlen( buf[i].s);
  }
  Gotoxy(count,0);
}

void ShowState(int state)
{
  char buf[100];

  if( state == CHINESE_MODE )
    strcpy( buf,"Chinese");
  else
    strcpy( buf,"English");
  Gotoxy(0,3);
  ClrEol();
  PutText(buf);
}

//-----------------------------------------------------

void UIReDraw(ChewingOutput *pgo)
{

  ShowText(pgo->chiSymbolBuf,pgo->chiSymbolBufLen,pgo->zuinBuf,pgo->chiSymbolCursor);
  ShowInterval(pgo->chiSymbolBuf,pgo->chiSymbolBufLen,pgo->dispInterval,pgo->nDispInterval);
  ShowChoose(pgo->pci, pgo);
  ShowState(pgo->bChiSym);
  SetCursor(pgo->chiSymbolBuf, pgo->chiSymbolCursor);
}

void UICommitString(ChewingOutput *pgo)
{
  int i;
  static FILE *fpout = NULL ;

  if(fpout==NULL) fpout = fopen("output.txt","w");

  for(i=0;i<pgo->nCommitStr; i++) {
    // assume byte 3 and byte 4 were zero filled
    fprintf(fpout,"%s",pgo->commitStr[i].s);
  }
  fprintf(fpout,"\n");
  fflush(fpout);
  UIReDraw(pgo) ;
}

//-----------------------------------------------------
int CallSetConfig(ChewingData *pgdata)
{
  ConfigData config ;
  int i ;

  config.selectAreaLen = 40 ;
  // config.maxChiSymbolLen = 30 ;
  config.maxChiSymbolLen = 16 ;
  for(i=0; i<9; i++)
    config.selKey[i] = i + '1' ;
  config.selKey[9] = '0' ;
  SetConfig(pgdata, &config) ;
  return 0 ;
}

int main(void)
{
  int key;
  ChewingData *pgdata;
  ChewingOutput gOut ;
  ChewingConf cf ;

  cf.kb_type = KB_DEFAULT;
  // do some initialization
#ifdef DEBUG
  fp_g = fopen("debug.txt", "w") ;
#endif
  ReadTree(".") ; 
  InitChar(".") ; 
  InitDict(".") ; 
  ReadHash(".") ;
  IO_Init() ;
  Live() ; // 2000.8.28 kpchen
  pgdata = ALC(ChewingData,1) ; 
  assert(pgdata) ;
  InitChewing(pgdata, &cf) ;
  CallSetConfig(pgdata) ;

  for(;;) {
    key = GetKey();
    Live() ; // kpchen 2000.8.28
    switch(key) {
    case 13: // ENTER KEY
      OnKeyEnter(pgdata, &gOut);
      break;
    case KEY_ESC:
      OnKeyEsc( pgdata, &gOut) ;
      break ;
    case KEY_DEL:
      OnKeyDel( pgdata, &gOut);
      break;
    case KEY_BACK:
      OnKeyBackspace( pgdata, &gOut);
      break;
    case KEY_UP:
      OnKeyUp( pgdata, &gOut) ;
      break ;
    case KEY_DOWN:
      OnKeyDown( pgdata, &gOut);
      break;
    case KEY_LEFT:
      OnKeyLeft( pgdata, &gOut);
      break;
    case KEY_RIGHT:
      OnKeyRight( pgdata, &gOut);
      break;
    case KEY_TAB:
      OnKeyTab( pgdata, &gOut);
      break;
    case KEY_CTRL_A:
      OnKeyCapslock( pgdata, &gOut);
      break;
    default:
      OnKeyDefault( pgdata,key, &gOut);
    }
    if(gOut.nCommitStr)
      UICommitString(&gOut) ;
    else
      UIReDraw(&gOut) ;
  }
  
  return 0;
}










