// Based on OrderForm.js - v0.4 -  mredkj.com
// Modified by XNDR - Machinecollective.org
// CC-BY-SA - March 2009

var weightError = 0; // used for checking shipmethod / weight ratio

function OrderForm(prefix, precision, firstChoice) {
	
	this.prefix = prefix ? prefix : '';
	
	// ****************************
	// Configure here
	// ****************************
	// form element id's
	this.FORM_NAME = this.prefix + 'mcOrderForm';
	this.BTN_TOTAL = this.prefix + 'mcBtnTotal';
	this.TXT_WEIGHT = this.prefix + 'mcWeightTotal';
	this.FRM_WEIGHT = this.prefix + 'mcFrmWeight';
	this.TXT_OUT = this.prefix + 'mcCostTotal';
	this.FRM_OUT = this.prefix + 'mcFrmOut';
	
	// item id's
	this.CHK = this.prefix + 'chk';
	this.SEL = this.prefix + 'qty';
	this.WEIGHT = this.prefix + 'weight';
	this.PRICE = this.prefix + 'cost';

	// precision for the decimal places
	// If not set, then no decimal adjustment is made
	this.precision = precision ? precision : -1;
	
	// if the drop down has the first choice after index 1
	// this is used when checking or unchecking a checkbox
	this.firstChoice = firstChoice ? firstChoice : 1;
	// ****************************
	
	// form
	this.frm = document.getElementById(this.FORM_NAME);
	
	// checkboxes
	this.chkReg = new RegExp(this.CHK + '([0-9]+)');
	this.getCheck = function(chkId) {
		return document.getElementById(this.CHK + chkId);
	};
	
	// selects
	this.selReg = new RegExp(this.SEL + '([0-9]+)');
	this.getSelect = function(selId) {
		return document.getElementById(this.SEL + selId);
	};
	
	// weight spans
	this.weightReg = new RegExp(this.WEIGHT + '([0-9]+)');
	
	// price spans
	this.priceReg = new RegExp(this.PRICE + '([0-9]+)');
	
	// weight output
	this.txtWeight = document.getElementById(this.TXT_WEIGHT);
	this.frmWeight = document.getElementById(this.FRM_WEIGHT);
	
	// price output
	this.txtOut = document.getElementById(this.TXT_OUT);
	this.frmOut = document.getElementById(this.FRM_OUT);
	
	// button
	this.btnTotal = document.getElementById(this.BTN_TOTAL);
	
	// weight array
	this.weights = new Array();
	
	// price array
	this.prices = new Array();
	
	var o = this;
	this.getCheckEvent = function() {
		return function() {
			o.checkRetotal(o, this);
		};
	};
	
	this.getSelectEvent = function() {
		return function() {
			o.totalWeight(o);
			o.totalCost(o);
		};
	};
	
	this.getBtnEvent = function() {
		return function() {
			o.totalWeight(o);
			o.totalCost(o);
		};
	};
	
	/*
	 * Calculate the cost
	 */
	this.totalCost = function(orderObj) {
		var spanObj = orderObj.frm.getElementsByTagName('span');
		var total = 0.0;
		for (var i=0; i<spanObj.length; i++) {
			var regResult = orderObj.priceReg.exec(spanObj[i].id);
			if (regResult) {
				var itemNum = regResult[1];
				var chkObj = orderObj.getCheck(itemNum);
				var selObj = orderObj.getSelect(itemNum);
				var price = orderObj.prices[itemNum];
				var quantity = 0;
				if (selObj) {
					quantity = parseFloat(selObj.options[selObj.selectedIndex].text);
					quantity = isNaN(quantity) ? 0 : quantity;
				if (chkObj) chkObj.checked = quantity;
				} else if (chkObj) {
					quantity = chkObj.checked ? 1 : 0;
				}
				total += quantity * price;
			}
		}
		if (this.precision == -1) {
			orderObj.frmOut.value = total;
			orderObj.txtOut.innerHTML = total;
		} else {
			orderObj.frmOut.value = total.toFixed(this.precision);
			orderObj.txtOut.innerHTML = total.toFixed(this.precision);
		}
		setVatRate(0); // 0 = don't update total because setOrderTotal is called after (to prevent double execution)
		setShipRate(0);
		setOrderTotal();
	};

	/*
	 * Calculate the weight
	 */
	this.totalWeight = function(orderObj) {
		var spanObj = orderObj.frm.getElementsByTagName('span');
		var total = 0.0;
		for (var i=0; i<spanObj.length; i++) {
			var regResult = orderObj.weightReg.exec(spanObj[i].id);
			if (regResult) {
				var itemNum = regResult[1];
				var chkObj = orderObj.getCheck(itemNum);
				var selObj = orderObj.getSelect(itemNum);
				var weight = orderObj.weights[itemNum];
				var quantity = 0;
				if (selObj) {
					quantity = parseFloat(selObj.options[selObj.selectedIndex].text);
					quantity = isNaN(quantity) ? 0 : quantity;
					if (chkObj) chkObj.checked = quantity;
				} else if (chkObj) {
					quantity = chkObj.checked ? 1 : 0;
				}
				total += quantity * weight;
			}
		}

		orderObj.frmWeight.value = total;
		orderObj.txtWeight.innerHTML = total;
		// orderObj.txtWeight.value = total.toFixed(this.precision);
	};

	/*
	 * Handle clicks on the checkboxes
	 */
	this.checkRetotal = function(orderObj, obj) {
		var regResult = orderObj.chkReg.exec(obj.id);
		if (regResult) {
			var optObj = orderObj.getSelect(regResult[1]);
			if (optObj) {
				if (obj.checked) {
					optObj.selectedIndex = orderObj.firstChoice;
				} else {
					optObj.selectedIndex = 0;
				}
			}
			orderObj.totalCost(orderObj);
		}
	};
	
	/*
	 * Set up events
	 */
	this.setEvents = function(orderObj) {
		var spanObj = orderObj.frm.getElementsByTagName('span');
		for (var i=0; i<spanObj.length; i++) {
			var regResultPrice = orderObj.priceReg.exec(spanObj[i].id);
			var regResultWeight = orderObj.weightReg.exec(spanObj[i].id);
			if (regResultPrice) {
				var itemNum = regResultPrice[1];
				var chkObj = orderObj.getCheck(itemNum);
				var selObj = orderObj.getSelect(itemNum);
				if (chkObj) {
					chkObj.onclick = orderObj.getCheckEvent();
				}
				if (selObj) {
					selObj.onchange = orderObj.getSelectEvent();
				}
				if (orderObj.btnTotal) {
					orderObj.btnTotal.onclick = orderObj.getBtnEvent();
				}
			} else if (regResultWeight) {
				var itemNum = regResultWeight[1];
				var chkObj = orderObj.getCheck(itemNum);
				var selObj = orderObj.getSelect(itemNum);
				if (chkObj) {
					chkObj.onclick = orderObj.getCheckEvent();
				}
				if (selObj) {
					selObj.onchange = orderObj.getSelectEvent();
				}
				if (orderObj.btnTotal) {
					orderObj.btnTotal.onclick = orderObj.getBtnEvent();
				}
			}
		}
	};
	this.setEvents(this);

	/*
	 *
	 * Grab the prices from the html
	 */
	this.grabPrices = function(orderObj) {
		var spanObj = orderObj.frm.getElementsByTagName('span');
		for (var i=0; i<spanObj.length; i++) {
			if (orderObj.priceReg.test(spanObj[i].id)) {
				var regResult = orderObj.priceReg.exec(spanObj[i].id);
				if (regResult) {
					orderObj.prices[regResult[1]] = parseFloat(spanObj[i].innerHTML);
				}
			}
		}
	};
	this.grabPrices(this);
	
	/*
	 *
	 * Grab the weights from the html
	 */
	this.grabWeights = function(orderObj) {
		var spanObj = orderObj.frm.getElementsByTagName('span');
		for (var i=0; i<spanObj.length; i++) {
			if (orderObj.weightReg.test(spanObj[i].id)) {
				var regResult = orderObj.weightReg.exec(spanObj[i].id);
				if (regResult) {
					orderObj.weights[regResult[1]] = parseFloat(spanObj[i].innerHTML);
				}
			}
		}
	};
	this.grabWeights(this);
	
}

