/******************************************************************************
 * program:     wp2latex                                                      *
 * function:    module for conversion Accent files into LaTeX 		      *
 * modul:       pass1acc.cc                                                   *
 * description: This module contains parser for Accent documents. It could be *
 *		optionally compiled with WP2LaTeX package.		      *
 * licency:     GPL		                                              *
 ******************************************************************************/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stringa.h>

#include<lists.h>
#include<dbllist.h>

#include"wp2latex.h"
#include"pass1xml.h"
#include "cp_lib/cptran.h"


/*Register translators here*/
class TconvertedPass1_Accent: public TconvertedPass1_XML
     {
public:
     virtual int Convert_first_pass(void);

      void AccentImage(void);
      void AccentLanguage(void);
      void ProcessKeyAccent(void);
     };
TconvertedPass1 *Factory_Accent(void) {return new TconvertedPass1_Accent;}
FFormatTranslator FormatAccent("Accent",Factory_Accent);


typedef enum
{
    ACC_SOFT_RETURN = 128,
    ACC_ATTR_ON = 129,
    ACC_ATTR_OFF = 130,
    ACC_HRT = 131,
    ACC_SRT = 132,
    ACC_PAR_OFF = 133,
    ACC_JUSTIFICATION = 134,
    ACC_START_SECTIO =135,
    ACC_END_SECTION = 136,
    ACC_HLINE = 139,
    //	case 140:IndentHTML(this);	 break;
    ACC_END_INDENT = 141,
    ACC_TABLE = 143,

    ACC_IMAGE = 145,
    ACC_LANGUAGE = 146
} E_ACCENT_OPS;


#define AccentVersion "0.5"


void TconvertedPass1_Accent::AccentImage(void)
{
#ifdef DEBUG
  fprintf(log,"\n#AccentImage() ");fflush(log);
#endif
int i;
long len;
const char *TAG;
TBox Box;
string NewFilename;

  if(length(TAG_Args)<1) return;
  TAG = TAG_Args[0];
  if(TAG==NULL) return;
  if(!strncmp(TAG,"GRAPHIC",7)) TAG+=7;
  while(isspace(*TAG)) TAG++;
  NewFilename = '.';
  while(isalnum(*TAG))
  {
    NewFilename += *TAG;
    TAG++;
  }
  while(isspace(*TAG)) TAG++;
  i = sscanf(TAG,"%ld",&len);
  if(len<0 || i<1)
     {
     if(err != NULL)
	fprintf(err,_("\nError: Length of embedded image is not specified!"));
     return;
     }
  NewFilename = GetSomeImgName(NewFilename());
  NewFilename = MergePaths(OutputDir,RelativeFigDir) + NewFilename;

  i = fgetc(wpd);
  if(i=='\n' || i=='\r')
      i=fgetc(wpd);
  //fseek(wpd, 4, SEEK_CUR);

  //if(CopyFile(NewFilename(), wpd, len) < 0)
  {
    fseek(wpd,len,SEEK_CUR);  //Skip image - this might be improved
    //if(err != NULL)
    //	fprintf(err,_("\nError: cannot open file \"%s\"!"),NewFilename());
    NewFilename = "dummy";
  }
  //NewFilename = "dummy";	///!!!!!!!! vyhodit

  Box.Width = -1; 		// Undefined, use default 100mm
  Box.Image_type=0;		// Image on disk
  Box.AnchorType = 0; 	// 0-Paragraph, 1-Page, 2-Character
  Box.HorizontalPos=2;	// 0-Left, 1-Right, 2-Center, 3-Full
  Box.Image_size=0;

  ImageWP(this, NewFilename(), Box);
}


void TconvertedPass1_Accent::AccentLanguage(void)
{
#ifdef DEBUG
  fprintf(log,"\n#TconvertedPass1_Accent::AccentLanguage() ");fflush(log);
#endif
const char *TAG;
unsigned LangCode;

  if(length(TAG_Args)<1) return;
  TAG = TAG_Args[0];
  if(TAG==NULL) return;
  while(isspace(*TAG)) TAG++;

  if(TAG[0]=='0' && TAG[1]=='x')
    LangCode = strtoul(TAG+2, NULL, 16);
  else
    LangCode = strtoul(TAG+2, NULL, 10);

  if(LangCode==0x2d171800)	// Czech
  {
    SelectTranslator("cp1250");
  }
  else if(LangCode==0x4f1b4a00) // Hebrew
  {
    SelectTranslator("cp1255");
  }
  else
  {
    ConvertCpg = NULL;
  }
}


