 // JavaScript Document

var lastRowInserted = null;
var productSelector = null;
var serviceSelector = null;
var qualitySelector = null;
var quantitySelector = null;
var priceField = null;
var priceFieldHidden = null;
var defaultServiceModel = null;
var totalPrice = 0;
var rowAutoIncrement = 0;
var entryPrices = new Array();
var entryIds = new Array();

function arrayContains( arr, value ) {
	for( var i = 0; i < arr.length; i++ ) {
		if( arr[i] == value ) {
			return true;
		}
	}
	
	return false;
}

function Service() {}
Service.REPLATE = "Re-plate";
Service.REHANDLE = "Rehandle";

function Quality() {}
Quality.AMBASSADOR = "Ambassador";
Quality.DIPLOMAT = "Diplomat";
Quality.SSTEEL = "S/Steel";
Quality.GRAINED = "Grained Cream";
Quality.PLAIN = "Plain Cream"

function ServiceModel() {
	this.serviceList = new Array();
}

ServiceModel.prototype.populate = function() {
	this.serviceList.push( new ServiceStruct( "Table knife", Service.REPLATE, Quality.DIPLOMAT, 6.85 ) );
	this.serviceList.push( new ServiceStruct( "Table knife", Service.REPLATE, Quality.AMBASSADOR, 8.25 ) );
	this.serviceList.push( new ServiceStruct( "Table knife", Service.REPLATE, Quality.SSTEEL, 3.15 ) );
	this.serviceList.push( new ServiceStruct( "Table knife", Service.REHANDLE, Quality.GRAINED, 6.95 ) );
	this.serviceList.push( new ServiceStruct( "Table knife", Service.REHANDLE, Quality.PLAIN, 7.45 ) );
	this.serviceList.push( new ServiceStruct( "Table fork", Service.REPLATE, Quality.DIPLOMAT, 7.20 ) );
	this.serviceList.push( new ServiceStruct( "Table fork", Service.REPLATE, Quality.AMBASSADOR, 8.85 ) );
	this.serviceList.push( new ServiceStruct( "Table fork", Service.REPLATE, Quality.SSTEEL, 3.35 ) );
	this.serviceList.push( new ServiceStruct( "Dinner knife", Service.REHANDLE, Quality.GRAINED, 6.95 ) );
	this.serviceList.push( new ServiceStruct( "Dinner knife", Service.REHANDLE, Quality.PLAIN, 7.45 ) );
	this.serviceList.push( new ServiceStruct( "Dessert knife", Service.REPLATE, Quality.DIPLOMAT, 6.85 ) );
	this.serviceList.push( new ServiceStruct( "Dessert knife", Service.REPLATE, Quality.AMBASSADOR, 8.25 ) );
	this.serviceList.push( new ServiceStruct( "Dessert knife", Service.REPLATE, Quality.SSTEEL, 3.15 ) );
	this.serviceList.push( new ServiceStruct( "Dessert knife", Service.REHANDLE, Quality.GRAINED, 6.45 ) );
	this.serviceList.push( new ServiceStruct( "Dessert knife", Service.REHANDLE, Quality.PLAIN, 6.85 ) );
	this.serviceList.push( new ServiceStruct( "Dessert fork", Service.REPLATE, Quality.DIPLOMAT, 6.45 ) );
	this.serviceList.push( new ServiceStruct( "Dessert fork", Service.REPLATE, Quality.AMBASSADOR, 8.25 ) );
	this.serviceList.push( new ServiceStruct( "Dessert fork", Service.REPLATE, Quality.SSTEEL, 3.15 ) );
	this.serviceList.push( new ServiceStruct( "Dessert spoon", Service.REPLATE, Quality.DIPLOMAT, 6.45 ) );
	this.serviceList.push( new ServiceStruct( "Dessert spoon", Service.REPLATE, Quality.AMBASSADOR, 8.25 ) );
	this.serviceList.push( new ServiceStruct( "Dessert spoon", Service.REPLATE, Quality.SSTEEL, 3.15 ) );
	this.serviceList.push( new ServiceStruct( "Soup spoon", Service.REPLATE, Quality.DIPLOMAT, 6.45 ) );
	this.serviceList.push( new ServiceStruct( "Soup spoon", Service.REPLATE, Quality.AMBASSADOR, 8.25 ) );
	this.serviceList.push( new ServiceStruct( "Soup spoon", Service.REPLATE, Quality.SSTEEL, 3.15 ) );
	this.serviceList.push( new ServiceStruct( "Tea spoon", Service.REPLATE, Quality.DIPLOMAT, 5.20 ) );
	this.serviceList.push( new ServiceStruct( "Tea spoon", Service.REPLATE, Quality.AMBASSADOR, 6.30 ) );
	this.serviceList.push( new ServiceStruct( "Tea spoon", Service.REPLATE, Quality.SSTEEL, 2.70 ) );
	this.serviceList.push( new ServiceStruct( "Tea knife", Service.REHANDLE, Quality.GRAINED, 5.95 ) );
	this.serviceList.push( new ServiceStruct( "Tea knife", Service.REHANDLE, Quality.PLAIN, 6.40 ) );
	this.serviceList.push( new ServiceStruct( "Steak knife", Service.REHANDLE, Quality.GRAINED, 6.95 ) );
	this.serviceList.push( new ServiceStruct( "Steak knife", Service.REHANDLE, Quality.PLAIN, 7.45 ) );
	this.serviceList.push( new ServiceStruct( "Coffee spoon", Service.REPLATE, Quality.DIPLOMAT, 4.60 ) );
	this.serviceList.push( new ServiceStruct( "Coffee spoon", Service.REPLATE, Quality.AMBASSADOR, 5.75 ) );
	this.serviceList.push( new ServiceStruct( "Coffee spoon", Service.REPLATE, Quality.SSTEEL, 2.25 ) );
	this.serviceList.push( new ServiceStruct( "Fisheaters (pair)", Service.REPLATE, Quality.DIPLOMAT, 13.85 ) );
	this.serviceList.push( new ServiceStruct( "Fisheaters (pair)", Service.REPLATE, Quality.AMBASSADOR, 16.70 ) );
	this.serviceList.push( new ServiceStruct( "Fisheaters (pair)", Service.REPLATE, Quality.SSTEEL, 6.30 ) );
	this.serviceList.push( new ServiceStruct( "Serving/Table Spoon/Fork", Service.REPLATE, Quality.DIPLOMAT, 8.20 ) );
	this.serviceList.push( new ServiceStruct( "Serving/Table Spoon/Fork", Service.REPLATE, Quality.AMBASSADOR, 9.80 ) );
	this.serviceList.push( new ServiceStruct( "Serving/Table Spoon/Fork", Service.REPLATE, Quality.SSTEEL, 3.45 ) );
	this.serviceList.push( new ServiceStruct( "Small Ladle", Service.REPLATE, Quality.DIPLOMAT, 8.50 ) );
	this.serviceList.push( new ServiceStruct( "Small Ladle", Service.REPLATE, Quality.AMBASSADOR, 10.20 ) );
	this.serviceList.push( new ServiceStruct( "Small Ladle", Service.REPLATE, Quality.SSTEEL, 3.15 ) );
	this.serviceList.push( new ServiceStruct( "Medium Ladle", Service.REPLATE, Quality.DIPLOMAT, 12.00 ) );
	this.serviceList.push( new ServiceStruct( "Medium Ladle", Service.REPLATE, Quality.AMBASSADOR, 14.50 ) );
	this.serviceList.push( new ServiceStruct( "Medium Ladle", Service.REPLATE, Quality.SSTEEL, 3.45 ) );
	this.serviceList.push( new ServiceStruct( "Large Ladle", Service.REPLATE, Quality.DIPLOMAT, 23.80 ) );
	this.serviceList.push( new ServiceStruct( "Large Ladle", Service.REPLATE, Quality.AMBASSADOR, 28.55 ) );
	this.serviceList.push( new ServiceStruct( "Large Ladle", Service.REPLATE, Quality.SSTEEL, 6.35 ) );
	this.serviceList.push( new ServiceStruct( "Pie slice", Service.REPLATE, Quality.DIPLOMAT, 10.30 ) );
	this.serviceList.push( new ServiceStruct( "Pie slice", Service.REPLATE, Quality.AMBASSADOR, 12.30 ) );
	this.serviceList.push( new ServiceStruct( "Pie slice", Service.REPLATE, Quality.SSTEEL, 4.10 ) );
	this.serviceList.push( new ServiceStruct( "Sugar tong", Service.REPLATE, Quality.DIPLOMAT, 8.90 ) );
	this.serviceList.push( new ServiceStruct( "Sugar tong", Service.REPLATE, Quality.AMBASSADOR, 10.90 ) );
	this.serviceList.push( new ServiceStruct( "Ice tong", Service.REPLATE, Quality.DIPLOMAT, 11.85 ) );
	this.serviceList.push( new ServiceStruct( "Ice tong", Service.REPLATE, Quality.AMBASSADOR, 14.45 ) );
	this.serviceList.push( new ServiceStruct( "2pce carver set", Service.REPLATE, Quality.DIPLOMAT, 25.40 ) );
	this.serviceList.push( new ServiceStruct( "2pce carver set", Service.REPLATE, Quality.AMBASSADOR, 30.35 ) );
	this.serviceList.push( new ServiceStruct( "2pce carver set", Service.REPLATE, Quality.SSTEEL, 13.30 ) );
	this.serviceList.push( new ServiceStruct( "3pce carver set", Service.REPLATE, Quality.DIPLOMAT, 32.60 ) );
	this.serviceList.push( new ServiceStruct( "3pce carver set", Service.REPLATE, Quality.AMBASSADOR, 39.75 ) );
	this.serviceList.push( new ServiceStruct( "3pce carver set", Service.REPLATE, Quality.SSTEEL, 19.45 ) );
}

