// author: anonymous SUNY Stony Brook student

#include <stdio.h>
#include <string.h>

char *testPrefix(char *root_name)
{
        if (!root_name || strlen(root_name)<3)
                return 0;
        if (root_name[0] == 'P' && root_name[1] == 'r' &&
            root_name[2] == 'o' && root_name[3] == 'g')
		return root_name+4;
        if (root_name[0] == 'U' && root_name[1] == 's' &&
            root_name[2] == 'e' && root_name[3] == 'r')
		return root_name+4;
        if (root_name[0] == 'G' && root_name[1] == 'U' &&
            root_name[2] == 'I')
		return root_name+3;
}


main(int argc, char* argv[])
{
    FILE *in, *out;

    int LINEOPEN=0, CLAUSEOPEN=0, NUMBERCLAUSE=0, CLAUSES_IN_ONE =0, NESTS=0;
    int TILDA_OPEN=0, TILDA_COUNT=0;
    int IND=0;

    char* INname, OUTname[300],  ROOTname[80];

    char suffix[5] = ".tex";
    INname=argv[1];

    const char INTRO[]                =  "";
    const char END_BRACKETS_ONE[]   =  "";
    const char START_BRACKETS_ONE[]     =  "\\begin{minipage}[t]{8in}\n"
                                           "\\begin{tabular}{ll}\n";
    const char START_BRACKETS_TWO[]   =  " & ";
    const char END_BRACKETS_TWO[]     =  "\n\\end{tabular}\\\\\n";
    const char START_BRACKETS_THREE[] =  "\n \\parbox[b]{2in} \\ \\ \n\\begin{minipage}[t]{4in}";
    const char END_BRACKETS_THREE[]   =  "\\end{minipage}\n\\end{minipage}\n\\vspace{0.2in}\n";
    const char newline[] = "\\\\\n";
    const char CONCLUDE[] =  ""; 
    const char index[] = "\\index{";                    

    const char asperand[] =    "\\&";
    const char lessthan[] = "$<$";
    const char greaterthan[] = "$>$";
    const char underscore[] = "\\_";
    const char hat[] ="\\^{}";
    const char vs[]  = "\\vspace{-0.5in}\n";
    const char parenth[] = "()";
    
    int i=0;
    while(INname[i]!=' '&&INname[i]!='.'&&INname[i]!='\n'){
       OUTname[i]=INname[i++];
    }
    OUTname[i]='\0';
    strcpy(ROOTname, OUTname);
    char *root_minus_prefix = testPrefix(ROOTname);
    OUTname[i]=INname[i++];
    OUTname[i]=INname[i++];
    OUTname[i]=INname[i++];
    OUTname[i]=INname[i++];
    OUTname[i++]='.';
    OUTname[i++]='t';
    OUTname[i++]='e';
    OUTname[i++]='x';
    OUTname[i]=NULL;
       
    printf("%40s\n",OUTname);

    if((in=fopen(INname,"r"))==NULL){
        fprintf(stderr, "Cannot open input file.\n");
        return 1;
    }

    if((out=fopen(OUTname,"w"))==NULL){
        fprintf(stderr, "Cannot open output file.\n");
        return 1;
    } 

    fputs(INTRO,out);
    char s;
    int num_commands_seen=0;
    s=fgetc(in);
    while(s!=EOF){
        if(s=='@'){
	    num_commands_seen++;
            if(CLAUSEOPEN==0) {   
                   if(LINEOPEN==0){
                      LINEOPEN=1;
                      NUMBERCLAUSE=0;
                      CLAUSES_IN_ONE = 0;
                   }
                   else {
                       LINEOPEN=0;
                       NUMBERCLAUSE=0;
                       CLAUSES_IN_ONE =0;
	           }
	    }
            else {
                 printf("Error: end of line ('@') with open clauses at"
			" command %d.\n", num_commands_seen);
                 CLAUSEOPEN=0;
                 NUMBERCLAUSE=0;
	    }
        }
        if(s=='{'){
             if(CLAUSEOPEN==0){
                if(TILDA_OPEN==0){ 
                    CLAUSEOPEN=1;
                    NUMBERCLAUSE++;
                    if(NUMBERCLAUSE==1){
                         fputs(START_BRACKETS_ONE,out);
                    }
                    else {
                       if(NUMBERCLAUSE==2){
                         fputs(START_BRACKETS_TWO,out);
                         char function[50];
                         int j=0;
                         s=fgetc(in);
                         while(s!='('&&s!='}'&&j<300){
                                if(s=='&'){
                                      function[j++]='\\'; 
                                      function[j++]='\\';
                                      function[j++]='&';
                                }
                                if(s=='<'){
                                      function[j++]='$';
                                      function[j++]='<';
                                      function[j++]='$';
                                }
                                if(s=='>'){
                                      function[j++]='$';
                                      function[j++]='>';
                                      function[j++]='$';
                                }
                                if(s=='_'){
                                      function[j++]='\\';
                                      function[j++]='_';
                                      
                                }
                                //if(s=='^'){
                                //    function[j++]='\\';
                                //    function[j++]='^';
                                //    function[j++]='{';
                                //    function[j++]='}';
                                //}
                                //if(s!='&'&&s!='<'&&s!='>'&&s!='_'&&s!='^')
                                if(s!='&'&&s!='<'&&s!='>'&&s!='_')
				{
                                    function[j++]=s;
				}
                                s=fgetc(in);
                         }
                         if(j==8){
                            if(function=="operator")
                                function[j++]=' ';
                                function[j++]='(';
                                function[j++]=')';
                                s=fgetc(in);
                                s=fgetc(in);
			 }
                         function[j]=NULL;
                         fputs(function,out);
                         fputs(index,out);
			 fprintf(out, "%s!%s", root_minus_prefix, function);
                         //fputs(function,out);
                         fputc('}',out);
                         if(s=='}'){
                             s=' ';
                             fputs(END_BRACKETS_TWO,out);
                             CLAUSEOPEN=0;
                         }
                       }
                       else{
                          if(NUMBERCLAUSE==3){
                              fputs(START_BRACKETS_THREE,out);
                          }
                       }
                    }
                }
                else {
                   if(TILDA_COUNT%2==0&&TILDA_COUNT!=0){
                       fputs(newline,out);
                   }
                   CLAUSEOPEN=1;
                   TILDA_COUNT++;
                }
	     }
             else{
                  NESTS++;
                  fputc(s,out);
             }
        }
        if(s=='}'){
             if(CLAUSEOPEN==1&&NESTS==0){
                if(TILDA_OPEN==0){
                    CLAUSEOPEN=0;
                    if(NUMBERCLAUSE==1){
                         fputs(END_BRACKETS_ONE,out);
                    }
                    else {
                       if(NUMBERCLAUSE==2){
                         fputs(END_BRACKETS_TWO,out);
                       }
                       else{
                             if(NUMBERCLAUSE==3){
                                fputs(END_BRACKETS_THREE,out);     
                             }
                       }
                    }
		}
                else{
                   CLAUSEOPEN=0;
                }
             }
             else {
                 if(CLAUSEOPEN==0){
                      printf("ERROR");
                 }
                 else {
                     NESTS--;
                     fputc(s,out);
		 }
             }
        }
        if(s=='~') {
            if(TILDA_OPEN==0){
                fputs(START_BRACKETS_ONE,out);
                TILDA_OPEN=1;
                TILDA_COUNT=0;
	    }
            else {
                fputs(END_BRACKETS_TWO,out);
                TILDA_OPEN=0;
                NUMBERCLAUSE=2;
            }
        }
        if(s=='&'){
            fputs(asperand,out);
        }
        if(s=='<'){
            fputs(lessthan,out);
        }
        if(s=='>'){
            fputs(greaterthan,out);
        }
        if(s=='_'){
            fputs(underscore,out);
        }
        //if(s=='^'){
        //    fputs(hat,out);
        //}
        //if(s!='@'&&s!='{'&&s!='}'&&s!='&'&&s!='<'&&s!='>'&&s!='_'&&s!='^'&&s!='~')
        if(s!='@'&&s!='{'&&s!='}'&&s!='&'&&s!='<'&&s!='>'&&s!='_'&&s!='~')
	{
             fputc(s,out);
        }
        s=fgetc(in);
   }

   fputs(CONCLUDE,out);

   fclose(in); 
   fclose(out); 
}