void TconvertedPass1_Accent::ProcessKeyAccent(void)
{
#ifdef DEBUG
  fprintf(log,"\n#TconvertedPass1_Accent::ProcessKeyAccent() ");fflush(log);
#endif
string TAG;
const char *tag;
uint8_t by, subby;

 *ObjType=0;
 if(this->TAG.isEmpty()) ReadXMLTag();
 by = this->by;
 subby = this->subby;

 switch(by)
	{
	case XML_char:
               switch(this->subby)                        //Normal character
		  {
		  case 10:
		  case 13:by=128;break; //CR
		  case  9:strcpy(ObjType, "!Tab");
		  case 32:by=32;break;  //Space
		  }
	       break;
	case XML_extchar:
               if(this->TAG.isEmpty()) break;			//Extended chatacter &xxx;
	       TAG = Ext_chr_str(this->TAG[0],this) + copy(this->TAG,1,length(this->TAG)-1);
	       tag = TAG();
	       by = 201;
	       break;
	case XML_tag:
               TAG = copy(this->TAG,1,length(this->TAG)-2);	//Normal tag <xxx>
	       if((tag=TAG())==NULL) break;
	       if(TAG=="AC"){by=134;subby=0x82;break;}	//Justification Center
	       if(TAG=="AJ"){by=134;subby=0x81;break;}	//Justification Full
	       if(TAG=="AL"){by=134;subby=0x80;break;}	//Justification Left
	       if(TAG=="AR"){by=134;subby=0x83;break;}	//Justification Right
	       if(TAG=="B")
			{
			if(StrStr(TAG_Args.Member(0,0),"/B"))
			     by=ACC_ATTR_OFF;
			else by=ACC_ATTR_ON;
			subby=12;break;
			}   //ATTR on bold
	       if(TAG=="BIG")  {by=ACC_ATTR_ON;subby=2;break;}    //ATTR on large
	       if(TAG=="BR")   {by=131;break;} 	   	  //HRt
	       if(TAG=="DD")   {by=140;break;} 	   	  //Indented definition
	       if(TAG=="FLD")  {by=ACC_IMAGE;break;} 	   	  //Image
	       if(TAG=="H1")   {by=135;subby=1;break;}    //section level 1
	       if(TAG=="H2")   {by=135;subby=2;break;}    //section level 2
	       if(TAG=="H3")   {by=135;subby=3;break;}    //section level 3
	       if(TAG=="H4")   {by=135;subby=4;break;}    //section level 4
	       if(TAG=="H5")   {by=135;subby=1;break;}    //section level 5
	       if(TAG=="H6")   {by=135;subby=2;break;}    //section level 6
	       if(TAG=="HR")   {by=139;subby=0;break;}    //horizontal line
	       if(TAG=="I")				  //ATTR on italic
			{
			if(StrStr(TAG_Args.Member(0,0),"/I"))
			     by=ACC_ATTR_OFF;
			else by=ACC_ATTR_ON;
			subby=8;break;
			}
	       if(TAG=="IMG")  {by=142;break;}		  //Image
//	       if(TAG=="LI")   {by=144;subby=2;break;}    //Start of item
	       if(TAG=="LANG") {by=ACC_LANGUAGE;break;}
	       if(TAG=="META") {by=137;subby=0;break;}  //meta tag
	       if(TAG=="P")    {by=132;break;}		//new paragraph
	       if(TAG=="S")				//ATTR on strike out
			{
			if(StrStr(TAG_Args.Member(0,0),"/S"))
			     by=ACC_ATTR_OFF;
			else by=ACC_ATTR_ON;
			subby=13;break;
			}
	       if(TAG=="SMALL"){by=ACC_ATTR_ON;subby=3;break;}    //ATTR on small
	       if(TAG=="SCRIPT"){by=138;subby=0;break;}    //start SCRIPT
	       if(TAG=="SUB")  {by=ACC_ATTR_ON;subby=6;break;}    //ATTR on subscript
	       if(TAG=="SUP")  {by=ACC_ATTR_ON;subby=5;break;}    //ATTR on superscript
	       if(TAG=="T")    {by=ACC_TABLE;subby=0;break;}    //Start of the table
	       if(TAG=="TD")   {by=ACC_TABLE;subby=4;break;}    //Start of cell
	       if(TAG=="TH")   {by=ACC_TABLE;subby=6;break;}    //Start of head cell
	       if(TAG=="TR")   {by=ACC_TABLE;subby=2;break;}    //Start of row
	       if(TAG=="TT")   {by=ACC_ATTR_ON;subby=16;break;}	  //ATTR on typewriter
	       if(TAG=="U")				  //ATTR on underline
			{
			if(StrStr(TAG_Args.Member(0,0),"/U"))
			     by=ACC_ATTR_OFF;
			else by=ACC_ATTR_ON;
			subby=14;break;
			}
//	       if(TAG=="UL")   {by=144;subby=0;break;}    //Start of itemize
	       break;
	case XML_closetag:
               TAG = copy(this->TAG,2,length(this->TAG)-3);	//Closing tag </xxx>
	       if( (tag=TAG())==NULL) break;
	       if(TAG=="B")    {by=ACC_ATTR_OFF;subby=12;break;}  //ATTR off bold
	       if(TAG=="BIG")  {by=ACC_ATTR_OFF;subby=2;break;}   //ATTR off large
	       if(TAG=="DD")   {by=141;break;} 	   	  //End of indented definition
	       if(TAG=="DL")   {by=141;break;} 	   	  //End of definition list
	       if(TAG=="H1")   {by=136;subby=1;break;}    //section off level 1
	       if(TAG=="H2")   {by=136;subby=2;break;}    //section off level 2
	       if(TAG=="H3")   {by=136;subby=3;break;}    //section off level 3
	       if(TAG=="H4")   {by=136;subby=4;break;}    //section off level 4
	       if(TAG=="H5")   {by=136;subby=1;break;}    //section off level 5
	       if(TAG=="H6")   {by=136;subby=2;break;}    //section off level 6
//	       if(TAG=="LI")   {by=144;subby=3;break;}    //End of item
	       if(TAG=="I")    {by=ACC_ATTR_OFF;subby=8;break;}    //ATTR off italic
	       if(TAG=="P")    {by=ACC_PAR_OFF;break;} 		  //end paragraph
	       if(TAG=="S")    {by=ACC_ATTR_OFF;subby=13;break;}	  //ATTR off strike out
	       if(TAG=="SMALL"){by=ACC_ATTR_OFF;subby=3;break;}    //ATTR off small
	       if(TAG=="SCRIPT"){by=138;subby=1;break;}   //end SCRIPT
	       if(TAG=="SUB")  {by=ACC_ATTR_OFF;subby=6;break;}    //ATTR off subscript
	       if(TAG=="SUP")  {by=ACC_ATTR_OFF;subby=5;break;}    //ATTR off superscript
	       if(TAG=="T")    {by=ACC_TABLE;subby=1;break;}    //End of Table
	       if(TAG=="TD")   {by=ACC_TABLE;subby=5;break;}	  //End of cell
	       if(TAG=="TH")   {by=ACC_TABLE;subby=7;break;}    //End of head cell
	       if(TAG=="TR")   {by=ACC_TABLE;subby=3;break;}    //End of row
	       if(TAG=="TT")   {by=ACC_ATTR_OFF;subby=16;break;}	  //ATTR off typewriter
	       if(TAG=="U")    {by=ACC_ATTR_OFF;subby=14;break;}   //ATTR off underline
//	       if(TAG=="UL")   {by=144;subby=1;break;}    //End of itemize
	       break;
        case XML_CDATA:
	case XML_comment:				//comment
	       break;
	case XML_badextchar:
               if(this->TAG.isEmpty()) break;		//Extended chatacter &xxx
	       this->TAG[length(this->TAG)-1]=' ';
	       TAG = Ext_chr_str(this->TAG[0],this) + copy(this->TAG,1,length(this->TAG)-1);
	       tag = TAG();
	       by = 201;
	       break;
	}

  this->by=by;
  this->subby=subby;
  if(this->flag<Nothing)
    switch(by)
	{
	case XML_char:                  //Normal character
                tag = Ext_chr_str(subby,this,this->ConvertCpg);
	        CharacterStr(this,tag);
	        break;
        case XML_CDATA:
	case XML_comment:		//comment
                this->CommentXML();
	        break;
	case XML_unicode:
                CharacterStr(this,this->TAG);
	        break;		//Already expanded unicode character

	case 32:putc(' ', this->strip);   /*soft space*/
		break;

	case 128:if(TablePos!=1 && TablePos!=3)
		   if(this->char_on_line)
			SoftReturn(this);
		 break;
	case ACC_ATTR_ON:AttrOn(this->attr,subby); break;
	case ACC_ATTR_OFF:AttrOff(this,subby); break;
	case 131:HardReturn(this); break;
	case 132:if(this->char_on_line) HardReturn(this);  //Paragraph on
		 SoftReturn(this);
		 break;
	case ACC_PAR_OFF:if(this->char_on_line) HardReturn(this);  //Paragraph off
		 break;
	case 134:Justification(this,subby);break;
	case 135:StartSection(this,-subby);break;
	case 136:EndSection(this,-subby);	 break;
//	case 137:MetaHTML(this);		 break;
//	case 138:ScriptXML(this);		 break;
	case 139:HLine(this,-16);		 break;
//	case 140:IndentHTML(this);	 break;
	case 141:End_of_indent(this);	 break;
//	case 142:ImageHTML(this);		 break;
	case ACC_TABLE:switch(subby)
		   {
//		   case 0:TableHTML(this);TablePos=1;break;
		   case 1:EndTable(this); TablePos=0; break;
		   case 2:RowTable(this); TablePos|=2;break;
		   case 3:TablePos&=~2;break;
		   case 4:
		   case 6:CellTable(this); TablePos|=4;break;
		   case 5:
		   case 7:TablePos&=~4;break;
		   }
		 break;
	case ACC_IMAGE: AccentImage();break;
	case ACC_LANGUAGE: AccentLanguage();break;

	case 200:fputc('~', strip);strcpy(ObjType, " ");
		 break;
	case 201:CharacterStr(this,tag);break; //
	}


 this->by=by;
 this->subby=subby;
 if (this->log != NULL)
    {   /**/
    if(by==128) fputc('\n',this->log);
    else if(by==' ' || by==200) fputc(' ',this->log);
    else if(by==0 || by==201)
	{
	fprintf(this->log,"%s",tag);
	}
    else
	{
	fprintf(this->log, _("\n%*s [%s %s]   "),
		  this->recursion * 2, "", this->TAG(), this->ObjType);
//	if(*this->ObjType==0) UnknownObjects++;
	}
    }

 this->ActualPos = ftell(this->wpd);
}


int TconvertedPass1_Accent::Convert_first_pass(void)
{
#ifdef DEBUG
  fprintf(log,"\n#TconvertedPass1_Accent::Convert_first_pass() ");fflush(log);
#endif
uint32_t fsize;

  if(Verbosing >= 1)
     printf(_("\n>>>Accent2LaTeX<<< Conversion program: From Accent to LaTeX Version %s\n"
	      "      Made by J.Fojtik  (Hosted on WP2LaTeX :))))\n\n"),
			AccentVersion);
  ConvertHTML = GetTranslator("htmlTOinternal");
  CharReader = &ch_fgetc;

  TablePos=0;

  DocumentStart = ftell(wpd);
  fsize = FileSize(wpd);
  perc.Init(ftell(wpd), fsize,_("First pass Accent:") );

  ActualPos = ftell(wpd);
  while (ActualPos < fsize)
      {
      if(Verbosing >= 1)		//actualise a procentage counter
	      perc.Actualise(ActualPos);

      TAG.erase();
      ProcessKeyAccent();
      }

  Finalise_Conversion(this);
  return(1);
}

