/******************************************************************************
 * program:     wp2latex                                                      *
 * function:    module for conversion Text602 files into LaTeX 		      *
 * modul:       pass1602.cc                                                   *
 * description: This module contains parser for T602 documents. It could be   *
 *		optionally not 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 "cp_lib/cptran.h"


#define T602Version "0.03"


class TconvertedPass1_602: public TconvertedPass1
{
public:
     string cmd,args;

     int color;
     int beg_par;  /* is begining of paragraph ? */
     int is_link;  /* is this a link ? */
     int wendl;    /* is this end of line only ? */
     int nsp;      /* nmuber of spaces */

     virtual int Convert_first_pass(void);

     void ProcessKey602(void);
     void HeaderFooter602(const string &args, char He_Fo=0);
};


/*Register translators here*/
TconvertedPass1 *Factory_602(void) {return new TconvertedPass1_602;}
FFormatTranslator Format602("T602",Factory_602);


/* Definition of special characters */
#define CR '\xd'
#define ENDL 141

#define NNSP 10

/* Known text styles */
#define BLD 2
#define ITL 4
#define UND 19
#define ENL 15
#define HIG 16
#define BIG 29
#define SUB 22
#define SUP 20

#define COLOR_SIZE 6


static void ChangeEncoding(TconvertedPass1_602 *cq)
{
#ifdef DEBUG
  fprintf(cq->log,"\n#ChangeEncoding() ");fflush(cq->log);
#endif
long value;
string translator;

  cq->args.trim();
  value=atol(cq->args());
  switch(value)
     {
     case 0:translator="kam";break;	//"895"
     case 1:translator="cp852";break;	//latin2
     case 2:translator="koi8cs";break;	//koi8cs
     default:cq->ConvertCpg = NULL;
     }
  if(!translator.isEmpty())
     {
     translator+="TOinternal";
     cq->ConvertCpg = GetTranslator(translator);
     }
}


void TconvertedPass1_602::HeaderFooter602(const string &args, char He_Fo)
{
#ifdef DEBUG
  fprintf(log,"\n#HeaderFooter602() ");fflush(log);
#endif
  attribute OldAttr;
  string s;
  unsigned char OldFlag,OldEnvir;
  int i;
  const char *Header_Text = args();
  
  if(Header_Text==NULL) return;

  OldFlag = flag;
  OldEnvir= envir;

  recursion++;

  line_term = 's';		//Soft return
  if(char_on_line == -20)   /* Left one empty line for new enviroment */
      {
      fputc('%', table);
      fputc('%', strip);
      NewLine(this);
      }
  if(char_on_line==true)
      {
      NewLine(this);
      }

  Close_All_Attr(attr,strip);
  OldAttr=attr;		/* Backup all attributes */

				/* Any of section's attr cannot be opened */
  for(i=First_com_section;i<=Last_com_section;i++)
		  _AttrOff(attr,i,s); // !!!!!! toto predelat!

  InitHeaderFooter(this,He_Fo,1);

  envir='!';		//Ignore enviroments after header/footer
  NewLine(this);

  attr.InitAttr();		//Turn all attributes in the header/footer off

  flag = HeaderText;
  envir = ' ';
  ActualPos = ftell(wpd);
  char_on_line = -10;
  while(*Header_Text!=0)
	{
	by=*Header_Text++;

	if(by=='#') PageNumber(this);
		   else ProcessKey602();
	}

  Close_All_Attr(attr,strip);
  if(char_on_line==true)
     {
     line_term = 's';    	//Soft return
     NewLine(this);
     }
  putc('}', strip);

  line_term = 's';    	//Soft return
  envir = '^';		//Ignore enviroments after header/footer
  NewLine(this);

  attr = OldAttr;		// Restore backuped attributes
  flag = OldFlag;
  envir = OldEnvir;
  char_on_line = -10;		// stronger false;
  recursion--;

  strcpy(ObjType,(He_Fo & 3)<=1?"Header":"Footer");
}


static void Image602(TconvertedPass1_602 *cq)
{
#ifdef DEBUG
  fprintf(cq->log,"\n#Image602() ");fflush(cq->log);
#endif
TBox Box;
char *str,ch;
char CommaCount;

  CommaCount=0;
  str = cq->args();
  if(str==NULL) return;
  initBox(Box);

  while((ch=*str)!=0)
     {
     switch(CommaCount)
	{
	case 0:if(isspace(ch) || ch==',') *str=0;
	       break;
	case 4:if(isdigit(ch))		//4'th argument is rotation angle
		  {
		  Box.RotAngle=atoi(str);
		  goto skip;
		  }
	       break;
	case 5:goto skip;
	}
     if(ch==',') CommaCount++;
     str++;
     }
skip:
  Box.Image_type=0;	//Image on disk
  Box.Contents = 3;
  Box.HorizontalPos=3;	//Full

  ImageWP(cq,cq->args,Box);
  *str=ch;
}


