//xdict
//version 1.0
//Writen by ȯTC
//CopyLeft
//Compiled by PݽsĶ2.20
//2008.03.15

//*****eϱ`*****
#define COPY 1
#define NOT 2
#define OR 3
#define AND 4
#define XOR 5
#define LINECLEAN 0
#define LINENORMAL 1
#define LINEFAN 2
#define LINEBUFFER 0x40

//*****L*****
#define ESC_KEY 27
#define RIGHT_KEY 22
#define LEFT_KEY 23
#define UP_KEY 20
#define DOWN_KEY 21
#define CAPS_KEY 18
#define SHIFT_KEY 26
#define F1_KEY 28
#define F2_KEY 29
#define F3_KEY 30
#define F4_KEY 31
#define ENTER_KEY 13
#define DUP_KEY 19
#define DDOWN_KEY 14
#define HELP_KEY 25

//******ܶqƭ******
#define STREND 0x23
#define ADDREND 0x40
#define MAXINDEX 250
#define MAXSIZE 2500
#define MAXBUFLINE 150

char jiaming[10][5][3]= //W
{"","","","","",
"","","","","",
"","","@","B","D",
"F","H","K","M","O",
"Q","R","S","T","U",
"V","Y","\","_","b",
"e","f","g","h","i",
"k","z","m","X","o",
"p","q","r","s","t",
"v","w","x","X","y"};

long dicaddr,indexaddr;//Mުa}
int indexcount=0;//ʯުӼ
struct INDEX //ʲjɥΪ
{
char str[5]; //
long addre; //Vӯުa}
}index[MAXINDEX];

struct CMPSTR
{
char str[30]; //W
long addre; //Vw
long poi; //VU@ުw
long addrb; //U@a}ΩpŪjp
}cmpstr[4];  //ӷjɥΪ
char istr=0;  //Vcmpstr

struct INPUTSTR
{
char str[27]; //ݬd
char poi;  //Ыw
char length; //er
}inputstr;

struct BUFFER
{
char buf[MAXSIZE]; //ws
int ptl[MAXBUFLINE]; //Cq}Ya}
char lines; //`q
}buffer;

char fp; //w
char immediate=0;  //!0ɧYɬd


//P_O_re@
int ishead(char &string[],int poi)
{
char i;

for(i=0;i<=poi;i++)
 if(!(string[poi-i]&0x80))break;
return (i-((i>>1)<<1));
}


//Ūäq
void readbuf()
{
int tmp;

memset(buffer.buf,0,MAXSIZE);
fseek(fp,cmpstr[istr].addre,0);
fread(buffer.buf,1,cmpstr[istr].addrb-cmpstr[istr].addre,fp);
tmp=buffer.buf;
for(buffer.lines=0;;buffer.lines++)
 {
 buffer.ptl[buffer.lines]=tmp;
 tmp=strchr(buffer.ptl[buffer.lines],0xd);
 if(!tmp)break;
 if((tmp-buffer.ptl[buffer.lines])>26)
  {
  if(!ishead(buffer.ptl[buffer.lines],25))//re@r`
   tmp=buffer.ptl[buffer.lines]+26;
  else 
   tmp=buffer.ptl[buffer.lines]+25;
  memmove(tmp+1,tmp,strlen(tmp)+1);
  *(tmp++)=0;
  }//if>26
 else
  {
  memmove(tmp+1,tmp+2,strlen(tmp+2)+1);
  *(tmp++)=0;
  }
 }//for
}

//hX
int exitpro()
{
char key;

Block(33,24,128,56,0);
TextOut(35,26,"Exit programme?",COPY);
TextOut(52,39,"Yes",COPY);
TextOut(90,39,"No",COPY);
Rectangle(34,25,126,54,1);
Line(127,26,127,55,0x41);
Line(35,55,127,55,0x41);
Rectangle(51,38,71,51,1);
Line(72,39,72,52,0x41);
Line(52,52,72,52,0x41);
Rectangle(86,38,106,51,1);
Line(107,39,107,52,0x41);
Line(87,52,107,52,0x41);
Refresh();
for(;;)
{
key=getchar();
if(key==ENTER_KEY||key=='y')
 {
 fclose(fp);
 Block(52,39,70,50,2);
 Refresh();
 Delay(200);
 Block(52,39,70,50,2);
 Refresh();
 Delay(200);
 return TRUE;
 }
else if(key==ESC_KEY||key=='n')
 {
 Block(87,39,105,50,2);
 Refresh();
 Delay(200);
 Block(87,39,105,50,2);
 Refresh();
 Delay(200);
 return FALSE;
 }
}//for
}

