(function(){

/**
 * TPOffset singleton
 *
 * Depends on jquery and TPCalc.
 */

window.TPOffset = {};

///////////////
// Constants //
///////////////

TPOffset.AUTO_UPDATE_TIMEOUT = 2000;  // in msecs

TPOffset.DEFAULT_PORTFOLIO_ALLOC = {
	clean:    0.35,
	farm:     0.20,
	landfill: 0.45
};

TPOffset.DEFAULT_POSTCARD_STICKER_COUNT = 1;
TPOffset.DEFAULT_LUGGAGE_TAG_COUNT = 0;

TPOffset.ATTRIBUTES = [
	{code: 'SX-TPX-CO2GEN', price: 5.95},
	{code: 'SX-TPX-CO2CLE', price: 5.95},
	{code: 'SX-TPX-CO2FAR', price: 5.95},
	{code: 'SX-TPX-CO2LFG', price: 5.95},
	{code: 'SX-TPX-D-DCL',  price: 0.00},
	{code: 'SX-TPX-D-BMP',  price: 0.00},
	{code: 'SX-TPX-A-STK',  price: 0.00},
	{code: 'SX-TPX-A-LTG',  price: 3.00},
	{code: 'SX-TPX-H-FMG',  price: 0.00},
	{code: 'SX-PORTCARBON01', price: 0.00}		// Dummy attribute
];

TPOffset.LUGGAGE_TAG_PROD_CODE = 'TPX-A-TAG';

/////////////
// Members //
/////////////

TPOffset.portfolioNode = null;
TPOffset.optionNode = null;

/////////////
// Methods //
/////////////

TPOffset.init = function(totalKlbsCo2, numVehicles, numFlights, numHomes, numLuggageTags) {

	// Clean arguments

	totalKlbsCo2 = parseInt(totalKlbsCo2) || 0;
	numVehicles = parseInt(numVehicles) || 0;
	numFlights = parseInt(numFlights) || 0;
	numHomes = parseInt(numHomes) || 0;
	numLuggageTags = parseInt(numLuggageTags)||0;
	
	
	// Modify the Number prototype

	Number.prototype.toFormattedString = TPCalc.formatNumber;
	Number.prototype.toCurrency = TPCalc.formatCurrency;

	// Start initialization

	$(document).ready(function(){

		// Set BODY ID attribute for CSS contextual selectors

		$('body').attr('id', 'carbon_offset_product');

		// Initialize DOM nodes

		// Add hidden inputs for attributes

		var numAttribs=TPOffset.ATTRIBUTES.length;
		var newHtml = '<input type="hidden" name="AttributeCount" value="' + numAttribs + '">';
		var codeName, valName;

		for(var i=0; i < numAttribs; i++) {
			codeName = 'AttributeCode[' + (i+1) + ']';
			valId = 'attrib_' + TPOffset.ATTRIBUTES[i].code;
			valName = 'AttributeValue[' + (i+1) + ']';
			newHtml += '<input type="hidden" name="' + codeName + '" value="' + TPOffset.ATTRIBUTES[i].code + '">';
			newHtml += '<input type="hidden" id="' + valId + '" name="' + valName + '" value="">';

		}
		$('#miva form[name="PRODProducts"]').eq(0).append(newHtml);

		// Remove unneeded DOM nodes

		if(numVehicles < 1) {
			$('#road_option_controls').remove();
		}
		if(numFlights < 1 && numLuggageTags<1) {
			$('#air_option_controls').remove();
		}
		if(numHomes < 1) {
			$('#residential_option_controls').remove();
		}

		// Update the UI and form controls

		$('#attrib_SX-PORTCARBON01').val(totalKlbsCo2);
		$('#attrib_SX-TPX-CO2GEN').val(totalKlbsCo2);
		$('#attrib_SX-TPX-CO2CLE,#attrib_SX-TPX-CO2FAR,#attrib_SX-TPX-CO2LFG').val('');	// In Safari, navigate away, hit back button, and these inputs have old values
		$('#carbon_total_display').html((totalKlbsCo2 * 1000).toFormattedString());
		
		

		TPOffset.updateOptions(
			numVehicles,
			numVehicles,
			// numFlights > 0 ? TPOffset.DEFAULT_POSTCARD_STICKER_COUNT : 0,
			( numFlights > 0 && numLuggageTags==0 ) ? TPOffset.DEFAULT_POSTCARD_STICKER_COUNT : 0,
			numLuggageTags > 0 ? numLuggageTags : TPOffset.DEFAULT_LUGGAGE_TAG_COUNT ,
			numHomes
		);
		TPOffset.updatePriceTotal();

		// Bind event handlers

		// Do some hacks just before form submission

		$('form[name="PRODProducts"]').submit(function(){

			var $form = $(this);
			var exc;

			try {
				// Workaround: Prefix all CO2 portfolio attribute values with ': '

				$('#attrib_SX-TPX-CO2GEN, #attrib_SX-TPX-CO2CLE, #attrib_SX-TPX-CO2FAR, #attrib_SX-TPX-CO2LFG').each(function(){
					var val = $(this).val();
					if(val != '') {
						$(this).val(': ' + val);
					}
				});
			} catch(exc) {
				// Ignore failure //
			}
			try {
				// Workaround: POST a separate "add to cart" operation for luggage tags

				var numLugTags = parseInt($('#attrib_SX-TPX-A-LTG').val()) || 0;

				if(numLugTags > 0) {

					// Disable submit/image inputs

					$('input[type=image], input[type=submit]', $form).attr('disabled', 'disabled').addClass('disabled');

					$.ajax({
						async: false,
						url: $form.attr('action'),
						type: 'get',
						contentType: 'application/x-www-form-urlencoded; charset=ISO-8859-1',
						data: {
							'Action':       'ADPR',
							'Product_Code': TPOffset.LUGGAGE_TAG_PROD_CODE,
							'Store_Code':   'TerraPass',
							'Screen':       'BASK',
							'Quantity':     numLugTags
						}
					});
				}

			} catch(exc) {
				// Ignore failure //
			}

			return true;
		});

		// Open the overlay window that allows the user to customize
		// his/her offset portfolio

		$('#change_offset_total, #change_portfolio').click(function(evt){

			var exc;
			try{

				TPOffset.openOverlay(TPOffset.portfolioNode);

				// Re-bind events to overlay elements

				// Restrict keyboard input to digits and
				// auto update after a short duration

				$('#portfolio_controls :text').each(function(){

					AutoComplete.bindInputFilter(this, function(evt) {

						var $input = $(evt.target);

						var oldTid = $input.data('autoSaveTid');
						if(oldTid) {
							clearTimeout(oldTid);
						}

						var tid = setTimeout(function(){
							$input.change();
						}, TPOffset.AUTO_UPDATE_TIMEOUT);
						$input.data('autoSaveTid', tid);

						return AutoComplete.filterForDigit(evt);
					});

					$(this).bind('change', function() {
						var oldTid = $(this).data('autoSaveTid');
						if(oldTid) {
							clearTimeout(oldTid);
						}
						$(this).val( parseInt($(this).val()) || 0 );
					});
					$(this).bind('keydown', function() {
						var valLen = $(this).val() !== undefined ? String($(this).val()).length : 0;

						if(valLen > 3) {
							$(this).css('width', (valLen * 0.75) + 'em')
						} else {
							$(this).css('width', '')
						}
					});
				});

				$('#save_portfolio').click(function() {
					var totalOffset;

					if($('input[name=use_custom_portfolio]:checked').val() > 0) {
						$('#attrib_SX-TPX-CO2GEN').val('');
						$('#attrib_SX-TPX-CO2CLE').val($('#clean_offset').val() || '');
						$('#attrib_SX-TPX-CO2FAR').val($('#farm_offset').val() || '');
						$('#attrib_SX-TPX-CO2LFG').val($('#landfill_offset').val() || '');

						var cleanOffset = parseInt($('#clean_offset').val()) || 0;
						var farmOffset = parseInt($('#farm_offset').val()) || 0;
						var landfillOffset = parseInt($('#landfill_offset').val()) || 0;

						totalOffset = cleanOffset + farmOffset + landfillOffset;

						$('#portfolio_type').html('Custom');
						$('#portfolio_description dd').remove();
						if(cleanOffset > 0) {
							$('#portfolio_description dt:last-child').before('<dd>Clean energy: ' + (cleanOffset * 1000).toFormattedString() + '</dd>');
						}
						if(farmOffset > 0) {
							$('#portfolio_description dt:last-child').before('<dd>Farm power: ' + (farmOffset * 1000).toFormattedString() + '</dd>');
						}
						if(landfillOffset > 0) {
							$('#portfolio_description dt:last-child').before('<dd>Landfill gas: ' + (landfillOffset * 1000).toFormattedString() + '</dd>');
						}
					} else {
						$('#attrib_SX-TPX-CO2GEN').val($('#total_offset').val() || '');
						$('#attrib_SX-TPX-CO2CLE').val('');
						$('#attrib_SX-TPX-CO2FAR').val('');
						$('#attrib_SX-TPX-CO2LFG').val('');
						totalOffset = parseInt($('#total_offset').val()) || 0;

						$('#portfolio_type').html('Standard');
						$('#portfolio_description dd').remove();
					}

					$('#attrib_SX-PORTCARBON01').val(totalOffset);
					$('#carbon_total_display').html((totalOffset * 1000).toFormattedString());
					TPOffset.updatePriceTotal();

					TPOffset.closeOverlay();
				});

				$('#use_custom_portfolio_no').click(function(){
					if(this.checked) {
						TPOffset.disableCustomPortfolio();
					}
				});

				$('#use_custom_portfolio_yes').click(function(){
					if(this.checked) {
						TPOffset.enableCustomPortfolio();
					}
				});

				$('#total_offset').bind('change', function(){
					var totalPrice, totalOffset;

					if('input[mame=use_custom_portfolio]:checked', $(this.form).val() > 0) {
						var cleanOffset = parseInt($('#clean_offset').val()) || 0;
						var farmOffset = parseInt($('#farm_offset').val()) || 0;
						var landfillOffset = parseInt($('#landfill_offset').val()) || 0;

						var cleanPrice = TPOffset.lookupAttribPrice('SX-TPX-CO2CLE');
						var farmPrice = TPOffset.lookupAttribPrice('SX-TPX-CO2FAR');
						var landfillPrice = TPOffset.lookupAttribPrice('SX-TPX-CO2LFG');

						totalPrice = (cleanOffset * cleanPrice)
						 + (farmOffset * farmPrice)
						 + (landfillOffset * landfillPrice);

						totalOffset = parseInt($(this).val()) || 0;
					} else {
						var genOffset = parseInt($('#total_offset').val()) || 0;
						var genPrice = TPOffset.lookupAttribPrice('SX-TPX-CO2GEN');
						totalPrice = genOffset * genPrice;
					}

					$('#total_offset_price').html('$' + totalPrice.toCurrency());
				});

				// Update UI in overlay

				var totalOffset, cleanOffset, farmOffset, landfillOffset;

				if($('#attrib_SX-TPX-CO2GEN').val() != '') {
					totalOffset = parseInt($('#attrib_SX-TPX-CO2GEN').val()) || 0;
				} else {
					cleanOffset = parseInt($('#attrib_SX-TPX-CO2CLE').val()) || 0;
					farmOffset = parseInt($('#attrib_SX-TPX-CO2FAR').val()) || 0;
					landfillOffset = parseInt($('#attrib_SX-TPX-CO2LFG').val()) || 0;
					totalOffset = cleanOffset + farmOffset + landfillOffset;
				}

				$('#total_offset').val(totalOffset);
				$('#clean_offset').val(cleanOffset);
				$('#farm_offset').val(farmOffset);
				$('#landfill_offset').val(landfillOffset);

				if(evt.target.id == 'change_portfolio') {
					$('#use_custom_portfolio_yes').attr('checked', true).click();
				} else {
					$('#use_custom_portfolio_no').attr('checked', true).click();
				}

				// Update offset price display

				$('#total_offset').change();

			} catch(exc) {
			}
			return false;
		});

		// Open the overlay window that allows the user to customize
		// his/her accessory options

		$('#change_options').click(function(){
			var exc;
			try{
				TPOffset.openOverlay(TPOffset.optionNode);

				// Dynamically build form input values:
				// the user is allowed as many vehicle/home accessories as
				// vehicles/homes that were indicated in the carbon calculator
				// but may select fewer

				for(var i=1; i <= numVehicles; i++) {
					$('#car_decal_count,#bumper_sticker_count').append('<option value="'+ i +'">'+ i +'</option>');
				}
				for(var i=1; i <= numHomes; i++) {
					$('#fridge_magnet_count').append('<option value="'+ i +'">'+ i +'</option>');
				}

				// Update form controls for accessory options

				setTimeout(function(){

					// The following is wrapped in a setTimeout()
					// to avoid an IE6 bug

					$('#car_decal_count').val($('#attrib_SX-TPX-D-DCL').val());
					$('#bumper_sticker_count').val($('#attrib_SX-TPX-D-BMP').val());
					$('#postcard_sticker_count').val($('#attrib_SX-TPX-A-STK').val());
					$('#luggage_tag_count').val($('#attrib_SX-TPX-A-LTG').val());
					$('#fridge_magnet_count').val($('#attrib_SX-TPX-H-FMG').val());
				}, 1);

				// Re-bind events to overlay elements

				$('#save_options').click(function() {
					var numDecals = parseInt($('#car_decal_count').val()) || 0;
					var numBumSticks = parseInt($('#bumper_sticker_count').val()) || 0;
					var numPostSticks = parseInt($('#postcard_sticker_count').val()) || 0;
					var numLugTags = parseInt($('#luggage_tag_count').val()) || 0;
					var numMagnets = parseInt($('#fridge_magnet_count').val()) || 0;

					TPOffset.updateOptions(numDecals, numBumSticks, numPostSticks, numLugTags, numMagnets);
					TPOffset.updatePriceTotal();
					TPOffset.closeOverlay();
				});

			} catch(exc) {
			}
			return false;
		});

		// Set all accessory option quantities to zero

		$('#clear_options').click(function(){
			TPOffset.updateOptions(0, 0, 0, 0, 0);
			TPOffset.updatePriceTotal();
			return false;
		});

		// Save DOM nodes for later use and remove from DOM

		TPOffset.portfolioNode = $('#portfolio_controls').remove().removeClass('hidden').get(0);
		TPOffset.optionNode = $('#option_controls').remove().removeClass('hidden').get(0);
	});
};

TPOffset.openOverlay = function(node, callback) {
	TPCalc.openOverlay(TPOffset.toHTML(node), callback);
};

TPOffset.closeOverlay = TPCalc.closeOverlay;

TPOffset.toHTML = function(node) {
	return $('<div></div>').append($(node)).html();
};

TPOffset.enableCustomPortfolio = function() {

	$('#custom_portfolio').removeClass('hidden').find(':input').removeAttr('disabled');
	$('#total_offset').attr('readonly', 'readonly').addClass('read-only');

	var cleanOffset = $('#clean_offset').val();
	var farmOffset = $('#farm_offset').val();
	var landfillOffset = $('#landfill_offset').val();

	if(cleanOffset == ''
	&& farmOffset == ''
	&& landfillOffset == '') {

		var totalOffset = parseInt($('#total_offset').val()) || 0;
		cleanOffset = Math.floor(TPOffset.DEFAULT_PORTFOLIO_ALLOC.clean * totalOffset);
		farmOffset = Math.floor(TPOffset.DEFAULT_PORTFOLIO_ALLOC.farm * totalOffset);
		landfillOffset = totalOffset - cleanOffset - farmOffset;

		$('#clean_offset').val(cleanOffset);
		$('#farm_offset').val(farmOffset);
		$('#landfill_offset').val(landfillOffset);
		$('#custom_total_offset_display').html( (totalOffset * 1000).toFormattedString() );
	}

	$('#clean_offset,#farm_offset,#landfill_offset').bind('change.customPortfolio', function() {
		var cleanOffset = parseInt($('#clean_offset').val()) || 0;
		var farmOffset = parseInt($('#farm_offset').val()) || 0;
		var landfillOffset = parseInt($('#landfill_offset').val()) || 0;
		var totalOffset = parseInt($('#total_offset').val()) || 0;

		if(cleanOffset + farmOffset + landfillOffset != totalOffset) {
			if($(this).attr('id') != 'landfill_offset') {
				if(cleanOffset + farmOffset + landfillOffset < totalOffset) {
					landfillOffset = totalOffset - cleanOffset - farmOffset;
				} else if(cleanOffset + farmOffset + landfillOffset > totalOffset) {
					var diff = cleanOffset + farmOffset + landfillOffset - totalOffset;
					landfillOffset -= diff;
					if(landfillOffset < 0) {
						diff = Math.abs(landfillOffset);
						landfillOffset = 0;
						farmOffset -= diff;
						if(farmOffset < 0) {
							diff = Math.abs(farmOffset);
							farmOffset = 0;
							cleanOffset -= diff;
							if(cleanOffset < 0) {
								cleanOffset = 0;
							}
						}
					}
				}
			} else {
				alert("Your custom portfolio carbon amounts must total "
				      + totalOffset.toFormattedString() + " lbs.");
				landfillOffset = totalOffset - cleanOffset - farmOffset;
				$('#clean_offset').focus();
			}
			$('#clean_offset').val(cleanOffset);
			$('#farm_offset').val(farmOffset);
			$('#landfill_offset').val(landfillOffset);
		}
		TPOffset.drawPortfolioChart(cleanOffset, farmOffset, landfillOffset);
	});

	TPOffset.drawPortfolioChart(cleanOffset, farmOffset, landfillOffset);

	// If the total offset field is changed, then update the individual
	// offset distribution with new values but preserving the current
	// allocation percentages

	$('#total_offset').bind('change.customPortfolio', function(){
		var cOff = parseInt($('#clean_offset').val()) || 0;
		var fOff = parseInt($('#farm_offset').val()) || 0;
		var lOff = parseInt($('#landfill_offset').val()) || 0;
		var oldTotalOff = cOff + fOff + lOff;
		var newTotalOff = parseInt($(this).val()) || 0;

		var cleanPct = cOff/oldTotalOff || 0;
		var farmPct = fOff/oldTotalOff || 0;
		//var landfillPct = lOff/oldTotalOff || 0;

		var newCleanOff = Math.floor(cleanPct * newTotalOff);
		var newFarmOff = Math.floor(farmPct * newTotalOff);
		var newLandfillOff = newTotalOff - newCleanOff - newFarmOff;

		$('#clean_offset').val(newCleanOff);
		$('#farm_offset').val(newFarmOff);
		$('#landfill_offset').val(newLandfillOff);
		$('#custom_total_offset_display').html( (newTotalOff * 1000).toFormattedString() );

		TPOffset.drawPortfolioChart(newCleanOff, newFarmOff, newLandfillOff);
	});
};

TPOffset.disableCustomPortfolio = function() {
	$('#custom_portfolio').addClass('hidden').find(':input').attr('disabled', 'disabled').val('');
	$('#total_offset').removeAttr('readonly').removeClass('read-only');
	$('#custom_portfolio_chart img').remove();
	$('#total_offset,#clean_offset,#farm_offset,#landfill_offset').unbind('change.customPortfolio');
	$('#custom_total_offset_display').html('');
	$('#total_offset').unbind('change.customPortfolio');
};

TPOffset.updateOptions = function(numDecals, numBumSticks, numPostSticks, numLugTags, numMagnets) {
	$('#attrib_SX-TPX-D-DCL').val(numDecals || '');
	$('#car_decal_count_display').html(numDecals.toFormattedString());
	if(numDecals > 0) {
		$('#car_decal_count_display').parent('li').removeClass('hidden');
	} else {
		$('#car_decal_count_display').parent('li').addClass('hidden');
	}

	$('#attrib_SX-TPX-D-BMP').val(numBumSticks || '');
	$('#bumper_sticker_count_display').html(numBumSticks.toFormattedString());
	if(numBumSticks > 0) {
		$('#bumper_sticker_count_display').parent('li').removeClass('hidden');
	} else {
		$('#bumper_sticker_count_display').parent('li').addClass('hidden');
	}

	$('#attrib_SX-TPX-A-STK').val(numPostSticks || '');
	$('#postcard_sticker_count_display').html(numPostSticks.toFormattedString());
	if(numPostSticks > 0) {
		$('#postcard_sticker_count_display').parent('li').removeClass('hidden');
	} else {
		$('#postcard_sticker_count_display').parent('li').addClass('hidden');
	}

	$('#attrib_SX-TPX-A-LTG').val(numLugTags || '');
	$('#luggage_tag_count_display').html(numLugTags.toFormattedString());
	if(numLugTags > 0) {
		$('#luggage_tag_count_display').parent('li').removeClass('hidden');
	} else {
		$('#luggage_tag_count_display').parent('li').addClass('hidden');
	}

	$('#attrib_SX-TPX-H-FMG').val(numMagnets || '');
	$('#fridge_magnet_count_display').html(numMagnets.toFormattedString());
	if(numMagnets > 0) {
		$('#fridge_magnet_count_display').parent('li').removeClass('hidden');
	} else {
		$('#fridge_magnet_count_display').parent('li').addClass('hidden');
	}

	// Show or hide option groups

	if(numDecals + numBumSticks > 0) {
		$('#options_description dd.road').removeClass('hidden');
	} else {
		$('#options_description dd.road').addClass('hidden');
	}

	if(numPostSticks + numLugTags > 0) {
		$('#options_description dd.air').removeClass('hidden');
	} else {
		$('#options_description dd.air').addClass('hidden');
	}

	if(numMagnets > 0) {
		$('#options_description dd.residential').removeClass('hidden');
	} else {
		$('#options_description dd.residential').addClass('hidden');
	}

	if(numDecals + numBumSticks + numPostSticks + numLugTags + numMagnets > 0) {
		$('dl#options_description dd.none').remove();
	} else if($('dl#options_description dd.none').length < 1) {
		$('dl#options_description dt').eq(0).after('<dd class="none"><em>None selected</em></dd>');
	}
};

TPOffset.lookupAttribPrice = function(attrCode) {

	for(var i=0, numAttribs=TPOffset.ATTRIBUTES.length; i < numAttribs; i++) {
		if(attrCode == TPOffset.ATTRIBUTES[i].code) {
			return TPOffset.ATTRIBUTES[i].price;
		}
	}
	return 0;
};

TPOffset.updatePriceTotal = function() {
	var numAttribs = TPOffset.ATTRIBUTES.length;
	var qty, total = 0.00;

	for(var i=0; i < numAttribs; i++) {
		qty = parseInt($('#attrib_' + TPOffset.ATTRIBUTES[i].code).val()) || 0;
		total += qty * TPOffset.ATTRIBUTES[i].price;
	}

	$('#total_price').html('$' + total.toCurrency());
};

TPOffset.drawPortfolioChart = function(cleanOffset, farmOffset, landfillOffset) {

	var totalOffset = cleanOffset + farmOffset + landfillOffset;
	var cleanPct = Math.floor((cleanOffset / totalOffset || 0) * 100);
	var farmPct = Math.floor((farmOffset / totalOffset || 0) * 100);
	var landfillPct = 100 - cleanPct - farmPct;

	var cleanLabel = "Clean energy (" + cleanPct + "%)";
	var farmLabel = "Farm power (" + farmPct + "%)";
	var landfillLabel = "Landfill gas (" + landfillPct + "%)";

	var cleanColor = '3c094a';
	var farmColor = '79ae3e';
	var landfillColor = '357ca2';

	var data = {};
	if(cleanPct > 0) {
		data[cleanLabel] = {value: cleanPct, color: cleanColor};
	}
	if(farmPct > 0) {
		data[farmLabel]  = {value: farmPct, color: farmColor};
	}
	if(landfillPct > 0) {
		data[landfillLabel] = {value: landfillPct, color: landfillColor};
	}

	var imgUrl = TPOffset.buildPortfolioChartUrl(data);
	var altText = 'Clean energy '+cleanOffset+', Farm power '+farmOffset+', Landfill gas '+landfillOffset;

	$('#custom_portfolio_chart')
	  .find('img').remove().end()
	  .append('<img src="'+imgUrl+'" alt="'+altText+'">');
};

TPOffset.buildPortfolioChartUrl = function(data) {

	var width = 400;
	var height = 100;
	var type = "p3";

	var url = "http://chart.apis.google.com/chart";

	url += "?chs=" + width + "x" + height;
	url += "&cht=" + type;

	var dataVal = '', labelVal = '', colorVal = '';

	for(var key in data) {
		if(dataVal != '') {
			labelVal += '|';
			dataVal += ',';
			colorVal += ',';
		}
		labelVal += encodeURIComponent(key);
		dataVal += data[key].value;
		colorVal += data[key].color;
	}

	url += "&chl=" + labelVal;
	url += "&chd=t:" + dataVal;
	url += "&chco=" + colorVal;

	return url;
};

// End TPOffset //

})();