ServiceModel.prototype.get = function( filter, expectedResult ) {
	
	var result;
	if( expectedResult == "product" ) {
		result = new Array();
		for( var i = 0; i < this.serviceList.length; i++ ) {
			if( $.inArray( this.serviceList[i].product, result ) == -1 ) {
				result.push( this.serviceList[i].product );
			}
		}
	} else if( expectedResult == "service" ) {
		result = new Array();
		
		for( var i = 0; i < this.serviceList.length; i++ ) {
			if( this.serviceList[i].product == filter.product ) {
				if( $.inArray( this.serviceList[i].service, result ) == -1 ) {
					result.push( this.serviceList[i].service );
				}
			}
		}
	} else if( expectedResult == "quality" ) {
		result = new Array();
		
		for( var i = 0; i < this.serviceList.length; i++ ) {
			if( this.serviceList[i].product == filter.product && this.serviceList[i].service == filter.service ) {
				if( $.inArray( this.serviceList[i].quality, result ) == -1 ) {
					result.push( this.serviceList[i].quality );
				}
			}
		}
		
	} else {
		//must be price otherwise
		
		for( var i = 0; i < this.serviceList.length; i++ ) {
			if( this.serviceList[i].product == filter.product &&
								 this.serviceList[i].service == filter.service &&
								 this.serviceList[i].quality == filter.quality ) {
				result = Math.round( (this.serviceList[i].price * filter.quantity) * 100 ) / 100;
			}
		}
	}
	
	return result;
}


