/*
 * utilities.js v0.0.1
 * by Keith Gaughan <kgaughan@chipeservices.com>
 *
 * JavaScript utility functions used throughout the application.
 */

/*
 * *** IMPORTANT!!! ***
 *
 *  1. Add any new code to the appropriate section.
 *  2. Use existing code if possible.
 *  3. Fix buggy code rather than creating your own new function.
 *  4. Use the same 
 */

/**************************************************** String Manipulation **/

String.prototype.trim = function()
{
	var str = this;
	var iStart = 0, iEnd = str.length - 1;

	while (iStart <= iEnd && str.charAt(iStart) == ' ')
		iStart++;

	while (iEnd >= iStart && str.charAt(iEnd) == ' ')
		iEnd--;

	return str.substring(iStart, iEnd + 1);
}

/**
 * Trims any leading or trailing spaces from the string.
 *
 * @param  str  String to trim
 * @returns     Trimmed string.
 */
function TrimString(str)
{
	return str.trim();
}

/****************************************************** String Validation **/

function IsLetter(c)
{
	return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}

function IsDigit(c)
{
   return c >= '0' && c <= '9';
}

function IsPunctuation(c)
{
	var punctuation = ' \'\",:;-?()&!£$%=+#';

	c = c.charAt(0); // just in case a string is passed in.
	return punctuation.indexOf(c, 0) != -1;
}

function IsNumber(qty)
{
	return /^-?\d+$/.test(qty.trim());
}

function IsPositiveWholeNumber(qty)
{
	return /^\d+$/.test(qty.trim());
}

/**
 * Verifys whether an email address is valid.
 */
function IsValidEmail(email)
{
	return email.indexOf("@") != -1 && email.lastIndexOf(".") >= email.indexOf("@");
}

/************************************************************ UI Handling **/

/**
 * Sets the input focus to the given object if it exists.
 *
 * @param  elem  Object to give focus to.
 */
function FocusIfExists(elem)
{
	if (elem != null && elem.type != 'hidden')
		elem.focus();
}

/**
 * For query listings, causes the form to submit with an empty string.
 */
function ViewAll()
{
	document.frm.query.value = '';
	document.frm.submit();
}

/**
 * Sets the checkboxes with the given name on or off.
 *
 * @param  frm    Form object containing the checkboxes.
 * @param  group  Name of the checkbox group.
 * @param  val    True to set them on, otherwise false.
 */
function CheckGroup(frm, group, val)
{
	var elem;

	for (var i = 0; i < frm.elements.length; i++)
	{
		elem = frm.elements[i];

		if (elem.name == group && !elem.disabled)
			elem.checked = val;
	}
}

/**
 * Sets the checkboxes with the given prefix on or off.
 *
 * @param  frm    Form object containing the checkboxes.
 * @param  group  Prefix of the checkbox group.
 * @param  val    True to set them on, otherwise false.
 */
function CheckPrefixedGroup(frm, group, val)
{
	var elem;

	for (var i = 0; i < frm.elements.length; i++)
	{
		elem = frm.elements[i];

		if (elem.name.substr(0, group.length) == group && !elem.disabled)
			elem.checked = val;
	}
}

/**
 * Sets the value of a form object, if it exists.
 *
 * @param  elem  Object to set.
 * @param  val   Value to give to it.
 */
function SetIfExists(elem, val)
{
	if (elem != null)
		elem.value = val;
}

/**
 * Causes the page's form to submit.
 *
 * @param  action  Page to submit to (optional).
 */
function SubmitForm()
{
	// If an action is specified
	if (arguments.length == 1)
		document.frm.action = arguments[0];

	document.frm.submit();
}

/******************************************************** Form Validation **/

/**
 * Checks if the given form element has a value.
 *
 * @param  elem  Form element to check.
 * @return       True if has a value, otherwise false.
 *
 * @note  This function strips any spaces in the element's value before
 *        checking.
 */
function HasValue(elem)
{
	elem.value = elem.value.trim();
	return elem.value != "";
}

/**
 * Checks to see if any of the items in the given group are selected.
 *
 * @param  frm    Form object containing the group.
 * @param  group  Name of the checkbox group.
 * @return        True if has checked items, otherwise false.
 */
function HasCheckedItems(frm, group)
{
	var elem;

	for (var i = 0; i < frm.elements.length; i++)
	{
		elem = frm.elements[i];

		if (elem.name == group && elem.checked)
			return true;
	}

	return false;
}

/**
 * Checks to see if any of the items in the given group are selected.
 *
 * @param  frm    Form object containing the group.
 * @param  group  Name of the checkbox group.
 * @returns       True if has checked items, otherwise false.
 */
