// JavaScript Document
//---------------------  File Header  -----------------------
//  onsiteCookieHandler.js
//
// Purpose:		Load and store saved evaluations in cookies
//
//	Defines:		global variables
//
//	Functions:	initForm ()					Initializes the form to "new"
//					loadGlobal ()				loads global memory with contents of form
//					formatCookie()				Creates the cookie string from the form
//					saveEval()					Saves the current evaluation
//					saveNewEval()				Saves the current evaluation as a new cookie
//					deleteEval()				Deletes the saved evaluation
//					loadEval()					Loads the specified evaluation into the form
//					determineScores ()		Calculates results in global (no display)
//					displayGlobal ()			Pushes the global onto the screen
//					evalVendors()				Evaluates the curren vendors (and loads internal memory)
//					determineSavedEvals()	finds and lists saved evaluations
//					emailResults()				e-mail results for tracking
//
// Internal:	getCookieString			gets a piece of a string (by delimiter)
//
//	Requires:	cookies.js					general cookie handlers
//					onsiteOperatingDefs.php (js scripts created by php)
//
// Note: we use max numbers when creating the cookie.
//			we use num numbers when creating the screen.
//			that allows us to expand later without fussing with the cookie formats
//			global memory holdx max numbers
// ===============================  LOAD GLOBAL  ==============================================
function loadGlobal ()
// ----------  Function Header  --------------
//	Name:			loadGloabl ()
//	Purpose:		copy contents of screen into global memory
//					the function also calculates all scores
//	Inputs:		none
//	Process:		
//					initialize computed scores
//					get evaluation information
//					get vendor information
//					scan fields for scores 
//						decode vendor, category, score indexes from field name
//						store score
//						add to score for category:vendor
//					compute vendor results
//	Outputs:		globals only.
//	-------------------------------------------
{
	var i, j, k;					// general purpose indexes
	var elname;						// field (element) name holder
	var lenPrefix = inputPrefix_GS.length;
	var vendorIndx, categoryIndx, valueIndx;
	var score;						// score holder
	
	//--------  Get evaluation header information  -------------------------//
	osvTitle_G 			= F_G [evalTitleFName_GS].value;			// Evaluation Title
	osvGoal_G 			= F_G [evalGoalFName_GS].value;			// Seminar Goal
	osvDiscipline_G 	= F_G [evalDisciplineFName_GS].value;	// get discipline
	
	//--------- Get Vendor Information  -------------------------//
	for (i=0; i<numVendors_GS; i++)		// each vendor
	{
		osvName_G [i] = F_G [vendNamePrefix_GS+i].value;
		osvLink_G [i] = F_G [vendLinkPrefix_GS+i].value;
	}
	
	//-------- Get ranking Data  ---------------------------------//
	// Note: Values are stored by vendor:category:value
	// 
	for (i=0; i<F_G.length; i++)			// Scan all form fields for the right ones
	{
		elName = F_G [i].name;													// Get the next field
		if (elName.substr(0, lenPrefix) == inputPrefix_GS)				// Then it's our input field
		{
			vendorIndx 		= parseInt(elName.substr(lenPrefix, 1));	// Vendor number
			categoryIndx 	= parseInt(elName.substr(lenPrefix+1, 1));// Category number
			valueIndx 		= parseInt(elName.substr(lenPrefix+2, 1));// Value Index
		
			// All the prep work is done. handle the data.
			score = parseInt(F_G [i].value);									// get the value
		
			// Validate the number (it's either valid or blank (=NaN) then store it.
			if (isNaN(score))															// >if : Emplty
				score = nullScore_GS;												// then: make zero if empty
			osvValue_G [vendorIndx][categoryIndx][valueIndx] = score;	// Save raw data in global
		}
	}
	computeScores();
}

//==========================  FORMAT COOKIE  =========================================
function formatCookie ()
// ----------  Function Header  --------------
//	Name:			formatCookie
//	Purpose:		Create the cookie string
//	Inputs:		none (form)
//	Process:		Start with evaluation title
//					add goal
//					add discipline
//					Add scores
//	Outputs:		cookie formatted string
//	-------------------------------------------
{
	var cValue;			// The cookie string
	var i, j, k;		// Loop variables
	var val;				// value place holder
	
	loadGlobal();		// save screen data into global
	
	cValue = osvTitle_G + cookieDelimiter;
	cValue += osvGoal_G + cookieDelimiter;
	cValue += osvDiscipline_G + cookieDelimiter;
	for (i=0; i<maxVendors_GS; i++)	// for each possible vendor
	{
		cValue += osvName_G[i] + cookieDelimiter;
		cValue += osvLink_G[i] + cookieDelimiter;
		for (j=0; j<maxCategories_GS; j++)
		{
			for (k=0; k<maxScores_GS; k++)
			{
				val = osvValue_G [i][j][k];
				if ((val == null) || (val == nullScore_GS))
					cValue += nullScore_GS;
				else
					cValue += val;
			}
		}
	}
	return cValue;
}

