/******************************************************************************
 * program:     wp2latex                                                      *
 * function:    module for conversion DocBook files into LaTeX		      *
 * modul:       pass1dcb.cc                                                   *
 * description: This module contains parser for DocBook 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"


extern list HTMLChars;


/*Register translators here*/
class TconvertedPass1_Docbook: public TconvertedPass1_XML
     {
protected:
     void Chapter(void);
     void Itemize(void);
     void ProcessKey(void);

public:
     virtual int Convert_first_pass(void);
     };
TconvertedPass1 *Factory_Docbook(void) {return new TconvertedPass1_Docbook;}
FFormatTranslator FormatDocbook("docbook",Factory_Docbook);

#define DocbookVersion "0.3"


void TconvertedPass1_Docbook::Itemize(void)
{
#ifdef DEBUG
  fprintf(log,"\n#TconvertedPass1_Docbook::Itemize() ");fflush(log);
#endif
unsigned char OldFlag;
char OldEnvir;
long FilePos;

  FilePos = ftell(wpd);
  OldFlag = flag;
  OldEnvir = envir;
  flag = Nothing;
  recursion++;

  line_term = 's';   /* Soft return */
  if(char_on_line == LEAVE_ONE_EMPTY_LINE)  /* Left one enpty line for new enviroment */
	{
	fputc('%', table);fputc('%', strip);
	NewLine(this);
	}
  if(char_on_line>=CHAR_PRESENT) //  if(char_on_line>=-1)
	{
	NewLine(this);
	}
  envir='!';
  fputc('%', table);fputc('%', strip);
  NewLine(this);

  envir = ' ';

  if(OldEnvir=='B') fprintf(strip, "\\vbox{"); //protect itemize inside table
  fprintf(strip, "\\begin{itemize}");

  char_on_line = false;
  nomore_valid_tabs = false;
  rownum++;
  Make_tableentry_attr(this);
  latex_tabpos = 0;

	/*Process all content of the table */
  flag=OldFlag;
  fseek(wpd,FilePos,SEEK_SET);
  ReadXMLTag(false);
  while(!feof(wpd))
	{
/*	if(by==0 && (subby==10 || subby==13))
		{
		subby=' ';	// remove \n from cell text
		} */
	ProcessKey();
	if(by==144)
		{
		if(subby==1) break; /*End of itemize*/
		if(subby==2) fprintf(strip, "\\item ");
		}

	ReadXMLTag(false);
	}

  fprintf(strip, "\\end{itemize}");
  if(OldEnvir=='B') fprintf(strip, "}");
  if(char_on_line <= FIRST_CHAR_MINIPAGE) // Left one enpty line for ending enviroment.
	{
	fputc('%', table);fputc('%', strip);
	NewLine(this);
	}
  envir='^';		//Ignore enviroments after table
  fputc('%', table);
  NewLine(this);
  char_on_line = FIRST_CHAR_MINIPAGE;		// stronger false;

  recursion--;

  flag = OldFlag;
  envir = OldEnvir;
  TAG = "ITEMIZE";
strcpy(ObjType, "Itemize Start");
}


/// This function extracts some information from meta ?xml tag.
static void MetaXML(TconvertedPass1_XML *cq)
{
#ifdef DEBUG
  fprintf(cq->log,"\n#MetaXML() ");fflush(cq->log);
#endif
int i;
char *charset;
  //strcpy(cq->ObjType, "?xml");

  if((i=cq->TAG_Args IN "encoding")>=0)
	{
	charset = cq->TAG_Args.Member(i,1);
	if(charset==NULL) return;

	cq->SelectTranslator(charset);
	}
}


void TconvertedPass1_Docbook::Chapter(void)
{
#ifdef DEBUG
  fprintf(log,"\n#TconvertedPass1_Docbook::Chapter() ");fflush(log);
#endif
unsigned char OldFlag;
char OldEnvir;

OldFlag = flag;
OldEnvir = envir;
recursion++;

//fprintf(log,"!!!<chapter>");

do {
   TAG.erase();
   ProcessKey();

   //fprintf(log,TAG);

   if(by==135)
	{
	if(subby==1) break; //</chapter>
	}

   if(by==150)
     {
     if(subby == 0) StartSection(this,-1);  // <title>
     if(subby == 1) EndSection(this,-1);    // </title>
     }
   } while(!feof(wpd));

  recursion--;

  flag=OldFlag;
  envir=OldEnvir;
TAG="CHAPTER";
strcpy(ObjType, "chapter");
}


