// JavaScript Document

<!--
/* javascript functions to calculate order total with taxes and shipping */

// Global Variables available in any funciton
var Global_MainProdQuantity = 0;
var Global_OtherProdQuantity = 0;

function init()
{
var orderingid = document.getElementById("orderingid"); 
orderingid.value = CalculateOrderID();  /* changes value in form */

var orderid = document.getElementById("orderid"); 
orderid.value = orderingid.value;  /* sets hidden form field */
}

function formreset()
{
	if (confirm("Are you sure you want to clear the form?"))
	{
		document.OrderForm.reset();
		init(); // reset orderid
	}
}


function CalculateOrderID()
{
	return GetDateString();
}

function GetDateString()
{
	var dt = new Date();
	var dtstring = dt.getFullYear()
	+ pad(dt.getMonth()+1,2)  // returns 0-11 so add 1
	+ pad(dt.getDate(),2)     // returns day of month 1-31
	+ pad(dt.getHours(),2)
	+ pad(dt.getMinutes(),2)
	+ pad(dt.getSeconds(),2)
	+ pad(dt.getMilliseconds(),3);

    return dtstring;
}


function Validate()
{
	if ( isValidForm() )
	{
		if ( isValidTransaction() )
			return true;
		else
			return false;
	}
	else
		return false;
}


function isValidTransaction()
{
	var iIncError = 0;
	
    // get values from form
	var GrandTotal = document.getElementById("GrandTotal");  	
	
	if (GrandTotal.value < 1)  //TODO set to zero temporarily only
	{
		window.alert("Grand Total has not been calculated or is less than $1.00");
		iIncError++;
	} // if	

	if (iIncError > 0)
		return false;
	else
		return true;
}

function isValidForm()
// call form validation before form submit like: <form name="exampleForm" onsubmit="return Validate()">
// The "onsubmit" event handler is called before the form is submitted and the form is only submitted if the handler returns "true". 
{
	// get values from form
	var country = document.getElementById("CCCountry");
	var q1 = document.getElementById("quantity_1");
	var q2 = document.getElementById("quantity_2");
	var q3 = document.getElementById("quantity_3");
	
	// validations start here
	var iTotal = 0;
	var iTotal = parseInt(q1.value) + parseInt(q2.value) + parseInt(q3.value);
	if (iTotal == 0 )
	{
		window.alert("Quantities are all zero.");   
		return false;
	}
	
	// verify the drop down selections and the quantities
	if ( ! Verify_ComboBoxAndInteger(document.getElementById("product1"), q1) )
		return false;
	
	if ( ! Verify_ComboBoxAndInteger(document.getElementById("product2"), q2) )
		return false;
	
	if ( ! Verify_ComboBoxAndInteger(document.getElementById("product3"), q3) )
		return false;
		
	if (country.value < 1)
	{
		window.alert("Please select a country to calculate shipping.");   
		return false;
	}

	if (country.options[country.selectedIndex].text == "Canada") // if Canada
	{
		if (document.getElementById("CCProvince").value < 1)
		{
			window.alert("Please select a province to calculate shipping.");   
			return false;
		}
	}

	return true;
}