// ===============================  SAVE EVAL  =====================================
function saveEval()
// ----------  Function Header  --------------
//	Name:			saveEval()
//	Purpose:		Resaves the current evaluation in it's cookie format
//	Inputs:		none
//	Process:		Overwrite the cookie
//					update form status
//	Outputs:		cookie & globals
//	-------------------------------------------
{
	putCookie (currCookieO_G.name, formatCookie(), 6, "");
	
	setSaved();
	setUnChanged();
}

// ===============================  SAVE NEW EVAL  ====================================
function saveNewEval()
// ----------  Function Header  --------------
//	Name:			saveNewEval()
//	Purpose:		Saves the current screen into a new cookie
//					Note: upon entry, we must ensure an available name
//	Inputs:		none
//	Process:		Scan cookie names to find an unused one
//					when found, save the cookie
//					update the options list on the screen
//					update all global and screen parameters
//
//	Outputs:		cookie & globals
//	-------------------------------------------
{
	var cookieNo, optionIndex, cookieName;
	var cookie = formatCookie();
	
	for (cookieNo=0; cookieNo<maxCookies_GS; cookieNo++)
	{
		cookieName = cookieNamePrefix_GS + cookieNo;
		if (getCookie (cookieName) == null)			// we can use this name
		{
			putCookie (cookieName, cookie, 6, "");
			break;
		}
	}
	
	// -------------  Find where the cookie handler put it  -------------------
	setCookieGlobal (cookieName);
	
	// ---------  Add the new saved eval to the options list  -------------------
	optionIndx = F_G.savedList.options.length; 	// add on to end.
	F_G.savedList.options [optionIndx] = new Option (osvTitle_G.substr(0, maxTitleSize), i);
	
	addEvalNum();				// another eval saved
	setSaved();					// tell user
	setUnChanged();			// tell user and set flag
	//
	// ------------  Add warning here if numEvals is max'd out
	//
}

// ==================================  DELETE EVAL  =========================================
function deleteEval (evalNo)
// ----------  Function Header  --------------
//	Name:			deleteEval()
//	Purpose:		Deletes a saved evaluation and frees up the cookie
//	Inputs:		evaluation number
//	Process:		Delete the cookie
//					delete the option
//					update global
//	Outputs:		none
//	-------------------------------------------
{
	var i, j;
	var cname = cookieNamePrefix_GS + evalNo;
	
	//----------------  delete the cookie  -------------------
	deleteCookie (cookieNamePrefix_GS+evalNo);
	
	// Remove the option from the pick list
	for (i=0; i<F_G.savedList.options.length; i++)
	{
		if (F_G.savedList.options[i].value == evalNo)
		{
			F_G.savedList.options[i] = null;
			break;
		}
	}
	subtractEvalNum();
}

// ==========================  GET COOKIE STRING  ==========================================
function getCookieString (string, start, delimiter)
{
	var send = string.indexOf(delimiter, start);
	return string.substring(start, send);
}

// ===============================  LOAD EVAL  ================================================
function loadEval(evalNo)
// ----------  Function Header  --------------
//	Name:			loadEval()
//	Purpose:		Loads the screen with a saved cookie
//	Inputs:		evalNo - cookie name suffix holding the evaluation
//	Process:		parse the cookies into global membory, then display
//					parse evaluation header information
//					for each vendor
//						parse vendor information
//						parse detailed scores
//					display the evaluation (also computes results)
//	Outputs:		none;
//	-------------------------------------------
{
	var cName = cookieNamePrefix_GS + evalNo;
	var cookie;
	var is = 0;		// starting substring position
	var ie = 0;		// ending substring position
	var i, j, k;
	
	// ------------------  find the cookie  -----------------------
	setCookieGlobal (cName);
	cookie = currCookieO_G.value;

	// Parse the evaluation header information
	osvTitle_G = getCookieString (cookie, is, cookieDelimiter);
	is += osvTitle_G.length;
	osvGoal_G = getCookieString (cookie, ++is, cookieDelimiter);
	is += osvGoal_G.length;
	osvDiscipline_G = parseInt(getCookieString (cookie, ++is, cookieDelimiter));
	is++;
	
	// Parse Vendor information
	for (i=0; i<numVendors_GS; i++)
	{
		osvName_G [i] = getCookieString (cookie, ++is, cookieDelimiter);
		is += osvName_G [i].length;
		osvLink_G [i] = getCookieString (cookie, ++is, cookieDelimiter);
		is += osvLink_G [i].length+1;				// get past delimiter
		for (j=0; j<maxCategories_GS; j++)
			for (k=0; k<maxScores_GS; k++)
				osvValue_G [i][j][k] = parseInt(cookie.substr(is++, 1));
		is--;		// there's no delimiter before the next company name
	}
	computeScores();
	displayGlobal();
	setSaved();
	setUnChanged();
}