void TconvertedPass1_Docbook::ProcessKey(void)
{
#ifdef DEBUG
  fprintf(log,"\n#TconvertedPass1_Docbook::ProcessKey() ");fflush(log);
#endif
string loc_TAG;
const char *tag;
uint8_t loc_by, loc_subby;
int i;

 *ObjType = 0;
 if(TAG.isEmpty()) ReadXMLTag(false);
 loc_by = by;
 loc_subby = subby;

 switch(loc_by)
	{
	case XML_char:
               switch(subby)                        //Normal character
		  {
		  case 10:
		  case 13:loc_by=128;break; //CR
		  case  9:strcpy(ObjType, "!Tab");
		  case 32:loc_by=32;break;  //Space
		  }
	       break;
/*	case 1:if(TAG.isEmpty()) break;			//Extended chatacter &xxx;
	       loc_TAG=Ext_chr_str(TAG[0],cq)+copy(TAG,1,length(TAG)-1);
	       tag=TAG();
	       by=201;
	       break;*/
	case XML_extchar:
	case XML_badextchar:
               loc_TAG = copy(TAG,1,length(TAG)-2);   //Extended chatacter &xxx;
	       if( (tag=loc_TAG())==NULL) break;
	       if(loc_TAG=="nbsp")	{loc_by=200;break;}  	//Hard space

	       if((i=(loc_TAG() IN HTMLChars))>0)
		  {
		  i--;
		  loc_by = 201;
		  tag = Ext_chr_str(i, this, ConvertHTML); /*Translate HTML character set to WP5.x one*/
		  }
	       break;

	case XML_tag:
               loc_TAG = copy(TAG,1,length(TAG)-2);	//Normal tag <xxx>
	       if( (tag=loc_TAG())==NULL) break;

	       if(loc_TAG=="?xml")    {MetaXML(this);break;}
	       if(loc_TAG=="para")    {loc_by=132;break;} 	//new paragraph
	       if(loc_TAG=="chapter") {loc_by=135;loc_subby=0;break;} //section level 1
	       if(loc_TAG=="title")   {loc_by=150;loc_subby=0;break;}
	       if(loc_TAG=="orderedlist"){loc_by=144;loc_subby=0;break;} //Start of itemize
	       if(loc_TAG=="listitem"){loc_by=144;loc_subby=2;break;} //Begin of item

	       break;
	case XML_closetag:
               loc_TAG = copy(TAG,2,length(TAG)-3);	//Closing tag </xxx>
	       if((tag=loc_TAG())==NULL) break;

	       if(loc_TAG=="para")    {loc_by=133;break;} 	//end paragraph
	       if(loc_TAG=="chapter") {loc_by=135;loc_subby=1;break;} //section off level 1
	       if(loc_TAG=="title")	  {loc_by=150;loc_subby=1;break;}
	       if(loc_TAG=="orderedlist"){loc_by=144;loc_subby=1;break;} //End of itemize
	       if(loc_TAG=="listitem"){loc_by=144;loc_subby=3;break;} //End of item

	       break;
	case XML_comment: 			//comment
        case XML_CDATA:
	       break;
	}

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

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

	case 128:if(TablePos!=1 && TablePos!=3)
		   if(char_on_line)
			SoftReturn(this);
		 break;
	case 129:AttrOn(attr,loc_subby);break;
	case 130:AttrOff(this,loc_subby);     break;
	case 131:HardReturn(this);        break;
	case 132:if(char_on_line) HardReturn(this);  //Paragraph on
		 SoftReturn(this);
		 break;
	case 133:if(char_on_line) HardReturn(this);  //Paragraph off
		 break;

	case 135:if(loc_subby==0) Chapter();
		 break;

        case 144:switch(loc_subby)
		   {
		   case 0:Itemize();break;
		   }
		 break;

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


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

 ActualPos = ftell(wpd);
}


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

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

  TablePos=0;

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

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

      TAG.erase();
      ProcessKey();
      }

  Finalise_Conversion(this);
  return(1);
}