function setOrderTotal(){
	var orderSubTotal = parseFloat(document.getElementById('mcFrmOut').value);
	var vatTotal = parseFloat(document.getElementById('vat').value);
	var shipFee = parseFloat(document.getElementById('frmShipping').value);
	
	var grandTotal = orderSubTotal + vatTotal + shipFee;
	grandTotal = grandTotal.toFixed(2);
	
	document.getElementById('frmGrandTotal').value = grandTotal;
	document.getElementById('txtGrandTotal').innerHTML = grandTotal;
	
}

function setShipRate(updateTotal){
	
	/* 
	Options currently in shipping dropdown menu:
	0 NL - Pick up in The Hague
    1 NL - Basis Pakket (next day)
    2 NL - Zeker Pakket (next day, insured)
    3 EU < 500 g - not insured
    4 EU < 2 kg - not insured
    5 WORLD < 500 g - not insured
    6 WORLD < 2 kg - not insured
    7 EU ZONE I < 2 kg - insured
    8 EU ZONE I < 5 kg - insured
    9 EU ZONE I < 10 kg - insured
    10 EU ZONE II < 2 kg - insured
    11 EU ZONE II < 5 kg - insured
    12 EU ZONE II < 10 kg - insured
    13 WORLD ZONE I < 2 kg - insured
    14 WORLD ZONE I < 5 kg - insured
    15 WORLD ZONE I < 10 kg - insured
    16 WORLD ZONE II < 2 kg - insured
    17 WORLD ZONE II < 5 kg - insured
    18 WORLD ZONE II < 10 kg - insured
    19 COURIER - UPS Express < 2.5 kg
	20 COURIER - UPS Express < 5 kg
	*/
	
	// use array with weights for each shipping method to check against order weight
	var allowedWeight = new Array(100000, 10000, 10000, 500, 2000, 500, 2000, 2000, 5000, 10000, // t/m EU I
								  2000, 5000, 10000,2000, 5000, 10000,2000, 5000, 10000, 2500, 5000);
	// prices of each shipping option
	var shippingFee = new Array("0.00", "7.50", "10.00", "7.50", "12.50", "12.50", "22.50", "15.00", "22.50", "27.50", // t/m EU I
								  "20.00", "27.50", "32.50","22.50", "27.50", "32.50","25.50", "36.50", "60.00", "35.00", "65.00");
	
	var selectedOption = document.getElementById('shipSelect').value; // shipping option select menu
	
	var orderWeight = document.getElementById('mcFrmWeight').value; // total order weight
	
	if(orderWeight > allowedWeight[selectedOption]){
		document.getElementById("weightCheckOk").style.display = 'none';
		document.getElementById("weightCheckError").style.display = 'block';
		document.getElementById("weightCell").style.color = '#FF0000';
		document.getElementById("weightCell").style.fontWeight = 'bold';
		weightError = 1;
		
	}else{
		document.getElementById("weightCheckOk").style.display = 'block';
		document.getElementById("weightCheckError").style.display = 'none';
		document.getElementById("weightCell").style.color = '#000000';
		document.getElementById("weightCell").style.fontWeight = 'normal';
		weightError = 0;
	}
	var shipRate = shippingFee[selectedOption];
	shipRate = parseFloat(shipRate);
	shipRate = shipRate.toFixed(2);
	
	document.getElementById('frmShipping').value = shipRate;
	document.getElementById('txtShipping').innerHTML = shipRate;
	
	// update order total if called by onchange event
	if(updateTotal > 0){
		setOrderTotal();
	}
	
	
}

