/*
 *
 * UNICON - The Console Chinese & I18N
 * Copyright (c) 1999-2000
 *
 * This file is part of UNICON, a console Chinese & I18N
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * See the file COPYING directory of this archive
 * Author: see CREDITS
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ImmHzInput.hpp>
#include <xl_key.h>

CImmHzInput::CImmHzInput (int nTty0, ImmServer_T ImmServer, 
                    CConfigManager *pMyConfig0, CUniKey *pCMyKey):
                    CAImmHzInput (nTty0, ImmServer, pMyConfig0, pCMyKey) 
{
    pMyConfig = pMyConfig0;
}

CImmHzInput::~CImmHzInput ()
{
}

#include <MyConfig.hpp>
int CImmHzInput::DoSelectMethod (int method)
{
    assert (method >= 0 && method < 10); //Rat:只有0-9个选择键
    ImmOpMethod *p = &pMyConfig->GetTtyConfig (nTty-1)->aInputMethod[method];
//Rat:取得当前TTY的输入法
    if (p->szImmModule != NULL)
    {
        int b = OpenInputMethod (p->szImmModule, p->szImmTable, 
                                 p->type, p->szMethodName);
        if (b == 0)
            return 0;
        if (!IsHanziInput)
            ToggleInputMethod();//Rat:非汉字输入状态时转入汉字输入状态
        else
        {
            RefreshInputArea ();//Rat:否则只是输入法的切换
            RefreshInputMode ();
        }
        return b;
    }
    return 0;
}

/*************************************************************************
 *                        public function                                *
 *************************************************************************/
void CImmHzInput::SwitchHelpToNormal ()
{
    if (bShowFirstStartMsg == 0)
        return;
    bShowFirstStartMsg = 0;
    RefreshInputArea();
}

void CImmHzInput::ToggleInputMethod(void)
{
    if (pImm == NULL)
    {
        DoSelectMethod (0);
        return;
    }
    if (bShowFirstStartMsg == 1)
        SwitchHelpToNormal ();
   if (IsMakingPhrase)
       return;
    if (pImm != NULL)
    {
        IsHanziInput ^= 1;
        IsHanziInputBackup = IsHanziInput;
        if (IsHanziInput == 1)
        {
            IsFullCharBackup = IsFullChar;
            IsFullComma = IsFullCommaInChinese;
            IsFullChar = 0;
        }
        else
        {
            IsFullChar = IsFullCharBackup;
            IsFullComma = IsFullCommaInEnglish;
        }
        RefreshInputMode ();
        RefreshInputArea();
   }
}

void CImmHzInput::ToggleHalfFull(void)
{
   if (bShowFirstStartMsg == 1)
       SwitchHelpToNormal ();
   if (IsMakingPhrase)
       return;
   IsFullChar ^= 1;
   IsFullCharBackup = IsFullChar;
   if (IsFullChar == 1)
   {
       IsHanziInputBackup = IsHanziInput;
       IsHanziInput = 0;
   }
   else
   {
       IsHanziInput = IsHanziInputBackup;
   }
   RefreshInputMode ();
   RefreshInputArea ();
}

void CImmHzInput::ToggleUserDefinePhrase ()
{
   if (IsHanziInput != 1)
       return;
   if (IsMakingPhrase)
   {
       if (szUserPhrase[0] != '\0')
           MakingUserPhrase (szUserPhraseCode, szUserPhrase);
       pCMyInputArea->SetNewMethod (szOldMethod);
       RefreshInputArea ();
       pCMyKey->WriteKeys (nTty, szUserPhrase, strlen (szUserPhrase));
   }
   else
   {
       char buf[256];
       szUserPhrase[0] = '\0';
       GetInputDisplay (szUserPhraseCode, sizeof (szUserPhraseCode));
       if (szUserPhraseCode[0] == '\0')
           return;
       ResetInput ();
       strcpy (szOldMethod, pCMyInputArea->GetNewMethod ());
       sprintf (buf, "造词<%s>", szUserPhraseCode);
       pCMyInputArea->SetNewMethod (buf);
       RefreshInputArea ();
   }
   IsMakingPhrase = 1 - IsMakingPhrase;
}

int CImmHzInput::SendSysHelpKey (unsigned char key)
{
    int nDone = 0;
    switch (key)
    {
        case '\033':  /* ESCAPE */
            ShowTipItem = 0;
            return 1;
        case 255: /* Help */
            ShowTipItem = 0;
        case ' ':
            pCMyInputArea->ShowHelpItem (ShowTipItem++);
            break;
/*
        case HOME: // HOME 
	    ShowTipItem=0;
            pCMyInputArea->ShowHelpItem (ShowTipItem);
            break;
        case END: // END 
	    ShowTipItem=0;
            pCMyInputArea->ShowHelpItem (ShowTipItem--);
            break;
*/
        case '\010':
        case '\177':
            pCMyInputArea->ShowHelpItem (ShowTipItem--);
            break;
        default:
            nDone = 0;
            break;
    }
    return nDone;
}

void CImmHzInput::DoSwitchLang (int Tty, int coding)
{
    switch (coding)
    {
        case XL_DB_GB:
            ResetCoding (Tty, XL_DB_GB);
            break;
        case XL_DB_BIG5:
            ResetCoding (Tty, XL_DB_BIG5);
            break;
        case XL_DB_JIS:
            ResetCoding (Tty, XL_DB_JIS);
            break;
        case XL_DB_KSCM:
            ResetCoding (Tty, XL_DB_KSCM);
            break;
        case XL_DB_GBK:
            ResetCoding (Tty, XL_DB_GBK);
            break;
    }
}

