/* *****************************************************************

        File    : decada.c
        Author  : Himanshu A. Sanghavi, (modified by Sudhir, Vigyan)
        Advisor : Dr. Vijay K. Garg, (modified under Dr R.Kumar)
        Date    : August 1, 1991, (modified in '95, '98)
                   
        This file contains a program that illustrates the use of the
        finite state machine library.  To run this program, it is
        necessary to have the various "*.data" files that come with
        this library in the same directory as this file.  Results are
        printed in files named "*.results".


   ***************************************************************** */

#include "fsm.h"
#include "Reachability.h"
#include "Minimization.h"
#include "RemoveEp.h"
#include "NDFSMtoDFSM.h"
#include "Complement.h"
#include "StrictSynchComp.h"
#include "Union.h"
#include "Concatenation.h"
#include "Quotient.h"
#include "SupremalContSubLang.h"
#include "AsynchComp.h"
#include "Rename.h"
#include "Trim.h"
#include "Mask.h"
#include "UnMask.h"
/*#include "CheckFunct.h"*/
#include "Completion.h"
#include "Augmentation.h"
#include "SupConNorm.h"
#include "ControlCheck.h"
/*#include "MultifSynchComp.h"*/
#include "CompSynchComp.h"
#include "Observability.h"
#include "Normality.h"
#include "Diagnosability.h"

