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

        Final Project                                 MMU 1996

        ######################################################
        #                                                    #
        #               A Logical Neural Network             #   
        #                                                    #
        #            User interface for the logical NN       #  
        #                                                    #
        ######################################################
 
        Albrecht Schmidt                              17.09.96
 
        FILE: CRamUI.C                            Version 1.0
 
   ************************************************************* */

#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>

#include "CRamUI.h"

// constructor
CRamUserIF::CRamUserIF()
{
	changed = FALSE;
	installed = FALSE;
};

// displays a menu and let the user chose
TAction CRamUserIF::Menu()
{
   char choise;
   char inStr[MAX_STR_LEN];
   do
   {
     cout << "\n\nWelcome to the";
     cout <<   "\n       L O G I C A L  N E U R A L  N E T W O R K ";
     cout <<   "\n                                            User Interface!";

     cout << "\n\n-----------------------------------------------------------";
     cout <<   "\n   <N>ew network. User will be asked for parameters.";
     cout <<   "\n   <L>oad a network form a description-file.";
     cout <<   "\n   <S>tore the actuell network in a description-file.";

     cout << "\n\n   <T>rain the network on a data-file.";
     cout <<   "\n   <P>erformance test of the network (on a data-file)";
     cout <<   "\n   <R>eset the the actuell network.";

     cout << "\n\n   <C>alculate outputs for given input file.";

     cout << "\n\n   <H>elp gives help on data-file and";
     cout <<   "\n          desciption-file structure.";

     cout << "\n\n   <Q>uit!";
     cout <<   "\n-----------------------------------------------------------";
     cout << "\n\n>>>";
     gets(inStr);
     choise = inStr[0];
     switch (choise)
     {
	case 'n': case 'N': return new_net;
			    break;
	case 'l': case 'L': return load;
			    break;
	case 's': case 'S': return store;
			    break;
	case 't': case 'T': return train;
			    break;
	case 'p': case 'P': return test;
			    break;
	case 'r': case 'R': return reset;
			    break;
	case 'c': case 'C': return work;
			    break;
	case 'h': case 'H': return help;
			    break;
	case 'q': case 'Q': return quit;
			    break;
	default:
		cout << "\n\n >>>>>> Not a valid choise !";
     }
   }
   while(TRUE);
}

void CRamUserIF::LoadNet()
{
	char yes_no[MAX_STR_LEN]="y";
	char desc_file[MAX_STR_LEN];
	cout <<"\n\nLoad a Neural Network from file:";
	if (changed == TRUE)
	{
		cout << "\n\nWARNING: The existing network has changes since last saving!";
		cout <<   "\n         If a new net is loaded this changes will bi lost!";
		cout << "\n\n         Create new network anyway (y/n) ?";
		cout <<   "\n         >>>";
		cin >> yes_no;
	}
	if (yes_no[0] == 'y')
	{
		cout << "\n Network description file: ";
		cin >> desc_file;
		if (installed == TRUE)
		{
			network->CRamNet::~CRamNet();
		};
		network = new CRamNet(desc_file);
		changed = FALSE;
		installed = TRUE;
	}
}

void CRamUserIF::StoreNet()
{
	char desc_file[MAX_STR_LEN];
	cout <<"\n\nStore a Logical Neural Network in a description file:";

	if (installed == FALSE)
	{
		cout << "\n\nThere is no network loaded !!!";
		cout <<   "\nLoad or create an New Network";
		cout <<   "\nand try again!";
		return;
	}

	cout << "\nNetwork description file: ";
	cin >> desc_file;
	network->StoreNet(desc_file);
	changed = FALSE;
}

void CRamUserIF::TestNet()
{
	char data_file[MAX_STR_LEN];
	char inStr[MAX_STR_LEN];
	double diff;
	cout <<"\n\nTest the Logical Neural Network with a data-file:";

	if (installed == FALSE)
	{
		cout << "\n\nThere is no network loaded !!!";
		cout <<   "\nLoad or create an New Network";
		cout <<   "\nand try again!";
		return;
	}

	cout << "\nName of the data-file: ";
	cin >> data_file;
	cout << "\nConfidence (difference bewteen winner and runner-up) [0.01]? ";
  	gets( inStr);
  	// convert string in number, if string is no valid take default
  	if (sscanf(inStr, "%lf", &diff) < 1) diff = 0.01;
	network->Test(data_file, diff);
}

void CRamUserIF::WorkNet()
{
	char in_file[MAX_STR_LEN],
	     out_file[MAX_STR_LEN];
	cout <<"\n\nCalculate the outputs for a file:";

	if (installed == FALSE)
	{
		cout << "\n\nThere is no network loaded !!!";
		cout <<   "\nLoad or create an New Network";
		cout <<   "\nand try again!";
		return;
	}

	cout << "\nName of the input file: ";
	cin >> in_file;
	cout << "\nName of the output file: ";
	cin >> out_file;
	network->Work(in_file, out_file);
}