function ServiceStruct( productName, serviceName, qualityType, priceValue ) {
	this.product = productName;
	this.service = serviceName;
	this.quality = qualityType;
	this.price = priceValue ? priceValue : 0.0;
}

function createRowSeparator() {
	var element = document.createElement( "tr" );
	element.setAttribute( "rowId", rowAutoIncrement );
	var td = document.createElement( "td" );
	td.setAttribute( "colspan", "6" );
	td.setAttribute( "style", "padding:0px" );
	
	var div = document.createElement( "div" );
	div.setAttribute( "style", "height:1px; border-bottom:1px #CCC solid" );
	td.appendChild( div );
	element.appendChild( td );
	
	return element;
}

function Entry( productName, serviceName, qualityType, quantity, price ) {
	this.product = productName;
	this.service = serviceName;
	this.qualityType = qualityType;
	this.quantity = quantity;
	this.price = price;
	this.id = rowAutoIncrement;
	entryIds.push( this.id );
	
	this.html = document.createElement( "tr" );
	this.html.setAttribute( "rowId", rowAutoIncrement );
	this.html.setAttribute( "align", "center" );
	var element;
	
	element = document.createElement( "td" );
	element.appendChild( document.createTextNode( this.product ) )
	this.html.appendChild( element );
	
	element = document.createElement( "td" );
	element.appendChild( document.createTextNode( this.service ) );
	this.html.appendChild( element );
	
	element = document.createElement( "td" );
	element.appendChild( document.createTextNode( this.qualityType ) );
	this.html.appendChild( element );
	
	element = document.createElement( "td" );
	element.appendChild( document.createTextNode( this.quantity ) );
	this.html.appendChild( element );
	
	element = document.createElement( "td" );
	$(element).html( "&pound;" + this.price );
	this.html.appendChild( element );
	
	entryPrices[this.id] = this.price;
	
	var editLink = document.createElement( "a" )
	editLink.appendChild( document.createTextNode( "Edit" ) );
	editLink.setAttribute( "href", "" );
	$(editLink).addClass( "ch_button" );
	
	var removeLink = document.createElement( "a")
	removeLink.appendChild( document.createTextNode( "Remove" ) );
	removeLink.setAttribute( "href", "javascript:removeEntry(" + rowAutoIncrement + ")" );
	$(removeLink).addClass("ch_button" );
	
	var linksTD = document.createElement( "td" );
//	add these only when remove option is available
	//linksTD.appendChild( editLink );
	//linksTD.appendChild( document.createTextNode( " | " ) );
	linksTD.appendChild( removeLink );
	
	this.html.appendChild( linksTD );
}

