#include <iostream>
#include <fstream>
#include <sstream>
#include <time.h>
#include <conio.h> 

#include "interface.h"

//#define MAX_LENGTH 1024

//#define DEBUG

//======================================================
//ukazka pouziti interfacu
//#define TEST

#ifdef TEST
int main (int argc, char * argv[])
{
  ifstream * input = new ifstream("input.pla");
  ofstream * output = new ofstream("output.pla");
  
  //ifstream * script = new ifstream("script.txt");
  istringstream * script = new istringstream("y3 <= 0 or 1 or 2;");
  
  init();
  autoprint = true; //nastaví ukládání bez interakce
	
  readpla(input);
	
  performScript(script);
  performOp(NEG);
  performOp(COF, NULL, 3, 0, 1);
  performOp(SAVEPLA, output);
	
  clean();
}
#endif

//======================================================
/*====================================================*/
//main - parametr muze byt pozadovana operace
#ifndef TEST
int main (int argc, char * argv[])
{
 cout<<argv[0]<<endl;
 string file_path = "";
 string out_path = "";
 string script_path ="";
 //"output.txt";
 int opt1 = 0;
 int option = 0;
 int iter = 0;
 bool use_script = false;
 bool typeset = false;
 
 ifstream * input = NULL;
 ifstream * script = NULL;
 ofstream * output = NULL;
 
 
 
 //cout<<file_path<<endl;
 
 //inicializace
 init();
 
 //pokud je zadano jmeno vstupu/vystupu nebo skript
 if (argc > 1)
 {
	 file_path = argv[1];
	 if (argc > 2) out_path = argv[2];
	 
	 //pokud je zadan skript
	 if (argc > 3)
	 {
		 script_path = argv[3];
		 use_script = true;
		 autoprint = true;
	 }
 }
 
 
 //use_script = true;
 
 #ifdef DEBUG
 file_path = "i.txt"; 
 #endif
 


 
 //otevreni vstupu a vystupu
 input = new ifstream(&file_path[0]);
 
 if (input->fail())
 {
   delete input;
   cout<<"Enter legal input file path :";
   cin>>file_path;
   input = new ifstream(&file_path[0]);
 }

 if (input->fail())
 {
 	delete input;
 	cout<<"Cannot open input file - terminating"<<endl;
 	return 0;
 }

 output = new ofstream(&out_path[0]);
 
 /*
 if ( output->fail() )
 {
 	delete output;
 	cout<<"Enter legal output file path :";
 	cin>>out_path;
 	output = new ofstream(&out_path[0]);
 }
 
 if ( output->fail() )
 {
 	delete input;
 	delete output;
 	cout<<"Cannot open output file - terminating"<<endl;
 	return 0;
 }
 */
 
 if (use_script)
 {
	 script = new ifstream(&script_path[0]);
	 
	 if ( script->fail() )
	  {
	  	delete script;
	  	cout<<"Enter legal script file path :";
	  	cin>>script_path;
	  	script = new ifstream(&script_path[0]);
	  }
	  
	  if ( script->fail() )
	  {
	  	delete input;
	  	delete output;
	  	delete script;
	  	cout<<"Cannot open script file - terminating"<<endl;
	  	return 0;
	  }
 }
 
 
 
 //vyber typu vstupniho souboru
 while (true)
 {
	 cout<<"Select input type:"<<endl;
	 cout<<"1. PLA"<<endl;
	 cout<<"2. VHDL"<<endl;
	 cout<<"Choice:";
	 
	 #ifdef DEBUG
	 opt1 = 1;
	 #endif
	 
	 if (file_path.find(".pla") != string::npos)
	 {
		 opt1 = 1;
		 typeset = true; 
	 }
	 
	 if (file_path.find(".vhd") != string::npos)
	 {
		 opt1 = 2;
		 typeset = true;
	 }
	 
     #ifndef DEBUG
	 if ( (!use_script) && (!typeset) ) cin>>opt1;
	 else
	 {
		 opt1 = 1;
		 cout<<opt1<<endl;
	 }
	 #endif
	 
	 if (opt1 == 1 || opt1 == 2) break;
	 if (opt1 == 0)
	 {
	 	cout<<"Exiting"<<endl;
	 	return 0;
	 }
 }
 
 //analyza PLA
 if (opt1 == 1)
 {
	 readpla(input);
	 //cout<<"terms:"<<terms<<endl;
 }
 
 
 //analyza VHDL
 if (opt1 == 2) readvhdl(input);

 
 
 //hlavni cyklus - operace se stromem
 while (true)
 {
	 
	 //vyber pozadovane operace
	 cout<<endl;
	 cout<<"Select action:"<<endl;
	 cout<<NEG<<". Negation"<<endl;
	 cout<<AON<<". And-Or-Not form"<<endl;
	 cout<<CNF<<". CNF"<<endl;
	 cout<<DNF<<". DNF"<<endl;
	 cout<<SAT<<". Satisfiability test"<<endl;
	 cout<<NANDF<<". Nand form"<<endl;
	 cout<<NORF<<". Nor form"<<endl;
	 cout<<ADDF<<". Add function"<<endl;
	 cout<<SAVEPLA<<". Save as PLA"<<endl;
	 cout<<SAVEVHDL<<". Save as VHDL"<<endl;
	 cout<<SAVEBLIF<<". Save as BLIF"<<endl;
	 cout<<ABS<<". Enable/disable absorption"<<endl;
	 cout<<COF<<". Create cofactor"<<endl;
	 cout<<EXIT<<". Exit"<<endl;
	 //cout<<"x. Evaluation"<<endl;
	 cout<<"Choice:";
	 option = EXIT;
	 iter++;
	 
	 #ifdef DEBUG
	 if (iter==1) option = SAVEPLA;
	 if (iter==2) option = EXIT;
	 if (iter==3) option = EXIT;
	 if (iter==4) option = EXIT;
	 #endif
	 
	 #ifndef DEBUG
	 if (!use_script) cin>>option;
	 else 
	 {
		 performScript(script);
		 if (iter == 1) option = SAVEPLA;
		 if (iter == 2) option = EXIT;
		 cout<<option;
	 }
	 #endif
	 cout<<endl;
	 
	 performOp(option, output);
	 
	 if ((option > EXIT-1) or (option < 1)) {break;}
 }
 
 
 
 //dealokace objektu 
 clean();
 input->close();
 delete input;
 output->close();
 delete output;
 
 cout<<endl<<"Exiting"<<endl;
 //cout<<"Press any key to close the application"<<endl;
 //getch();
 return 1;
}
#endif