//ojp
long fsize(char file)
{
long a,b;
a=ftell(file);
b=fseek(file,0,2);
fseek(file,a,0);
return b;
}

//ܦr
void changedic()
{
char datf;
char x,i,y;
char key;
int tmp;

datf=fopen("xdict.dat","r+");
fseek(datf,16,0);
buffer.ptl[0]=buffer.buf;
fread(buffer.buf,1,fsize(datf)-48,datf);
for(i=1;;i++)
 {
 x=strlen(buffer.ptl[i-1]);
 if(!x){buffer.ptl[i]=0;break;}
 buffer.ptl[i]=buffer.ptl[i-1]+x+strlen(buffer.ptl[i-1]+x+1)+2;
 }
i--;
x=y=0;
for(;;)
{
ClearScreen();
Rectangle(1,0,159,79,1);
for(key=x;key<(x+6)&&key<i;key++)
 {
 TextOut(2,1+(key-x)*13,buffer.ptl[key],COPY);
 }
if(y>key-x)y=key-x;
Block(2,1+y*13,158,13+y*13,2);
Refresh();
key=getchar();
Block(2,1+y*13,158,13+y*13,2);
if(key==UP_KEY)
 {
 if(y)y--;
 else if((--x)<0)x=0;
 }
else if(key==DOWN_KEY)
 {
 if(x+y+1<i)
  {
  if(y<5)y++;
  else x++;
  }
 else y=i-x-1;
 }
else if(key==DDOWN_KEY)
 {
 if(x+6<i)x=x+6;
 }
else if(key==DUP_KEY)
 {
 if(x-6<0)x=0;
 else x=x-6;
 }
else if(key==ENTER_KEY)
 {
 fclose(fp);
 fp=fopen(buffer.ptl[x+y]+strlen(buffer.ptl[x+y])+1,"r");
 if(!fp)
  {
  Block(30,31,130,49,0);
  Rectangle(32,33,129,48,1);
  Block(32,33,128,47,0);
  Rectangle(31,32,128,47,1);
  TextOut(32,34,"Can't open file!",COPY);
  Refresh();
  Delay(1000);
  }
 else
  {
  fseek(datf,0,0);
  tmp=buffer.ptl[x+y]+strlen(buffer.ptl[x+y])+1;
  fwrite(tmp,1,strlen(tmp)+1,datf);
  fclose(datf);
  return;
  }
 }//ENTER_KEY
else if(key==ESC_KEY)
 {fclose(datf);if(exitpro())exit(0);}
}//for
}

//Ūdat
void readdat()
{
char datf;
char buf[16];

ChDir("/");
if(!ChDir("/LavaData"))
 if(!ChDir("/GVMData"))
  {
  SetScreen(1);
  printf("Can't open path!\nPress any key to exit......");
  getchar();
  exit(0);
  }
memset(buf,0,16);
datf=fopen("xdict.dat","r");
fread(buf,1,16,datf);
fclose(datf);
fp=fopen(buf,"r");
if(!fp)changedic();
}

//VinputstrJstring
void insertstr(char &string[])
{
char buf[30];
strcpy(buf,inputstr.str+inputstr.poi);
strcpy(inputstr.str+inputstr.poi,string);
strcat(inputstr.str,buf);
inputstr.poi=inputstr.poi+strlen(string);
inputstr.length=inputstr.length+strlen(string);
}

//b̹WLݬd
void updatestr()
{
TextOut(2,1,"                         ",COPY);
TextOut(2,1,inputstr.str,COPY);
Line(2+inputstr.poi*6,1,2+inputstr.poi*6,12,0x42);
Refresh();
}

//RinputstrЫe@Ӧr
void deletestr()
{
char buf[30];
if(inputstr.poi)
 {
 strcpy(buf,inputstr.str+inputstr.poi);
 inputstr.length--;
 if(inputstr.str[--inputstr.poi]&0x80){inputstr.poi--;inputstr.length--;}
 strcpy(inputstr.str+inputstr.poi,buf);
 }
}