int CImmHzInput::SendSysMenuKey (unsigned key)
{
    int nDone = 1;
    switch (key)
    {
        case '\033':  /* ESCAPE */
            break;
        case '0':
            //bExitInput = 1;
            break;
        case '1':     // GB
            DoSwitchLang (nTty, XL_DB_GB);
            break;
        case '2':     // Big5
            DoSwitchLang (nTty, XL_DB_BIG5);
            break;
        case '3':     // JIS
            DoSwitchLang (nTty, XL_DB_JIS);
            break;
        case '4':     // KSCM
            DoSwitchLang (nTty, XL_DB_KSCM);
            break;
        case '5':     // GBK 
            DoSwitchLang (nTty, XL_DB_GBK);
            break;
        default:
            nDone = 0;
            break;
    }
    return nDone;
}

int CImmHzInput::ExecPreFuncKey (u_char key)
{
    if (IsHelpMenu == 1)
    {
        if (SendSysHelpKey (key) == 1)
        {
            IsHelpMenu = 0;
            RefreshInputArea ();
        }
        return 1;
    }
    else if (IsSysMenu == 1)
    {
        if (SendSysMenuKey (key) == 1)
        {
            IsSysMenu = 0;
            RefreshInputArea ();
        }
        else
            pCMyInputArea->ShowSysMenu ();
        return 1;
    }
    return 0;
}

int CImmHzInput::ExecSystemFuncKey (u_char key)
{
    switch ( key )
    {
        case CTRL_ALT_0:
        case CTRL_ALT_1:
        case CTRL_ALT_2:
        case CTRL_ALT_3:
        case CTRL_ALT_4:
        case CTRL_ALT_5:
        case CTRL_ALT_6:
        case CTRL_ALT_7:
        case CTRL_ALT_8:
        case CTRL_ALT_9:
            DoSelectMethod (key - CTRL_ALT_0);
            break;
        case SHIFT_TAB: //Need inpbuf has some codes
	case CTRL_PLUS:
            ToggleUserDefinePhrase ();
            break;
        case CTRL_F5:
            IsSysMenu = 1;
            RefreshInputArea ();
            pCMyInputArea->ShowSysMenu ();
            break;
        case CTRL_SPACE:
            ToggleInputMethod(); //ShowHideInputMethod(int flag)
            break;
	case CTRL_ALT_G:
            DoSwitchLang (nTty, XL_DB_GBK);
	    break;
	case CTRL_ALT_B:
            DoSwitchLang (nTty, XL_DB_BIG5);
	    break;
	case CTRL_ALT_J:
            DoSwitchLang (nTty, XL_DB_JIS);
	    break;
	case CTRL_ALT_K:
            DoSwitchLang (nTty, XL_DB_KSCM);
	    break;
/*
	case CTRL_ALT_V:
	    break;
	case ARROW_UP:
	case ARROW_DOWN:
	case ARROW_LEFT:
	case ARROW_RIGHT:
	case PAGE_UP:
	case PAGE_DOWN:
	    break;
	case CTRL_SHIFT: 
	case CTRL_ALT_SHIFT:
	    break;
*/

        case SHIFT_SPACE:
	case CTRL_COMMA:
            ToggleHalfFull();
            break;
        case ALT_SPACE:
            if (IsHanziInput == 1)
            {
                IsFullCommaInChinese ^= 1;
                IsFullComma = IsFullCommaInChinese;
            }
            else
            {
                IsFullCommaInEnglish ^= 1;
                IsFullComma = IsFullCommaInEnglish;
            }
            RefreshInputMode ();
            RefreshInputArea ();
            break;
        case F1_HELP:
            if (IsHelpMenu == 1)
                return 1;
            IsHelpMenu = 1;
            SendSysHelpKey (255);
            break;
        default:
            return 0;
    };
    return 1;
}

int CImmHzInput::AllKeyFilter (u_char key, char *buf, int *len)
{
    if (ExecPreFuncKey (key) == 1)
        return 1;
    if (ExecSystemFuncKey (key) == 1)
        return 1;
    if (IsFullChar == 1 || 
        IsHanziInput == 1 ||
        IsFullComma == 1)
        return KeyFilter (key, buf, len);
    return 0;
}

int CImmHzInput::KeyFilters (u_char *key, int total)
{
    int n, len;
    char buf[32];
    for (int i = 0; i < total; i++)
    {
        n = AllKeyFilter (key[i], buf, &len);
        switch (n)
        {
            case 2:
               if (WriteUserDefinedPhrase (buf, len) == 0)
                   pCMyKey->WriteKeys (nTty, buf, len);
               break;
            case 0:
               if (WriteUserDefinedPhrase ((char *) &key[i], 1) == 0)
                   pCMyKey->WriteKeys (nTty, (char *) &key[i], 1);
               break;
        }
    }
    return total;
}

void CImmHzInput::PrintAll ()
{
//   CMyConfig *p = pMyConfig->GetTtyConfig (nTty-1);
//   printf ("CImmHzInput::nTty=%d, pMyConfig=0x%x\n", nTty, p);
}
