#include "inputoutput.h"


#define OUTPUT_FILENAME "out.csv"


bool getContinue()
{
	string input;

	do
	{
		cout << "Continue? (Y/N): ";
		getline(cin, input);

		if (input.length() > 1 || (tolower(input[0]) != 'y' && tolower(input[0]) != 'n'))
			continue;
		else if (tolower(input[0]) == 'y')
			return true;
		else
			return false;

	} while (true);
}



string getFileName()
{
	string filename;

	cout << "Enter the name of the transaction file: ";
	getline(cin, filename);

	return filename;
}



int	getMinimumSupport(const int totalTransactionCount)
{
	cout << "Enter the desired transactions for minimum support.\n"
		<< "This can either be an exact number of transactions, \n"
		<< "or a percentage of all transactions if you begin with\n"
		<< "a % sign.\n";
	
	string input;
	int support = -1;
	bool enteredPercent, valid;

	do
	{
		enteredPercent = false;
		valid = true;

		cout << "Enter minimum support: ";
		getline(cin, input);

		if (input[0] == '%')
		{
			enteredPercent = true;
			input.erase(0, 1);
		}

		for (size_t i = 0; i < input.size() && valid; i++)
		{
			if (input[i] < '0' || input[i] > '9')
				valid = false;
		}

		if (valid)
			support = (enteredPercent) ? (stoi(input) * static_cast<int>(0.01 * totalTransactionCount)) : stoi(input);

	} while (support < 0 || support > totalTransactionCount);

	return support;
}


void initializeTransactionArray(bool** &transactions, ArrayInfo2D &arrayInfo, int sizeI, int sizeJ)
{
	transactions = new bool*[sizeI];
	for (int i = 0; i < sizeI; i++)
	{
		transactions[i] = new bool[sizeJ];

		for (int j = 0; j < sizeJ; j++)
		{
			transactions[i][j] = false;
		}
	}

	arrayInfo.sizeI = sizeI;
	arrayInfo.sizeJ = sizeJ;
}



bool loadData(bool** &transactions, ArrayInfo2D &arrayInfo, const string &filename,string numTransactions, string numItems)
{
	ifstream fin;

	fin.open(filename);
	if (!fin.good())
		return false;

	/*string numTransactions, numItems;*/

	//Determine the size of our array and initialize it
	//parseFileName(numTransactions, numItems, filename);
	//numTransactions = 10;
/*cout << "number Transactions: ";
	getline(cin, numTransactions);*/	
	//numItems = 16;
	
	//cin >> numTransactions;
	/*cout << "number Items: ";
	getline(cin, numItems);*/
	//cin >> numItems;
	initializeTransactionArray(transactions, arrayInfo, stoi(numTransactions), stoi(numItems));

	//Actually load the data
	readDataFile(transactions, arrayInfo, fin);

	return true;
}



void outputResults(double time, const Trie& largeItemsets)
{
	DynamicArray<DynamicArray<int>> itemsets;
	largeItemsets.getAllPaths(itemsets);

	for (int i = 0; i < itemsets.count(); i++)
	{
		//ex: "Set 1: 4 5
		//	   Set 2: 4 7"
		cout << "Set " << i + 1 << ": ";
		itemsets[i].display();
	}

	cout << "All sets found in " << time << " seconds." << endl;
}

void WriteOutputResults(double time, const Trie& largeItemsets)
{
	FILE *fp;
	DynamicArray<DynamicArray<int>> itemsets;
	largeItemsets.getAllPaths(itemsets);
	fopen_s(&fp, OUTPUT_FILENAME, "a");

	for (int i = 0; i < itemsets.count(); i++)
	{
		//ex: "Set 1: 4 5
		//	   Set 2: 4 7"
		fprintf(fp, "Set %d :", (i + 1));
		for (int j = 0; j < itemsets[i].numIndexesFilled; j++)
			fprintf(fp, "%d ", itemsets[i].mData[j]);
		fprintf(fp, "\n");
	}
	fprintf(fp, "All sets found in %Lf seconds.",time);
	fclose(fp);
}

void parseFileName(int &transactions, int &items, const string &filename)
{
	//Values in title
	string transactionsStr = "";   //D value
	string itemsStr = "";          //N value

	//Track what to store from filename string
	bool readN = false;
	bool readD = false;

	for (size_t i = 0; i < filename.size(); i++)
	{
		if (toupper(filename[i]) == toupper('k'))
			readN = readD = false;

		if (readN)
			itemsStr += filename[i];
		else if (readD)
			transactionsStr += filename[i];

		if ((filename[i]) == toupper('n'))
			readN = true;
		else if ((filename[i]) == toupper('d'))
			readD = true;
	}

	transactions = static_cast<int>(stof(transactionsStr) * 1000);
	items = static_cast<int>(stof(itemsStr) * 1000);
}

void CreateData(char *fn)
{
	FILE *fp;
	fopen_s(&fp, fn, "w");
	fprintf(fp, "%s,%s,%s,%s,%s,%s,%s,%s\n", "nbThreads","numTransactions","numItems", "minSupport", "executionTime", "speedUp", "efficacity", "realEfficacity");
	fclose(fp);
}
void WriteData(char *fn, int nbThreads, int numTransactions, int numItems, int minSupport, float timeExec, float speedUp, float efficacity, float realEfficacity)
{
	FILE *fp;
	fopen_s(&fp, fn, "a");
	fprintf(fp, "%d,%d,%d,%d,%lf,%lf,%lf,%lf\n", nbThreads, numTransactions, numItems, minSupport, timeExec, speedUp, efficacity, realEfficacity);
	fclose(fp);
}

void readFile(bool **transactions, const ArrayInfo2D &arrayInfo, ifstream& fin)
{
	int currentTransaction, currentItem;

	fin >> currentTransaction >> currentItem;

	bool *thisTransaction;

	--currentTransaction;
	while (!fin.eof())
	{
		thisTransaction = transactions[currentTransaction];
		*(thisTransaction + currentItem) = true;
		
		fin >> currentTransaction >> currentItem;

		--currentTransaction;
	}
}

void readDataFile(bool **transactions, const ArrayInfo2D &arrayInfo, ifstream& fin)
{
   char  c;
   int   pos;
   bool *thisTransaction;
   int currentTransaction = 0;
   do
   {
      int item = 0;
      pos = 0;
	  thisTransaction = transactions[currentTransaction];
      c = fin.get();
      while((c >= '0') && (c <= '9'))
      {
         item *= 10;
         item += int(c)-int('0');
		 c = fin.get();
         pos++;
      }
	  if (pos){
		  *(thisTransaction + item) = true;
		  //cout << item<<endl;
	  }
	  if (c == '\n')
		  currentTransaction++;
	 // cout << currentTransaction << endl;
   } while (!fin.eof());
}