// lyx2lyx version 0.0.2
#include <stdio.h>
#include <iostream.h>
#include <string.h>
#include <stdlib.h>
#include <float.h>
#include <ctype.h>

#define LYX2LYX_LINELENGTH 1000

void phae(){
cout
<< "lyx1.2-to-lyx1.1: attempts to convert a LyX 1.2 document to LyX 1.1\n"
<< "Syntax: lyx1.2-to-lyx1.1 infile outfile\n"
<< "by Steven Homolya, October 2002.\n";
	exit(0);
}

int main(int argc, char *argv[]){
	if (argc < 3) phae();
	
	FILE *in_fptr = fopen(argv[1], "rt");
	FILE *out_fptr = fopen(argv[2], "wt");
	
	if (!in_fptr || !out_fptr){
		cerr << "Can't open file. Exiting...\n";
		exit(1);
	}
	
	// **************
	// depth counters
	// **************

	// this is the number of levels of nesting within the current inset:
	int inset = 0;

	// These are the inset depth immediately after the beginning of the
	// corresponding inset. They are used for pairing up the beginning
	// and end of for various types of insets.
	int note = 0, formula = 0, ert = 0, foot = 0;
	int figfloat = 0, tabfloat = 0, figure = 0, table = 0; 

	bool subfigure = false;
	char subcaption[LYX2LYX_LINELENGTH];
	
	subcaption[0] = '\0';
	
	int lyxwidth = 50, lyxheight = 50;
	double width = 0., height = 0.;
	int width_type = 1, height_type = 1;			
	bool beg_of_doc = true;		// true until '\layout' is encoutered
	bool beg_of_inset = false;	// true until '\layout' is encoutered after a '\begin_inset'
	char line_in[LYX2LYX_LINELENGTH];
	char line_out[4*LYX2LYX_LINELENGTH];
	char fig_fname[LYX2LYX_LINELENGTH/2];
	char tmp_string[LYX2LYX_LINELENGTH];
	int tmp_ctr;
	
	char *s_ptr;
		
	int line_ctr = 0;

	fprintf(out_fptr, "# If all went well ... this will be a LyX 1.1 file.\n");
	fprintf(out_fptr, "# LyX 1.2 created the original version of this file.\n");
	fprintf(out_fptr,
"# The file you are viewing now has been converted, to what will hopefully\n");
	fprintf(out_fptr,
"# function as a LyX 1.1 file, by lyx2lyx (version 0.0.2), a program written\n");
	fprintf(out_fptr,
"# by Steven Homolya in October 2002. The program was written for my limited\n");
	fprintf(out_fptr,
"# purposes. If you want new features, it's up to you to add them.\n");
	fprintf(out_fptr,
"# Questions? Email me at Steven.Homolya@spme.monash.edu.au\n");
	fprintf(out_fptr,
"# Converted text follows.\n\n");
	while (1){
		s_ptr = fgets(line_in, LYX2LYX_LINELENGTH, in_fptr);	// reading next line
		strcpy(line_out, line_in);	// in -> out
		
		// end of file:
		if (s_ptr == NULL) break;
		
		// empty line:
		if (strlen(line_in) == 0) continue;
		
		// comment line:
		if (line_in[0] == '#'){
			fputs(line_in, out_fptr);
			fputc('\n', out_fptr);
			continue;
		}
		
		if (beg_of_doc){	// here we handle all the things that may come before
				// the first paragraph (i.e., \layout)
			if	(strstr(line_in, "\\use_natbib")
					|| strstr(line_in, "\\use_numerical_citations"))
				continue;
				
			if (strstr(line_in, "\\lyxformat"))
				strcpy(line_out, "\\lyxformat 218\n");	// changing lyxformat number
			else if (strstr(line_in, "\\use_natbib")
					|| strstr(line_in, "\\use_numerical_citations"))	// deleting these
				continue;
			else if (strstr(line_in, "\\layout")){	// first paragraph reached
				beg_of_doc = false;
			}
		}
		
		if (beg_of_inset){
			if ((inset == figure && strstr(line_in, "display "))
				|| (inset == figure && strstr(line_in, "keepAspectRatio"))
				|| (inset == figure && strstr(line_in, "scale"))
				|| (inset == ert && strstr(line_in, "status "))
				|| strstr(line_in, "collapsed true")
				|| strstr(line_in, "collapsed false")
				|| ((inset == figfloat || inset == tabfloat)
						&& strstr(line_in, "placement"))
				|| (inset == figure && 
						(strstr(line_in, "display ") 
							|| strstr(line_in, "size_type")
							|| strstr(line_in, "rotateOrigin ")
						)
					)
				)
				{
				continue;
			}
			
			if ((s_ptr = strstr(line_in, "filename"))){
				strcpy(fig_fname, &s_ptr[9]);
				line_out[0] = '\0';
			}
			else if (inset == figure && (s_ptr = strstr(line_in, "lyxwidth "))){
				if (strstr(line_in, "pt") == NULL || lyxwidth < 10)
					lyxwidth = 50;	// default width, if we dont know the units
				else
					lyxwidth = atoi(&s_ptr[9]);
				line_out[0] = '\0';
			}
			else if (inset == figure && (s_ptr = strstr(line_in, "lyxheight "))){
				if (strstr(line_in, "pt") == NULL || lyxheight < 10)
					lyxheight = 50;	// default height, if we dont know the units
				else
					lyxheight = atoi(&s_ptr[9]);
				line_out[0] = '\0';
			}
			else if (inset == figure && (s_ptr = strstr(line_in, "width "))){
				tmp_ctr = 0;

				while (isdigit(s_ptr[tmp_ctr + 6])
						|| s_ptr[tmp_ctr + 6] == '.')
					tmp_ctr++;

				strncpy(tmp_string, &s_ptr[6], tmp_ctr*sizeof(char));
				tmp_string[tmp_ctr] = '\0';
				width = atof(tmp_string);
				
				if (strstr(line_in, "cm")) width_type = 1;
				else if (strstr(line_in, "in")) width_type = 2;
				else if (strstr(line_in, "page\%")) width_type = 3;
				else if (strstr(line_in, "col\%")) width_type = 4;
				else {	// defaults for unknown types:
					width = 45;
					width_type = 4;
				}
				
				line_out[0] = '\0';
			}
			else if (inset == figure && (s_ptr = strstr(line_in, "height "))){
				tmp_ctr = 0;

				while (isdigit(s_ptr[tmp_ctr + 7])
						|| s_ptr[tmp_ctr + 7] == '.')
					tmp_ctr++;

				strncpy(tmp_string, &s_ptr[7], tmp_ctr*sizeof(char));
				tmp_string[tmp_ctr] = '\0';
				height = atof(tmp_string);

				if (strstr(line_in, "cm")) height_type = 1;
				else if (strstr(line_in, "in")) height_type = 2;
				else if (strstr(line_in, "page\%")) height_type = 3;
				else {	// defaults for unknown types:
					height = 20;
					height_type = 3;
				}
				line_out[0] = '\0';
			}
			else if (inset == figure && (s_ptr = strstr(line_in, "subcaptionText "))){
				subfigure = true;
				s_ptr = &s_ptr[15];
				while (*s_ptr != '\"')
					s_ptr = &s_ptr[1];
				tmp_ctr = 0;
				while (s_ptr[tmp_ctr+1] != '\"') tmp_ctr++;
				strncpy(subcaption, &s_ptr[1], tmp_ctr);
				subcaption[tmp_ctr] = '\0';
				line_out[0] = '\0';
			}
			else if (inset == figure && (s_ptr = strstr(line_in, "subcaption"))){
				subfigure = true;
				line_out[0] = '\0';
			}
			else if (inset == table && (s_ptr = strstr(line_in, " width=\"0pt\""))){
				tmp_ctr = 0;
				while (strncmp(&line_in[tmp_ctr++], " width=\"0pt\"", 12) != 0);
				strncpy(line_out, line_in, (tmp_ctr-1)*sizeof(char));
				line_out[(tmp_ctr-1)*sizeof(char)] = '\0';
				strcat(line_out, &line_in[tmp_ctr+11]);
				strcat(line_out, "\n");
			}
			else if (strstr(line_in, "wide false")){	// normal float
				if (inset == figfloat)
					strcpy(line_out, "\\begin_float fig \n");	// figure
				else if (inset == tabfloat)
					strcpy(line_out, "\\begin_float tab \n");	// table
			}
			else if (strstr(line_in, "wide true")){	// wide float
				if (inset == figfloat)
					strcpy(line_out, "\\begin_float wide-fig \n");	// figure
				else if (inset == tabfloat)
					strcpy(line_out, "\\begin_float wide-tab \n");	// table
			}
			else if (inset == table && strstr(line_in, "lyxtabular")){
				s_ptr = strstr(line_in, "rows=");
				if (s_ptr){
					strcpy(line_out, "<lyxtabular version=\"2\" ");
					strcat(line_out, s_ptr);
				}
				else
					strcpy(line_out, line_in);										
			}
			else if (inset == formula && (s_ptr = strstr(line_in, "$"))){
				// replacing $ sign in formula with \)
				s_ptr[0] = '\0';
				strcpy(line_out, line_in);
				strcat(line_out, " \\)");
				strcat(line_out, &s_ptr[1]);
			}
		}
		
		if (strstr(line_in, "\\begin_inset")){	// beginning of inset
			inset++;
			beg_of_inset = true;
			
			if (strstr(line_in, "Note")){
				note = inset;
				strcpy(line_out, "\\begin_inset Info\n");
			}
			else if (strstr(line_in, "ERT")){
				ert = inset;
				strcpy(line_out, "\\latex latex \n");				
			}
			else if (strstr(line_in, "Foot")){
				foot = inset;
				strcpy(line_out, "\\begin_float footnote \n");				
			}
			else if (strstr(line_in, "Formula")){
				formula = inset;
				// replacing first $ sign with \(:
				s_ptr = strstr(line_in, "$");

				if (s_ptr != NULL){
					s_ptr[0] = '\0';
					strcpy(line_out, line_in);
					strcat(line_out, "\\( ");
					strcat(line_out, &s_ptr[1]);
				}
				else
					strcpy(line_out, line_in);

				// replacing second $ sign with \):
				strcpy(line_in, line_out);
				s_ptr = strstr(line_in, "$");

				if (s_ptr != NULL){
					s_ptr[0] = '\0';
					strcpy(line_out, line_in);
					strcat(line_out, " \\)");
					strcat(line_out, &s_ptr[1]);
				}
			}
			else if (strstr(line_in, "Float figure")){
				figfloat = inset;
				line_out[0] = '\0';
			}
			else if (strstr(line_in, "Float table")){
				tabfloat = inset;
				line_out[0] = '\0';
			}
			else if (strstr(line_in, "Graphics")){
				figure = inset;
				line_out[0] = '\0';
			}
			else if (strstr(line_in, "Tabular")){
				table = inset;
			}
		}
		
		if (strstr(line_in, "\\end_inset")){	// end of inset
			beg_of_inset = false;
			if (inset == ert)
				strcpy(line_out, "\\latex default \n");
			else if (inset == tabfloat || inset == figfloat || inset == foot)
				strcpy(line_out, "\\end_float \n");
			else if (inset == figure){
				sprintf(line_out, "\\begin_inset Figure size %d %d\n",
					lyxwidth, lyxheight);
				strcat(line_out, "file ");
				strcat(line_out, fig_fname);
				if (strlen(subcaption) > 0){
					strcat(line_out, "subcaption ");
					strcat(line_out, subcaption);
					strcat(line_out, "\n");
				}
				if (width > FLT_EPSILON){
					strcat(line_out, "width ");
					sprintf(tmp_string, "%d %g\n", width_type, width);
					strcat(line_out, tmp_string);
					width = 0.;
				}
				if (height > FLT_EPSILON){
					strcat(line_out, "height ");
					sprintf(tmp_string, "%d %g\n", height_type, height);
					strcat(line_out, tmp_string);
					height = 0.;
				}
				strcat(line_out, "flags 9\n");
				if (subfigure)
					strcat(line_out, "subfigure\n");
				strcat(line_out, "\\end_inset\n");
				
				subfigure = false;
				subcaption[0] = '\0';
			}
			else
				strcpy(line_out, "\\end_inset \n");

			if (inset == ert) ert = 0;
			else if (inset == tabfloat) tabfloat = 0;
			else if (inset == figfloat) figfloat = 0;
			else if (inset == table) table = 0;
			else if (inset == figure) figure = 0;
			else if (inset == formula) formula = 0;
			else if (inset == note) note = 0;
			else if (inset == foot) foot = 0;
		
			inset--;							
		}

		if (strstr(line_in, "\\layout")){	// start of paragraph in inset
			beg_of_inset = false;
			if (inset != 0 && (inset == note || inset == ert))
				line_out[0] = '\0';
					// no paragraph layouts for notes and ERT
		}

		fputs(line_out, out_fptr);
	}
	
	fclose(in_fptr);
	fclose(out_fptr);
}

