//load in the the external car data.
var carData, rawData;
var pageInited = false, docReady = false;
//var polkServiceURL = "http://mercedescalculator.clemengerdigital.com.au/jsonp_service.php";
var polkServiceURL = "http://www.calc.mercedes-benz.com.au/jsonp_service.php";
var polkServiceRequest = false;// current request ID;
var polkServiceTimout;
var polkServiceRetries = 5;
var polkServiceAttempt;
var polkServiceParams;
var currentModelButton;
if (typeof(animDuration) == "undefined") animDuration = 500;
var overlayOpacity = 0.7;
$.ajax({
	   url:"csv/cardata.csv",
	   success:function(data) {
		   rawData = data;
		   carData = csvToArray(data);
		   if (!pageInited && docReady) init();
	   },
	   error:function(error) {
		   alert("Error getting car data: " + error);
	   }
	}
);

jQuery.fn.extend({ 
        disableSelection : function() { 
                this.each(function() { 
                        this.onselectstart = function() { return false; }; 
                        this.unselectable = "on"; 
                        jQuery(this).css('-moz-user-select', 'none').css('-webkit-user-select', 'none').css('-khtml-user-select', 'none').css('user-select', 'none'); 
                }); 
        } 
}); 

$(document).ready(function() {
	docReady = true;
	if (typeof(carData) != "undefined") init();
});
function init() {
	$("#step3").hide();
	//Reset to default state on page load.
	$('#choose-state select').find('option:first').attr('selected', 'selected').parent('select');
	
	//Overlay and disclaimer show & hide
	var state_select = $(".state_select");
	
	$('#choose-state select').change(function() {
		var val = $(this).val();
		var state = ["", "ACT", "NSW", "NT", "QLD", "SA", "TAS", "WA", "VIC"][this.selectedIndex];
		if (Number(val)) {
			state_select.hide();
			$("." + state).show();
		}
		$(".costing_state").html(state + " ");
		if (this.selectedIndex == 2 || this.selectedIndex == 4) {
			$(".cost_combined").hide();
			$(".cost_separate").show();
		} else {
			$(".cost_combined").show();
			$(".cost_separate").hide();
		}
		if (currentModelButton) currentModelButton.click();
		if(val == 0) {
			$('#overlay').fadeTo(animDuration, overlayOpacity);
			$("#step3").slideUp(animDuration);
		} else {
			$('#overlay').fadeOut(animDuration);
		}
		$(window).focus();
	});

	//Detect active container height and set overlay to match
	var overlay = $('#overlay');
	overlay.css("opacity", overlayOpacity);
	overlay.height($('#active-container').height() + 4);
	overlay.css("top", ($("#active-container").offset().top - 2) + "px");
	
	//$(".costing_state").html("");
	//$("#model-select div").remove();
	//$("#costing_title").html("");
	$("#slider-gallery").disableSelection(); 
	
	pageInited = true;
}

function displayModelVariants(index) {
	$("#step3").slideDown(animDuration, function() {
		if ($("#model-select").offset().top > $(window).height() + $(window).scrollTop() - 200) {
			$.scrollTo("#active-container", animDuration, {axis:'y'});
		}
	});
	//$("#costings").hide();
	var modelList = ["smart fortwo", "B-Class Sports Tourer", "C-Class Sedan", "C-Class Estate", "C-Class Coup%E9", "SLK-Class Roadster", "E-Class Sedan", "E-Class Estate", "E-Class Coup%E9", "E-Class Cabriolet", "CLS-Class Coup%E9", "M-Class SUV", "R-Class SUV Tourer", "GL-Class SUV", "G-Class SUV", "S-Class Saloon", "CL-Class Coup%E9", "SL-Class Roadster", "SLS AMG", "Viano Multi-Purpose Vehicle"];
	//var modelList = ["smart fortwo", "B-Class Sports Tourer", "C-Class Sedan", "C-Class Estate", "CLC-Class Sports Coup%E9", "SLK-Class Roadster", "E-Class Sedan", "E-Class Estate", "E-Class Coup%E9", "E-Class Cabriolet", "CLS-Class Coup%E9", "M-Class SUV", "R-Class SUV Tourer", "GL-Class SUV", "S-Class Sedan", "CL-Class Coup%E9", "SL-Class Roadster", "SLS AMG", "Viano Multi-Purpose Vehicle"];
	//var modelList = ["smart fortwo", "B-Class", "C-Class Sedan", "C-Class Estate", "CLC Coup%E9", "SLK-Class", "E-Class Sedan", "E-Class Estate", "E-Class Coup%E9", "CLS-Class", "M-Class", "R-Class", "GL-Class", "S-Class", "CL-Class", "SL-Class", "Viano"];
	//var modelList = ["smart fortwo", "B-Class", "C-Class Saloon", "C-Class Estate", "CLC Coup%E9", "SLK-Class", "E-Class Sedan", "E-Class Coup%E9", "CLS-Class", "M-Class", "R-Class", "GL-Class", "S-Class", "CL-Class", "SL-Class", "Viano"];
	var model = modelList[index];
	$("#model-select h3").html(htmlFriendly(model));
	$("#model-select div").remove();
	var first;
	for (i = 0, il = carData.length; i < il; i++) {
		if (carData[i][0] != null &&  
			carData[i][0].indexOf(model) == 0) {
			var variant = carData[i];
			var button = createVariantButton(model, variant);
			if (!first) first = button;
			$("#model-select").append(button);
		}
	}
	first.click();
	
}

