/*
 *
 * 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/time.h>
#include <assert.h>
#include <AImmHzInput.hpp>
#include <UniKey.hpp>

CAImmHzInput::CAImmHzInput (int nTty0, ImmServer_T ImmServer0,
                      CConfigManager *pMyConfig,
                      CUniKey *pCMyKey0)
{
    pCMyKey = pCMyKey0;
    nTty = nTty0;
    pCMyInputArea = new CMyInputArea 
          (nTty, pMyConfig->GetTtyConfig (nTty - 1), pCMyKey);
    ImmServer = ImmServer0;
    IsMakingPhrase = 0;
    bShowFirstStartMsg = 1,
    IsHelpMenu = 0,
    IsSysMenu = 0,
    IsFullChar = 0,
    IsHanziInput = 0,
    IsFullComma = 0;
    IsHanziInputBackup = 0,
    IsFullCharBackup = 0,
    IsFullCommaInChinese = 0,
    IsFullCommaInEnglish = 0;
    ShowTipItem = 0;
    nTotalSelection = 0;
    pImm = NULL;
}

void CAImmHzInput::ResetCoding (int nTTY, int coding)
{
//    printf ("void CAImmHzInput::ResetCoding (coding=%d, ntty=%d)\n", 
//             coding, nTTY);
    if (pMyConfig->GetTtyCoding (nTTY - 1) == coding)
        return;
    CloseInputMethod ();
    pMyConfig->SetTtyCoding (nTTY - 1, coding);
    pCMyKey->SetCurrentFont (nTTY - 1, coding);
    CMyConfig *p = pMyConfig->GetTtyConfig (nTTY - 1);
//  p->PrintAll ();
    pCMyInputArea->ResetMyConfig (p); //MyConfig->GetTtyConfig (nTTY - 1));
//    RefreshInputArea ();
//    RefreshInputMode ();
//    printf ("ResetCoding RefreshingInputArea (0,0)\n");
//    usleep (200);
    if (pCMyKey->GetCurrentTTY () == nTTY - 1)
        pCMyInputArea->RefreshInputArea (0, 0);
}

int CAImmHzInput::OpenInputMethod 
            (char *szImmModule, 
             char *szImmTable, 
             u_long type,
             char *szMethod) 
{
    IMM *p;
    if (IsMakingPhrase == 1)
        return 0;
    // printf ("%ld %s %s %ld\n", ImmServer, szImmModule, szImmTable, type);
    CloseInputMethod ();
    p = IMM_OpenInput (ImmServer, szImmModule, szImmTable, type);

    assert (p != NULL);

    /* Save all the system phrase and user phrase into disk */
    DoFlush ();

    /* Reset the Input method */
    // CloseInputMethod ();
    pImm = p;
    pCMyInputArea->SetNewMethod (szMethod);
    return 1;
}

int CAImmHzInput::CloseInputMethod () 
{
    if (IsMakingPhrase == 1)
        return 0;
    if (pImm == NULL)
        return 0;
    IMM_CloseInput (pImm);
    pCMyInputArea->SetNewMethod ("Unknown");
    IsMakingPhrase = 0;
    bShowFirstStartMsg = 1,
    IsHelpMenu = 0,
    IsSysMenu = 0,
    IsFullChar = 0,
    IsHanziInput = 0,
    IsFullComma = 0;
    IsHanziInputBackup = 0,
    IsFullCharBackup = 0,
    IsFullCommaInChinese = 0,
    IsFullCommaInEnglish = 0;
    ShowTipItem = 0;
    nTotalSelection = 0;
    pImm = NULL;
    return 1;
}

CAImmHzInput::~CAImmHzInput ()
{
    CloseInputMethod ();
    delete pCMyInputArea;
}

int CAImmHzInput::KeyFilter (u_char key, char *buf, int *len)
{
    if (pImm == NULL)
        return 0;
    int n = IMM_KeyFilter (pImm, key, buf, len);
    RefreshInputArea ();
    return n;
}

int CAImmHzInput::RefreshInputMode ()
{
    long mode = 0;
    if (pImm == NULL)
        return 0;
    if (IsFullChar)
        mode |= IMM_FULL_CHAR_MODE;
    if (IsHanziInput)
        mode |= IMM_DOUBLE_BYTE_MODE;
    if (IsFullComma)
        mode |= IMM_FULL_SYMBOL_MODE;
    return IMM_SetInputMode (pImm, mode);
}

void CAImmHzInput::RefreshInputArea ()
{
   pCMyInputArea->ClearInputArea ();
   if (bShowFirstStartMsg == 1)
       pCMyInputArea->ShowFirstStartMsg ();
   else if (IsHelpMenu == 1)
       pCMyInputArea->ShowHelpItem (ShowTipItem);
   else if (IsSysMenu == 1)
       pCMyInputArea->ShowSysMenu ();
   else
   {
       if (pImm == NULL)
           return;
       int which;
       if (IsFullChar == 1)
           which = 3;
       else
           which = IsHanziInput;
       char buf[1024];

       if (IMM_GetInputDisplay (pImm, buf, sizeof (buf)) == 0)
           buf[0] = '\0';
       pCMyInputArea->SetInputDisplay (buf);
       nTotalSelection = IMM_GetSelectDisplay (pImm, buf, sizeof (buf));
       if (nTotalSelection == 0)
           buf[0] = '\0';
       pCMyInputArea->SetSelectDisplay (buf);
       pCMyInputArea->RefreshInputArea (which, IsFullComma);
   }
}
void CAImmHzInput::ResetInput ()
{
    IMM_ResetInput (pImm);
}

int CAImmHzInput::MakingUserPhrase (char *szCode, char *szPhrase)
{
    IMM_AddUserPhrase (pImm, szCode, szPhrase, USER_PHRASE_FREQ);
    DoFlush (); 
    return 1;
}

void CAImmHzInput::DoFlush ()
{
/*
    if (pImm != NULL) 
        IMM_FlushUserPhrase (pImm); 
 */
}

int CAImmHzInput::WriteUserDefinedPhrase (char *szPhrase, int len)
{
   if (IsMakingPhrase)
   {
       char buf[256];
       int n = strlen (szUserPhrase);

       if (len == 1 && isalnum (szPhrase[0]) == 0)
       {
           switch (szPhrase[0])
           {
               case '\010':  /* BackSpace Ctrl+H */
               case '\177':  /* BackSpace */
                   if (isalnum (szUserPhrase[n-1]) == 1)
                       n --;
                   else
                       n -= 2;
                   if (n < 0)
                       n = 0;
                   break;
               default:
                   return 1;
           }
       }
       else
       {
           memcpy (&szUserPhrase[n], szPhrase, len);
           n += len;
       }
       szUserPhrase[n] = '\0';
       sprintf (buf, "ิ์ดส:<%s>%s", szUserPhraseCode, szUserPhrase);
       pCMyInputArea->SetNewMethod (buf);
       RefreshInputArea ();
       return 1;
   }
   return 0;
}

void CAImmHzInput::GetInputDisplay (char *buf, int len)
{
   char buf0[256];
   if (pImm == NULL)
      return;
   if (IsFullChar == 1)
      return;
   if (IMM_GetInputDisplay (pImm, buf0, sizeof (buf0)) == 0)
   {
      buf[0] = '\0';
      return;
   }
   char *p = buf;
   for (int i = 0; i < (int) strlen (buf0); i++)
   {
      if (buf0[i] == '-')
         continue;
      if (buf0[i] == ' ')
         break;
      *p++ = buf0[i];
   }
   *p = '\0';
}