function setVatRate(updateTotal){
	var vatRate = 19;
	var vatStatus = document.getElementById('vatSelect').value; // vat status select menu
	var orderSubTotal = document.getElementById('mcFrmOut').value; // hidden total field

	// set vat rate according to selected vat status
	if(vatStatus == 1){
		vatRate = 19;
		document.getElementById('vatAmt').value = vatRate;
		document.getElementById('txtVatAmt').innerHTML = vatRate;
	} else if (vatStatus == 0){
		vatRate = 0;
		document.getElementById('vatAmt').value = vatRate;
		document.getElementById('txtVatAmt').innerHTML = vatRate;
	}

	// calculate vat total
	
	var vatTotal = (orderSubTotal/100)*vatRate;
	vatTotal = vatTotal.toFixed(2);
	document.getElementById('vat').value = vatTotal; // hidden field
	document.getElementById('txtVat').innerHTML = vatTotal; // displayed txt
	
	// update order total if called by onchange event
	if(updateTotal > 0){
		setOrderTotal();
	}
	
}

function checkForm(){

	var status = true; // boolean return value
	var orderSubTotal = document.getElementById('mcFrmOut').value; // hidden total field
	var minOrderAmt = 20; // minimum order amount
	var msg = "Please check your order:\n";
	
	if(orderSubTotal < minOrderAmt){
		status = false; // don't post form
		msg = msg + "The minimum order amount is " + minOrderAmt + " euros.\n";
	}
	
	if(weightError){
		status = false; // don't post form
		msg = msg + "The selected shipping method must fit the shipping weight.\n";
	}

	if(!status){
		alert(msg);
	}

return status;
}