void TconvertedPass1_602::ProcessKey602(void)
{
#ifdef DEBUG
  fprintf(log,"\n#ProcessKey602() ");fflush(log);
#endif
string TAG;
const char *tag;

 *ObjType = 0;
 if(by==0) by=fgetc(wpd);

 switch(by)
    {
    case '@':if(char_on_line<=0)
		    {
		    cmd.erase();
		    while(!feof(wpd))
		       {
		       const char c = fgetc(wpd);
		       if(isspace(c)) break;
		       cmd += c;
		       }
		    fGets2(wpd, args);
		    char_on_line=0;
		    if(cmd=="CT") ChangeEncoding(this);
		    if(cmd=="FO") HeaderFooter602(args,2);
		    if(cmd=="HE") HeaderFooter602(args,1);
		    if(cmd=="PA") HardPage(this);
		    break;
		    }
	      goto DEFAULT;
     case '{':if(!is_link)
		  {
		  const char tmp = fgetc(wpd);
		  if(tmp=='#')
		      {
		      //scanf("%s", cmd);
		      printf("<A NAME=\"POS%s\">", cmd());
		      is_link=1;
		      }
		  else if(tmp=='!')
		      {
		      //scanf("%s", cmd());
		      printf("<A HREF=\"#POS%s\">", cmd());
		      is_link=1;
		      }
		  else
		      {
		      ungetc(tmp, wpd);
		      goto DEFAULT;
		      }
		  }
		  break;
      case '}' :if(is_link)
		    {
		    is_link=0;
		    printf("</A>");
		    }
		  else goto DEFAULT;
		  break;
      case CR   : break;
      case ENDL : SoftReturn(this);
		  wendl=1;
		  break;
      case BLD  : if(IsAttrOn(attr,12)<0) Attr_ON(this,12);
					  else Attr_OFF(this,12);
		  break;
      case ITL  : if(IsAttrOn(attr,8)<0) Attr_ON(this,8);
					 else Attr_OFF(this,8);
		  break;
      case UND  : if(IsAttrOn(attr,14)<0) Attr_ON(this,14);
					  else Attr_OFF(this,14);
		  break;
      case ENL  : if(IsAttrOn(attr,2)<0) Attr_ON(this,2);
					 else Attr_OFF(this,2);
		  break; 		//<FONT SIZE=+1>
      case HIG  : if(IsAttrOn(attr,1)<0) Attr_ON(this,1);
					 else Attr_OFF(this,1);
		  break; 		//<FONT SIZE=+3>
      case BIG  : if(IsAttrOn(attr,0)<0) Attr_ON(this,0);
					 else Attr_OFF(this,0);
		  break; 		//<FONT SIZE=+4>
      case SUB  : if(IsAttrOn(attr,6)<0) Attr_ON(this,6);
					 else Attr_OFF(this,6);
		  break;
      case SUP  : if(IsAttrOn(attr,5)<0) Attr_ON(this,5);
					 else Attr_OFF(this,5);
		  break;
      case '\n' : beg_par=1;
		  if(!wendl) HardReturn(this);
		  wendl=0;
		  break;
      case ' '  : if(char_on_line<=0) nsp++;
				      else fputc(' ',strip);
		  break;
      case '.'  : if(char_on_line<=0)
		    {
		    cmd.erase();
		    while(!feof(wpd))
		       {
		       const char c = fgetc(wpd);
		       if(isspace(c)) break;
		       cmd += c;
		       }
		    fGets2(wpd, args);
		    if(cmd=="PI") Image602(this);
		    else {
			 fprintf(strip,"%% .%s %s",cmd(),args());
			 }
		    char_on_line=0;
		    break;
		    }
		  goto DEFAULT;
      default   :
DEFAULT:          if(beg_par)
		    {
		    if(nsp > NNSP)
			{if(toupper(envir)!='C') Justification(this,0x82);} //center
		    else if(char_on_line<=0 && toupper(envir)=='C')
			Justification(this,0x81);	//full
		    }

		  if(nsp>0) fputc(' ',strip);
		  if((unsigned)by > ' ')
		       {		//Normal character
		       tag = Ext_chr_str(by,this,ConvertCpg);
		       CharacterStr(this,tag);
		       }
		  char_on_line=1;
		  beg_par=nsp=wendl=0;
		  break;
    }

 ActualPos = ftell(wpd);
}


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

  if(Verbosing >= 1)
     printf(_("\n>>>T602toLaTeX<<< Conversion program: From T602 to LaTeX Version %s\n"
	      "      Made by J.Fojtik  (Hosted on WP2LaTeX :))))\n\n"),
	    T602Version);

  DocumentStart=ftell(wpd);

  fsize=filesize(wpd);
  perc.Init(ftell(wpd), fsize,_("First pass T602:") );

  color=1;
  beg_par=1;
  is_link=0;
  wendl=0;
  nsp=0;

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

      by = 0;
      ProcessKey602();
      }

  Finalise_Conversion(this);
  return(1);
}


/*------------------------------------------------------------------------*/