var itemList = new Array();
var count = 0;

function addEntry() {
	
	var productName = productSelector.options[productSelector.selectedIndex].text;
	var serviceName = serviceSelector.options[serviceSelector.selectedIndex].text;
	var qualityType = qualitySelector.options[qualitySelector.selectedIndex].text;
	var quantity = quantitySelector.value.length > 0 ? quantitySelector.value : "1";
	var itemPrice = priceFieldHidden.value;
	
	var entry = new Entry( productName, serviceName, qualityType, quantity, itemPrice );
	var isFirstEntry = false;
	if( lastRowInserted == null ) {
		isFirstEntry = true;
		lastRowInserted = document.getElementById( "lastRowInserted" );
	}
	
	lastRowInserted.parentNode.insertBefore( entry.html, lastRowInserted.nextSibling );
	if( !isFirstEntry ) {
		lastRowInserted.parentNode.insertBefore( createRowSeparator(), entry.html );
		//maybe other statements as well
	}
	lastRowInserted = entry.html;
	rowAutoIncrement++;
	
	updateTotalPrice( itemPrice );
}


function editEntry( id ) {
	
}

function removeEntry( id ) {
	var rem = $("tr[rowId=" + id + "]");
	var row = rem.get( 1 );
	if( row == lastRowInserted ) {
		var prev = rem.prev();
		lastRowInserted = ( prev.get( 0 ) );
	}
	rem.remove(); 
	updateTotalPrice( -parseFloat(entryPrices[id]) );
}

function updateTotalPrice( value ) {
	totalPrice += parseFloat( value );
	var displayPrice = Math.round( totalPrice * 100 ) / 100;
	displayPrice = addZeros( displayPrice );
	$("#totalPrice").html( "Total: &pound;" + displayPrice );
}

function resetCalculator() {
	for( var i = 0; i < entryIds.length; i++ ) {
		removeEntry( entryIds[i] );
	}
	
	totalPrice = 0;
	updateTotalPrice( 0 );
}