function createVariantButton(modelName, details) {
	//return $('<div class="model active"><h5>' + htmlFriendly(modelName) + '</h5><p>' + htmlFriendly(details[0].substring(modelName.length)) + '</p></div>').click(function() {
	return $('<div class="model active"><h5>' + htmlFriendly(details[0].substring(modelName.length)) + '</h5></div>').click(function() {
		var self = $(this);
		currentModelButton = self;
		self.parent().find('.model.active').removeClass('active');
		self.addClass('active');
		$("#costing_title").html('<h5>' + htmlFriendly(modelName) + '</h5><p>' + htmlFriendly(details[0].substring(modelName.length)) + '</p>');
		polkServiceParams = details;
		polkServiceAttempt = 0;
		
		var testDrive = $(".test-drive");
		
		if(modelName == "SLS AMG")
		{
			$(".test-drive").hide();
		} else {
			$(".test-drive").show();
		}
		
		//$("#costings").fadeIn("slow");
		calculatePrice();
	}).hover(function() {
		$(this).find('h5').prepend($("<span class='calc'>Calculate</span>"));										
	},function () {
		$(this).find("span:last").remove();
	});
}
function htmlFriendly(str) {// get rid of eacutes and egraves from strings
	return str.replace("%E9", "&eacute;");
}