function CalculateTotal(frm) 
{
	// clear variables
	var item_price = 0
	var item1_price = 0
	var item2_price = 0
	var item3_price = 0
	var order_shipping = 0
	var order_subtotal = 0
	var order_GST = 0
	var order_PST = 0
	var order_HST = 0
    var order_total = 0	
    var coupon = 0
	var selIndex = 0
	// clear Global variables
	Global_MainProdQuantity = 0;
	Global_OtherProdQuantity = 0;
	
    // clear form values
	frm.itemprice.value = 0;   
    frm.Shipping.value = 0;
	frm.GSTTax.value = round_decimals(0, 2);
	frm.PSTTax.value = round_decimals(0, 2);
	frm.HSTTax.value = round_decimals(0, 2);
	frm.GrandTotal.value = round_decimals(0, 2);
	// clear hidden form values
	frm.shipping_cost.value = round_decimals(0, 2);
	frm.gst.value = round_decimals(0, 2);
	frm.pst.value = round_decimals(0, 2);	
	frm.hst.value = round_decimals(0, 2);	
	frm.chargetotal.value = round_decimals(0, 2);			
	
	//clear all hidden line item values on form
	frm.description1.value = '';
	frm.quantity1.value = 0;
	frm.price1.value = 0;
	frm.subtotal1.value = 0;
	frm.description2.value = '';
	frm.quantity2.value = 0;
	frm.price2.value = 0;
	frm.subtotal2.value = 0;
	frm.description3.value = '';
	frm.quantity3.value = 0;
	frm.price3.value = 0;
	frm.subtotal3.value = 0;

    //Set variables
	GSTRate = 0;  
	PSTRate = 0;  
	HSTRate = 0;
	
    // get values from form
	var countryLabel = frm.CCCountry.options[frm.CCCountry.selectedIndex].text;
	var isCanada = ( countryLabel == "Canada" );
	var provinceLabel = frm.CCProvince.options[frm.CCProvince.selectedIndex].text;
	var isQuebec = ( provinceLabel == "Quebec" );

	// run form validations
    if ( ! isValidForm() )
   		return false;
		
    var product1 = document.getElementById("product1").value;
    var product2 = document.getElementById("product2").value;
    var product3 = document.getElementById("product3").value;
    var item_quantity1 = document.getElementById("quantity_1").value;
    var item_quantity2 = document.getElementById("quantity_2").value;
    var item_quantity3 = document.getElementById("quantity_3").value;   
    var isproduct1 = (product1 > 0) && (item_quantity1 > 0);
    var isproduct2 = (product2 > 0) && (item_quantity2 > 0);
    var isproduct3 = (product3 > 0) && (item_quantity3 > 0);
    //coupon = frm.coupon.value;  // not using coupon textbox anymore
 
	// Update the order total and shipping and taxes etc.
	if ( isproduct1 || isproduct2 || isproduct3 )
	{
		if (isproduct1 )
		{
			product1_price = GetProductPrice(product1);
			item1_price = item_quantity1 * product1_price;
			item_price = parseFloat(item1_price);
			order_shipping = GetShipping ( product1, item_quantity1, countryLabel )
			// set hidden form fields to send to Moneris eSelectPlus
			selIndex = document.OrderForm.product1.selectedIndex; 
			frm.description1.value = document.OrderForm.product1.options[selIndex].text;
			frm.quantity1.value = item_quantity1.toString();
			frm.price1.value = product1_price;
			frm.subtotal1.value = item1_price;
		}

		if (isproduct2 )
		{
			product2_price = GetProductPrice(product2);
			item2_price = item_quantity2 * product2_price;
			item_price = parseFloat(item1_price)+ parseFloat(item2_price);
			order_shipping = order_shipping + GetShipping ( product2, item_quantity2, countryLabel )
			// set hidden form fields to send to Moneris eSelectPlus
			selIndex = document.OrderForm.product2.selectedIndex; 
			frm.description2.value = document.OrderForm.product2.options[selIndex].text;
			frm.quantity2.value = item_quantity2;
			frm.price2.value = product2_price;
			frm.subtotal2.value = item2_price;
 		}

		if (isproduct3 )
		{
			product3_price = GetProductPrice(product3);
			item3_price = item_quantity3 * product3_price;
			item_price = parseFloat(item1_price)+ parseFloat(item2_price)+ parseFloat(item3_price);
			order_shipping = order_shipping + GetShipping ( product3, item_quantity3, countryLabel )
			// set hidden form fields to send to Moneris eSelectPlus
			selIndex = document.OrderForm.product3.selectedIndex; 
			frm.description3.value = document.OrderForm.product3.options[selIndex].text;
			frm.quantity3.value = item_quantity3;
			frm.price3.value = product3_price;
			frm.subtotal3.value = item3_price;
		}
		
		if (! VerifyProductQuantity() )
			return false;
		
		order_subtotal = item_price;
		// calculate discounts
		if (coupon == "201002")
		{
			order_subtotal = order_subtotal - (order_subtotal * .10);
		}
		
		if ( isCanada )
		{
			var taxRates = GetTaxRates( provinceLabel );  // get all threee tax rates.  
			GSTRate = taxRates.GSTRate;  
			PSTRate = taxRates.PSTRate;  
			HSTRate = taxRates.HSTRate;
		}
		
		order_GST = order_subtotal * GSTRate;
		order_PST = order_subtotal * PSTRate;
		order_HST = order_subtotal * HSTRate;
		if ( isCanada && isQuebec )  // Note: The Quebec QST is calculated on the selling price (including the GST) at the rate of 7.5%. 
		    order_total = (order_subtotal + order_GST) * (1 + PSTRate) + order_shipping
		else
			order_total = order_subtotal + order_GST + order_PST + order_HST + order_shipping;
	}
			
    // Update form values rounded to two decimal places
	frm.itemprice.value = round_decimals(order_subtotal, 2)    
    frm.Shipping.value = round_decimals(order_shipping, 2)    
	frm.GSTTax.value = round_decimals(order_GST, 2)
	frm.PSTTax.value = round_decimals(order_PST, 2)
	frm.HSTTax.value = round_decimals(order_HST, 2)
	frm.GrandTotal.value = round_decimals(order_total, 2)
	
	// set hidden form fields to send to Moneris eSelectPlus
	frm.shipping_cost.value = round_decimals(order_shipping, 2);	
	frm.gst.value = round_decimals(order_GST, 2);
	frm.pst.value = round_decimals(order_PST, 2);	
	frm.hst.value = round_decimals(order_HST, 2);	
	frm.chargetotal.value = round_decimals(order_total, 2);		
//frm.chargetotal.value = round_decimals(1, 2);  //TODO: temp code for testing so we are only charged $1.00 per test.
	
	return true;
}

