/* Orthogonalization */ 
/* Lukas Hoger */


#include <iostream>
#include "stdafx.h"
#include <time.h>
#include <stdio.h>

using namespace std;

#include "Kernel/bitvector.h"

#include "Kernel/myExcept.h"

#include "Kernel/SoTerm.h"
#include "Kernel/Cube.h"
#include "Kernel/Term.h"
#include "Kernel/PLA_type.h"
#include "Kernel/TTree.h"
#include "Kernel/PLA.h"

#include "PLA_operations.h"



void sleep(unsigned int mseconds)
/* 
Sleep (time....ms)
*/
{
    clock_t goal = mseconds + clock();
    while (goal > clock());
}



void help()
{
/*
Help - display on screen
*/    
   
  fprintf( stderr, "syntax:  method_of_algorithm  source_file  output_file \n\n" );
  fprintf( stderr, "method_of_algorithm: \n" );
  fprintf( stderr, " 'best' -  Algorithm '9' with eliminate terms where aren't any 1 in output \n" );
  fprintf( stderr, " '0'    -  Algorithm without term sort \n" );
  fprintf( stderr, " '1'    -  Algorithm with term size sort (inc) \n" );
  fprintf( stderr, " '2'    -  Algorithm with term size sort (dec) \n" );
  fprintf( stderr, " '3'    -  Algorithm with term intersect sort (inc) \n" );
  fprintf( stderr, " '4'    -  Algorithm with term intersect sort (dec) \n" );
  fprintf( stderr, " '5'    -  Algorithm with term intersect sort (inc) and term size sort (dec) \n" );
  fprintf( stderr, " '6'    -  Algorithm with term intersect sort (dec) and term size sort (dec)\n" );
  fprintf( stderr, " '7'    -  Algorithm with term sort term mergeNeighbors sort (inc) \n" );
  fprintf( stderr, " '8'    -  Algorithm with term sort term mergeNeighbors sort (dec) \n" );
  fprintf( stderr, " '9'    -  Algorithm '2' with back merge \n" );
  fprintf( stderr, " '10'   -  Algorithm '9' with eliminate terms where aren't any 1 in output \n" );
  fprintf( stderr, " '11'   -  Algorithm '10' with minimization terms with espresso before orthogonalization (needs espresso.exe in local directory) \n" );
 
  sleep(2000);
}


/* main programme */
int main(int argc, char* argv[])
{
    PLA source; 
    PLA *dest;
	unsigned int op;


    if ( argc != 4 ) {
      help();
      exit(1);
    }
    
    op = 20; // default
    
    // setting - argument
    if ( strcmp(argv[1], "0" ) == 0 )  op = 0;
    if ( strcmp(argv[1], "1" ) == 0 )  op = 1;
    if ( strcmp(argv[1], "2" ) == 0 )  op = 2;
    if ( strcmp(argv[1], "3" ) == 0 )  op = 3;
    if ( strcmp(argv[1], "4" ) == 0 )  op = 4;
    if ( strcmp(argv[1], "5" ) == 0 )  op = 5;
    if ( strcmp(argv[1], "6" ) == 0 )  op = 6;
    if ( strcmp(argv[1], "7" ) == 0 )  op = 7;
    if ( strcmp(argv[1], "8" ) == 0 )  op = 8;
    if ( strcmp(argv[1], "9" ) == 0 )  op = 9;
    if ( strcmp(argv[1], "10" ) == 0 ) op = 10;
    if ( strcmp(argv[1], "11" ) == 0 ) op = 11;
    
    // best
    if ( strcmp(argv[1], "best" ) == 0 ) op = 10;
   

    if (op == 20) {
      help();
      exit(1);
    }
        
    try {
        source.LoadPLA(argv[2]);
    } catch (IOException e) {
            cerr << e.GetMsg() << endl;
            exit(1);
    }


  /* ----------- run algorithm ------------*/


  source.LoadPLA(argv[2]);  // load PLA from file
 
  
  if (op != 11) {

    dest = Orto(source, op); // orthogonalization        
    dest->SavePLA(argv[3]);  // save PLA to file
    delete dest;

  } else {
    /* op = with espresso */   
   
    /* if file exists? */   
    FILE *test_file;
    test_file = fopen("espresso.exe", "r");
    if (!test_file) {
        fputs("Doesnt exist espresso.exe in local directory.\n", stderr);
        return 1;
    }
    fclose(test_file);
      
    PLA source2; 
    PLA *dest2;
    
    dest2 = &source;
    dest2->SavePLA("file_for_espresso.pla");  // save PLA to file

    system("espresso.exe file_for_espresso.pla >> output_file_espresso.pla");

    source2.LoadPLA("output_file_espresso.pla");  // load PLA from file    } catch (IOException e) {

    dest = Orto(source2, op); // orthogonalization        
    dest->SavePLA(argv[3]);  // save PLA to file

    system("del file_for_espresso.pla");
    system("del output_file_espresso.pla");
  }
  
return 0;
}