// create global identifier of current service request detail, refer to it in ajax callback and abort if not current;
function calculatePrice() {

	$("#cost_MLP").html("");
	$("#cost_dealer").html("");
	$("#cost_LCT").html("");
	$("#cost_totalReg").html("");
	$("#cost_reg").html("");
	$("#cost_CTP").html("");
	$("#cost_stampduty").html("");
	$("#cost_driveaway").html("<img src='css/imgs/loading.gif' width='16' height='16' /> Calculating");
	
	var data = new Object();
	
	data.Postcode = $("#sel-postcode").val();
	data.MLP = polkServiceParams[1];
	data.OptionsPrice = polkServiceParams[2];
	data.DealerDeliveryCharge = polkServiceParams[3];
	data.DriveAwayCalculationFlag = polkServiceParams[4];
	data.HybridVehicle = polkServiceParams[5];
	data.PrivateOrBusinessUse = polkServiceParams[6];
	data.VehicleTareWeight = polkServiceParams[7];
	data.EngineCapacity = polkServiceParams[8];
	data.NumberOfCylinders = polkServiceParams[9];
	data.CombinedCyclefuelConsumption = polkServiceParams[10];
	data.InsurerCode = polkServiceParams[11];
	data.ElectricVehicle = polkServiceParams[12];
	data.GVR = polkServiceParams[13];
	
	/*if (polkServiceRequest) {
		if (polkServiceRequest.readyState == 1) {
			try {
				polkServiceRequest.abort();
			} catch(e) {
			}
		}
	}*/
	polkServiceRequest = data.Postcode;
	for (var i = 0, il = polkServiceParams.length; i < il; i++) polkServiceRequest += polkServiceParams[i];
	polkServiceRequest = polkServiceRequest.replace(/\W/g, "");
	
	//See if request is cached. If so, retreive it
	if (polkServiceParams["p" + data.Postcode]) {
		parseResult(polkServiceParams["p" + data.Postcode]);
		if (typeof(polkServiceTimout) != "undefined") clearTimeout(polkServiceTimout);
		return;
	}
	
	function parseResult(output) {
		$("#cost_MLP").html(dollarFormat(output.MLP));
		$("#cost_dealer").html(dollarFormat(output.DealerDeliveryFee));
		$("#cost_LCT").html(dollarFormat(output.LCT));
		$("#cost_totalReg").html(dollarFormat(output.TotalRegistration));
		$("#cost_reg").html(dollarFormat(output.RegistrationAmount));
		$("#cost_CTP").html(dollarFormat(output.CTPAmount));
		$("#cost_stampduty").html(dollarFormat(output.StampDuty));
		$("#cost_driveaway").html(dollarFormat(output.VehicleDriveAwayPrice));
	}
	var requestId = polkServiceRequest;
	$.ajax({
		url:polkServiceURL,
		type:"GET",
		dataType:'jsonp',
		jsonp:'callback',
		data:data,
		success:function(result) {
			//console.log(result);
			//The requestId is a local variable that will be unique to this callback. polkServiceRequest is a global variable who's value changes to the most recent request
			//Therefore when the callback runs, the requestId will not equal the polkServiceRequest if a more recent request was made and no updates will occur.
			if (requestId == polkServiceRequest) {
				var output = result.PriceCalculationResult.Output;
				polkServiceParams["p" + data.Postcode] = output;
				parseResult(output);
				clearTimeout(polkServiceTimout);
			}
		}
	});
	if (polkServiceAttempt < polkServiceRetries) {
		polkServiceAttempt++;
		if (typeof(polkServiceTimout) != "undefined") clearTimeout(polkServiceTimout);
		polkServiceTimout = setTimeout(calculatePrice, 10000);
	} else {
		/*if (polkServiceRequest) if (polkServiceRequest.readyState == 1) {
				try {
					polkServiceRequest.abort();
				} catch(e) {
			}
		}*/
		if (confirm("Connection to the calculator server failed. Retry?")) {
			polkServiceAttempt = 0;
			calculatePrice();
		}
	}
}
function dollarFormat(str) {
	var n = Number(str); //Get the number
	var s = String(Math.round(n * 100)); //Move decimal to the end of the cents and round off the rest
	while (s.length < 3) { //If the number is small or zero, add preceding "0"s
		s = "0" + s;
	}
	s = s.substring(0, s.length - 2) + "." + s.substr(s.length - 2); //Add the decimal point back in as a string (dividing by 100 may not work if there are no cents)
	var rs = "";
	var sl = s.length;
	var i_old = sl;
	for (var i = sl - 6; i > -3; i -= 3) {
		if (i_old != sl) rs = "," + rs;
		rs = s.substring(Math.max(0, i), i_old) + rs;
		i_old = i;
	}
	return "$" + rs;
}