function VerifyProductQuantity()
//return false is there are more than two main products ordered.
{
	if ( (Global_MainProdQuantity > 2) || (Global_OtherProdQuantity > 2) )
	{
		alert("Please call in for orders greater than two.");
		return false;
	}	
	else
		return true;
}

function Verify_ComboBoxAndInteger(elemCombo, elemInteger)
// return false if there is no valid combobox/dropdown list choice selected and quantity (integer) combination.
{
	var iIncError = 0;
	
	// if quantity is > 0 then a product must be chosen
	var iInt = elemInteger.value;
	var iCombo = elemCombo.value;
	
	if( iInt > 0)
	{
		if (iCombo < 1)
		{
			alert(elemInteger.id + " is greater than one but no product is selected.");
			elemCombo.focus();
			iIncError++;
		}
	} // if

	// if a product is chosen then quantity must be greater than zero.
	/*
	if( iCombo > 0)
	{
		if (iInt < 1)
		{
			alert(elemCombo.id + " is set but quantity is less than one.");
			elemInteger.focus();
			iIncError++;
		}
	} // if
	*/
	
	if ( iIncError > 0)
	{
		return false;
	}
	else
	{
	 	return true;
	}
} // function Verify_ComboBoxAndInteger()

function GetTaxRates( province )
// Send a province text string and return any or all 3 Tax rates (float)
// How to call: var a = xyz();  then call: document.write('x=' + a.x + ' and y = ' + a.y); 
{
	var GST = 0.00;
	var PST = 0.00;
	var HST = 0.00;
	
	switch (province)
	{
	  case "PEI": GST = .05;  PST = 0.10;
				break;
	  case "Nova Scotia": HST = 0.15;
				break;
	  case "Newfoundland": HST = 0.13;
				break;
	  case "New Brunswick": HST = 0.13;
				break;
	  case "Quebec": GST = .05;  PST = 0.075;  // Note: PST/QST is on top of GST
				break;				
	  case "Ontario": HST = 0.13;
				break;
	  case "Manitoba": GST = .05;  PST = 0.07;
				break;
	  case "Saskatchewan": GST = 0.05;  PST = 0.05;
				break;
	  case "Alberta": GST = .05;
				break;
	  case "British Columbia": HST = 0.12;
				break;				
	}
	
	return { HSTRate: HST, GSTRate: GST, PSTRate: PST };	
}

function GetProductPrice( productNumber )
// return price based on product number code
{
	var the_price = 0.00;
	RopeKnight = 105.82
	RopeKnightFullyArmed = 126.34
	RopeShieldSmallCone = 34.71
	RopeShieldLargeCone = 34.71
	BoredAndTapedSteelWeight = 40.00
	FoamProtector = 10.00
	VinylAndRubberProtector = 6.00
	SpareBoltOrSetScrew = 1.50
	
	switch (productNumber)
	{
	  case "1": the_price = RopeKnight;
				break;
	  case "2": the_price = RopeKnightFullyArmed;
				break;
	  case "3": the_price = RopeShieldSmallCone;
				break;
	  case "4": the_price = RopeShieldLargeCone;
				break;
	  case "5": the_price = BoredAndTapedSteelWeight;
				break;
	  case "6": the_price = FoamProtector;
				break;
	  case "7": the_price = VinylAndRubberProtector;
				break;
	  case "8": the_price = SpareBoltOrSetScrew;
				break;
				
	  default: the_price = RopeKnight;
	}
	
	return the_price;
}


