/*****  ru32lat.c *****/

#include <stdio.h>
#include <string.h>
#include <malloc.h>

#include "ru32var.h"

# define MAXTABLEN  10000

void InitLatinTable (void);
void ReplaceSubWord (char* gr1, char* gr2, char* ssource);
void SubstFromLat (char* LatinTable, char* trg);
void SubstToLat (char* LatinTable, char* trg);
void CreateStandardLatin (void);
void CreateHtmlTable (void);
void WriteToTable (char* src);
void ReadFromTable(char* gr1, char* gr2);
void SaveLatinFile(char* myfilename);
void LoadLatinFile(char* myfilename);

/* for interface:
procedure ExposeCurrentInMemo(my_latin : TStrings);
procedure ApplyLatinMemo(my_latin : TStrings);
procedure LoadEditLatinFile(my_latin :TStrings; myfilename :String);
procedure SaveEditLatinFile(my_latin :TStrings; myfilename :String);
*/



 char* LatinTable = NULL;
 char* HtmlTable = NULL;
 int /*bool*/  isStandardLatin;
 char CurrentLatin [81];
 char EditLatin [81];
 int /*bool*/  isStandardEdit;

 char* StandardLatin = "__stdlat.txt";

 char* CurrentTablePos;

// -------------- //

 char wrkstr_lat[257], wrkstr_lat1[257], wrkstr_lat2[257];;
   /* working string buffer */

// -------------- //

void InitLatinTable (void)
{
  CreateStandardLatin();
  CreateHtmlTable();

  strcpy (CurrentLatin, StandardLatin);
};

void ReplaceSubWord (char* gr1, char* gr2, char* ssource)
{
  int newmax, k, lengr1, lengr2;  char* cc;
//  printf ("replace- gr1,gr2: %s %s\n",gr1,gr2);

  cc = strstr (ssource, gr1);
  if (cc == NULL) return;

  lengr1 = strlen(gr1);   lengr2 = strlen(gr2);
  newmax = 256 - (lengr2 - lengr1);
  if (newmax > 256) newmax = 256;

  while (cc != NULL)
    {
      strncpy (wrkstr_lat, ssource, newmax);
      wrkstr_lat[newmax] = '\0';
      cc = strstr (wrkstr_lat, gr1);

      k = cc - wrkstr_lat;
      if (k > 0) strncpy (ssource, wrkstr_lat, k);
      ssource[k] = '\0';
      strcat (ssource, gr2);
      strcat (ssource, cc + lengr1);

      cc = strstr (ssource +k +lengr2, gr1);
    };
};


void SubstFromLat (char* LatinTable, char* trg)
{
  char  *gr1, *gr2;
// standart vars as in Win2Pol + additional variations: ju,ja etc

  gr1 = wrkstr_lat1;  gr2 = wrkstr_lat2;
  CurrentTablePos = LatinTable;

  while (*CurrentTablePos > '\1')
  {
    ReadFromTable(gr1,gr2);
    ReplaceSubWord (gr1,gr2,trg);
  };
};


void SubstToLat (char* LatinTable, char* trg)
{
  char *gr1, *gr2;

  gr1 = wrkstr_lat1;  gr2 = wrkstr_lat2;
  CurrentTablePos = LatinTable;

  while (*CurrentTablePos > '\1')
  {
    ReadFromTable(gr1,gr2);
    ReplaceSubWord (gr2,gr1,trg);
  };
};