//Take standard CSV formatting and turn it into a two dimensional array of strings
function csvToArray(s) {
	var a = s.split(/[\f\r\n]+(?=(?:[^"]*"[^"]*")*(?![^"]*"))/g);
	for (var i = 0, il = a.length; i < il; i++) {
		a[i] = a[i].split(/,(?=(?:[^"]*"[^"]*")*(?![^"]*"))/g);
		for (var j = 0, jl = a[i].length; j < jl; j++) {
			a[i][j] = a[i][j].replace(/"(?!")/g, '');
			a[i][j] = a[i][j].replace(/["]{2}/g, '\"');
		}
	}
	return a;
}

//Scroller class
function CarScroller() {
		
	//Configuration of the magnification effect
	var smallScale = CarScroller.allowScaling ? 0.6 : 1; // The size of the unfocused item in the carousel. 0 is shrunk to nothing, 1 is original size.
	var largeScale = CarScroller.allowScaling ? 1 : 1; // The size of the focused item is the carousel.
	var focusRange = 0; //The number of items either side of the focused item affected by the magnification effect.
	var selectFunction = function(index) { //The function that is called whenever an item is selected. An index of the selected item is passed in
		//console.log(index);
		displayModelVariants(index);
	}
	
	//layout constants
	var galleryHeight = 135; // The height of the gallery area so that the vertical padding for the images can be calculated to keep the images centered.
	var liMargins = 10; //The margin separating each image.
	var scrollBgMargins = 19; //The space on either end of the scroll background that is not included in the clickable area.
	
	//internal variables used by the carousel
	var gallery, carousel, imgs, hotLinks, imgCount, lowFocus, currentFocus, highFocus, focusRange, focusIndex = 0, selectedIndex = -1, magnifyRange;
	var scrollBar, moveFn, scrollRange, offsetMouseX, offsetBar = 19, scrollTargetOld = 0, mouseX, scrollTimer, scrolling, intervalTime = 33;
	
	var inst = this;
	
	this.init = function() {
		
		//Set up references to dom elements
		gallery = $("#slider-gallery");
		carousel = gallery.find("ul.items");
		var imgs_pngfix = $("#slider-gallery li shape"); // If the DD_belatedPNG has been employed to fix transparency in IE6, assign the mouse events to the li rather than the img.
		if (imgs_pngfix.length) {
			imgs = gallery.find("li");
		} else {
			imgs = gallery.find("img");
		}
		hotLinks = $("#slider-bar span");
		var galWidth = gallery.find("ul.items").width();
		var currentWidth = 0;
		//Set up variables for magnifications and scroll position
		imgCount = imgs.length;
		magnifyRange = (1 + focusRange) / imgCount;
		imgs.each(function(i) {
			var self = $(this);
			self.data("orig_width", self.width());
			self.data("orig_height", self.height());
			self.data("index", i);
			self.data("orig_pos", ((self.data("orig_width") / 2) + currentWidth) / galWidth);
			self.data("hotlink", $(hotLinks[i]));
			currentWidth += self.data("orig_width") + liMargins;
		});
		imgs.css("cursor", "pointer");
		lowFocus = $(imgs[0]).data("orig_pos");
		currentFocus = lowFocus;
		highFocus = $(imgs[imgCount - 1]).data("orig_pos");
		focusRange = highFocus - lowFocus;
		//Initialize the scrollbar UI
		var scrollCanvas = $("#slider-bar");
		scrollBar = scrollCanvas.find(".handle");
		scrollBar.css("cursor", "pointer");
		scrollRange = scrollCanvas.width() - scrollBar.width();
		//Add scrollbar mouse events
		scrollBar.mousedown(function(e) {
			scrolling = true;
			$(document).disableTextSelect();
			$(document).bind("mousemove", inst.moveFn);
			$(document).bind('mouseup', inst.releaseScrollBar);
			inst.moveFn(e);
			offsetMouseX = (mouseX + offsetBar) - scrollBar.position().left;
			scrollTargetOld = mouseX - offsetMouseX;
			clearInterval(scrollTimer);
			scrollTimer = setInterval(inst.scrollFn, intervalTime);
			return false;
		}).click(function() {
			return false; //Stops the click bubbling down to the $("#slider-bar").click event handler
		});
		var scrollVal;
		scrollCanvas.mousedown(function(e) {
			var self = $(this);
			scrollVal = (e.pageX - (self.offset().left + scrollBgMargins)) / (self.width() - scrollBgMargins * 2);
			if (scrollVal > 0 && scrollVal < 1) {
				scrolling = true;
				$(document).disableTextSelect();
				$(document).bind("mousemove", inst.moveFn);
				$(document).bind('mouseup', inst.releaseScrollBar);
				offsetMouseX = ((scrollBar.width() / 2) + $(this).offset().left) + offsetBar;
				inst.moveFn(e);
				scrollTargetOld = scrollBar.position().left;
				clearInterval(scrollTimer);
				scrollTimer = setInterval(inst.scrollFn, intervalTime);
				return false;
			}
		}).click(function(e) {
			//This code selects the car and displays the variants
			/*if (scrollVal < 0) { //On prev arrow
				$(hotLinks[Math.max(0, selectedIndex - 1)]).click();
			} else if (scrollVal > 1) { //On next arrow
				$(hotLinks[Math.min(selectedIndex + 1, hotLinks.length - 1)]).click();
			}*/
			//This code scrolls to the next visible car but does no selection.
			if (scrollVal < 0) { //On prev arrow
				focusIndex = Math.max(0,focusIndex - 1);
			} else if (scrollVal > 1) { //On next arrow
				focusIndex = Math.min(focusIndex + 1, imgs.length - 1);
			} else {
				return;
			}
			mouseX = $(imgs[focusIndex]).data("scroll_pos");
			offsetMouseX = 0;
			clearInterval(scrollTimer);
			scrollTimer = setInterval(inst.scrollFn, intervalTime);
		});

		//Initialize scrollbar hotlinks. If the following hotLinks event handlers are disabled, then clicks on them will be translated to the $("#slider-bar") above.
		hotLinks.each(function(i) {
			var self = $(this);
			self.data("index", i);
			self.data("img", $(imgs[i]));
			self.click(function() {
				var index = $(this).data("index");
				mouseX = $(imgs[index]).data("scroll_pos");
				offsetMouseX = 0;
				inst.selectItem(index);
				selectFunction(self.data("index"));
				clearInterval(scrollTimer);
				scrollTimer = setInterval(inst.scrollFn, intervalTime);
				return false; //Stops the click bubbling down to the $("#slider-bar").click event handler
			}).hover(function() {
				if (!scrolling) $(this).addClass("over");
			},
			function() {
				$(this).removeClass("over");
			}).mousedown(function(e) {
				return false;
			});
		});/**/
		
		//Setup the starting scrollposition and magnification as well as calculating the scrollposition for each element. Also make each item clickable
		imgs.each(function() {
			var self = $(this);
			self.data("scroll_pos", ((self.data("orig_pos") - lowFocus) / focusRange) * scrollRange);
			inst.sizeImg(self);
			self.click(function() {
				var self = $(this);
				mouseX = self.data("scroll_pos");
				offsetMouseX = 0;
				if (self.data("index") != selectedIndex) {
					inst.selectItem(self.data("index"));
				}
				selectFunction(self.data("index"));
				clearInterval(scrollTimer);
				scrollTimer = setInterval(inst.scrollFn, intervalTime);
			});
		});
		//inst.selectItem(0);
		gallery.find("ul.items").css("visibility", "");
	}
	
	//Tracks the mouse position for the scrollbar while the mouse is down
	this.moveFn = function(e) {
		mouseX = e.pageX;
	}
	//The scrolling engine positions the scrollbar and detects when to clear the timer
	this.scrollFn = function() {
		var target = scrollTargetOld + ((mouseX - offsetMouseX - scrollTargetOld) / 10);
		var scrollBarPos = Math.max(offsetBar, Math.min(target + offsetBar, scrollRange + offsetBar));
		if (!scrolling && Math.round(target * 100) == Math.round(scrollTargetOld * 100)) {
			clearInterval(scrollTimer);
			//console.log("scroll stop");
		}
		scrollTargetOld = target;
		scrollBar.css("left", scrollBarPos + "px");
		var scrollVal = (scrollBarPos - offsetBar) / scrollRange;
		currentFocus = lowFocus + (focusRange * scrollVal);
		imgs.each(function() {
			inst.sizeImg($(this));
		});
		carousel.css("left", -((carousel.width() - gallery.width()) * scrollVal) + "px");
		//console.log(mouseX, offsetMouseX, scrollTargetOld);
	}
	//Finds the nearest gallery item relating to the input position (based on the mouse position)
	this.snapToItem = function(inputPos) {
		var searchIndex = Math.max(0, Math.min(Math.round((inputPos / scrollRange) * (imgCount - 1)), imgCount - 1));
		var outputPos = $(imgs[searchIndex]).data("scroll_pos");
		var searchDir = (2 * (inputPos > outputPos)) - 1;
		var breaker = 0;
		while (Math.abs(inputPos - $(imgs[searchIndex]).data("scroll_pos")) > Math.abs(inputPos - $(imgs[Math.max(0, Math.min(searchIndex + searchDir, imgCount - 1))]).data("scroll_pos"))) {
			searchIndex += searchDir
			if (++breaker > 10) break;
		}
		outputPos = $(imgs[searchIndex]).data("scroll_pos");
		focusIndex = searchIndex;
		return outputPos;
	}
	//Simply unsets the events that are set on mousedown
	this.releaseScrollBar = function() {
		$(document).enableTextSelect();
		$(document).unbind('mousemove', inst.moveFn);
		$(document).unbind('mouseup', inst.releaseScrollBar);
		mouseX = inst.snapToItem(mouseX - offsetMouseX);
		offsetMouseX = 0;
		//inst.selectItem(focusIndex);
		//selectedIndex = index;
		scrolling = false;
	}
	//Select Item
	this.selectItem = function(index) {
		selectedIndex = index;
		focusIndex = selectedIndex;
		hotLinks.removeClass("selected");
		$(hotLinks[index]).addClass("selected");
		//selectFunction(index);
	}
	//Sizes the images using the smallScale, largeScale and focus range based on the currentFocus value which is based on the position of the scrollbar
	this.sizeImg = function(img) {
		var focusDiff = Math.abs(currentFocus - img.data("orig_pos"));
		var scale = smallScale + ((largeScale - smallScale) * (Math.max(0, magnifyRange - focusDiff) / magnifyRange));
		img.css("width", img.data("orig_width") * scale);
		img.css("height", img.data("orig_height") * scale);
		var margin_tb = (galleryHeight - img.height()) / 2;
		img.css("margin-top", margin_tb).css("margin-bottom", margin_tb);
	}
}
//Static function 
CarScroller.allowScaling = true;
CarScroller.noScaling = function() {
	CarScroller.allowScaling = false;
}
