#include "hache.h"
#include "quadra.h"
#include "general.h"
#include <stdio.h>
#include <varargs.h>  
#include <malloc.h>


extern char * Version;



PRIVATE TABLE signes;
PUBLIC TABLE definitions;
/* PUBLIC TABLE phonetiques; not used now */

PUBLIC int numligne;
PUBLIC int signe_trouve;

enum direction { gauche_a_droite, droite_a_gauche};

PRIVATE char liste_fontes[][3]=
{
	"A",
	"B",
	"C",
	"D",
	"E",
	"F",
	"G",
	"H",
	"I",
	"K",
	"L",
	"M",
	"N",
	"O",
	"P",
	"Q",
	"R",
	"S",
	"T",
	"U",
	"V",
	"W",
	"X",
	"Y",
	"Z",
	"Aa"
};


struct donne {
	char * entree;
	char * phon;
	struct caractere {int sym; unsigned  char numero;} symbole;
};

PRIVATE void quadra_parenthese();

PUBLIC union _Donnees g(x, sens)				/* OK, c'est mal */
	char *x; int sens;
{
	union _Donnees D;
	struct caractere* txt;

	if ((txt=(struct caractere*)trouve(x,signes)))
	{
		signe_trouve= TRUE;
		D.hieroglyphe.lettre= txt->sym;
		D.hieroglyphe.caractere= txt->numero + sens * 128;
	}
	else
		signe_trouve= FALSE;
	return D;
}


PUBLIC void stocke(nom, valeur)
		char *nom, *valeur;
{
		insere(nom,valeur,definitions);
}

PRIVATE struct donne les_donnees[]=
{
#include "seshSource.h"
    {0,0,{0,0}}
}
;

PRIVATE void initialise_lex()
{
		struct donne *i;
		signes= creer_table();
		definitions= creer_table();
		/* phonetiques= creer_table(); */
		/* indexmots= fopen("index.mot", "w");*/
		/* fflush(indexmots); */
  
		for (i= les_donnees; i->entree; i++)
				{
						insere(i->entree,&(i->symbole), signes);
						/* insere(i->entree,i->phon, phonetiques);*/
				}
}

PUBLIC void yyerror(s)
		char *s;
{
		extern int yytext;
		fprintf(stderr, "\n\n%s, pres de %s ligne %d\n",s, yytext, numligne);
		exit(-1);
}

PRIVATE void affiche_hiero();

PRIVATE void affiche_un_hieroglyphe(s, externe, hachure, size, rotation)
	char * s;
	int externe;
	Typehachure hachure;
	int size, rotation;
{
	switch(hachure)
	{
	case S_aucune:
		break;
	case S_ga:
		printf("\\hachurega{");
		break;
	case S_ha:
		printf("\\hachureha{");
		break;
	case S_va: 
		printf("\\hachureva{");
		break;
	case S_ta:
		printf("\\hachureta{");
		break;
	}
	if (externe)
		printf("\\Hunh{");
	if (size > 0)
	{
		int masize= size;
		printf("{");
		while ((masize--) > 0)
			printf("\\Hsmaller");
	}
	if (rotation != 0)
	{
		printf("\\Hrotate{%d}{", -rotation);
	}
	printf(s);
	if (size > 0)
		printf("}");
	if (rotation != 0)
	{
		printf("}");
	}
	if (externe)
		printf("}");
	if (hachure != S_aucune)
		printf("}");
}

