var JSON;JSON||(JSON={}); (function(){function k(a){return a<10?"0"+a:a}function o(a){p.lastIndex=0;return p.test(a)?'"'+a.replace(p,function(a){var c=r[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function l(a,j){var c,d,h,m,g=e,f,b=j[a];b&&typeof b==="object"&&typeof b.toJSON==="function"&&(b=b.toJSON(a));typeof i==="function"&&(b=i.call(j,a,b));switch(typeof b){case "string":return o(b);case "number":return isFinite(b)?String(b):"null";case "boolean":case "null":return String(b);case "object":if(!b)return"null"; e+=n;f=[];if(Object.prototype.toString.apply(b)==="[object Array]"){m=b.length;for(c=0;c<m;c+=1)f[c]=l(c,b)||"null";h=f.length===0?"[]":e?"[\n"+e+f.join(",\n"+e)+"\n"+g+"]":"["+f.join(",")+"]";e=g;return h}if(i&&typeof i==="object"){m=i.length;for(c=0;c<m;c+=1)typeof i[c]==="string"&&(d=i[c],(h=l(d,b))&&f.push(o(d)+(e?": ":":")+h))}else for(d in b)Object.prototype.hasOwnProperty.call(b,d)&&(h=l(d,b))&&f.push(o(d)+(e?": ":":")+h);h=f.length===0?"{}":e?"{\n"+e+f.join(",\n"+e)+"\n"+g+"}":"{"+f.join(",")+ "}";e=g;return h}}if(typeof Date.prototype.toJSON!=="function")Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+k(this.getUTCMonth()+1)+"-"+k(this.getUTCDate())+"T"+k(this.getUTCHours())+":"+k(this.getUTCMinutes())+":"+k(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()};var q=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, p=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,e,n,r={"\u0008":"\\b","\t":"\\t","\n":"\\n","\u000c":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},i;if(typeof JSON.stringify!=="function")JSON.stringify=function(a,j,c){var d;n=e="";if(typeof c==="number")for(d=0;d<c;d+=1)n+=" ";else typeof c==="string"&&(n=c);if((i=j)&&typeof j!=="function"&&(typeof j!=="object"||typeof j.length!=="number"))throw Error("JSON.stringify");return l("", {"":a})};if(typeof JSON.parse!=="function")JSON.parse=function(a,e){function c(a,d){var g,f,b=a[d];if(b&&typeof b==="object")for(g in b)Object.prototype.hasOwnProperty.call(b,g)&&(f=c(b,g),f!==void 0?b[g]=f:delete b[g]);return e.call(a,d,b)}var d,a=String(a);q.lastIndex=0;q.test(a)&&(a=a.replace(q,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)}));if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return d=eval("("+a+")"),typeof e==="function"?c({"":d},""):d;throw new SyntaxError("JSON.parse");}})();
 
/* Autoedit generic library
 * 
 */

var AE = (function(d, w){
	"use strict";

	// Array.indexOf method
	if (!Array.prototype.indexOf) {
		Array.prototype.indexOf = function(elt /*, from*/) {
			var len = this.length,
				from = Number(arguments[1]) || 0;
			from = (from < 0) ? Math.ceil(from) : Math.floor(from);
			if (from < 0) from += len;
			for (; from < len; from++) {
				if (from in this && this[from] === elt)
					return from;
			}
			return -1;
		};
	}
	
	// Array.lastIndexOf method	
	if (!Array.prototype.lastIndexOf) {
		Array.prototype.lastIndexOf = function(elt /*, from*/) {
			var len = this.length,
				from = Number(arguments[1]);
			if (isNaN(from)) {
				from = len - 1;
			} else {
				from = (from < 0) ? Math.ceil(from) : Math.floor(from);
				if (from < 0)
					from += len;
				else if (from >= len)
					from = len - 1;
			}
			for (; from > -1; from--) {
				if (from in this &&
					this[from] === elt)
						return from;
			}
			return -1;
		};
	}
	
	// hide broken images
	function hideBrokenImages(el, alt) {
		if (el && el.tagName) {
			$('img', el).one('error', function () { 
				if (alt) {
					this.src = alt;
				} else {
					this.style.visibility = "hidden";					
				}
			});
		}
	}
	
	// get and set cookies
	var cookieHandler = (function() {
		function setCookie(name, value, days) {
			var date, expires = "";
			if (days) {
				date = new Date();
				date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
				expires = "; expires=" + date.toGMTString();
			}
			d.cookie = name + "=" + escape(value) + expires + "; path=/"; //safari doesn't like the unescaped val
		}
		function getCookie(name) {
			var cookieArr, cookie, i = 0;
			name += "=";
			cookieArr = d.cookie.split(';');
			for (; i < cookieArr.length; i++) {
				cookie = cookieArr[i];
				while (cookie.charAt(0) === ' ') {
					cookie = cookie.substring(1, cookie.length);
				}
				if (cookie.indexOf(name) === 0) {
					return unescape(cookie.substring(name.length, cookie.length));
				}
			}
			return null;
		}
		return {
			set: setCookie,
			get: getCookie
		}
	}());
	
	// search panel handler (jQuery)
	var searchPanelHandler = function() {
		var panel = d.getElementById('pnlSearchTabs'),
			tabs,
			$tabLI;
		if (panel) {
			tabs = panel.getElementsByTagName('UL')[0],
			$tabLI = $('li', tabs);
			$tabLI.live('click', function(){
				var tabType = this.innerHTML.split(' Cars')[0];
				if (tabType.toLowerCase() == "new") { window.location.href = "/new-cars.aspx"; return false; } // to be removed
				d.getElementById('radVehicle' + tabType).checked = true;
				$tabLI.removeClass('active');
				this.className = 'active';
				panel.className = 'searchpanel col-inner ' + tabType.toLowerCase();
			});
		}
	};

	// map direction handler 1.1 (jQuery)
	// + added inline target to dest url
	// + pass dest as param
	var autoDirections = function(dest){
		var mapInput = (function(){
				var el = d.getElementById('map_query');
				return (el && el.tagName === 'INPUT') ? el : null;
			}()),
			queryString = (function () {
				var queryArr = window.location.search.substr(1).split('&'),
					queryObj = {},
					temp,
					i;
				for (i in queryArr) {
					if (queryArr.hasOwnProperty(i)) {
						temp = queryArr[i].split('=');
						queryObj[temp[0]] = temp[1];
					}
				}
				return queryObj;
			}()); 
		if (mapInput && queryString && queryString.origin) {
			mapInput.value = unescape(queryString.origin);
			if (typeof submitMapQuery === 'function')
				submitMapQuery();
		} 
		$('#dirButton').live('click', function(){
			window.location.href = '/' + dest + '?origin=' + $('#dirInput').val() + '#directionsPanel';
			return false;
		});
	};
	
	// car compare 1.1
	// + rewrote the logic from the ground up
	// + added templates for markup
	// + store original garage markup
	var carCompareHandler = (function() {
			
		var o = {
			"cookie": {
				"compare": {
					"name": "AEcompare",
					"json": false
				}
			},
			"garage": {
				"targ": "myGarage",
				"el": false,
				"max": 4,
				"old": false,
				"template": "<div class=\"{{class}}\" id=\"garage-{{id}}\"><img src=\"http://images.autoexposure.co.uk/AETA48051/{{id}}_1a.jpg\"><div class=\"titles\"><h4>{{a}}</h4><span class=\"price\">{{g}}</span></div><div class=\"controls\"><a class=\"button cta\" href=\"/vehicle.aspx?id={{id}}\">view</a><a id=\"garageRemove-{{id}}\" class=\"addToGarage remove button undo\">remove</a></div></div>",
				"wrapper": "{{inner}}<a href=\"#\" id=\"myGarageCompare\" class=\"button cta\">Compare {{count}} cars now</a>",
				"popup": {
					"full": "<div class=\"popup\">Garage full!</div>"
				}
			},
			"compare": {
				"wrapper": "<table class=\"compare\"><tr><th class=\"title\" colspan=\"2\">Comparing <span id=\"compareCount\">{{count}}</span> cars</th><th>Doors</th><th>Bodystyle</th><th>Colour</th><th>Mileage</th><th>Year</th><th colspan=\"2\">Price</th></tr>{{inner}}</table>",
				"template": "<tr class=\"{{class}}\" id=\"compare-{{id}}\"><td><img class=\"photo\" src=\"http://images.autoexposure.co.uk/AETA48051/{{id}}_1a.jpg\"></td><td class=\"model\">{{a}}</td><td class=\"doors\">{{b}}</td><td class=\"body\">{{c}}</td><td class=\"colour\">{{d}}</td><td class=\"miles\">{{e}}</td><td class=\"year\">{{f}}</td><td class=\"price\">{{g}}</td><td><a class=\"button cta\" href=\"/vehicle.aspx?id={{id}}\">view</a></td></tr>"
			},
			"curtain": {
				"targ": "carCompareCurtain",
				"template": "<div id=\"carCompareCurtain\" class=\"curtain\"></div>"
			}
		};
		
		// construct a list of cars using markup specified in JSON.
		function buildHTML(context) {
			var vehicle, 
				vehicleObj,
				vehicleHTML = '',
				vehicleProperty,
				vehicleCount = 0,
				returnHTML = '',
				strReplace;
			for (vehicle in o.cookie.compare.json) {
				if ((o.cookie.compare.json.hasOwnProperty(vehicle)) && (vehicleCount < o.garage.max)) {
					vehicleHTML = o[context].template.replace(/{{id}}/gi, vehicle).replace(/{{class}}/gi, ((vehicleCount%2) ? 'car even' : 'car odd'));
					vehicleObj = o.cookie.compare.json[vehicle];
					for (vehicleProperty in vehicleObj) {
						strReplace = '{{'+vehicleProperty+'}}';
						vehicleHTML = vehicleHTML.replace(strReplace, vehicleObj[vehicleProperty]);
					}
					returnHTML += vehicleHTML;
					vehicleCount++;
				}
			}
			if (vehicleCount <= 0) {
				return false;
			} else if (o[context].wrapper) {
				returnHTML = o[context].wrapper.replace(/{{inner}}/gi, returnHTML);
			}
			return returnHTML.replace(/{{count}}/gi, vehicleCount);
		}
				
		// populate the MyGarage element if it's present - persistent object was causing issues so we re-grab the el each time.
		function populateGarage() {
			var garageHTML,
				garageEL = d.getElementById(o.garage.targ);
			if (garageEL && o.cookie.compare.json) {
				garageHTML = buildHTML('garage');
				if (!o.garage.old)
					o.garage.old = garageEL.innerHTML; // store base value
				if (!garageHTML)
					garageHTML = o.garage.old; // reset base value
				garageEL.innerHTML = garageHTML;
			}
			hideBrokenImages(garageEL);	
		}
	
		// show the popup and prime JSON
		function showCurtain(curtainHTML) {
			var curtain = o.curtain.el || d.getElementById(o.curtain.targ);
			if (!curtainHTML)
				return false;
			if (!curtain) {
				d.body.innerHTML += o.curtain.template;
				curtain = d.getElementById(o.curtain.targ);
				o.curtain.el = curtain;				
			} else {
				curtain.style.display = "block";
			}
			curtain.innerHTML = curtainHTML + '<a href="javascript:void(0)" class="closeCurtain">close</a>';
			hideBrokenImages(curtain);	
		}
		
		// grab by id from cardata global var and update the cookie
		function addRemoveCar(carID) {
			var jsonLen = (function(){
					var jsonObj, l = 0;
					for (jsonObj in o.cookie.compare.json) { l++; }
					return l;
				}());
			if (!o.cookie.compare.json) 
				o.cookie.compare.json = {};
			if (!o.cookie.compare.json || !o.cookie.compare.json[carID]) {
				if (jsonLen < o.garage.max) {
					o.cookie.compare.json[carID] = cardata[carID]; // add
				} else {
					showCurtain(o.garage.popup.full); // full
				}
			} else {
				delete o.cookie.compare.json[carID]; // remove
			}
			populateGarage();
			cookieHandler.set(o.cookie.compare.name, JSON.stringify(o.cookie.compare.json), 365);
		}

		// update all buttons from json (run once onload)
		function updateSearchResultButtons() {
			var carID, 
				buttonEl;
			for (carID in o.cookie.compare.json) {
				buttonEl = d.getElementById('addtogarage-'+carID)
				if (buttonEl) {
						buttonEl.className = "addToGarage button remove";
						buttonEl.innerHTML = "-";
				}
			}
		}
				
		// toggle specific button state and update json + cookie
		function setButtonState(el){
			var newClass = "remove",
				oldClass = "add",
				newText = "-",
				carID = el.id.split('-')[1];
			if (o.cookie.compare.json[carID]) {
				newClass = "add";
				oldClass = "remove";
				newText = "+";
			}
			$('#addtogarage-'+carID)
					.addClass(newClass)
					.removeClass(oldClass)
					.text(newText);
			addRemoveCar(carID);					
		}

		// jQuery binds
		function eventBinds() {
			$('#carCompareCurtain').live('click', function(e){
				if (e.target.id == 'carCompareCurtain')
					this.style.display = "none";
			});
			$('#myGarageCompare').live('click', function(e){
				e.preventDefault();
				showCurtain(buildHTML('compare'));
			});			
			$('a.addToGarage').live('click', function(e){
				e.preventDefault();
				setButtonState(e.target);
			});
			$('a.closeCurtain').live('click', function(e){
				$('#carCompareCurtain')
					.html('')
					.hide();
			});
		}
			
		function initialiseCarCompare(){
			var cookieData = cookieHandler.get(o.cookie.compare.name);
			if (cookieData)
				o.cookie.compare.json = JSON.parse(cookieData);
			eventBinds();
			populateGarage();
			d.body.className += " carCompare";
			updateSearchResultButtons();
		}
		
		return {
			init: initialiseCarCompare
		}
	}());
	
	// init page
	var initialiseJS = function() {
		autoDirections('location.aspx');
		//searchPanelHandler();
		carCompareHandler.init();
	};
	
	// expose funcitons
	return {
		init: initialiseJS
	}
	
}(document, this));

// lite showcase 1.2
// + added state.inProgress
// + fixed callback timings
// + fixed position tracking
// + made transform more robust
$.fn.liteShowcase = function(options) {
	return this.each(function() {   
		$.liteShowcase(this, options);
	});
};
$.liteShowcase = function (container, options) {
	"use strict";

	var $el = $(container),
		$cache = $el.children(),
		config = {
			"el": $el[0],
			"parentId": $el[0].parentNode.id,
			"position": 0,
			"timeout": 7000,
			"speed": 1000,
			"transition": "fade",
			"pagination": false,
			"prevnext": false,
			"counter": 0
		},
		state = {
			"pause": false,
			"inProgress": false
		},
		$page = $('#' + config.parentId + '-pagination');

	document.body.className += " liteShowcase";	
		
	// merge in use-selected options json
	$.extend(config, options);
	
	// allow transform selection by name 
	// TODO: eval method was nasty, tried this[config.transition] but it wasn't working
	// properly because i couldn't easily expose values from within $. so we're left with this.
	if (typeof config.transition === 'string') { 
		switch (config.transition) {
			case 'swipe':
				config.transition = transitionSwipe;
				break;
			case 'shrink':
				config.transition = transitionShrink;
				break;
			default:
				config.transition = transitionFade;
		}
	}
	
	function updatePagination(newPos) {
		$page.find('li')
			.removeClass('active')
			.eq(newPos)
			.addClass('active');
	}
	
	function applyTransition(newPos, direction) {
		if ($('li.active', config.el).queue('fx').length === 0) {
			if ($el.is(':visible') && document.hasFocus && !state.inProgress && !state.pause) {
				var newPos = (newPos === false) ? ((config.position < $cache.length-1) ? config.position + 1 : 0) : newPos,
					$oldEl = $('li.active', config.el),
					$newEl = $cache.eq(newPos);						
				state.inProgress = true;
				clearTimeout(config.auto);
				config.transition($oldEl, $newEl, newPos, function(){
					if (config.pagination)
						updatePagination(newPos);
					state.inProgress = false;
					++config.counter;														
				});
				config.position = newPos;		
			}
			config.auto = setTimeout(function(){ applyTransition(false) }, config.timeout);
		}
	}
	
	function createPagination() {
		var html = '<ul id="'+config.parentId+'-pagination" class="pagination">', i;
		for (i = 0; i < $cache.length; i++) {
			html += '<li' + ((i===0) ? ' class="active"' : '') + '><a href="#">'+(i+1)+'</a></li>';
		}
		html += '</ul>';
		$('#'+config.parentId).append(html);
		$page = $('#'+config.parentId+'-pagination');
	}
	
	function bindPagination() {
		$page.find('a').bind({
			click: function(e) {
				var newPos = parseInt(this.innerHTML, 10) - 1;
				e.preventDefault();
				if (newPos !== config.position) {
					applyTransition(newPos);
				}
			}
		});
	}
	
	function createPrevNext() {
		var html = '<a href="#" class="prev">&lt;</a><a href="#" class="next">&gt;</a>';
		$('#'+config.parentId).append(html);
	}
	
	function bindPrevNext() {
		$('#'+config.parentId).find('a').bind({
			click: function(e) {
				var valSet = true, newPos;
				switch (this.className) {
					case 'prev':
						newPos = config.position - 1;
						break;
					case 'next':
						newPos = config.position + 1;
						break;
					default:
						valSet = false;
				}
				if (valSet) {
					e.preventDefault();
					if (newPos >= $cache.length) {
						newPos = 0;
					} else if (newPos < 0) {
						newPos = $cache.length-1;
					}
					applyTransition(newPos);
				}
			}
		});
	}

	// simple fade transition
	function transitionFade($oldEl, $newEl, newPos, callback) {
			$oldEl.stop().fadeTo(config.speed, 0).removeClass('active');
			$newEl.stop().fadeTo(config.speed, 1, function(){
				callback();
			}).addClass('active');
	}

	// ugly shrink transition
	function transitionShrink($oldEl, $newEl, newPos, callback) {
			$oldEl.stop().css({'z-index':'100','box-shadow':'5px 5px 10px #000'}).animate({height:'0', width:'0'}, config.speed,function(){
				$oldEl.hide().css({height:'100%', width:'100%', 'box-shadow':'none'});
				callback();
			}).removeClass('active');
			$newEl.stop().css({'z-index':'99'}).show().addClass('active');
	}
	
	// split/clone horizontal fadeout transition
	function transitionSwipe($oldEl, $newEl, newPos, callback) {
			var clones = 9,
				speedModifier = 250,
				elWidth = $oldEl.width(),
				elHeight = $oldEl.height(),
				animA = {'opacity':'0'},
				animB = {'margin-top':'250px'},
				$elArr,
				a,
				i,
				$strays = $('li.clone', $el);
			if ($strays.length > 0)
				$strays.remove(); // clean up
			for (i=1; i<=clones; i++) {
				a = $oldEl.clone(true);
				a[0].style.clip = 'rect(0px,'+((elWidth/(clones))*i)+'px,'+elHeight+'px,0px)';
				a[0].style.zIndex = 100;
				a[0].className = 'clone';
				$oldEl.after(a);
			}
			$oldEl.removeClass('active').hide();
			$newEl.css({'z-index':'99'});
			$elArr = $('li.clone', $oldEl[0].parentNode);
			for (i=0; i<$elArr.length; i++) {
				/*
				$($elArr[i]).fadeTo(config.speed + (speedModifier * i), 0, function(){
					$(this).remove();
					if (i >= $elArr.length) {
						callback();		
					}
				});
				*/
				$($elArr[i]).animate(animA, config.speed + (speedModifier * i), function(){
					$(this).remove();
					if (i >= $elArr.length) {
						callback();		
					}
				})			
			}
			$newEl.show().addClass('active');
	}
	
	if (config.pagination === true && $page.length === 0) {
		createPagination();
	}
	
	if (config.prevnext === true) {
		bindPrevNext();
	}	
		
	if ($page.length > 0) {
		bindPagination();
	}
		
	$cache.each(function(i){
		this.style.position = "absolute";
		this.zIndex = i;
		if (i >= 1) {
			this.style.display = "none";
		} else {
			this.className = "active";
		}
	});

	config.auto = setTimeout(function(){ applyTransition(false); }, config.timeout);
};

/*
 * 	Panelflow test build
 */

var panelFlow = (function(w, d) {
	"use strict";
	
	var el = d.getElementById('pnlSearchTabs'), 
		$el = $(el),
		$w = $(w),
		$d = $(d),
		baseOffset, 
		clientHeight, 
		docHeight,		
		offsetModifier = 10,
		scrollStart = false,
		scrollTimer;

	function findOffTop(el) {
		// find the true offset top of element
		var offTop = 0;
		if (el.offsetParent) {
			do {
				offTop += el.offsetTop;
			} while (el = el.offsetParent);
		}
		return offTop;
	}			

	function scrollHandler(reset) {
		var scrollAmount = d.body.scrollTop || d.documentElement.scrollTop,
			heightTo = (scrollAmount - baseOffset) + offsetModifier,
			retVal = 0;
		if (!reset) {
			if ( ( docHeight - $w.height()) > heightTo ) {
				if (scrollAmount > baseOffset) {
					retVal = heightTo;
				}
				$(el)
					.stop()
					.animate({
						marginTop: retVal
					}, 'fast');
			}
		} else {
			el.style.marginTop = "0px";
		}
	}

	function activateScroll() {
		scrollStart = true;
		// once the scroll is active we can detach these
		if (w.removeEventListener) {
			w.removeEventListener('scroll', activateScroll, false); 
		} else if (w.detachEvent) {			
			w.detachEvent('scroll', activateScroll);
		} else {			
			w.onscroll = null;
		}
	}
	
	if (el && d.body.id === "bodySearch") {
		baseOffset = findOffTop(el);
		docHeight = $d.height();		
		// force reset on scroll handler if the window is not in desktop
		scrollTimer = setInterval(function() {
			if (scrollStart && $w.width() > 768) {
				scrollHandler();
			} else {
				scrollHandler(true);
			}
		}, 500);
		// attach trigger for scrollable pages
		if (w.addEventListener) {
			w.addEventListener('scroll', activateScroll, false);		
		} else if (w.attachEvent) {
			w.attachEvent('scroll', activateScroll);
		} else {
			w.onscroll = activateScroll();
		}
	}
	
}(this, document));

/* onload events
 * 
 */

$(function(){
	$('#showcaseHome').find('ul').liteShowcase({"transition":"swipe"});
	AE.init();
});