function cascadeChange( sm, selectorIndex ) {
	
	var product = productSelector.options[productSelector.selectedIndex].text;
	if( selectorIndex == -1 ) {
		//populate products
		var products = sm.get( null, "product" );
		productSelector.innerHTML = "";
		$(productSelector).append( "<option selected=\"selected\">" + products[0] + "</option>");
		for( var i = 1; i < products.length; i++ ) {
			$(productSelector).append( "<option>" + products[i] + "</option>" );
		}
		cascadeChange( sm, 0 );
	} else if( selectorIndex == 0 ) {
		var services = sm.get( { product : productSelector.options[productSelector.selectedIndex].text }, "service" );
		serviceSelector.innerHTML = "";
		$(serviceSelector).append( "<option selected=\"selected\">" + services[0] + "</option>");
		for( var i = 1; i < services.length; i++ ) {
			$(serviceSelector).append( "<option>" + services[i] + "</option>" );
		}
		cascadeChange( sm, 1 );
	} else if( selectorIndex == 1 ) {
		var qualities = sm.get( { product : productSelector.options[productSelector.selectedIndex].text,
								  service: serviceSelector.options[serviceSelector.selectedIndex].text }, "quality" );
		qualitySelector.innerHTML = "";
		$(qualitySelector).append( "<option selected=\"selected\">" + qualities[0] + "</option>");
		for( var i = 1; i < qualities.length; i++ ) {
			$(qualitySelector).append( "<option>" + qualities[i] + "</option>" );
		}
		cascadeChange( sm, 3 );
	} else if( selectorIndex == 2 ) {
		//do nothing
		cascadeChange( sm, 3 );
	} else if( selectorIndex == 3 ) {
		var quantityVal = parseInt( quantitySelector.value );
		if( !quantityVal ) {
			quantityVal = 1;
		}
		
		quantitySelector.value = quantityVal;
		
		var price = sm.get( { product: productSelector.options[productSelector.selectedIndex].text,
							  service: serviceSelector.options[serviceSelector.selectedIndex].text,
							  quality: qualitySelector.options[qualitySelector.selectedIndex].text,
							  quantity: parseInt( quantitySelector.value ) }, "price" );
		if( !price ) {
			price = 0;
		}
		
		price = addZeros( price );
		priceField.innerHTML = "&pound;" + price;
		priceFieldHidden.value = price;
	}
}

function addZeros( priceValue ) {
	//convert to string
	priceValue = priceValue + "";
	var dotIndex = priceValue.indexOf( "." );
	if( dotIndex == -1 ) {
		return priceValue + ".00";
	} else {
		var dif = priceValue.length - dotIndex;
		if( dif < 3 ) {
			for( var i = 1; i < dif; i++ ) {
				priceValue += "0";
			}
		} else {
			//the dif will never be > 3 because we round up the result
		}
	}
	
	return priceValue;
}

function init() {
	defaultServiceModel = new ServiceModel();
	defaultServiceModel.populate();
	
	
	var f = document.forms["selector"];
	productSelector = f.productSelect;
	$(productSelector).change( function() { cascadeChange( defaultServiceModel, 0 ); } );
	serviceSelector = f.serviceSelect;
	$(serviceSelector).change( function() { cascadeChange( defaultServiceModel, 1 ); } );
	qualitySelector = f.qualitySelect;
	$(qualitySelector).change( function() { cascadeChange( defaultServiceModel, 2 ); } );
	quantitySelector  = f.quantitySelect;
	$(quantitySelector).keyup( function( event ) { if( !(event.keyCode == 8 && quantitySelector.value.length < 1 ) ) { cascadeChange( defaultServiceModel, 3 ); } } );
	priceFieldHidden = f.itemPrice;
	priceField = document.getElementById( "itemPrice" );
	
	cascadeChange( defaultServiceModel, -1 );
	
	var calcSelector = $("#chCalculator");
	var wSize = getWindowSize();
	var xPos = ( wSize.w - 719 ) / 2;
	calcSelector.css( "left", xPos + "px" ).css( "top", "100px" );
	calcSelector.draggable( {
								handle : "#chHandle"
								} );
}

function showCalculator() {
	$("#chCalculator").show( 1000 );
}

function hideCalculator() {
	$("#chCalculator").hide( 1000 );
}

//real code to execute on page
$(document).ready( init );