void CreateStandardLatin (void)
{
  int tablen;
// standart vars as in Win2Pol + additional variations: ju,ja etc
  isStandardLatin = true;
  isStandardEdit  = true;

  if (LatinTable != NULL) free(LatinTable);
  LatinTable = (char*) malloc(1000);
  CurrentTablePos = LatinTable;

  WriteToTable ("BACbKA#ÂÀÑÜÊÀ");
  WriteToTable ("BCE#ÂÑÅ");
  WriteToTable ("Myppp#Ìóððð");
  WriteToTable (" eto# ýòî");
  WriteToTable (" ekz# ýêç");
  WriteToTable (" eks# ýêñ");
  WriteToTable (" eshcho # åùå ");
  WriteToTable ("tsya#òñÿ");
  WriteToTable ("tsia#òñÿ");
  WriteToTable ("tsja#òñÿ");
  WriteToTable ("otsuts#îòñóòñ");
  WriteToTable ("prisuts#ïðèñóòñ");
  WriteToTable ("molodets#ìîëîäåö");
  WriteToTable ("dets#äåòñ");
  WriteToTable ("Shch#Ù");
  WriteToTable ("Ch#×");
  WriteToTable ("Sh#Ø");
  WriteToTable ("Yu#Þ");
  WriteToTable ("Ya#ß");
  WriteToTable ("Iu#Þ");
  WriteToTable ("Ia#ß");
  WriteToTable ("Ju#Þ");
  WriteToTable ("Ja#ß");
  WriteToTable ("Yo#¨");
  WriteToTable ("YO#¨");
  WriteToTable ("Zh#Æ");
  WriteToTable ("E\x27#Ý");
  WriteToTable ("shch#ù");
  WriteToTable ("ch#÷");
  WriteToTable ("sh#ø");
  WriteToTable ("yu#þ");
  WriteToTable ("ya#ÿ");
  WriteToTable ("iu#þ");
  WriteToTable ("ia#ÿ");
  WriteToTable ("ju#þ");
  WriteToTable ("ja#ÿ");
  WriteToTable ("yo#¸");
  WriteToTable ("zh#æ");
  WriteToTable ("e\x27#ý");
  WriteToTable ("SHCH#Ø");
  WriteToTable ("CH#×");
  WriteToTable ("SH#Ø");
  WriteToTable ("YU#Þ");
  WriteToTable ("YA#ß");
  WriteToTable ("IU#Þ");
  WriteToTable ("IA#ß");
  WriteToTable ("JU#Þ");
  WriteToTable ("JA#ß");
  WriteToTable ("ZH#Æ");
  WriteToTable ("TSYA#ÒÑß");
  WriteToTable ("TSIA#ÒÑß");
  WriteToTable ("TS#Ö");
  WriteToTable ("H#Õ");
  WriteToTable ("h#õ");
  WriteToTable ("ts#ö");
  WriteToTable ("^#ú");
  WriteToTable ("^#Ú");
  WriteToTable ("\x27#ü");
  WriteToTable ("\x27#Ü");

  WriteToTable ("\x01");
};


void CreateHtmlTable (void)
{
  if (HtmlTable != NULL) free(HtmlTable);
  HtmlTable = (char*) malloc(1000);
  CurrentTablePos = HtmlTable;

  WriteToTable ("&Agrave;#À");
  WriteToTable ("&Aacute;#Á");
  WriteToTable ("&Acirc;#Â");
  WriteToTable ("&Atilde;#Ã");
  WriteToTable ("&Auml;#Ä");
  WriteToTable ("&Aring;#Å");
  WriteToTable ("&AElig;#Æ");
  WriteToTable ("&Ccedil;#Ç");
  WriteToTable ("&Egrave;#È");
  WriteToTable ("&Eacute;#É");
  WriteToTable ("&Ecirc;#Ê");
  WriteToTable ("&Euml;#Ë");
  WriteToTable ("&Igrave;#Ì");
  WriteToTable ("&Iacute;#Í");
  WriteToTable ("&Icirc;#Î");
  WriteToTable ("&Iuml;#Ï");

  WriteToTable ("&ETH;#Ð");
  WriteToTable ("&Ntilde;#Ñ");
  WriteToTable ("&Ograve;#Ò");
  WriteToTable ("&Oacute;#Ó");
  WriteToTable ("&Ocirc;#Ô");
  WriteToTable ("&Otilde;#Õ");
  WriteToTable ("&Ouml;#Ö");
  WriteToTable ("&times;#×");
  WriteToTable ("&Oslash;#Ø");
  WriteToTable ("&Ugrave;#Ù");
  WriteToTable ("&Uacute;#Ú");
  WriteToTable ("&Ucirc;#Û");
  WriteToTable ("&Uuml;#Ü");
  WriteToTable ("&Yacute;#Ý");
  WriteToTable ("&THORN;#Þ");
  WriteToTable ("&szlig#ß");

  WriteToTable ("&agrave;#à");
  WriteToTable ("&aacute;#á");
  WriteToTable ("&acirc;#â");
  WriteToTable ("&atilde;#ã");
  WriteToTable ("&auml;#ä");
  WriteToTable ("&aring;#å");
  WriteToTable ("&aelig;#æ");
  WriteToTable ("&ccedil;#ç");
  WriteToTable ("&egrave;#è");
  WriteToTable ("&eacute;#é");
  WriteToTable ("&ecirc;#ê");
  WriteToTable ("&euml;#ë");
  WriteToTable ("&igrave;#ì");
  WriteToTable ("&iacute;#í");
  WriteToTable ("&icirc;#î");
  WriteToTable ("&iuml;#ï");

  WriteToTable ("&eth;#ð");
  WriteToTable ("&ntilde;#ñ");
  WriteToTable ("&ograve;#ò");
  WriteToTable ("&oacute;#ó");
  WriteToTable ("&ocirc;#ô");
  WriteToTable ("&otilde;#õ");
  WriteToTable ("&ouml;#ö");
  WriteToTable ("&divide;#÷");
  WriteToTable ("&oslash;#ø");
  WriteToTable ("&ugrave;#ù");
  WriteToTable ("&uacute;#ú");
  WriteToTable ("&ucirc;#û");
  WriteToTable ("&uuml;#ü");
  WriteToTable ("&yacute;#ý");
  WriteToTable ("&thorn;#þ");
  WriteToTable ("&yuml;#ÿ");

  WriteToTable ("\x01");

};