//b̹WXҦW
void paintjiaming()
{
char i,j;

Block(2,14,158,78,0);
for(i=0;i<5;i++)
 for(j=0;j<10;j++)
  TextOut(4+j*15,14+i*13,jiaming[j][i],COPY);
Refresh();
}


//JyW,Ϧ^
char inputjiaming()
{
char i,j;
char pian,zhuo;
char key;

i=j=pian=zhuo=0;
Rectangle(1,0,159,79,1);
Rectangle(1,0,159,13,1);
paintjiaming();
for(;;)
{

Block(4+j*15,14+i*13,16+j*15,26+i*13,2);
//Refresh();
updatestr();
key=getchar();
Block(4+j*15,14+i*13,16+j*15,26+i*13,2);
if((key==ESC_KEY)||(key==F3_KEY)||(key==F4_KEY))return key;
else if(key==RIGHT_KEY)
 {
 if((++j)>9) j=0;
 }
else if(key==LEFT_KEY)
 {
 if((--j)<0)j=9;
 }
else if(key==UP_KEY)
 {
 if((--i)<0)i=4;
 }
else if(key==DOWN_KEY)
 {
 if((++i)>4)i=0;
 }
else if(key==DUP_KEY)
 {
 if(inputstr.poi)
  {if(inputstr.str[--inputstr.poi]&0x80)inputstr.poi--;}
 else inputstr.poi=inputstr.length;
 }
else if(key==DDOWN_KEY)
 {
 if(inputstr.poi<inputstr.length)
  {if(inputstr.str[++inputstr.poi]&0x80)inputstr.poi++;}
 else inputstr.poi=0;
 }
else if(key==F2_KEY)
 {
 deletestr();
 }
else if(key==ENTER_KEY)
 {
 if((inputstr.length+2)<27)
  {
  insertstr(jiaming[j][i]);
  }
 }
else if(key==CAPS_KEY)
 {
 if(pian)
  {
  if(zhuo)
   {
   zhuo=0;
   #loaddata jiaming=  //W
   {"|","~","Ǣ","Ǥ","Ǧ",
   "ǧ","ǩ","ǫ","ǭ","ǯ",
   "Ǳ","ǳ","ǵ","Ƿ","ǹ",
   "ǻ","ǽ","","","",
   "","","","","",
   "","","","","",
   "","","","","",
   "","","","X","",
   "","","","","",
   "","","","X",""};
   paintjiaming();
   }
  else  //zhuo==0
   {
   zhuo=1;
   #loaddata jiaming=  //WB
   {"{","}","ǡ","ǣ","ǥ",
   "Ǩ","Ǫ","Ǭ","Ǯ","ǰ",
   "ǲ","Ǵ","Ƕ","Ǹ","Ǻ",
   "Ǽ","Ǿ","","","",
   "","","","","",
   "","","","","",
   "","","","","",
   "","","","X","",
   "","","","","",
   "","","","X",""};
   paintjiaming();
   }
  } //if pian
 else //pian==0
  {
  if(zhuo)
   {
   zhuo=0;
   #loaddata jiaming=
   {"","","","","",
   "","","","","",
   "","","@","B","D",
   "F","H","K","M","O",
   "Q","R","S","T","U",
   "V","Y","\","_","b",
   "e","f","g","h","i",
   "k","z","m","X","o",
   "p","q","r","s","t",
   "v","w","x","X","y"};
   paintjiaming();
   }
  else //zhuo==0
   {
   zhuo=1;
   #loaddata jiaming=  //WB
   {"","","","","",
   "","","","","",
   "","","A","C","E",
   "G","I","L","N","P",
   "X","[","^","a","d",
   "W","Z","]","`","c",
   "e","f","g","h","i",
   "j","z","l","X","n",
   "p","q","r","s","t",
   "u","w","x","X","y"};
   paintjiaming();
   }
  } //else pian
 } //if key
else if(key==SHIFT_KEY)
 {
 if(pian)
  {
  pian=zhuo=0;
  #loaddata jiaming=
  {"","","","","",
  "","","","","",
  "","","@","B","D",
  "F","H","K","M","O",
  "Q","R","S","T","U",
  "V","Y","\","_","b",
  "e","f","g","h","i",
  "k","z","m","X","o",
  "p","q","r","s","t",
  "v","w","x","X","y"};
  paintjiaming();
  }
 else //pian==0
  {
  pian=1;
  zhuo=0;
  #loaddata jiaming=  //W
  {"|","~","Ǣ","Ǥ","Ǧ",
  "ǧ","ǩ","ǫ","ǭ","ǯ",
  "Ǳ","ǳ","ǵ","Ƿ","ǹ",
  "ǻ","ǽ","","","",
  "","","","","",
  "","","","","",
  "","","","","",
  "","","","X","",
  "","","","","",
  "","","","X",""};
  paintjiaming();
  }
 }//if key
} //while
}



