// all manager related functions are in here
#include "common.h"
#include "menu.h"
#include "customer.h"
#include "md5.h"
#include <fstream>
#include "manager.h"
#include "time.h"
#include <iomanip>
using namespace std;

bool managerLogin(sysConfig *cfg)
{
	position topLeft;
	topLeft.row=SCREEN_HEIGHT/2;
	topLeft.col=(SCREEN_WIDTH/2)-10;

	drawBorder(topLeft,20,1,"Enter Password");
	setScreenPos(topLeft.row+1,topLeft.col+1);
	setColor(BRgreen,black);
	string tryPass=passwordPrompt('*',20);

	removeBorder(topLeft,20,1);

	if ( cfg->isManagerPassword(tryPass) ) 
		return true;
	else
		return false;
}

void managerMenu(sysConfig *cfg, forest &moviesForest)
{
	clock_t loginTime=clock();

	enum choices
	{ VIDEODB, ADDCUST, EDITCUST, NOTIFICATIONS, SHUTDOWN, CHANGEPASS, SAVEMOVIES, LOGOUT };

	menu mnuManager("Manager Menu");

	mnuManager.addChoice("Video Database");			
	mnuManager.addChoice("Add Customer");		
	mnuManager.addChoice("Edit/Delete Customer");	
	mnuManager.addChoice("List Notifications");
	mnuManager.addChoice("Shutdown System");		
	mnuManager.addChoice("Change Manager Password");
	mnuManager.addChoice("Save Movies");
	mnuManager.addChoice("Logout Manager");			
	int choice;
	do {
		choice = mnuManager.getUserChoice(LOGOUT);
		switch ( choice )
		{
			case VIDEODB:
				mgrMovieMenu(moviesForest);
				break;
			case ADDCUST:
				addCustomer();
				break;
			case EDITCUST:
				editCustomer();
				break;
			case NOTIFICATIONS:
				listNotifications();
				break;
			case SHUTDOWN:
				saveMovies(moviesForest);
				cfg->setShutdownFlag();
				choice = LOGOUT;
				break;
			case CHANGEPASS:
				newPassword(loginTime,cfg);
				break;
			case SAVEMOVIES:
				saveMovies(moviesForest);
				alert("Movies saved",BRyellow,blue,"Okay");
				break;
		};
	} while ( choice != LOGOUT );
}

void mgrMovieMenu(forest &moviesForest)
{
	enum choices
	{ LIST_VIDEOS, ADD_VIDEO, RETURN };

	menu mvMenu("Video Database");
	mvMenu.addChoice("List Videos");
	mvMenu.addChoice("Add Video");	
	mvMenu.addChoice("Return to Manager Menu");

	char choice;
	do {
		choice=mvMenu.getUserChoice(RETURN);
		if ( ADD_VIDEO == choice )
		{
			// add video
			movie *newMovie = new movie;
			if ( newMovie->initNewMovie() )
			{
				if ( duplicateTitle(moviesForest, newMovie->getTitle()) )
				{
					alert("A movie with that title already exists");
					delete newMovie;
				} else 
				{
					moviesForest.addMovie(newMovie);
					setStatus("Movie added to database.");
					// save to file
					ofstream outFile;
					outFile.open(MOVIES_FILE,ios::app);
					if ( outFile )
						newMovie->save(outFile);
					else
						alert("Cannot write new movie to database");
					outFile.close();
				}
			} else
				delete newMovie;
		} // end add new movie
		else if ( LIST_VIDEOS == choice )
		{
			listMovies(moviesForest, NULL,true);
		}
	} while ( choice != RETURN );
}

bool duplicateTitle(forest &theForest, string theTitle)
{
	movie::setSortField(SORT_FIELD_TITLE);
	movie *temp = theForest.trees[SORT_FIELD_TITLE].getNode(SORT_FIELD_TITLE,theTitle);

	if ( temp == NULL )
		return false;
	else
		return true;

}

void newPassword(clock_t loginTime, sysConfig *cfg)
{
	clock_t nowTime=clock();
	double loginDuration=(nowTime-loginTime)/1000;

	if ( (loginDuration < 60) || (loginDuration > 60 && managerLogin(cfg)) )
	{
		position topLeft;
		topLeft.row=SCREEN_HEIGHT/2;
		topLeft.col=(SCREEN_WIDTH/2)-10;

		drawBorder(topLeft,25,1,"Enter *NEW* Password");
		setScreenPos(topLeft.row+1,topLeft.col+1);
		setColor(BRgreen,black);
		string newPass=passwordPrompt('*',25);

		removeBorder(topLeft,25,1);

		if ( cfg->saveNewPassword(newPass) )
		{
			setStatus("System configuration saved.");
		} else {
			alert("Unable to save system configuration");
		}
	}

}

void addCustomer()
{
	// create a new account
	customer *theCustomer = new customer();
	if ( theCustomer->initNewCustomer() ) 
	{
		bool okayToAdd=true;

		// is the dl# valid and safe?
		if ( !safeFilename(theCustomer->getDriversLicense()) )
		{
			alert("Invalid Driver's License Entry");
			okayToAdd=false;
		}
		string custFile="customers\\";
		custFile.append(theCustomer->getDriversLicense());

		if ( okayToAdd )
		{
			// check for duplicates
			if ( doesFileExist(custFile) )
			{
				alert("That customer is already in the system");
				okayToAdd=false;
			}
		}

		if ( okayToAdd )
		{
			// no duplicates, add to file
			theCustomer->save(custFile);

			alert("Customer added");
		}		
	} // end if customer initialized properly

	delete theCustomer;
}