void WriteToTable (char* src)
{
  int i;

  strcpy (CurrentTablePos,src);
  strcat (CurrentTablePos, "\x10");  // var 1
//  strcat (CurrentTablePos, "\x13\x10");  // var 2

  CurrentTablePos += strlen(src)+1;
};


void ReadFromTable(char* gr1, char* gr2)
{
  char* posend1, *posend2, *posbeg2;
  int nbytes, maxlen;

  maxlen = strlen(CurrentTablePos); 

  posend1 = strchr (CurrentTablePos,'#');
  posend2 = strchr (CurrentTablePos,'\x10');
  posbeg2 = (posend1 != NULL ) ? posend1+1 : CurrentTablePos ;

  if (posend1 == NULL) strcpy(gr1,"______??????");
  else
    { nbytes = posend1 - CurrentTablePos;
      if (nbytes > 256) nbytes =256; 
      strncpy (gr1,CurrentTablePos,nbytes);
      gr1[nbytes] = '\0';
    }

  if (posend2 == NULL) strcpy(gr2,"______??????");
  else
    { nbytes = posend2 - posbeg2;
      if (nbytes > 256) nbytes =256; 
      strncpy (gr2,posbeg2,nbytes);
      gr2[nbytes] = '\0';
    }

  if (posend2 != NULL  &&  strlen(posend2) >0 )  
      CurrentTablePos =  posend2+1;
  else  CurrentTablePos += maxlen;
};


void SaveLatinFile(char* myfilename)
{
  FILE *f2;
  int maxlen;

  if (LatinTable == NULL) return;

  if ( (f2=fopen(myfilename,"wb")) == NULL )
  { 
    strcpy (wrkstr_lat,"can't open new file : ");
    strcat (wrkstr_lat,myfilename);
    re4ShowMessage (wrkstr_lat);
    return;
  }

  maxlen=strlen(LatinTable);
  fwrite (LatinTable,1,maxlen,f2);
  fclose (f2);
};


void LoadLatinFile(char* myfilename)
{
  FILE *f1;
  int maxlen;
  long offs;

  if ( (f1=fopen(myfilename,"rb")) == NULL )
  { 
    strcpy (wrkstr_lat,"can't open LatinTable-File : ");
    strcat(wrkstr_lat,myfilename);
    re4ShowMessage (wrkstr_lat);
   
    CreateStandardLatin ();
    strcpy (CurrentLatin, StandardLatin);
  }
  else
  {
    fseek (f1, 0L, SEEK_END);
    offs = ftell(f1);
    maxlen  =  (offs < MAXTABLEN) ? offs : MAXTABLEN;

    if (LatinTable != NULL) free(LatinTable);
    LatinTable = (char*) malloc(maxlen +1);

    fseek (f1, 0L, SEEK_SET);
    fread (LatinTable, 1, maxlen, f1);
    LatinTable[maxlen] = '\0';
    fclose (f1);

    strcpy (CurrentLatin, myfilename);
    isStandardLatin = false;
    isStandardEdit = false;
  };
};


//-----  for interface : -----//

/*
procedure LoadEditLatinFile(my_latin :TStrings; myfilename :String);
begin
  try
   my_latin.LoadFromFile(myfilename);
   EditLatin:=myfilename;
   isStandardEdit:=false;
  except
   ShowMessage ('failed');
  end;
end;

procedure SaveEditLatinFile(my_latin :TStrings; myfilename :String);
begin
  try
   my_latin.SaveToFile(myfilename);
   EditLatin:=myfilename;
  except
   ShowMessage ('failed');
  end;
end;

procedure ExposeCurrentInMemo(my_latin : TStrings);
var gr1,gr2 : string;
begin
  EditLatin:=CurrentLatin;
  my_latin.clear;

  LatinTable.Seek(0,soFromBeginning);
  while LatinTable.Position < LatinTable.Size do
  begin
    ReadFromTable(LatinTable, gr1,gr2);
    my_latin.add(gr1+'#'+gr2);
  end;
end;

procedure ApplyLatinMemo(my_latin : TStrings);
var i,n : integer;
begin
  LatinTable.clear;
  n:=my_latin.count;
  for i:=0 to n-1 do
     WriteToTable (my_latin.Strings[i]);
  CurrentLatin:=EditLatin;
  isStandardLatin:=isStandardEdit;
end;

*/
