/*
 *
 * 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 <errno.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <netdb.h>
#include <unistd.h>
#include <iostream.h>
#include <pth.h>

#include <TLS_MemFile.hpp>
#include <TLS_HzInput.hpp>
#include <TLS_ImmOp.hpp>
#include <ImmComm.h>
#include <TLS_PthSocket.hpp>
#include <TLS_LibMain.hpp>

TLS_CImmOp *pMyCImmOp = NULL;
static PhraseItem *pNewPhrase (char *szCode, char *szPhrase, u_long freq, 
                               char *buf, int len);

TLS_CServerMain::TLS_CServerMain ()
{
    pImmOp = NULL;
}

TLS_CServerMain::~TLS_CServerMain ()
{
}

long TLS_CServerMain::OpenServer (char *ImmModule, char *ImmTable, long type)
{
    ImmOp_T * pImmOp = pMyCImmOp->OpenImm (ImmModule, type);
    if (pImmOp == NULL) 
    {
        printf ("OpenServer() = 0\n");
        return 0;
    }
    pTLS_CHzInput = new TLS_CHzInput (pImmOp, ImmTable, type);
    if (pTLS_CHzInput == NULL)
        return 0;
    if (pTLS_CHzInput->pClient == NULL || 
        pTLS_CHzInput->pClient->pImmClientData == NULL)
    {
        delete pTLS_CHzInput;
        pMyCImmOp->CloseImm (pImmOp);
        return 0;
    }
    // printf ("Open Server %ld\n", (long) pTLS_CHzInput);
    return (long) pTLS_CHzInput;
}

int TLS_CServerMain::CloseServer (long handle)
{
    // printf ("Close Server %ld\n", handle);
    pTLS_CHzInput = (TLS_CHzInput *) handle;
    ImmOp_T *pImmOp = pTLS_CHzInput->pImmSlib;
    delete pTLS_CHzInput;
    pMyCImmOp->CloseImm (pImmOp);
    return 1;
}

int TLS_CServerMain::ResetInput (long handle)
{
    pTLS_CHzInput = (TLS_CHzInput *) handle;
    return pTLS_CHzInput->ResetInput ();
}  

int TLS_CServerMain::SetInputMode (long handle, long mode)
{
    pTLS_CHzInput = (TLS_CHzInput *) handle;
    return pTLS_CHzInput->SetInputMode (mode);
}

int TLS_CServerMain::KeyFilter (long handle, u_char key, char *buf, int *len)
{
    // printf ("Server:: key = %c\n", key);
    pTLS_CHzInput = (TLS_CHzInput *) handle;
    return pTLS_CHzInput->KeyFilter (key, buf, len);
}

int TLS_CServerMain::ConfigInputArea (long  handle, long TotalSelection)
{
    pTLS_CHzInput = (TLS_CHzInput *) handle;
    pTLS_CHzInput->ConfigInputArea (TotalSelection);
    return 1;
}

int TLS_CServerMain::GetInputDisplay (long handle, char *buf, int buflen)
{
    pTLS_CHzInput = (TLS_CHzInput *) handle;
    return pTLS_CHzInput->GetInputDisplay (buf, buflen);
}

int TLS_CServerMain::GetSelectDisplay (long handle, char *buf, int buflen)
{
    pTLS_CHzInput = (TLS_CHzInput *) handle;
    return pTLS_CHzInput->GetSelectDisplay (buf, buflen);
}

int TLS_CServerMain::SetPhraseItem (long handle, long n, 
                     char *szCode, char *szPhrase, u_long freq)
{
    pTLS_CHzInput = (TLS_CHzInput *) handle;
    char buf[256];
    PhraseItem *pNew = pNewPhrase (szCode, szPhrase, freq, buf, sizeof(buf));
    pTLS_CHzInput->ModifyPhrase (n, pNew);
    return 1;
}

int TLS_CServerMain::AddUserPhrase (long handle, 
                     char *szCode, char *szPhrase, u_long freq)
{
    pTLS_CHzInput = (TLS_CHzInput *) handle;
    char buf[256];
    PhraseItem *pNew = pNewPhrase (szCode, szPhrase, freq, buf, sizeof (buf));
    pTLS_CHzInput->AppendPhrase (pNew);
    return 1;
}

int TLS_CServerMain::FlushUserPhrase (long handle)
{
    pTLS_CHzInput = (TLS_CHzInput *) handle;
    pTLS_CHzInput->FlushUserPhrase ();
    return 1;
}

PhraseItem *pNewPhrase (char *szCode, char *szPhrase, u_long freq, 
                       char *buf, int len)
{
    char *p1 = buf;
    PhraseItem *p;

    p = (PhraseItem *) p1;
    p1 += sizeof (PhraseItem);
 
    p->szKeys = p1;
    strcpy (p->szKeys, szCode);
    p1 += strlen (szCode) + 1;

    p->KeyLen = (u_char *) p1;
    *p->KeyLen = strlen (szCode);
    p1 += sizeof (u_char);

    p->szPhrase = p1;
    strcpy (p->szPhrase, szPhrase);
    p1 += strlen (p->szPhrase) + 1;

    p->frequency = (freq_t *) p1;
    *p->frequency = freq;
    p1 += sizeof (freq_t);
    return p;
}

#include <TLS_DoubleByteConvertor.hpp>
#include <TLS_AsciiConvertor.hpp>
#include <TLS_const.h>

TLS_CDoubleByteConvertor *pCDoubleByteConvertor = NULL;
TLS_CAsciiConvertor *pCAsciiConvertor [N_ASCII_CONVERTOR];

static struct AsciiConvertorConf
{
    char *szFileName;
} 
AsciiConvertorConf[2] =
{
    {UNICON_LIB"/sys-gb.tab"},
    {UNICON_LIB"/sys-big5.tab"}
};

long TCP_Connect (char *szIpAddr, short Port)
{
     TLS_CServerMain *p = new TLS_CServerMain ();
     return (long) p;
}

int TCP_Disconnect (long handle)
{
     TLS_CServerMain *p = (TLS_CServerMain *) handle;
     delete p;
     return 1;
}

int LibOpen () 
{
    pMyCImmOp = new TLS_CImmOp ();

    pCDoubleByteConvertor = new TLS_CDoubleByteConvertor ();

    for (int i = 0; i < N_ASCII_CONVERTOR; i++)
        pCAsciiConvertor [i] = 
                  new TLS_CAsciiConvertor (AsciiConvertorConf[i].szFileName);
    return 1;
}

int LibRelease ()
{
    delete pMyCImmOp;
    delete pCDoubleByteConvertor;
    for (int i = 0; i < N_ASCII_CONVERTOR; i++)
        delete pCAsciiConvertor [i];
    return 1;
}