//VŪ@Ӳӯ,pGfilepoihsŪ,pGO̫@ӫh|TRUE
int readnext(long filepoi)
{
int tmp;
char x,y;

if(filepoi)
 {
 for(x=0;x<4;x++)
  {
  memset(cmpstr[x].str,0,30);
  cmpstr[x].poi=cmpstr[x].addre=cmpstr[x].addrb=0;
  }
 fseek(fp,filepoi,0);
 fread(&cmpstr[0].addre,1,4,fp);
 for(x=0;x<4;x++)
  {
  if(x)cmpstr[x].addre=cmpstr[x-1].addrb;
  getc(fp);
  for(y=0;;y++)
   {
   if((tmp=getc(fp))==STREND){cmpstr[x].str[y]=0;break;}
   cmpstr[x].str[y]=tmp;
   } //for y
  cmpstr[x].poi=ftell(fp);
  fread(&cmpstr[x].addrb,1,4,fp);
  if(cmpstr[x].addrb==indexaddr)break;
  }//for x
 return FALSE;
 }//if new

if(cmpstr[0].addrb==indexaddr)return TRUE; //last word

for(x=0;x<3;x++)
{
strcpy(cmpstr[x].str,cmpstr[x+1].str);
cmpstr[x].addre=cmpstr[x+1].addre;
cmpstr[x].addrb=cmpstr[x+1].addrb;
cmpstr[x].poi=cmpstr[x+1].poi;
}
if((cmpstr[2].addrb!=indexaddr)&&strcmp(cmpstr[2].str,""))
 {
 fseek(fp,cmpstr[3].poi,0);
 fread(&cmpstr[3].addre,1,4,fp);
 getc(fp);
 for(x=0;;x++)
  {
  if((tmp=getc(fp))==STREND){cmpstr[3].str[x]=0;break;}
  cmpstr[3].str[x]=tmp;
  }
 cmpstr[3].poi=ftell(fp);
 fread(&cmpstr[3].addrb,1,4,fp);
 }
else
{
strcpy(cmpstr[3].str,"");
cmpstr[3].poi=cmpstr[3].addre=cmpstr[3].addrb=0;
}
return FALSE;
}


int readbefore()
{
long poi;
char x,tmp;

poi=cmpstr[0].poi-strlen(cmpstr[0].str)-6;
if(poi==indexaddr)return TRUE;//the first one

for(x=3;x>0;x--)
{
strcpy(cmpstr[x].str,cmpstr[x-1].str);
cmpstr[x].addre=cmpstr[x-1].addre;
cmpstr[x].addrb=cmpstr[x-1].addrb;
cmpstr[x].poi=cmpstr[x-1].poi;
}

poi=poi-7;
for(;;poi--)
 {
 fseek(fp,poi,0);
 if(getc(fp)==STREND||ftell(fp)==indexaddr)
  {
  fseek(fp,4,1);
  if(getc(fp)==ADDREND)break;
  }
 }
fseek(fp,++poi,0);
fread(&cmpstr[0].addre,1,4,fp);
getc(fp);
for(x=0;;x++)
 {
 if((tmp=getc(fp))==STREND){cmpstr[0].str[x]=0;break;}
 cmpstr[0].str[x]=tmp;
 }
cmpstr[0].poi=ftell(fp);
cmpstr[0].addrb=cmpstr[1].addre;
return FALSE;
}



