/*
 *
 * 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
 */

/**********************************************************
 *
 *  UserPhrase.cpp  ==  User Phrase Class
 *
 *********************************************************/

//********************************************************
// *  User Phrase File Structure
//     Item            Len               Meaning
//     HeaderMark      16                "UserPhraseTable"
//     TotalItem       4
//     Each Item
//          ItemLen    2
//          struct PhraseItem {
//              u_char  *szKeys;         /* zhao */
//              u_char  KeyLen;          /* 4 */
//              u_char  *szPhrase;       /* ее */
//              u_short frequency;       /* 3232 */
//          };
//*********************************************************

#include <stdlib.h>
#include <stdio.h>
#include <UserPhrase.hpp>

CUserPhrase::CUserPhrase (char *szFileName /* = NULL */)
{
   FILE *fp;
   char buf[256];
   u_short len;
   PhraseItem Item;
   pCMemPhrase = new CMemPhrase (); 
   pCPhrase = new CPhrase (pCMemPhrase, 1024, 64);

   if (szFileName == NULL)
       return;

   if ((fp = fopen (szFileName, "rb")) == NULL)
   {
       perror (szFileName);
       exit (-1);
   }

   /* Mark Validation Verification */
   fread (buf, 1, 16, fp);
   if (strcmp (buf, USERPHRASEFILEMARK) != 0)
   {
      printf ("Bad File Mark.....\n");
      exit (-1);
   }
   u_long nTotalItem;
   fread (&nTotalItem, sizeof (u_long), 1, fp);
   for (u_long i = 0; i < nTotalItem; i++)
   {
       fread (&len, sizeof (u_short), 1, fp);
       fread (buf, 1, len, fp);
       bBufToPhraseItem ((u_char *) buf, len, &Item);
       pCPhrase->AddPhraseItem (&Item);
   } 
   fclose (fp);
}

CUserPhrase::~CUserPhrase ()
{
    delete pCPhrase;
    delete pCMemPhrase;
}

bool CUserPhrase::SaveUserPhrase (char *szFileName)
{
   FILE *fp;
   static char buf[1024];
   u_short len;
   if ((fp = fopen (szFileName, "wb")) == NULL)
   {
       perror (szFileName);
       exit (-1);
   }

   /* Mark Validation Verification */
   strcpy (buf, USERPHRASEFILEMARK);
   fwrite (buf, 1, 16, fp);

   u_long nTotalItem = pCPhrase->GetTotalItem ();
   fwrite (&nTotalItem, sizeof (u_long), 1, fp);

   for (u_long i = 0; i < nTotalItem; i++)
   {
       PhraseItem *pItem = pCPhrase->pGetPhraseItem (i);
       PhraseItemToBuf (pItem, (u_char *) buf, sizeof(buf), &len);
       fwrite (&len, sizeof (u_short), 1, fp);
       fwrite (buf, 1, len, fp);
   }
   fclose (fp);
   return true;
}

void CUserPhrase::AppendPhrase (PhraseItem *Item)
{
    pCPhrase->AddPhraseItem (Item);
}

u_long CUserPhrase::GetTotalItem ()
{
    return pCPhrase->GetTotalItem ();
}

bool CUserPhrase::bBufToPhraseItem (u_char *buf, u_short len, PhraseItem *Item)
{
    PhraseItem *p = Item;
    char *p1;

    p1 = (char *) buf;
    p->szKeys = p1;
    p1 += strlen (p->szKeys) + 1;

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

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

    p->frequency = (u_short *) p1;
    p1 += sizeof (*p->frequency);

    return true;
}

bool CUserPhrase::PhraseItemToBuf (PhraseItem *Item, u_char *buf, 
                      u_short maxlen, u_short *len)
{
    PhraseItem p, *q = Item;
    char *p1 = (char *) buf;

    u_short ItemLen = strlen (q->szKeys) + 1 +
                      sizeof (*q->KeyLen) +
                      strlen (q->szPhrase) + 1 +
                      sizeof (*q->frequency);
    if (ItemLen > maxlen)
    {
        printf ("fatal error, phrase is too long ....\n");
        exit (0);
    }
    p1 = (char *) buf;
    p.szKeys = p1;
    strcpy (p.szKeys, q->szKeys);
    p1 += strlen (q->szKeys) + 1;

    p.KeyLen = (u_char *) p1;
    *p.KeyLen = *q->KeyLen;
    p1 += sizeof (*q->KeyLen);

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

    p.frequency = (u_short *) p1;
    *p.frequency = *q->frequency;
    p1 += sizeof (*q->frequency);

    *len = ItemLen;

    return true;
}