// ================================  COMPUTE SCORES  ===============================
function computeScores()
// ----------  Function Header  --------------
//	Name:			computeScores ()
//	Purpose:		Computes the category and vendor scores 
//	Inputs:		global memory
//	Process:		Average the values of the scores within category
//					sum the categories for each vendor
//	Outputs:		global memory
//	-------------------------------------------
{
	var i, j, k;
	var catScore;
	
	//---------  Initialize computed scores  ----------------------
	for (i=0; i<numVendors_GS; i++)
	{
		osvVendScore_G [i] = 0;
		for (j=0; j<numCategories_GS; j++)
			osvCatScore_G [i][j] = 0;
	}
	
	// Run the math
	for (i=0; i<numVendors_GS; i++)
	{
		for (j=0; j<numCategories_GS; j++)
		{
			catScore = 0;
			for (k=0; k<numVarsPerCat_G [j]; k++)
			{
				if (osvValue_G [i][j][k] != nullScore_GS)
					catScore += osvValue_G [i][j][k];		// add to vendor's score for this category
			}
			osvCatScore_G [i][j] = catScore / numVarsPerCat_G [j];
			osvVendScore_G [i] += osvCatScore_G [i][j];
		}
	}
}

// ===================================  DISPLAY GLOBAL  ====================================
function displayGlobal ()
// ----------  Function Header  --------------
//	Name:			displayGlobal
//	Purpose:		Pushes global memory to the screen
//	Inputs:		global
//	Process:		Display the evaluation header information
//					Display the vendor information
//					for each vendor
//						Display vendor : category : values
//					Display results
//	Outputs:		fully loaded screen
//	-------------------------------------------
{
	var val;
	var i, j, k;
	
	// Display evaluation header information
	F_G [evalTitleFName_GS].value = osvTitle_G;				// Evaluation Title
	F_G [evalGoalFName_GS].value = osvGoal_G;					// Seminar Goal
	F_G [evalDisciplineFName_GS].value = osvDiscipline_G;	// get discipline
	
	// Display vendor information
	for (i=0; i<numVendors_GS; i++)
	{
		F_G [vendNamePrefix_GS+i].value = osvName_G [i];
		F_G [vendLinkPrefix_GS+i].value = osvLink_G [i];
		for (j=0; j<numCategories_GS; j++)
		{
			for (k=0; k<numVarsPerCat_G [j]; k++)
			{
				val = osvValue_G [i][j][k];
				if (val == nullScore_GS)
					F_G [inputPrefix_GS+i+j+k].value = "";
				else
					F_G [inputPrefix_GS+i+j+k].value = val;
			}
		}
	}
	
	// Display Results
	for (i=0; i<numVendors_GS; i++)
	{
		value = osvVendScore_G [i]
		if ((value == nullScore_GS) || (value == 0))
			F_G [vendTotPrefix_GS+i].value = "";
		else
			F_G [vendTotPrefix_GS+i].value = toDecimalString (value, 2, 6);
		for (j=0; j<numCategories_GS; j++)
		{
			value = osvCatScore_G [i][j];
			if ((value == nullScore_GS) || (value == 0))
				F_G [resultPrefix_GS+i+j].value = "";
			else
				F_G [resultPrefix_GS+i+j].value = toDecimalString (value, 2, 6);
		}
	}
}

// =============================  EVAL VENDORS  ==========================================
function evalVendors()
// ----------  Function Header  --------------
//	Name:			evalVendors ()
//	Purpose:		Display results of the evaluation
//	Inputs:		none
//	Process:		call loadGlobal to retrieve data and compute results
//					display results
//	Outputs:		none (display)
//	-------------------------------------------
{
	loadGlobal();			// loads global and computes all the numbers
	displayGlobal();
}

// ==============================  DETERMINE SAVED EVALS  ======================================
function determineSavedEvals()
// ----------  Function Header  --------------
//	Name:			deterineSavedEvals()
//	Purpose:		Find out which cookies are available
//	Inputs:		cookies
//	Process:		run through the cookie table
//						if one of ours, count it
//	Outputs:		global and pick list
//	-------------------------------------------
{
	var evalTitle;				// title of the saved evaluation
	var evalNo;					// number of the saved evaluation
	
	numEvals_G = 0;			// assume none
	
	for (i=0; i<numCookies_G; i++)
	{
		if (cookieLst_G [i].name.indexOf(cookieNamePrefix_GS, 0) == 0)
		{
			evalTitle = cookieLst_G [i].value.substring(0, cookieLst_G [i].value.indexOf("=", 0));
			evalNo = parseInt (cookieLst_G [i].name.substr (cookieNamePrefix_GS.length, 1));
			F_G.savedList.options [++numEvals_G] = new Option (evalTitle.substr(0, maxTitleSize), evalNo);
		}
	}
	F_G [numEvalsFldName].value = numEvals_G;
}