function GetShipping ( productNumber, ItemQuantity, CountryLabel )
// return shipping based on courntry code
// AUS, USA, Europe, Canada (order of drop down)
// Oct 8: The product price should be stated in Canadian funds only, and the shipping charges are:
// $10.00 Canada, 15.00 for U.S  30.00 for Europe and 40.00 for AUD but all these in Canadian prices.
{
	var CountryRate = 0.00;
	var shipping = 0.00;
	
	switch (CountryLabel)  // calculate shipping per country for main products
	{
	  case "Australia": CountryRate = 40.00;
				break;
	  case "U.S.A.": CountryRate = 15.00;
				break;
	  case "Europe": CountryRate = 30.00;
				break;
	  case "Canada": CountryRate = 10.00;
				break;
	  default: CountryRate = 10.00;  // This should never run
	}
	
	// For now, please don’t charge added shipping charges for the Foam Protector/Spare Bolt or Screw/Vinyl and Rubber Protector/Small Cone/Large Cone if the amounts are less than 2 items.  
	// With orders larger than 2 the customer should be prompted to call for a phone order.
	switch (true)   
	{
		case (productNumber < "3"):
			shipping = CountryRate * ItemQuantity;
			Global_MainProdQuantity = Global_MainProdQuantity + ItemQuantity;
			break;
		default:
			shipping = 0.00;
  		    Global_OtherProdQuantity = Global_OtherProdQuantity + ItemQuantity;
			break;
	}	
		
	return shipping;
}


function round_decimals(original_number, decimals)
{
    var result1 = original_number * Math.pow(10, decimals)
    var result2 = Math.round(result1)
    var result3 = result2 / Math.pow(10, decimals)
    return pad_with_zeros(result3, decimals)
}

function randwhole ( n )
// generate a random whole number between 1 and n
{
	return ( Math.floor ( Math.random ( ) * n + 1 ) );
}

function randrangewhole ( x, y )
// return a random range of whole numbers
{
	return ( Math.floor((y-(x-1))*Math.random()) + x);
}

function pad_with_zeros(rounded_value, decimal_places)
{
    // Convert the number to a string
    var value_string = rounded_value.toString()
    
    // Locate the decimal point
    var decimal_location = value_string.indexOf(".")

    // Are there a decimal point?
    if (decimal_location == -1) 
	{
        // If no, then all decimal places will be padded with 0s
        decimal_part_length = 0
        
        // If decimal_places is greater than zero, tack on a decimal point
        value_string += decimal_places > 0 ? "." : ""
    }
    else 
	{
        // If yes, then only the extra decimal places will be padded with 0s
        decimal_part_length = value_string.length - decimal_location - 1
    }
    
    // Calculate the number of decimal places that need to be padded with 0s
    var pad_total = decimal_places - decimal_part_length
    
    if (pad_total > 0) 
	{
        // Pad the string with 0s
        for (var counter = 1; counter <= pad_total; counter++) 
            value_string += "0"
    }
    return value_string
}

function pad(n, len)
{
// Pads a number with leading zeros. Make sure the '0000000000' part is big enough.
    s = n.toString();
    if (s.length < len) 
	{
        s = ('0000000000' + n.toString()).slice(-len);
    }
    return s;
}



function notEmpty(elem, helperMsg)
{
	if(elem.value.length == 0)
	{
		alert(helperMsg);
		elem.focus();
		return false;
	}
	return true;
}

function isNumeric(elem, helperMsg)
{
	var numericExpression = /^[0-9]+$/;
	if(elem.value.match(numericExpression))
	{
		return true;
	}
	else
	{
		alert(helperMsg);
		elem.focus();
		return false;
	}
}

function isNumberKey(evt)
// only allow numbers to be entered in text box
{
 var charCode = (evt.which) ? evt.which : event.keyCode
 if (charCode > 31 && (charCode < 48 || charCode > 57))
	return false;

 return true;
}


function isAlphabet(elem, helperMsg)
{
	var alphaExp = /^[a-zA-Z]+$/;
	if(elem.value.match(alphaExp))
	{
		return true;
	}
	else
	{
		alert(helperMsg);
		elem.focus();
		return false;
	}
}

function madeSelection(elem, helperMsg)
{
	if(elem.value == "0")
	{
		alert(helperMsg);
		elem.focus();
		return false;
	}
	else
	{
		return true;
	}
}


//-->