//X
void out(int boolean)
{
char i,y; //аOq
char key;

i=0;
Rectangle(1,0,159,79,1);
Block(2,1,158,78,0);
if(!boolean)
 {
 Rectangle(49,31,113,46,COPY);
 Block(48,10,112,45,0);
 Rectangle(48,30,112,45,COPY);
 TextOut(50,32,"Not found!",COPY);
 Refresh();
 Delay(1000);
 }
for(;;)
 {
 Block(2,1,158,78,0);
 for(y=0;y<6&&y<buffer.lines-i;y++)TextOut(2,1+y*13,buffer.ptl[y+i],COPY);
 Refresh();
 key=getchar();
 if(key==ESC_KEY)break;
 else if(key==DUP_KEY)
  {
  if((i-6)<0)i=0;
  else i=i-6;
  }
 else if(key==DDOWN_KEY)
  {
  if((i+6)<buffer.lines)i=i+6;
  }
 else if(key==UP_KEY){if((--i)<0)i=0;}
 else if(key==DOWN_KEY)
  {
  if((++i)>buffer.lines-6)i--;
  }
 else if(key==RIGHT_KEY)
  {
  if(cmpstr[istr].addrb!=indexaddr)
   {
   readnext(0);
   readbuf();
   i=0;
   }
  }
 else if(key==LEFT_KEY)
  {
  
  if(readbefore()&&istr)istr--;
  readbuf();
  i=0;
  }
 }//for
}

//qŪʯ
void readindex()
{
char i;
char x;

fseek(fp,10,0);
fread(&dicaddr,1,4,fp);
fread(&indexaddr,1,4,fp);
fseek(fp,2,1);
for(i=0;;i++)
 {
 fread(&index[i].addre,1,4,fp);
 if(!index[i].addre)break;
 }
indexcount=(--i);
fseek(fp,12,1);
for(i=0;i<indexcount;i++)
 {
 for(x=0;;x++)
  if((index[i].str[x]=getc(fp))==0)break;
 }
}

//d
int find(int boolean)
{
char i;
int y;

i=y=0;
Block(47,35,114,53,0);
Rectangle(49,37,113,52,COPY);
Block(48,36,112,51,0);
Rectangle(48,36,112,51,COPY);
TextOut(50,38,"Finding...",COPY);
Refresh();
if(boolean)
{
if(strcmp(inputstr.str,index[0].str)<0){readnext(index[0].addre);return FALSE;} //pGݬdĤ@ӳ٤p
//ʬd
for(i=1;i<indexcount;i++)
 {
 y=strcmp(index[i].str,inputstr.str);
 if(!y)break;
 if(y>0){i--;break;}
 }
if(i==indexcount)i--;
readnext(index[i].addre);
}
for(;;)
 {
 if(cmpstr[0].addrb==indexaddr) //last word
   {
   if(!strcmp(cmpstr[0].str,inputstr.str))return TRUE;
   else return FALSE;
   }
 y=strcmp(cmpstr[0].str,inputstr.str);
 if(!y)return TRUE;
 else if(y>0)return FALSE;
 else readnext(0);
 }//for
}

void list()
{
char i;

Block(2,14,158,61,0);
for(i=0;i<4;i++)
 {if(cmpstr[i].addre)TextOut(2,14+i*12,cmpstr[i].str,COPY);}
}

//,^
char listselect()
{
char key;
char i;

for(;;)
{
Block(2,14+istr*12,158,25+istr*12,2);
Refresh();
key=getchar();
Block(2,14+istr*12,158,25+istr*12,2);
if(key==UP_KEY)
 {
 if(istr)istr--;
 else readbefore();
 list();
 }
else if(key==DOWN_KEY)
 {
 if(istr<3&&cmpstr[istr+1].addre)istr++;
 else
  {
  readnext(0);
  if(!cmpstr[istr].addre)istr--;
  }
 list();
 }
else if(key==DDOWN_KEY)
 {
 readnext(0);
 readnext(0);
 readnext(0);
 readnext(0);
 for(i=4;i>0;i++)
  if(!cmpstr[istr].addre)istr--;
 list();
 }
else if(key==DUP_KEY)
 {
 for(i=0;i<4;i++)
  {if(readbefore())break;}
 list();
 }
else if(key==ENTER_KEY)
 {
 readbuf();
 out(TRUE);
 ClearScreen();
 Rectangle(1,0,159,62,1);
 Rectangle(1,0,159,13,1);
 list();
 updatestr();
 }
else if(key==ESC_KEY){find(TRUE);return key;}
}//for
}