main(argc, argv)
int argc;
char *argv[];
{
   int no_of_states, no_of_trans;
   int safe, normal;
   ST_LIST *st_ptr;
   TR_LIST *tr_ptr;
   FILE *f10;
   char cmd;
   char *ifile1, *ifile2, *ifile3, *ifile4, *ifile5;
   size_t strlen1, strlen2; /*for mask/cont*/
   char *periodptr; /*for mask/cont*/
   int twofiles = 0, threefiles = 0, fourfiles = 0, fivefiles=0;
   MASK_LIST *mask_list;
   MULT_MASKL *mmaskL;

   /* Open a log file logOfOperations in which operations being performed
   are written out*/
                
   f10 = fopen("logOfOperations", "w+");
   fprintf(f10,"\n\tOperations performed by `decada' are being recorded here\n");
   fprintf(f10, "\t\t\t\t in the order of execution\n\n");
   fprintf(f10, "\t\t ------------------------------------------ \n\n\n");

   if(argc <2){
           printf("\n%s","No argument given.  Would you like to run all functions? (y/n):");
           cmd = getchar();
           
           if(cmd == 'y')
                   cmd = 'A';
           else
                cmd = '~'; /*no argument given*/
   }
        else
                cmd = argv[1][0];

        if(cmd == 'A' && argc >=3){
                puts("Can not pass file name arguments with command A");
                fprintf(f10,"Can not pass file name arguments with command A");
                fclose(f10);    
                exit(1);
        }

        if(argc == 3){
                puts("Must pass at least 2 file names in argument");
                fprintf(f10,"Must pass at least 2 file names in argument");
                fclose(f10);    
                exit(1);
        }

        if(!((cmd >= 'a' &&  cmd <= 't') || cmd == 'u' || cmd == 'v' || cmd == 'y' || 
                cmd == 'A'|| cmd == 'M'|| cmd == 'O' || cmd == 'G'|| (cmd >= 'V' && cmd <= 'Z')))
        {
                puts("Proper usage is decada cmd where cmd is one letter pick cmd to demonstrate:\n");
                                puts("A = All functions\t\ta = Reachability\tb = Minimization");
                                puts("c = Remove Epsilon Trans.\td = NDFSM to DFSM\te = Complement");
                                puts("f = Strict Synch. Comp.\t\tg = Union");
                                puts("h = Concatenation\t\ti = Asynch Composition\tj = Quotient");
                                puts("k = Supremal Cont. Sub. Lang.\tl = Rename States\tm = Trim FSM");
                                puts("n = Masking\t\to = UnMasking");
                                puts("O = Non-Strict Synch. Comp.");
                                puts("r = Completion\t\t\ts = Augmentation\tu = Labelling Data");
                                puts("v = Relabelling\t\t\tV = Observability\tW = Normality");
                                puts("X = Diagnosability\t\ty = Controllability\tt = Supremal Controlable & Normal Sublanguage");
                        
                        fprintf(f10,"Invalid command");
                        fclose(f10);
                        exit(0);
        }
        
        /* could check to make sure appropriate number of files passed for each cmd, but not necessary */
        
        /*set up pointers to file names passed as input arguments*/
        if(argc > 3)            
                ifile1 = argv[2];
        if(argc >=4){
                ifile2 = argv[3];
                if(argc ==4) twofiles = 1;
        }
        if(argc >=5){
                ifile3 = argv[4];
                if(argc ==5) threefiles = 1;
        }
        if(argc >=6){
                ifile4 = argv[5];
                if(argc == 6) fourfiles = 1;
        }
        if(argc ==7){
                ifile4 = argv[6];
                if(argc == 7) fivefiles = 1;
        }

        if(cmd == 'a' || cmd == 'A')
        Reachability(ifile1, ifile2, twofiles, f10); /* see Reachability.h*/

        if(cmd == 'b' || cmd == 'A')
        Minimization(ifile1, ifile2, twofiles, f10); /*see Minimization.h*/

        if(cmd == 'c' || cmd == 'A')
        Removeep(ifile1, ifile2, twofiles, f10); /*see RemoveEp.h*/

        if(cmd == 'd' || cmd == 'A')
        NDFSM_to_DFSM(ifile1, ifile2, twofiles, f10);/* see NDFSMtoDFSM.h*/

        if(cmd == 'e' || cmd == 'A')
        Complement(ifile1, ifile2, twofiles, f10); /* see Complement.h*/

        if(cmd == 'f' || cmd == 'A')
        Strict_Synch_Comp(ifile1, ifile2, ifile3, threefiles, f10); /* see StrictSynchComp.h*/

        if(cmd == 'g' || cmd == 'A')
        Union(ifile1, ifile2, ifile3, threefiles, f10); /* see Union.h*/

        if(cmd == 'h' || cmd == 'A')
        Concatenation(ifile1, ifile2, ifile3, threefiles, f10); /* see Concatenation.h*/

        if(cmd == 'i' || cmd == 'A')
        Asynch_Comp(ifile1, ifile2, ifile3, threefiles, f10); /* see AsynchComp.h*/

        if(cmd == 'j' || cmd == 'A')
        Quotient(ifile1, ifile2, ifile3, threefiles, f10); /* see Quotient.h*/

        if(cmd == 'k' || cmd == 'A')
        Supremal_Cont_Sub_Lang(ifile1, ifile2, ifile3, ifile4, threefiles, fourfiles, f10); /* see SupremalContSubLang.h*/

        if(cmd == 'l' || cmd == 'A')
        Rename(ifile1, ifile2, twofiles, f10); /* see Rename.h*/

        if(cmd == 'm' || cmd == 'A')
        Trim(ifile1, ifile2, twofiles, f10); /* see Trim.h*/
        
        if(cmd == 'n'|| cmd == 'A') /*see Mask.h*/
	    Mask(ifile1, ifile2, ifile3, twofiles, f10);

	    if(cmd == 'o'|| cmd == 'A') /*see UnMask.h*/
	    UnMask(ifile1, ifile2, ifile4, twofiles, f10);
        /*CHECK_FUNCT /*see CheckFunct.h*/

        if(cmd == 'r' || cmd == 'A')
        Completion(ifile1, ifile2, ifile3, threefiles, f10); /* see Completion.h*/

        if(cmd == 's' || cmd == 'A')
        Augmentation(ifile1, ifile2, ifile3, threefiles, f10); /* see Augmentation.h*/

        if(cmd == 't' || cmd == 'A')
        Sup_Con_Norm(ifile1, ifile2, ifile3, ifile4, threefiles, fourfiles, f10); /*see SupConNorm.h*/

        if(cmd == 'y' || cmd == 'A')
        Control_Check(ifile1, ifile2, ifile3, ifile4, threefiles, fourfiles, f10); /* see ControlCheck.h*/

        /*MULTIF_SYNCH_COMP /*if(cmd == 'M' || cmd == 'A') see MultifSynchComp.h*/

        if(cmd == 'O' || cmd == 'A')
        Comp_Synch_Comp(ifile1, ifile2, ifile3, threefiles, f10); /* see CompSynchComp.h*/

        if(cmd == 'V' || cmd == 'A')
        Observability(ifile1, ifile2, ifile3, ifile4, threefiles, fourfiles, f10); /* see Observability.h*/

        if(cmd == 'W' || cmd == 'A')
        Normality(ifile1, ifile2, ifile3, ifile4, threefiles, fourfiles, f10); /* see Normality.h*/

        if(cmd == 'X' || cmd == 'A')
        Diagnosability(ifile1, ifile2, ifile3, ifile4, threefiles, fourfiles, f10); /* see Diagnosability.h*/

        fclose(f10); /*close log file*/
}
