function disable(input) {
	$(input).focus(function(){input.blur()})
}

function restrict(elements,regex,message) {
	// restricts an input to match a regex
	// ... reverts back to the last known good value
	//  and displays a message otherwise
	
	function ir() {
		// stands for inner-restrict
		
		var element = this

		if(element.value.match(regex))
			element.lastgood = element.value
		else {
			element.value = element.lastgood || ""

			if(element.tooltip)
				element.tooltip.show()
			else
				element.tooltip = $("<div/>").text(message).insertAfter(element)
				
			setTimeout(function(){
				element.tooltip.hide("slow")
			},1000)

			return false
		}
	}

	$(elements).keyup(ir).focus(ir).blur(ir)
}

function create_totals_table() {
	// there is no point having this dynamically generated table if we
	// can't update it, so it will be created dynamically in order to degrade the page gracefully
	
	var result = {}

	result.bottle_total = $("<input name='BottleTotal' value='0' type='text' readonly='readonly' class='readonly'/>")
	result.order_total = $("<input name='OrderTotal' type='text' readonly='readonly' class='readonly'/>")
	result.order_total_no_discount = $("<input name='OrderTotalNoDiscount' type='text' readonly='readonly' class='readonly'/>")
	result.case_discount = $("<input name='CaseDiscount' type='text' readonly='readonly' class='readonly'/>")
	result.shipping = $("<input name='SH' type='text' readonly='readonly' class='readonly'/>")
	result.grand_total = $("<input name='GrandTotal' type='text' readonly='readonly' class='readonly'/>")

	var total_heading = $("<h2>Totals</h2>").insertAfter($(".quantities:last"))
	
	$("<table id='totals'><tr><th/><th>Quantity</th><th>Total</th></tr></table>"
		)
	.append(
			$("<tr/>"
			).append(
				$("<td class='category'>Cost Without Discount</td>")
			).append(
				$("<td class='quantity'/>"
				).append(result.bottle_total)
			).append(
				$("<td class='total'/>"
				).append(result.order_total_no_discount)
			)
		).append(
			$("<tr/>"
			).append(
				$("<td class='category' colspan='2'>Case Discount</td>")
			).append(
				$("<td class='total'/>"
				).append(result.case_discount)
			)
		).append(
			$("<tr/>"
			).append(
				$("<td class='category' colspan='2'>Order Total</td>")
			).append(
				$("<td class='total'/>"
				).append(result.order_total)
			)
		).append(
			$("<tr/>"
			).append(
				$("<td class='category' colspan='2'>Shipping &amp; Handling</td>"
					).append("<div>(Cost of shipping outside WA to be determined later)</div>")
			).append(
				$("<td class='total'/>"
				).append(result.shipping)
			)
		).append(
			$("<tr/>"
			).append(
				$("<td class='category' colspan='2'>Grand Total</td>")
			).append(
				$("<td class='total'/>"
				).append(result.grand_total)
			)
		).insertAfter(
			total_heading
		)
		
		return result
}

function append_totals_columns() {
	$(".quantities").each(function(){

			$(this).find("tr.headings").append($("<th>Total</th>"))

			$(this).find("tr[class!=headings]").each(function(){
				$('<input type="text" readonly="readonly" class="readonly" />'
				).appendTo( $("<td class='total' />").appendTo($(this))
				).attr(
					"name",
					$(this).find("td:first input:first").attr("name").match(/Item\d+/)[0] + "Total"
				)
			})

	})

	$("ul.legend").append(
		$("<li class='readonly'><span class='text'>Field is read-only.</span></li>")
	)
}

$(function(){
	
	// declare the major areas of the document that we're working on
	var Quantities_table = $(".quantities")
	var Contact_information = $(".contact_information")

	// restrict certain fields to certain values
	restrict(Quantities_table.find("input[tabindex]"), /^\d*$/, "Numbers only please.")

	restrict(Contact_information.find("input[name=Telephone]").get(0), /^[0-9]*$/, "Numbers, hyphens, or spaces allowed.")

	append_totals_columns()

	var totals_table = create_totals_table()

	// prevent mucking with values

	// do not allow focusing on any of the last input elements in the quantities tables
	$("#totals input").each(function(){disable($(this))})

	$(".quantities td.total input").each(function(){
		disable($(this))
	})

	// used in sum to keep track of totals
	var total_info = {}
	
	function print_totals() {
		var total = {}
		for(var i in total_info)
			for(var j in total_info[i]){
				total[j] || (total[j] = 0)
				total[j] += total_info[i][j]
			}

		totals_table.bottle_total.get(0).value = total["items"]
		totals_table.order_total.get(0).value = "$" + total["cost"]
		totals_table.order_total_no_discount.get(0).value = "$" + total["super_cost"]
		totals_table.case_discount.get(0).value = "$" + total["discount"]
		var shipping = 0
		if(
				$("#orderform select[name=State] option[selected]").get(0).value == "WA"
			) {
				shipping = Math.ceil(total["items"] / 12) * 10
				totals_table.shipping.get(0).value = "$" + shipping
		} else {
				totals_table.shipping.get(0).value = "$---"
		}
		totals_table.grand_total.get(0).value = "$" + (total["cost"] + shipping)
	}

	function subtotal(el) {
		// remove non matching values

		var quantity = Number(el.value)

		var tr = $(el).parents("tr:first")

		var name = tr.find(".category input").get(0).value

		var setSize = Number(tr.find("td.pricePerSet input[type=hidden]").get(0).value)

		var price       = Number(tr.find("td.price       input[type=hidden]").get(0).value)
		var pricePerSet = Number(tr.find("td.pricePerSet input[type=hidden].pricePerSet").get(0).value)
		// default value
		var setSize     = 12

		// determine the set size
		// this is assumed to be 12 bottles unless specified in a hidden field
		try {
			var setSize = Number(tr.find("td.pricePerSet input[type=hidden].setSize").get(0).value)
		} catch(setSizeError) {
			// rely on the default value
		}

		var caseammount = Math.floor(quantity / setSize)
		var remainder   = quantity % setSize

		// wipe the last set
		var cost = caseammount * pricePerSet + remainder * price
		var super_cost = quantity * price

		total_info[name] = {
			items: quantity,
			"cost": cost,
			"super_cost": super_cost,
			discount: super_cost - cost
		}

		tr.find("input:last").get(0).value = cost > 0 ? "$" + cost : ""
	}

	// sum everything up to start with
	
	$(".quantities td.quantity input").each(function(){
			subtotal(this)
	})
	print_totals()

	function sum() {
		subtotal(this)
		print_totals()
	}

	$(".quantities td.quantity input").focus(sum).blur(sum).keyup(sum)
	$("#orderform select[name=State]").focus(print_totals).blur(print_totals).keyup(print_totals)

	// set up the submission criteria
	
	$('#orderform').submit(function(){
			var flag = false
			$(".required").each(function(){
				if(this.name && this.value == "")
				{
					alert(this.name + " is a required field.")
					$(this).css("borderColor","red")
					this.focus()
					flag = true
					return false
				}
				$(this).css("borderColor","green")
			})
			if(flag)
				return false

			if(Number(totals_table.bottle_total.get(0).value) == 0) {
				alert("Please order at least 6 Bottles")
				return false
			}
			if(Number(totals_table.bottle_total.get(0).value) % 6 != 0) {
				alert("The total number of bottles ordered must be a multiple of 6")
				return false
			}
			// remove unused fields
			$(this).find("input[value='']").each(function(){
					$(this).parents("tr:first").remove()
			})
	})
})