PRIVATE void affiche_signe(q, externe, sens)
	Quadra *q;
	int externe;
	enum direction sens;
{
	switch(q->contenu.un_signe.type)
	{
		static char tempo[30];
	case S_hieroglyphe:
		sprintf(tempo, "\\Aca %s/%u/", 
						liste_fontes[q->contenu.un_signe.
												 donnees.hieroglyphe.lettre],
						q->contenu.un_signe.
						donnees.hieroglyphe.caractere
						);										 /* ouf! */ 
		affiche_un_hieroglyphe(tempo, externe,
													 q->contenu.un_signe.typehachure, 
													 q->contenu.un_signe.size,
													 q->contenu.un_signe.rotation
													 );
		break;
	case S_ligature:
		affiche_un_hieroglyphe(q->contenu.un_signe.donnees.texte,
													 externe, 
 													 q->contenu.un_signe.typehachure, 
													 q->contenu.un_signe.size,
													 q->contenu.un_signe.rotation
													 ); 
		break;
	case S_romain:								/* passage en fonte romaine */
		if (externe)
			printf("{\\rm %s}", 
						 q->contenu.un_signe.donnees.texte);
		else
			printf("{\\footnotesize \\rm %s}", 
						 q->contenu.un_signe.donnees.texte);
		break;
	case S_textesuper:						/* texte au dessus d'un trait */
		printf("\\traittexte{%s}",
					 q->contenu.un_signe.donnees.texte);
		break;
	case S_pointrouge:
		printf("\\pointrouge");
		break;
	case S_pointnoir:
		printf("\\pointnoir");
	 break;
	case S_haplographie:
		break;
	case S_gauchedroite:
		printf("\\leftright");
		break;
	case S_droitegauche :
		printf("\\rightleft");
		break;
	case S_lacune :
		break;
	case S_lignelacune :
		break;
	case S_point:
		printf("\\Hqrtesp ");
		break;
	case S_pointpoint:
		printf("\\Hesp ");
		break;
	case S_hachureg:
		printf("\\hachureg ");
		break;
	case S_hachureh:
		printf("\\hachureh ");
		break;
	case S_hachurev:
		printf("\\hachurev ");
		break;
	case S_hachuret:
		printf("\\hachuret ");
		break;
	}
}

PRIVATE void affiche_horliste(h, externe, sens)
	Horliste *h;
	int externe;
	enum direction sens;
{
	if ((h->next == NULL) 
			)	/* un seul signe */
	{
		if (!h->un_quadra || !h->un_quadra->next)
			affiche_hiero(h->un_quadra, externe, sens);
		else												/* A*B*C.... */
		{
			printf("\\horligne{");
			affiche_hiero(h->un_quadra, externe, sens);
			printf("}");
		}
	}
	else													/* empilement */
	{
		Horliste *t= h;
		int depart= TRUE;
		if (externe)
			printf("\\Hbt{");
		else
			printf("\\Hbti{");
		while (t)
		{
			int i;
			for (i=0; i<t->kerning; i++)
				printf("\\negAROBvspace");
			if (depart)
			{
				printf("\\HhbtI{");
				depart= FALSE;
			}
			else
				printf("\\Hhbt{");
			affiche_hiero(t->un_quadra,FALSE, sens);
			printf("}");
			t= t->next;								/* this next is vertical */
		}
		printf("}");
	}
}

PRIVATE void quadra_parenthese(debut, q, externe, sens)
	char *debut;
	Quadra *q;
	int externe;
	enum direction sens;
{
	printf("%s", debut);
	affiche_hiero(q->contenu.des_quadras, externe, sens);
	printf("}\n");
}