function HasPrefixedCheckedItems(frm, group)
{
	var elem;

	for (var i = 0; i < frm.elements.length; i++)
	{
		elem = frm.elements[i];

		if ((elem.name.substr(0, group.length) == group) && elem.checked)
			return true;
	}

	return false;
}

/**
 * Checks if the given field has a valid numeric value.
 *
 * @param     elem  Form element to check.
 * @optional  min   Minimum value the field can have.
 * @optional  max   Maximum value the field can have.
 * @return          True if successful, false otherwise.
 */
function IsValidNumericField()
{
	var val = arguments[0].value;
	var min = GetArgument(arguments, 1, null);
	var max = GetArgument(arguments, 2, null);

	if (!IsNumber(val))
		return false;

	if ((max == null && min == null) || (max == null && val >= min) || (min == null && val <= max))
		return true;

	return val >= min && val <= max;
}

/******************************************************** Date Validation **/

function GetEra(year)
{
	return Math.floor(year / 100) * 100;
}

/**
 * Check's whether the given date is valid.
 */
function GetValidMonthLength(year, month)
{
	if (IsLeapYear(year) && month == 2)
		return 29;

	var MONTH_LENGTHS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

	return MONTH_LENGTHS[month - 1];
}

/**
 * Takes a 3 character string representation of a month and returns the
 * numeric equivalent of that month according to it's position in the
 * calendar.
 *
 * @param  month  Three letter representation of the month's name.
 * @returns       Numberic value of that month from 1-12
 *
 * @author ?
 */
function GetIntMonth(month)
{
	switch (month.toLowerCase())
	{
		case "jan": return 1;
		case "feb": return 2;
		case "mar": return 3;
		case "apr": return 4;
		case "may": return 5;
		case "jun": return 6;
		case "jul": return 7;
		case "aug": return 8;
		case "sep": return 9;
		case "oct": return 10;
		case "nov": return 11;
		case "dec": return 12;
		default:    return 0;
   }
}

function GetMonthName(month)
{
	var MONTHS_LIST = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];

	return MONTHS_LIST[month - 1];
}

/**
 * Compares two dates, returning 1 if the first parameter is greater than
 * the second, -1 if the second is greater than the first, and 0 if they
 * are the same date.
 *
 * @param  d1  First date.
 * @param  d2  Second date.
 * @returns    1: (d1 > d2); -1: (d1 < d2); 0: (d1 = d2)
 *
 * @author  Keith Gaughan <kgaughan@chipeservices.com>
 * @version 0.0.1 (2002-03-05)
 */
function CompareDates(d1, d2)
{
	var date1, date2;

	date1 = new Date(d1);
	date2 = new Date(d2);

	if (date1.valueOf() > date2.valueOf())
		return 1;

	if (date1.valueOf() < date2.valueOf())
		return -1;

	return 0;
}

function DateIsBefore(d1, d2)
{
	return CompareDates(d1, d2) != -1;
}

/**
 * Checks to see if the year passed in is a leap year.
 *
 * @param  year  Year to check.
 * @returns      True if a leap year; otherwise false.
 *
 * @author  Keith Gaughan <kgaughan@chipeservices.com>
 * @version 0.0.1 (2002-03-05)
 */
function IsLeapYear(year)
{
	if (year % 100 == 0 && year % 400 == 0)
		return true;

	return year % 4 == 0;
}

/************************************************** Miscellaneous Rubbish **/

/**
 * 
 */
function GetArgument(args, i, def)
{
	return (args.length > i) ? args[i] : def;
}

function openPartNumberSelector(idWarrantor, idCategory, submitIsRequired, section)
{ 
	var w_height	= 700;
	var w_width		= 600;
	var w_top		= (screen.height-w_height)/2;
	var w_left		= (screen.width-w_width)/2;
    
    var url = "/common/PartNumberSelector.asp?idWarrantor=" + idWarrantor + "&idCategory=" + idCategory + "&submitIsRequired=" + submitIsRequired + "&section=" + section;
    
    new_window = window.open(url, "PartNumberSelector", "toolbar=no,menubar=no,status=no,resizable=yes,scrollbars=yes,height="+w_height+",width="+w_width+",left="+w_left+",top="+w_top );
	new_window.focus();
}

function openSparePartSelector(idWarrantor, submitIsRequired, section)
{ 
	var w_height	= 700;
	var w_width		= 600;
	var w_top		= (screen.height-w_height)/2;
	var w_left		= (screen.width-w_width)/2;
    
    var url = "/common/SparePartSelector.asp?idWarrantor=" + idWarrantor + "&submitIsRequired=" + submitIsRequired + "&section=" + section;
    
    new_window = window.open(url, "PartNumberSelector", "toolbar=no,menubar=no,status=no,resizable=yes,scrollbars=yes,height="+w_height+",width="+w_width+",left="+w_left+",top="+w_top );
	new_window.focus();
}