function initHidden ()
{
	if (F_G.saved.value == "TRUE")
	{
		F_G [savedFldName].value="Saved"
		evalSaved_G = true;
	}
	else
	{
		F_G [savedFldName].value = "not saved";
		evalSaved_G = false;
	}
	if (F_G.changed.value == "TRUE")
	{
		F_G [changedFldName].value = "Changed";
		evalChange_G = true;
	}
	else
	{
		F_G [changedFldName].value = "Unchanged";
		evalChanged_G = false;
	}
	if (evalSaved_G)
		setCookieGlobal (F_G ['currCookie'].value);
}
// ===============================  INITFORM  ============================================
function initForm ()
// ----------  Function Header  --------------
//	Name:			initForm()
//	Purpose:		initializes the form to "new" state
//	Inputs:		none
//	Process:		
//					blank out the evaluation title
//					blank out the vendor information 
//						name and link
//					for each vendor
//						blank out the final vendor score field
//						for each category
//							blank out the category results field
//							for each score
//								blank out the score
//					reset global flags:
//						changed to false
//						saved to false
//					redisplay form status
//	Outputs:
//	-------------------------------------------
{
	var i, j, k;

	if (!cookieSupport_G)
		alert ("You don't have cookies activated. You won't be able to save your evaluations");
	
	F_G = document.SelectVendorForm;					// save form pointer for convenience
		
	for (i=0; i<maxVendors_GS; i++)
	{
		osvVendScore_G [i]	= 0;
		osvCatScore_G [i] 	= new Array;
		osvValue_G [i] 		= new Array;
		osvName_G [i] = "";
		osvLink_G [i] = "";
		for (j=0; j<maxCategories_GS; j++)
		{
			osvCatScore_G [i][j] = 0;
			osvValue_G[i][j] = new Array;
			for (k=0; k<maxScores_GS; k++)
				osvValue_G [i][j][k] = nullScore_GS;
		}
	}
	// Add in Ally as the default first vendor
	// User has three options that will get us here:
	//  1) Newly loaded screen (final else)
	//	 2) User requested an evaluation (evaluate)
	//  3) User requested save (submitted)
	if (submitted)
	{
		evalVendors ();
		initHidden();
	}
	else
	{
		F_G [vendNamePrefix_GS + 0].value = "Ally Business Developers";
		F_G [vendLinkPrefix_GS + 0].value = "http://www.AllyBusiness.com";
		setCookieGlobal (null);
		setNotSaved();						// current form unsaved
		setUnChanged ();					// not changed
	}
}

function vendLink (vendNo)
// ----------  Function Header  --------------
//	Name:		vendLink (vendNo)
//	Purpose:	Open a window with the vendor's link site name on the form
//	Inputs:	vendNo (Vendor number(0-based)
//	Process: verify that the link field requested isn't blank
//				create a name for the window (in case it's hidden behind the current window)
//				display the window
//	Outputs:	New window
//	-------------------------------------------
{
	var okay = false;
	var wLink, wName;
	
	wLink = F_G [vendLinkPrefix_GS + vendNo].value;
	wName = "Onsite Vendor: " + F_G [vendNamePrefix_GS + vendNo].value;
	if (wLink == "")
	{
		alert ("The vendor's URL field is blank");
		return;
	}
	newWindow = window.open(wLink, "OSV"+vendNo);
	newWindow.focus();			// in case it's hiding.
}

function windowUnload()
// ----------  Function Header  --------------
//	Name:		windowUnload()
//	Purpose:	The original purpose of this function was to as the user to confirm
//				the unload if the current evaluation wasn't saved. As far as I can tell,
//				if the user clicks the "X" in the upper right of the window, there's no
//				way to prevent the exit, and, therefore, no way to save the evaluation.
//				We keep this function here just in case we find a way to do that.
//	Inputs:		
//	Process:		
//	Outputs:
//	-------------------------------------------
{
	var ok2close = true;
	if (evalChanged_G) 
		ok2close =  confirm("You haven't saved the current evaluation. Are you sure you want to exit?");
	if (ok2close)
		window.close();
}

function reFocus(fElement)
// ----------  Function Header  --------------
//	Name:		reFocus(fElement)
//	Purpose:	Repositions the screen to the field indicated
//	Inputs:	name of the form field (element) to recieve focus to return the screen to normal
//	Process:	if fElement isn't null, set the field to focus
//	Outputs:	<none>
//	-------------------------------------------
{
	if (fElement != null)
		document.SelectVendorForm [fElement].focus();
}