PRIVATE void affiche_hiero(q, externe, sens)		/*  affichage de quadras */
	Quadra *q;
	int externe;
	enum direction sens;
{
	if (sens == droite_a_gauche)
		q= q-> last;
	while (q)
	{
		int i;
		for (i=0; i<q->kerning; i++)
			printf("\\negAROBspace");
		switch(q->type)
		{
		case S_quadra:
			affiche_horliste(q->contenu.horizontal, externe, sens);
			break;
		case S_hachure:
			quadra_parenthese("\\hachure{", q, externe, sens);
			break;
			/* les constructions de type cartouche */
		case S_carto :
			quadra_parenthese("\\cartouche{", q, externe, sens);
			break;
		case S_debcarto:
			quadra_parenthese("\\debcartouche{", q, externe, sens);
			break;
		case S_milcarto :
			quadra_parenthese("\\milcartouche{", q, externe, sens);
			break;
		case S_fincarto :
			quadra_parenthese("\\fincartouche{", q, externe, sens);
			break;
		case S_serekh :
			quadra_parenthese("\\serekh{", q, externe, sens);
			break;
		case S_enceinte :
			quadra_parenthese("\\enceinte{", q, externe, sens);
			break;
		case S_chateau :
			quadra_parenthese("\\chateau{", q, externe, sens);
			break;
		case S_debserekh :
			quadra_parenthese("\\debserekh{", q, externe, sens);
			break;
		case S_milserekh :
			quadra_parenthese("\\milserekh{", q, externe, sens);
			break;
		case S_finserekh :
			quadra_parenthese("\\finserekh{", q, externe, sens);
			break;
		case S_debenceinte :
			quadra_parenthese("\\debenceinte{", q, externe, sens);
			break;
		case S_milenceinte :
			quadra_parenthese("\\milenceinte{", q, externe, sens);
			break;
		case S_finenceinte :
			quadra_parenthese("\\finenceinte{", q, externe, sens);
			break;
		case S_debchateau :
			quadra_parenthese("\\debchateau{", q, externe, sens);
			break;
		case S_milchateau :
			quadra_parenthese("\\milchateau{", q, externe, sens);
			break;
		case S_finchateau :
			quadra_parenthese("\\finchateau{", q, externe, sens);
			break;
		case S_enrouge:
			quadra_parenthese("\\enrouge{", q, externe, sens);
			break;
		case S_rightleft:
			quadra_parenthese("\\boxrightleft{",
												q, externe, 
												droite_a_gauche);
			break;
		case S_overwrite : 
			printf("\\hsuperpose{");
			affiche_signe(q->contenu.des_quadras,
										externe, sens);
			printf("}{");
			affiche_signe(q->contenu.des_quadras->next,
										externe, sens);
			printf("}");
			break;
		case S_superfetatoire:
			quadra_parenthese("\\edisuperfet{", q, externe, sens);
			break;
		case S_efface:
			quadra_parenthese("\\ediefface{", q, externe, sens);
			break;
		case S_disparu:
			quadra_parenthese("\\edidisparu{", q, externe, sens);			
			break;
		case S_ajoutscribe:
			quadra_parenthese("\\ediajoutscribe{", q, externe, sens);
			break;
		case S_ajoutauteur:
			quadra_parenthese("\\ediajoutauteur{", q, externe, sens);
			break;
		case S_signe:
			affiche_signe(q, externe, sens);
		}
		if (externe)
			switch (q->separateur)
			{
			case S_espace:
				printf("\\Hitmts\n"); 
				break;
			case S_finligne:
				printf("}\\end{hieroglyph}\\HToLine\\begin{hieroglyph}{\\leavevmode\n");
				break;
			case S_finpage:
				printf("\\nouvPage\n");
				break;
			case S_intersignes:
				printf("\\Hrp ");
				break;
			case S_sansseparateur:
				break;
			}
		else
			switch (q->separateur)
			{
			case S_espace:
			case S_finligne:
			case S_finpage:
			case S_intersignes:
				printf("\\hfill");
			case S_sansseparateur:
				break;
			}
		if (sens == gauche_a_droite)
			q= q-> next;
		else
			q= q-> previous;
	}
}

PUBLIC void affiche_quadras(q)		/*  affichage de quadras */
	Quadra *q;
{
	printf("\\begin{hieroglyph}{\\leavevmode ");
	affiche_hiero(q, TRUE, gauche_a_droite);
	printf("}\\end{hieroglyph}");
	libere_quadras();
}

extern void yyparse(); 

PUBLIC void main(argc, argv)
	int argc;
	char ** argv;
{
	/*extern */int yydebug;
						 
						 if (argc > 1)
						 {
							 fprintf(stderr, "sesh nesou, version (%s)\n", Version);
							 exit(0);
						 }

						 initialise_lex();
						 yydebug= 1;
						 initialise_quadras();
						 (void)yyparse();
						 libere_quadras();
						 exit(0);
}