void help()
{
char i,y; //аOq
char key;

strcpy(buffer.buf,"bDɭU:k䲾ʥ, F1Yɬd,F2Rr, F3q{r,F4J, WMſJr,U oU. byJɭU:J J,F2Rr,F3d, WU½䲾ʥ.");
buffer.ptl[0]=buffer.buf;
for(i=1;i<8;i++)
 {
 buffer.ptl[i]=strchr(buffer.ptl[i-1],' ');
 *(buffer.ptl[i]++)=0;
 }
buffer.lines=8;
i=0;
Rectangle(1,0,159,79,1);
Block(2,1,158,78,0);
for(;;)
 {
 Block(2,1,158,78,0);
 for(y=0;y<6&&y<buffer.lines-i;y++)TextOut(2,1+y*13,buffer.ptl[y+i],COPY);
 Refresh();
 key=getchar();
 if(key==ESC_KEY)break;
 else if(key==DUP_KEY)
  {
  if((i-6)<0)i=0;
  else i=i-6;
  }
 else if(key==DDOWN_KEY)
  {
  if((i+6)<buffer.lines)i=i+6;
  }
 else if(key==UP_KEY){if((--i)<0)i=0;}
 else if(key==DOWN_KEY)
  {
  if((++i)>buffer.lines-6)i--;
  }
 }//for
}

//Dɭ
void win()
{
long c;
int bool;

readdat();
readindex();
for(;;)
{
istr=0;
SetScreen(0);
ClearScreen();
Rectangle(1,0,159,62,1);
Rectangle(1,0,159,13,1);
if(immediate&&strcmp(inputstr.str,""))
 {
 list();
 }
else
 {
 TextOut(2,14,"Welcome to use this progra",COPY);
 TextOut(2,26,"mme  You can push help",COPY);
 TextOut(2,38,"button to get some help",COPY);
 TextOut(2,50,"information!",COPY);
 }
updatestr();
c=GetWord(3);
if(isprint(c)|(c&0xff00))
 {
 if(strcmp(inputstr.str,""))bool=FALSE;
 else bool=TRUE;
 insertstr(&c);
 if(immediate){find(bool);list();}
 }
else if(c==ESC_KEY)
 {if(exitpro())exit(0);}
else if(c==DOWN_KEY)
 {
 istr=0;
 listselect();
 }
else if(c==LEFT_KEY)
 {
 if(inputstr.poi)
  {if(inputstr.str[--inputstr.poi]&0x80)inputstr.poi--;}
 else inputstr.poi=inputstr.length;
 }
else if(c==RIGHT_KEY)
 {
 if(inputstr.poi<inputstr.length)
  {if(inputstr.str[++inputstr.poi]&0x80)inputstr.poi++;}
 else inputstr.poi=0;
 }
else if(c==F2_KEY)
 {
 deletestr();
 if(immediate)find(TRUE);
 }
else if(c==ENTER_KEY)
 {
 if(strcmp(inputstr.str,""))
  {
  if(immediate){find(FALSE);readbuf();out(TRUE);}
  else {bool=find(TRUE);readbuf();out(bool);}
  }
 }
else if(c==F4_KEY)
 {
 if(inputjiaming()==F3_KEY)
  {
  if((!find(TRUE))&&(!immediate)){readbuf();out(FALSE);}
  else
   {
   readbuf();
   out(TRUE);
   }
  }
 else if(immediate)find(TRUE);
 }
else if(c==F3_KEY)
 {
 changedic();
 readindex();
 if(immediate&&strcmp(inputstr.str,""))find(TRUE);
 }
else if(c==DUP_KEY) //MŦr
 {
 strcpy(inputstr.str,"");
 inputstr.poi=0;
 inputstr.length=0;
 }
else if(c==F1_KEY) //Yɬd߼Ҧ
 {
 immediate=(!immediate);
 if(immediate&&strcmp(inputstr.str,""))find(TRUE);
 }
else if(c==HELP_KEY)
 {
 help();
 }
}//for


}

void main()
{

win();
}