void CRamUserIF::NewNet()
{
	char inStr[MAX_STR_LEN];
	char yes_no[MAX_STR_LEN]="y";
	int no_ins, no_class, no_inps_per_net, overlapp;

	cout <<"\n\nSetup a new Neural Network:";
	if (changed == TRUE)
	{
		cout << "\n\nWARNING: The existing network has changes since last saving!";
		cout <<   "\n         If a new net is created this changes will bi lost!";
		cout << "\n\n         Create new network anyway (y/n) ?";
		cout <<   "\n         >>>";
		cin >> yes_no;
	}
	if (yes_no[0] == 'y')
	{
		cout << "\n--- Network Parameter: --- ";
		cout << "\nNumber of inputs? ";
		cin >> no_ins;
		cout << "\nNumber of classes? ";
		cin >> no_class;
		cout << "\nNumber of inputs per net? [8] ";
  		gets( inStr);
    		// convert string in number, if string is no valid take default
    		if (sscanf(inStr, "%i", &no_inps_per_net) < 1) no_inps_per_net=8;

		cout << "\nOverlapp? [1]";
  		gets( inStr);
    		// convert string in number, if string is no valid take default
    		if (sscanf(inStr, "%i", &overlapp) < 1) overlapp=1;

		if (installed == TRUE)
		{
			network->CRamNet::~CRamNet();
		};
		network = new CRamNet(no_ins, no_class, 
                                      no_inps_per_net, overlapp);
 		changed = FALSE;
		installed = TRUE;
	}
}


void CRamUserIF::TrainNet()
{
	char yes_no[MAX_STR_LEN]="y";
	char data_file[MAX_STR_LEN];

	cout <<"\n\nTrain the Neural Network on a data-file:";

	if (installed == FALSE)
	{
		cout << "\n\nThere is no network loaded !!!";
		cout <<   "\nLoad or create an New Network";
		cout <<   "\nand try again!";
		return;
	}

	if (changed == TRUE)
	{
		cout << "\n\nWARNING: The existing network has changes since last saving!";
		cout <<   "\n         If the net is trained this changes will bi lost!";
		cout << "\n\n         Train anyway (y/n) ?";
		cout <<   "\n         >>>";
		cin >> yes_no;
	}
	if (yes_no[0] == 'y')
	{
		cout << "\n--- Learning Parameter: --- ";
		cout << "\nName of the data-file? ";
		cin >> data_file;

		network->Learn(data_file);
		changed = TRUE;
	}
}

void CRamUserIF::HelpNet()
{
  char yes_no;
  cout << "\n\nH E L P  on the file structures for this program!";
  cout << "\n\n* The data file: (for training and testing)";
  cout <<   "\n  For each recored one line is used. First there are the";
  cout <<   "\n  input values separetated by <SPACE>. Then a ':' follows.";
  cout <<   "\n  after this the output values are placed. The line is ended";
  cout <<   "\n  by a ';'. The last line is ended by a '.'.";
  cout <<   "\n  example:     1 -0.6 2.2 0.888 -1 : 1 0 1;";
  cout <<   "\n               ....";
  cout <<   "\n               3.2 -1 0.5 -1.1 -2.1 : 0 0 1.";
  cout << "\n\n* The work file: (for calculating the output)";
  cout <<   "\n  For each recored one line is used. First there are the";
  cout <<   "\n  input values separetated by <SPACE>. The line is ended";
  cout <<   "\n  by a ';'. The last line is ended by a '.'.";
  cout <<   "\n  example:     1 -0.6 2.2 0.888 -1 ;";
  cout <<   "\n               ....";
  cout <<   "\n               3.2 -1 0.5 -1.1 -2.1 .";
  cout <<   "\n\n\nBack to menu? (y) ";
  cin >> yes_no;
}

void CRamUserIF::QuitNet()
{
	char yes_no[MAX_STR_LEN]="y";
	cout <<"\n\nQuit this program:";
	if (changed == TRUE)
	{
		cout << "\n\nWARNING: The existing network has changes since last saving!";
		cout <<   "\n         If a new net is created this changes will bi lost!";
		cout << "\n\n         Quit anyway (y/n) ?";
		cout <<   "\n         >>>";
		cin >> yes_no;
	}
	if (yes_no[0] == 'y')
	{

		cout << "\n\nBYE !!!\n\n";
		if (installed == TRUE)
		{
			network->CRamNet::~CRamNet();
		};
		exit(1);
	}
}

void CRamUserIF::ResetNet()
{
 cout << "\n\n Sorry not implmented yet :  CRamUserIF::ResetNet() \n";
 cout << " Just restart the program -- same effect!!!! \n\n";
}

void CRamUserIF::Handle(TAction action)
{
	switch (action)
	{
	  case new_net: NewNet();
			break;
	  case load:    LoadNet();
			break;
	  case store:   StoreNet();
			break;
	  case train:   TrainNet();
			break;
	  case test:    TestNet();
			break;
	  case reset:   ResetNet();
			break;
	  case work:    WorkNet();
			break;
	  case help:    HelpNet();
			break;
	  case quit:	QuitNet();
			break;
	}
}