/**
 * Cascading Dropdown menu validation routine
 *
 * @param  obj  HTML select object i.e. &gt;select&lt;
 *
 * @note Requires two global arrays:
 *       <dl>
 
 *       </dl>
 *
 * You must set up 2 global arrays [in the calling page], of dropdown names and error messages.
 * arrDropdownNames -	This array holds the names of all the potential dropdowns - Both the ORDER and CASE of the items in this array is CRUCIAL.
 *			Make sure the entries are ordered in the same manner that the DDs will appear on the calling page
 * arrErrorMessages -	This array holds the error messages to display if there are any problems with the related DD: the DD at the same ordinal position in the _arrDropdownNames_ array			
 * 
 */
function ProcessForm(obj)
{
	// Test to see that the current selection of the current dropdown is
	// not the _prompt_ i.e. -- Select XXX --
	// If it is, do nothing: this stops reloading of the page on
	// selection of the prompt option.
	if (obj.value == 0)
		return;

	var clearFollowing = false;	// Note the dropdown hasn't been found yet.
	var errors = '';			//

	for (var i = 0; i < arrDropdownNames.length; i++)
	{
		var elem = obj.form.elements[arrDropdownNames[i]];

		if (obj == elem)
		{
			// We've found the DD which was selected
			// so mark the rest after it for clearing.
			clearFollowing = true;
		}
		else if (clearFollowing)
		{
			// The dropdown is after the selected one, so must be cleared.
			SetIfExists(elem, 0);
		}
		else if (elem.value == 0)
		{
			// It's before the selected one and has no value, so record its error.
			errors += "\n" + arrErrorMessages[i];
		}
	}

	if (errors != '')
	{
		alert("The following error(s) have occurred:\n" + errors);
	}
	else		
	{
		SubmitForm();
	}
}

//************************************************************** Transactions validation 
function valTxnLines(element, check, fieldName, lineNum)
{
	var value = eval(element + lineNum + ".value");
	var returnValue = "";
	
	if (check == "requiredField")
	{
		if (value == "")
			returnValue = "\n" + fieldName + " for line " + lineNum + " is required";
		return returnValue;
	}
	if (check == "requiredRMAField")
	{
		if (value == "0")
			returnValue = "\n" + fieldName + " for line " + lineNum + " is required";
		return returnValue;
	}
	if (check == "isPositiveWholeNumber")
	{
		if (!IsPositiveWholeNumber(value))
			returnValue = "\n" + fieldName + " for line " + lineNum + " must be a positive whole number";
		return returnValue;
	}
	
	if (check == "isPositiveNumber")
	{
		if (!(IsNumeric(value) && value > 0))
			returnValue = "\n" + fieldName + " for line " + lineNum + " must be a positive number";
		return returnValue;
	}
	
	
}

function IsEmptyLine(lineNum)
{

	//Service and Cost added 15.07.02; Sean Tynan
	
	if (lineNum == 1)
		return false;

	var emptyLine = true;
	
	var idRMA	= eval("frm.idRMA" + lineNum);
	var qty		= eval("frm.Qty" + lineNum);
	var idPN	= eval("frm.idPN" + lineNum);
	var desc	= eval("frm.Desc" + lineNum);
	var sn		= eval("frm.Sn" + lineNum);
	var status	= eval("frm.Status" + lineNum);
	var service	= eval("frm.Service" + lineNum);	
	var cost	= eval("frm.Cost" + lineNum);		
	
	if (idRMA != null && idRMA.value != 0) 
		emptyLine = false;
	if (qty != null && qty.value != "") 
		emptyLine = false;
	if (idPN != null && idPN.value != "") 
		emptyLine = false;
	if (desc != null && desc.value != "") 
		emptyLine = false;
	if (sn != null && sn.value != "") 
		emptyLine = false;
	if (status != null && status.value != "") 
		emptyLine = false;
	if (service != null && service.value != "") 
		emptyLine = false;
	if (cost != null && cost.value != "") 
		emptyLine = false;
	if (idRMA != null && idRMA.value != 0) 
		emptyLine = false;

	return emptyLine;
}
function submitTxn(errors, total)
{
	if (errors != "")
	{
		alert("The following error(s) have occurred:\n" + errors); 
		return false;
	}
	else
	{
			if(confirm("Units total " +total+ "\n Are you sure you want to continue?"))
				window.document.frm.submit();
			else
				return false;
	}
}