void editCustomer()
{
	customer *theCustomer=customerLogin();
	if ( theCustomer == NULL ) return;	// failed to identify the customer

	theCustomer->editDetails();
	
	delete theCustomer;
}

void saveMovies(forest &moviesForest)
{
	vector<movie*> sortedList=moviesForest.trees[SORT_FIELD_ID].getSortedList();

	setStatus("Saving movies to disk...");
	// re-writes the movies vector to the file (done just before closing or whenever else instructed to)
	ofstream outFile;
	outFile.open(MOVIES_FILE);
	if ( outFile )
	{
		for ( unsigned int i=0; i < sortedList.size(); i++ )
		{
			sortedList[i]->save(outFile);
		}
	} else {
		alert("Cannot save movies file!");
	}
	outFile.close();
	setStatus("");
}

void listNotifications()
{
	const unsigned int ITEMS_PER_PAGE=(SCREEN_HEIGHT-10)/4;
	char choice;
	enum choices
	{ NEXT_ITEM=80, PREV_ITEM=72, EXIT=27, PGDN=81, PGUP=73, ENTER=13 };

	// load the notifications from disk
	ifstream inFile;
	inFile.open(NOTIFY_FILE);
	vector<string> vecLine;
	while ( inFile )
	{
		string strLine;
		getline(inFile,strLine);
		if ( inFile )
			vecLine.push_back(strLine);
	}
	inFile.close();

	// parse them into seperate note vectors
	vector<vector<string>> note;

	for ( int i=vecLine.size()-1; i >= 0; i-- )
	{
		vector<string> temp=split(vecLine[i],'|');
		note.push_back(temp);
	}

	// list them
	setStatus("Press ENTER to toggle status code.");

	int topItem=0;			// the item that will appear at the top of the list
	int selectedItem=0;	

	do {
		int row=1;
		int lastItem=topItem + ITEMS_PER_PAGE;
		for ( int i=topItem; i <= lastItem; i++ )
		{
			setScreenPos(row,1);	

			if ( i < note.size() )
			{
				if ( i == selectedItem )
					setColor(BRyellow,BRblue);	// highlight selected item
				else if ( i%2 == 0 )
					setColor(black,BRblack);	// not selected, use normal color (even)
				else
					setColor(black,white);		// not selected, use normal color (odd)
			} else {
				setColor(black,black);			// blank line drawn black on black
			}

			if ( i < note.size() )
			{
				row++; setScreenPos(row,1);
				for ( int j=0; j < SCREEN_WIDTH-2; j++ ) cout << " ";	// fill line with space to erase previous entry
				setScreenPos(row,1);
				cout << left << setw(25) << note[i][0];	// date
				cout << " Status code: " << note[i][7];

				row++; setScreenPos(row,1);
				for ( int j=0; j < SCREEN_WIDTH-2; j++ ) cout << " ";	// fill line with space to erase previous entry
				setScreenPos(row,1);
				cout << left << setw(25) << note[i][1]; // customer name
				cout << left << setw(15) << note[i][2]; // customer phone #
				cout << left << setw(15) << note[i][3]; // customer DLN

				row++; setScreenPos(row,1);
				for ( int j=0; j < SCREEN_WIDTH-2; j++ ) cout << " ";	// fill line with space to erase previous entry
				setScreenPos(row,1);
				cout << left << setw(25) << note[i][4]; // movie title

				row++; setScreenPos(row,1);
				for ( int j=0; j < SCREEN_WIDTH-2; j++ ) cout << " ";	// fill line with space to erase previous entry
				setScreenPos(row,1);				
				cout << note[i][5]; // movie ID
				cout << "-";
				cout << note[i][6]; // copy number
			}
		}

		choice=_getch();

		if ( -32 == choice || 0 == choice ) 
			choice=_getch();

		// handle key presses
		if ( NEXT_ITEM == choice )
		{	// arrow down
			if ( selectedItem < note.size()-1 )
			{	
				selectedItem++;
				if ( selectedItem > lastItem ) topItem++;	// scroll down
			}
		} else if ( PREV_ITEM == choice ) 
		{	// arrow up
			if ( selectedItem > 0 )
			{
				selectedItem--;
				if ( selectedItem < topItem ) topItem--;	// scroll up
			}
		} else if ( PGDN == choice )
		{	// page down
			int tmp=topItem+ITEMS_PER_PAGE;
			if ( tmp >= note.size() )	tmp=note.size()-1;
			selectedItem=topItem=tmp;
		} else if ( PGUP == choice )
		{	// page up
			int tmp=topItem-ITEMS_PER_PAGE;
			if ( tmp < 0 ) tmp=0;
			selectedItem=topItem=tmp;
		} else if ( ENTER == choice )
		{	// toggle status
			if ( note[selectedItem][7] == "0" ) 
				note[selectedItem][7] = "1";
			else
				note[selectedItem][7] = "0";
		}

	} while ( choice != EXIT );

	// re-save the list excluding all those who have been notified
	ofstream outFile;
	outFile.open(NOTIFY_FILE);
	if ( outFile )
	{
		for ( int i=note.size()-1; i >= 0 ; i-- )
		{
			if ( note[i][7] == "0" )
			{
				string thisNote;
				thisNote=note[i][0]+"|"+note[i][1]+"|"+note[i][2]+"|"+note[i][3]+"|"+note[i][4]+"|"+note[i][5]+"|"+note[i][6]+"|"+note[i][7];
				outFile << thisNote << endl;
			}
		}
	}
	outFile.close();

	setStatus("");

	// clear list
	position topLeft;
	topLeft.row=1;
	topLeft.col=1;
	removeBorder(topLeft,SCREEN_WIDTH-4,SCREEN_HEIGHT-8);
}