var CORE = function () {
	return {};
}();

CORE.Utils = function () {
	var that = arguments.callee.prototype;
	that.getJson = function (settings, callback) {
		if (arguments[0].constructor != Object) settings = {};
		if (!settings.data) settings.data = '';
		if (!settings.url) return alert('No url provided.');
		if (!settings.dataType) settings.dataType = 'json';
		$.ajax({
			type: 'POST',
			url: settings.url,
			data: 'ajax=1&' + settings.data,
			dataType: settings.dataType,
			timeout: 15 * 1000, // quit trying after 5 secs
			success: function (data) {
				if (callback) callback(data);
			},
			error: function (xhr, status, error) {
				if (settings.error) {
					settings.error();
				} else {
					alert(status);
				}
			},
			complete: function () {
				if (settings.complete) settings.complete();
			}
		});
	};
	that.getCookie = function (name) {
		var i,x,y,ARRcookies=document.cookie.split(";");
		for (i=0;i<ARRcookies.length;i++) {
			x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
			y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
			x=x.replace(/^\s+|\s+$/g,"");
			if (x==name) return unescape(y);
		}
	};
	that.setCookie = function (name, value, exdays) {
		var exdate = new Date();
		exdate.setDate(exdate.getDate() + exdays);
		var val = escape(value) + ((exdays==null) ? "" : "; expires=" + exdate.toUTCString());
		document.cookie = name + "=" + val;
	}
	that.inArray = function (valOrArray, arr) {
		var i = arr.length;
		while (i--) if (arr[i] == valOrArray) return true;
		return false;
	};
	that.arrayIntersect = function (a1, a2) {
		var res = [];
		var i = a1.length;
		var j;
		while (i--) {
			j = a2.length;
			while (j--) {
				if (a1[i] == a2[j]) res.push(a1[i]);
			}
		}
		return res;
	};
	that.arrayDiff = function (a1, a2) {
		var res = [];
		var i = a1.length;
		var j, isMatch;
		while (i--) {
			j = a2.length;
			isMatch = false;
			while (j--) if (a1[i] == a2[j]) isMatch = true;
			if (!isMatch) res.push(a1[i]);
		}
		return res.reverse();
	};
	that.fixButton = function (isValid, button) {
		var isDisable = true;
		var opacity = 0.7;
		if (isValid) {
			isDisable = false;
			opacity = 1;
		}
		button.attr('disabled', isDisable).css('opacity', opacity);
	};
	that.prepareFormPop = function (link) {
		//window.location.hash = '';
		var href = link.attr('href');
		var url = (/#scheduleTestDrive/.test(href)) ? '/shopping-tools/schedule-test-drive' : '/shopping-tools/get-quote';
		var vars = href.split(',');
		if (vars.length > 1) {
			url += '?dealerCode=' + vars[1];
		} else {
			vars = href.split(';');
			if (vars.length > 1) url += '?cartID=' + vars[1];
			if (vars.length > 2) url += '&vehicleID=' + vars[2];
		}
		var popup = new CORE.Popup('', false);
		popup.open(CORE.wwwroot + url, function () {
			var mainForm = new CORE.FormHandler({
				selector: '#mainForm',
				isHaltOnSuccess: true,
				callback: function () {
					$('#mainForm').fadeOut(function () {
						var container = $(this);
						container.find('#success').remove();
						container.empty().prepend('<div id="success">Thanks! Your information has been successfully submitted.</div>').fadeIn(function () {
							setTimeout(function () {
								popup.close();
							}, 2000);
						});
					});
				}
			});
			var dealerForm = new CORE.FindDealerForm('#findDealerForm');
		});
	};
};

CORE.TopNav = function () {
	var that = arguments.callee.prototype;
	var opts = (arguments.length > 0 && arguments[0].constructor == Object) ? arguments[0] : {};
	if (!opts.popSelector) opts.popSelector = '#topPop';
	var isPopOpen = false;
	var isMouseOver = false;
	var isSupressClosing = false;
	var activeItem = null;
	var timer = null;
	function init() {
		$(document).click(function (e) {
			var target = $(e.target);
			//if (target.hasClass('navLink')) {
			//	e.preventDefault();
			//	openPop(target);
			//} else
			if (target = $(this)) {
				closePop();
			}
		});
		$('.navLink').mouseenter(function (e) {
			openPop($(this));
			isMouseOver = true;
		});
		$('#nav, #extraNav').mouseleave(function () {
			closePop();
			isMouseOver = false;
		}).mouseenter(function () {
			isMouseOver = true;
		});
	}
	function openPop(obj, callback) {
		if (activeItem != obj.text() || !isPopOpen) {
			isPopOpen = true;
			activeItem = obj.text();
			resetLinks();
			obj.parent().addClass('active');
			var utils = new CORE.Utils();
			var header = obj.closest('#nav, #extraNav');
			//obj.css('color', '#666').closest('li').append('<span class="preloader"></span>');
			//header.find(opts.popSelector).remove();
			//setTimeout(function () {
			utils.getJson({
				dataType: 'text',
				url: obj.attr('href')
			}, function (data) {
				if (isMouseOver) {
					header.find(opts.popSelector).remove();
					//obj.css('color', '#fff').closest('li').addClass('active').find('.preloader').remove();
					var pageID = obj.attr('id').replace(/[^0-9]+/, '');
					var content = header.find(opts.popSelector).find('.content').css('position', 'relative');
					updateContent(header.append(data).find(opts.popSelector), pageID);
					if (callback) callback();
				}
			});
			//}, 2000);
		}
	}
	function closePop() {
		if (!isSupressClosing) {
			$('#header').find(opts.popSelector).remove();
			resetLinks();
			isPopOpen = false;
			activeItem = null;
		}
	}
	function shift(obj, toX, callback) {
		var time = 500;
		obj.animate({
			left: toX
		}, time, function() {
			if (callback) callback();
		});
	}
	function setupVanEvents(obj) {
		return false;
	}
	function setupDealerEvents(obj) {
		var dd = $('#state');
		dd.focus(function () {
			if (timer) clearTimeout(timer);
			isSupressClosing = true;
			//$('#state').unbind('change').change(function (e) {
		}).blur(function () {
			supressClosing();
		});
	}
	function supressClosing() {
		isSupressClosing = true;
		if (timer) clearTimeout(timer);
		timer = setTimeout(function () {
			isSupressClosing = false;
			if (!isMouseOver) closePop();
			$(opts.popSelector).unbind('mouseleave');
		}, 2000);
	}
	function setupShoppingEvents(obj) {
		$('#extraNav').find('a').eq(1).click(function (e) {
			e.preventDefault();
		});
		$(opts.popSelector).find('.content').click(function (e) {
			var target = $(e.target);
			if (target.attr('href') && /#(getQuote|scheduleTestDrive)/.test(target.attr('href'))) {
				e.preventDefault();
				var utils = new CORE.Utils();
				utils.prepareFormPop(target);
			}
		});
	}
	function setupOwnersEvents(obj) {
		var pop = $(opts.popSelector);
		var tabs = pop.find('ul a');
		tabs.click(function (e) {
			e.preventDefault();
			tabs.removeClass('active');
			var obj = $(this);
			obj.addClass('active');
			if (obj.hasClass('enroll')) {
				pop.find('.content:visible').fadeOut(function () {
					$('#enrollForm').fadeIn();
				});
			} else if (obj.hasClass('sign-in')) {
				pop.find('.content:visible').fadeOut(function () {
					$('#loginForm').fadeIn();
				});
			}
		});
		pop.find('.forgot').click(function (e) {
			e.preventDefault();
			tabs.removeClass('active');
			pop.find('.content:visible').fadeOut(function () {
				$('#forgotForm').fadeIn();
			});
		});
	}
	function updateContent(container, pageID) {
		var item = container.click(function (e) {
			e.stopPropagation();
		});
		item.find('.content').eq(0).show();
		if (pageID == 22) { // find dealer
			setupDealerEvents(item);
		} else if (pageID == 4) { // shopping tools
			setupShoppingEvents(item);
		} else if (pageID == 5) { // owners
			setupOwnersEvents(item);
		} else { // van links
			setupVanEvents(item);
		}
	}
	function resetLinks() {
		$('#nav, #extraNav').find('li').removeClass('active');
	}
	init();
};

CORE.Slider = function () {
	var that = arguments.callee.prototype;
	var opts = (arguments[0].constructor == Object) ? arguments[0] : {};
	if (!opts.selector) opts.selector = arguments[0];
	if (!opts.stripeSelector) opts.stripeSelector = '.content';
	var startX = null;
	var posX = null;
	var objW = null;
	var shiftVal = null;
	var maxW = null;
	var currentPage = 0;
	function init() {
		var box = $(opts.selector);
		if (box.length > 0) {
			var container = box.find(opts.stripeSelector);
			container.css('left', container.position().left);
			if (container.length > 0) {
				var items = container.find('a');
				if (items.eq(1).length > 0) {
					shiftVal = items.eq(1).position().left - items.eq(0).position().left;
				} else {
					shiftVal = items.eq(0).width();
				}
				startX = container.position().left;
				posX = startX;
				objW = shiftVal * (items.length); //container.width();
				maxW = box.width();
				$(document).click(function (e) {
					var target = $(e.target);
					if (target.hasClass('prev')) {
						e.preventDefault();
						shift('prev', 1);
					} else if (target.hasClass('next')) {
						e.preventDefault();
						shift('next', 1);
					} else if (target.hasClass('sliderNavLink')) {
						e.preventDefault();
						var index = target.parent().find('a').index(target);
						if (currentPage != index) {
							var offset = currentPage - index;
							var direction = (offset < 0) ? 'next' : 'prev';
							shift(direction, Math.abs(offset));
						}
					}
				});
				var a = container.find('a');
				a.each(function () {
					showCaption($(this));
				});
				var pages = Math.ceil(objW / maxW);
				if (pages > 1) {
					var html = '<div id="sliderNav">';
					for (var i = 0; i < pages; i++) html += '<a href="" class="sliderNavLink">' + (i + 1) + '</a>';
					html += '</div>';
					html = $(html);
					html.find('a').eq(0).addClass('active');
					box.after(html);
				}
				adjustNav();
			}
		}
	}
	function showCaption(obj) {
		var alt = obj.find('img').attr('alt');
		if (alt.length > 0) {
			var caption = obj.append('<div class="caption"><div class="text">' + alt + '</div><div class="bg"></div></div>').find('.caption').hide().fadeIn();
			caption.find('.bg').height(caption.height());
		}
	}
	function hideCaption(obj) {
		obj.find('.caption').fadeOut(function () {
			$(this).remove();
		});
	}
	function shift(direction, offset, callback) {
		var time = 500;
		var moveX = getShiftSize(direction, offset);
		if (moveX !== 0) {
			posX += moveX;
			var obj = $(opts.selector).find(opts.stripeSelector);
			obj.animate({
				left: '+=' + moveX
			}, time, function() {
				adjustNav();
				if (callback) callback();
			});
		}
	}
	function getShiftSize(direction, offset) {
		var moveX = 0;
		var itemsPerSpan = Math.floor(maxW / shiftVal);
		var shiftX = itemsPerSpan * shiftVal * offset;
		if (direction == 'next') {
			var minX = startX - objW + itemsPerSpan * shiftVal;
			moveX = (posX - shiftX < minX) ? posX - minX : shiftX;
			moveX = -moveX;
		} else {
			var maxX = startX;
			moveX = (posX + shiftX > maxX) ? maxX - posX : shiftX;
		}
		return moveX;
	}
	function adjustNav() {
		var container = $(opts.selector).parent();
		var prev = container.find('.prev').removeClass('active').css('cursor', 'default');
		var next = container.find('.next').removeClass('active').css('cursor', 'default');
		if (getShiftSize('prev', 1) != 0) {
			prev.addClass('active').css('cursor', 'pointer');
		}
		if (getShiftSize('next', 1) != 0) {
			next.addClass('active').css('cursor', 'pointer');
		}
		var nav = $('#sliderNav');
		if (nav.length > 0) {
			var pageIndex = Math.ceil(Math.abs(posX - startX) / maxW);
			currentPage = pageIndex;
			nav.find('a').removeClass('active').eq(pageIndex).addClass('active');
		}
	}
	init();
};

CORE.TopGallery = function () {
	var that = arguments.callee.prototype;
	var opts = (arguments[0].constructor == Object) ? arguments[0] : {};
	if (!opts.selector) opts.selector = arguments[0];
	if (!opts.urls) opts.urls = [];
	if (!opts.index) opts.index = 0;
	if (!opts.delay) opts.delay = 5;
	that.timer = null;
	var imgSelector = '#topPromoImg';
	var contentSelector = '#topPromoContent';
	var navSelector = '#topPromoNav';
	var headerSelector = '#topPromoSide';
	var isMouseOver = false;
	function init() {
		that.play();
		var main = $('#wrapper3');
		main.prepend(makeNav()).find(navSelector).css('left', parseInt(((main.width() - $(navSelector).width()) / 2) + 132, 10) + 'px');
		$(document).click(function (e) {
			var target = $(e.target);
			if (/#slide[0-9]+/.test(target.attr('href'))) {
				e.preventDefault();
				var index = target.attr('href').replace('#slide', '');
				that.show(index);
			}
		});
	}
	function addHover(obj) {
		obj.unbind('hover');
		obj.hover(function () {
			isMouseOver = true;
			that.stop();
		}, function () {
			isMouseOver = false;
			that.play();
		});
	}
	that.show = function (i, callback) {
		i = parseInt(i);
		that.stop();
		var nav = $(navSelector).find('.wrapper');
		nav.find('a').removeClass('active');
		nav.find('a').eq(i).addClass('active');
		//alert(i + ' ' + nav.find('a').eq(i).attr('href'));
		if (opts.urls[i]) {
			var url = opts.urls[i];
			try {
			$.ajax({
				type: 'GET',
				url: url,
				//data: 'ajax=1',
				//dataType: 'json',
				//timeout: 5 * 1000, // quit trying after 5 secs
				success: function (data) {
					opts.index = i;
					var timing = 1000;
					data = $('<div>' + data + '</div>');
					var oldImg = $(imgSelector);
					var oldContent = $(contentSelector);
					//var oldHeader = $(headerSelector);
					if (oldContent.length > 0) {
						oldContent.unbind('hover');
						oldContent.fadeOut(timing);
					}
					oldImg.fadeOut(timing, function () {
						oldImg.remove();
						oldContent.remove();
						//oldHeader.remove();
					});
					var newImg = data.find(imgSelector);
					var newContent = data.find(contentSelector);
					//var newHeader = data.find(headerSelector);
					if (newContent.length > 0) {
						$('#wrapper3').prepend(newContent);
						newContent.fadeIn(timing, function () {
							addHover(newContent);
						});
					}
					
					$('#wrapper1').prepend(newImg);
					newImg.fadeIn(timing, function () {
						if (callback) callback();
					});
					//$('.txtPromo').attr('src', newHeader.attr('src'));
					//$('.txtPromo').fadeIn(timing);
					
				},
				error: function (xhr, status, error) {
					alert(status + ' ' + error + ' ' + url);
				},
				complete: function () {
					
				}
			});
			} catch (e) {
				// most likely timeout error
			}
		}
		//window.location.hash = 'showing' + i;
	};
	that.nextIndex = function (i) {
		var num = opts.urls.length;
		return (i < num - 1) ? i + 1 : 0;
	};
	that.wait = function () {
		that.stop();
		if (!isMouseOver) {
			that.timer = setTimeout(function () {
				that.show(that.nextIndex(opts.index), that.wait);
			}, opts.delay * 1000);
		}
	};
	that.stop = function () {
		if (that.timer) clearTimeout(that.timer);
	};
	that.play = function () {
		//window.location.hash = 'playing' + index;
		that.show(opts.index, that.wait);
	};
	function makeNav() {
		var html = '';
		html += '<div id="' + navSelector.replace('#', '') + '"><div class="wrapper">';
		var cssClass = 'first';
		for (var i = 0; i < opts.urls.length; i++) {
			cssClass += (i == opts.index) ? ' active' : '';
			html += '<a href="#slide' + i + '" class="' + cssClass + '"></a>';
			cssClass = '';
		}
		html += '</div></div>';
		return html;
	}
	init();
};

CORE.Gallery = function () {
	var that = arguments.callee.prototype;
	var opts = (arguments[0].constructor == Object) ? arguments[0] : {};
	if (!opts.selector) opts.selector = arguments[0];
	opts.popSelector = '#galleryPop';
	opts.overlaySelector = '#pageOverlay';
	opts.isCloseOnClickOut = true;
	opts.transitionTime = 0.2; // secs
	that.currentIndex = 0;
	init();
	function init() {
		var gallery = $(opts.selector);
		if (gallery.length > 0) {
			gallery.find('img').closest('a').each(function () {
				$(this).append('<div class="zoomer"></div>');
			});
			$(document).click(function (e) {
				var target = $(e.target);
				if (target.hasClass('thumb')) {
					e.preventDefault();
					that.open(target.attr('href'), target);
					that.currentIndex = gallery.find('a:visible').index(target);
				} else if (target.parent().hasClass('thumb')) {
					e.preventDefault();
					that.open(target.parent().attr('href'), target.parent());
					that.currentIndex = gallery.find('a:visible').index(target.parent());
				} else if (target.hasClass('galleryPrev')) {
					e.preventDefault();
					prev();
				} else if (target.hasClass('galleryNext')) {
					e.preventDefault();
					next();
				} else if (target.hasClass('galleryClose')) {
					close();
				}
			});
			$(document).keyup(function(e) {
				if (e.keyCode == 27) { // esc
					close();
				}
			});
			$(window).bind('resize scroll', function () {
				position();
			});
			checkboxSetup();
		}
	}
	function checkboxSetup() {
		var container = $('#content');
		container.find('.types input').click(function () {
			var val = $(this).val();
			var thumbs = container.find('.thumb');
			if (val == 0) {
				thumbs.show();
			} else {
				thumbs.hide();
				thumbs.filter('.type' + val).show();
			}
		});
	}
	function next() {
		show(that.currentIndex + 1);
	}
	function prev() {
		show(that.currentIndex - 1);
	}
	function show(index) {
		var gallery = $(opts.selector);
		var total = gallery.find('img').closest('a:visible').length;
		if (index >= 0 && index < total) {
			var pop = $(opts.popSelector);
			var obj = gallery.find('img').closest('a:visible').eq(index);
			var url = obj.attr('href') + '?random=' + (new Date()).getTime();
			pop.find('.image').attr('src', url).load(function () {
				pop.find('.preloader').remove();
				pop.find('.wrapper').empty().append('<strong>' + decode(obj.attr('title')) + '</strong><div class="description">' + decode(obj.find('img').attr('alt')) + '</div>');
				position();
				that.currentIndex = index;
				var nextButton = pop.find('.galleryNext').show();
				var prevButton = pop.find('.galleryPrev').show();
				if (index >= total - 1) {
					nextButton.hide();
				} else if (index == 0) {
					prevButton.hide();
				}
			});
		}
	}
	function position() {
		var pop = $(opts.popSelector);
		var overlay = $(opts.overlaySelector);
		if (pop.length > 0) {
			var w = $('body').width();
			var h = $(document).height();
			var popW = pop.width();
			var popH = pop.height();
			pop.css({
				left: Math.floor($(window).scrollLeft() + ($(window).width() - popW) / 2) + 'px',
				top: Math.floor($(window).scrollTop() + ($(window).height() - popH) / 2) + 'px'
			});
			overlay.width(w);
			overlay.height(h);
		}
	}
	function makePop() {
		$(opts.popSelector + ', ' + opts.overlaySelector).remove();
		$('body').append('<div id="' + opts.popSelector.replace('#', '') + '"><div class="content"><div class="wrapper"></div></div><a href="" class="galleryPrev"></a><a href="" class="galleryNext"></a><a href="" class="galleryClose"></a></div><div id="' + opts.overlaySelector.replace('#', '') + '"></div>');
		var pop = $(opts.popSelector).hide();
		pop.find('.galleryClose').click(function (e) {
			e.preventDefault();
			close();
		});
		var overlay = $(opts.overlaySelector).css('opacity', 0.8).hide().click(function (e) {
			e.preventDefault();
			if (opts.isCloseOnClickOut) close();
		});
	}
	function close() {
		var pop = $(opts.popSelector).remove();
		$(opts.overlaySelector).fadeOut(opts.transitionTime * 1000, function () {
			$(this).remove();
		});
	}
	that.open = function(url, obj) {
		makePop();
		var pop = $(opts.popSelector).fadeIn(opts.transitionTime * 1000).append('<div class="preloader"></div>');
		if (obj) pop.find('.wrapper').empty().append('<strong>' + decode(obj.attr('title')) + '</strong><div class="description">' + decode(obj.find('img').attr('alt')) + '</div>');
		$(opts.overlaySelector).fadeIn(opts.transitionTime * 1000);
		url += '?random=' + (new Date()).getTime();
		//setTimeout(function () {
		var img = pop.prepend('<img src="' + url + '" border="0" alt="" class="image" />').find('.image');
		position();
		img.attr('src', url).load(function () {
			pop.find('.preloader').remove();
			position();
			var total = $(opts.selector).find('img').closest('a:visible').length;
			var nextButton = pop.find('.galleryNext').show();
			var prevButton = pop.find('.galleryPrev').show();
			if (that.currentIndex >= total - 1) {
				nextButton.hide();
			} else if (that.currentIndex == 0) {
				prevButton.hide();
			}
		});
		//}, 2000);

	}
	function decode(str) {
		return unescape(str).replace(/[+]+/g, ' ');
	}
};

CORE.ShareStoryGallery = function () {
	var that = new CORE.Gallery(arguments[0]);
	var opts = {};
	opts.selector = arguments[0];
	that.currentIndex = 0;
	var imgNum = 0;
	init();
	function init() {
		var gallery = $(opts.selector);
		gallery.append('<a href="" class="next active"></a><a href="" class="prev active"></a><div class="caption"></div><div class="counter"></div>');
		var imgs = gallery.find('img').parent().addClass('thumb');
		imgNum = imgs.length;
		show(that.currentIndex, true);
		$(document).click(function (e) {
			var target = $(e.target);
			if (target.hasClass('prev')) {
				e.preventDefault();
				prev();
			} else if (target.hasClass('next')) {
				e.preventDefault();
				next();
			} else if (target.hasClass('thumb')) {
				e.preventDefault();
				var pop = new CORE.Gallery('');
				//alert(target.parent().attr('href'));
				pop.open(target.parent().attr('href'), target.parent());
			}
		});
	}
	function prev() {
		if (that.currentIndex > 0) show(that.currentIndex - 1);
	}
	function next() {
		if (that.currentIndex < imgNum - 1) show(that.currentIndex + 1);
	}
	function show(index, isStart) {
		if (index != that.currentIndex || isStart) {
			var gallery = $('#storyGallery');
			var img = gallery.find('img').hide().eq(index).show();
			gallery.find('.caption').html(img.attr('alt'));
			gallery.find('.counter').html((index + 1) + '/' + imgNum);
			that.currentIndex = index;
			gallery.find('.zoomer').hide().eq(index).show();
			var prev = gallery.find('.prev');
			if (!prev.hasClass('active')) prev.addClass('active');
			var next = gallery.find('.next');
			if (!next.hasClass('active')) next.addClass('active');
			if (index == 0) {
				gallery.find('.prev').removeClass('active');
			} else if (index == imgNum - 1) {
				gallery.find('.next').removeClass('active');
			}
		}
	}
};

CORE.Map = function () {
	var that = arguments.callee.prototype;
	var opts = (arguments[0].constructor == Object) ? arguments[0] : {};
	if (!opts.selector) opts.selector = '#map';
	if (!opts.markerSelector) opts.markerSelector = '#mbMarker';
	if (!opts.zoom) opts.zoom = 2;
	if (!opts.lat) opts.lat = 40;
	if (!opts.lng) opts.lng = -101;
	var utils = new CORE.Utils();
	that.map = null;
	that.markers = [];
	that.activeMarker = null;
	that.myDealerCode = utils.getCookie('myDealer');
	that.highestZ = 100;
	that.isMarkerSliding = false;
	that.addMarkers = function (markers) {
		if (that.map != null) {
			for (var i = 0; i < markers.length; i++) addMarker(markers[i], i);
		} else {
			setTimeout(function () {
				that.addMarkers(markers);
			}, 100);
		}
	};
	function addMarker(markerOpts, key) {
		var marker = new MQA.Poi({lat: markerOpts.lat, lng: markerOpts.lng});
		var icon = new MQA.Icon(CORE.wwwroot + '/images/icons/marker.png', 44, 60);
		marker.setIcon(icon);
		marker.setIconOffset({x: -22, y: -60});

		//var marker = new MQA.HtmlPoi({lat: markerOpts.lat, lng: markerOpts.lng});
		marker.key = key;
		that.highestZ = that.highestZ + key;
		marker.zIndex = that.highestZ;
		marker.title = markerOpts.title;

		//marker.setInfoTitleHTML(markerOpts.title);
		marker.titleVisible = false;
		marker.dealerCode = markerOpts.code;
		var html = '<strong class="title">' + markerOpts.title + '</strong>';
		html += '<div class="address">';
		if (markerOpts.address) html += markerOpts.address + '<br />';
		if (markerOpts.city && markerOpts.state) html += markerOpts.city + ', ' + markerOpts.state;
		if (markerOpts.zip) html += ' ' + markerOpts.zip;
		html += '</div>';
		html += '<div class="phones">';
		if (markerOpts.phone) html += '<div class="phones">Phone: ' + markerOpts.phone;
		if (markerOpts.fax) html += '<br />Fax: ' + markerOpts.fax;
		html += '</div>';
		if (opts.type == 'dealers') {
			if (markerOpts.mileage) html += '<div class="mileage">' + markerOpts.mileage + ' mi</div>';
			html += '<div class="options"><a href="javascript:window.mqMap.makeMyDealer(\'' + marker.dealerCode + '\')" class="makeMyDealer">Make My Dealer</a><br /><a href="http://www.mapquest.com/directions?2c='+escape(markerOpts.city)+'&2s='+escape(markerOpts.state)+'&2a='+escape(markerOpts.address)+'&2z='+escape(markerOpts.zip)+'" target="_blank">Get Directions</a></div>';
			html += '<div class="buttons">';
			html += '<a href="#getQuote,' + marker.dealerCode + '" class="button">Get a Quote</a>';
			html += '<a href="#scheduleTestDrive,' + marker.dealerCode + '" class="button">Request a Test Drive</a>';
			if (markerOpts.website) html += '<a href="http://' + markerOpts.website + '" target="_blank" class="button external">Visit Dealer Site</a>';
			html += '</div>';
		} else if (opts.type == 'events') {
			html += '<div class="dates">';
			if (markerOpts.dates) html += markerOpts.dates;
			html += '</div>';
			html += '<div class="options">';
			if (markerOpts.website) html += '<a href="http://' + markerOpts.website + '" target="_blank">View Event Site</a><br />';
			html += '<a href="javascript:void(0)">Add to My Calendar</a>';
			html += '</div>';
		}
		marker.setInfoContentHTML('<div class="mapOverlay">' + html + '</div>');
		marker.setRolloverContent('<em></em>'); // empty html not to show hover
		//marker.toggleInfoWindow();
		that.map.addShape(marker);
		MQA.EventManager.addListener(marker, 'mouseover', function (e) {
			showMarker(e.srcObject);
		});
		MQA.EventManager.addListener(marker, 'mouseout', function (e) {
			hideMarker(e.srcObject);
		});
		MQA.EventManager.addListener(marker, 'click', function (e) {
			showMarkerInfo(e.srcObject.key);
		});
		that.markers[key] = marker;
		return marker;
	}
	function showMarker(marker) {
		if (!that.isMarkerSliding && (marker != that.activeMarker || !isInfoWinOpen())) {
			closeWindow();
			that.isMarkerSliding = true;
			marker.zIndex = that.highestZ + 1;
			marker._applyZIndex();
			var point = that.map.llToPix(marker.latLng);
			var html = '<div id="' + opts.markerSelector.replace('#', '') + '" style="z-index: ' + (that.highestZ) + '; left: ' + (point.x) + 'px; top: ' + (point.y - 60) + 'px;"><strong>' + marker.title + '</strong></div>';
			var obj = $(opts.selector).find('div').eq(1).find('div').eq(0).prepend(html);
			obj = obj.remove(opts.markerSelector).find(opts.markerSelector);
			//alert(obj.length);
			var container = obj.find('strong');
			var w = container.innerWidth();
			container.css({left: -w + 'px'});
			obj.width(w);
			var time = 200;
			container.animate({
				left: '+=' + (w + 30)
			}, time, function() {
				that.isMarkerSliding = false;
			});
		}
	}
	function hideMarker(marker) {
		if (marker) {
			var time = 200;
			var obj = $(opts.selector).find(opts.markerSelector);
			var container = obj.find('strong');
			var w = container.outerWidth();
			container.animate({
				left: '-=' + w
			}, time, function() {
				marker.zIndex = that.highestZ - 1;
				marker._applyZIndex();
				obj.remove();
			});
		}
	}
	function showMarkerInfo(key) {
		if (that.markers[key]) {
			$(opts.markerSelector).hide();
			var marker = that.markers[key];
			that.activeMarker = marker;
			if (opts.type == 'dealers') {
				var html = $('<div>' + marker.infoContentHTML + '</div>');
				if (that.myDealerCode) {
					if (that.myDealerCode == marker.dealerCode) {
						html.find('span.resetter').remove();
						html.find('.makeMyDealer').replaceWith('<span class="makeMyDealer">This is My Dealer</span> <span class="resetter nobullet">(<a href="javascript:window.mqMap.resetMyDealer();" class="nobullet">Reset</a>)</span>');
					} else {
						html.find('.makeMyDealer').replaceWith('<a href="javascript:window.mqMap.makeMyDealer(\'' + marker.dealerCode + '\');" class="makeMyDealer">Make My Dealer</a>');
					}
				}
				marker.setInfoContentHTML(html.html());
			}
			
			//var point = that.map.llToDisplay(marker.latLng);
			//that.map.slideMapToPoint(point.x, point.y);
			that.map.setCenter(marker.latLng);
			//that.map.panToLatLng(marker.latLng); - does not work any more
			marker.toggleInfoWindow();
			setTimeout(function () {
				var button = $(opts.selector).find('.mapOverlay .button');
				if (button.length > 0) {
					button.click(function (e) {
						var target = $(e.target);
						if (!target.hasClass('external')) {
							e.preventDefault();
							utils.prepareFormPop(target);
						}
					});
				}
			}, 500);
		}
	}
	function addZoomControll() {
		MQA.withModule('largezoom', function() {
			that.map.addControl(
				new MQA.LargeZoom(), 
				new MQA.MapCornerPlacement(MQA.MapCorner.TOP_RIGHT, new MQA.Size(5,30))
			);
		});
	}
	function addViewControll() {
		MQA.withModule('viewoptions', function() {
			that.map.addControl(
				new MQA.ViewOptions(),
				new MQA.MapCornerPlacement(MQA.MapCorner.BOTTOM_RIGHT, new MQA.Size(5,30))
			);
		});
	}
	function closeWindow() {
		if (isInfoWinOpen()) {
			that.activeMarker.toggleInfoWindow();
			that.activeMarker = null;
		}
	}
	that.makeMyDealer = function (dealerCode) {
		var utils = new CORE.Utils();
		var url = CORE.wwwroot + '/find-dealer/make-my-dealer?dealerCode=';
		var container = $('#mapSearch');
		container.find('span.resetter').remove();
		utils.getJson({
			url: url + dealerCode
		}, function (data) {
			if (that.myDealerCode) {
				$('#dealer' + that.myDealerCode).replaceWith('<a href="' + url + that.myDealerCode + '" id="dealer' + that.myDealerCode + '" class="makeMyDealer">Make My Dealer</a>');
			}
			$('#dealer' + dealerCode).replaceWith('<span id="dealer' + dealerCode + '" class="makeMyDealer" id="dealer' + dealerCode + '">This is My Dealer</span> <span class="resetter nobullet">(<a href="" class="nobullet resetDealer">Reset</a>)</span>');
			that.myDealerCode = dealerCode;
			if (isInfoWinOpen()) {
				container = $(opts.selector).find('.mqabasicwnd');
				container.find('span.resetter').remove();
				var html = container.find('.makeMyDealer');
				if (that.activeMarker.dealerCode == dealerCode) {
					html.replaceWith('<span class="makeMyDealer">This is My Dealer</span> <span class="resetter nobullet">(<a href="javascript:window.mqMap.resetMyDealer();" class="nobullet">Reset</a>)</span>');
				} else {
					html.replaceWith('<a href="javascript:window.mqMap.makeMyDealer(\'' + dealerCode + '\')" class="makeMyDealer">Make My Dealer</a>');
				}
			}
		});
	}
	that.resetMyDealer = function () {
		var utils = new CORE.Utils();
		var url = CORE.wwwroot + '/find-dealer/make-my-dealer?dealerCode=';
		utils.getJson({
			url: url + 'remove'
		}, function (data) {
			var container, code, link;
			if (isInfoWinOpen()) {
				container = $(opts.selector).find('.mqabasicwnd');
				code = container.find('a.button').eq(0).attr('href').replace('#getQuote,', '');
				container.find('.makeMyDealer').replaceWith('<a href="javascript:window.mqMap.makeMyDealer(\'' + code + '\')" class="makeMyDealer">Make My Dealer</a>');
				container.find('.resetter').remove();
			}
			container = $('#mapSearch');
			link = $('#mapSearch').find('span.makeMyDealer');
			if (link.length > 0) {
				code = link.attr('id').replace('dealer', '');
				link.replaceWith('<a href="' + url + code + '" id="dealer' + code + '" class="makeMyDealer">Make My Dealer</a>');
			}
			container.find('.resetter').remove();
		});
	}
	function isInfoWinOpen() {
		return $(opts.selector).find('.mqabasicwnd').length > 0;
	}
	function init() {
		var id = opts.selector.replace('#', '');
		var container = $('#wrapper3').prepend('<div id="' + id + '" style="width: ' + opts.width + 'px; height: ' + opts.height + 'px; left: 0; top: 0; position: absolute; z-index: 11;"><div class="wrapper"></div></div>').find(opts.selector);
		MQA.EventUtil.observe(window, 'load', function() {
			that.map = new MQA.TileMap(document.getElementById(id), opts.zoom, {lat: opts.lat, lng: opts.lng}, id);
			addZoomControll();
			//addViewControll();
			container.css({position: 'absolute', 'z-index': 11});
			MQA.EventManager.addListener(that.map, 'click', function (e) {
				if (isInfoWinOpen()) closeWindow();
			});

			var map = $(opts.selector);
			map.find('img[src=http://api.mqcdn.com/sdk/js/v6.1.0/images/mqlogo.gif]').remove();
			map.find('img[src=http://api.mqcdn.com/sdk/js/v6.1.0/images/scales/scalebar.gif]').remove();
		});
		$(document).click(function (e) {
			var target = $(e.target);
			if (target.hasClass('dealer')) {
				e.preventDefault();
				var key = target.attr('href').replace(/[^0-9]*/, '');
				showMarkerInfo(key);
			} else if (target.hasClass('makeMyDealer') && target.attr('href') != null) {
				e.preventDefault();
				that.makeMyDealer(target.attr('id').replace('dealer', ''));
			} else if (target.hasClass('resetDealer')) {
				e.preventDefault();
				that.resetMyDealer();
			}
		});
	}
	init();
};

CORE.Byo = function () {
	var that = arguments.callee.prototype;
	var opts = (arguments[0].constructor == Object) ? arguments[0] : {};
	if (!opts.selector) opts.selector = arguments[0];
	if (!opts.vehicleID) opts.vehicleID = 0;
	var isPopOpen = false;
	function init() {
		if (opts.vehicleID > 0) {
			showByVehicleId(opts.vehicleID);
			getInitialData(opts.vehicleID);
		}
		wrapThings();
		$(document).click(function (e) {
			var target = $(e.target);
			if (target.hasClass('moreInfo')) {
				e.preventDefault();
				handleMoreInfo(target);
			} else if (target.is('input[type=checkbox], input[type=radio]') && target.is('[id^=option]')) {
				e.preventDefault();
				handleOptionClicks(target);
			} else if (target.hasClass('button') && target.is('[type=submit]')) {
				var container = target.closest('.byoSection');
				if (container.length > 0 && container.attr('id') != 'byoModels') {
					e.preventDefault();
					handleNextButtons(target);
				}
			} else if (target.hasClass('byoSectionLink')) {
				e.preventDefault();
				handleSectionNav(target);
			} else if (target.hasClass('byoNavImg')) {
				e.preventDefault();
				handleSideNav(target.parent());
			} else if (target.hasClass('byoNavLink')) {
				e.preventDefault();
				handleSideNav(target);
			} else if (target.hasClass('byoCartLink')) {
				e.preventDefault();
				handleSideNav(target);
			}
			$('.byoNavLink').click(function () {
				e.preventDefault();
				window.location.hash = this.hash;
			});
		});
	}
	function getInitialData(vehicleID) {
		var utils = new CORE.Utils();
		utils.getJson({
			data: 'vehicleID=' + vehicleID,
			url: CORE.wwwroot + '/build-and-equip/get-initial-data'
		}, function (data) {
			showConflictMessages(data.solutions);
		});
	}
	function showByVehicleId(vehicleID) {
		var selector;
		if (vehicleID > 0) {
			if (window.location.hash) {
				selector = window.location.hash;
			} else {
				selector = 'byoAppearance';
			}
		} else {
			selector = 'byoModels';
		}
		moveToSection(selector);
		var container = $('#byoOptions');
		container.find('h3').hide();
		container.find('.sectionNav a:first').addClass('active');
		container.find('.group').hide().eq(0).show();
		$('.byoSection').find('.moreInfo').empty();
	}
	function handleSideNav(obj) {
		if (opts.vehicleID) moveToSection(obj.attr('href'));
	}
	function moveToSection(selector) {
		selector = '#' + (selector.replace('#', ''));
		var section = $(opts.selector + ' .byoSection:visible');
		if (section.length > 1) { // all shown
			section.hide();
			$(selector).show();
		} else if (section.length == 1) {
			if (section.attr('id') == selector.replace('#', '')) return false;
			section.fadeOut(function () {
				$(selector).fadeIn();
			});
		} else {
			$(selector).fadeIn();
		}
		window.location.hash = selector.replace('#', '');
		if (isPopOpen) $('#byoPopup').remove();
		if (/summary$/i.test(selector)) getSummary();
		var href;
		$('#sidebar .fancyNav a').removeClass('active').each(function () {
			href = $(this).attr('href');
			if (href == selector) $(this).addClass('active');
		});
	}
	function handleSectionNav(obj) {
		var container = $('#byoOptions');
		container.find('.sectionNav a').removeClass('active');
		obj.addClass('active');
		var selector = obj.attr('href');
		var section = container.find('.group:visible');
		if (section.length > 0) {
			section.fadeOut(function () {
				$(selector).fadeIn();
			});
		} else {
			$(selector).fadeIn();
		}
	}
	function handleNextButtons(obj) {
		if (opts.vehicleID) {
			var container = obj.closest('.byoSection');
			var id = container.attr('id');
			if (id == 'byoModels') {
				id = 'byoAppearance';
			} else if (id == 'byoAppearance') {
				id = 'byoPackages';
			} else if (id == 'byoPackages') {
				id = 'byoOptions';
			} else if (id == 'byoOptions') {
				id = 'byoSummary';
			}
			moveToSection('#' + id);
		}
	}
	function handleOptionClicks(obj) {
		var sections = $(opts.selector).find('.byoSection');
		var fld = obj;
		var mode = (fld.is(':checked')) ? 'add' : 'remove';
		var category = fld.attr('name').replace(/\[\]/, '');
		var code = fld.val();
		var price;
		var url = fld.closest('form').attr('action');
		var utils = new CORE.Utils();
		var container = obj.closest('.line').append('<div class="preloader" style="height: ' + obj.closest('.line').height() + 'px;"></div>');
		try {
			utils.getJson({
				data: 'mode=' + mode + '&category=' + category + '&vehicleID=' + opts.vehicleID + '&optionCode=' + code,
				url: url,
				error: function () {
					alert('Your request was unable to be processed. Please retry your selection.');
				},
				complete: function () {
					container.find('.preloader').remove();
				}
			}, function (data) {
				$('#byoErrors').empty();
				if (data.success) {
					if (data.items) {
						for (var i = 0; i < data.items.length; i++) {
							fld = $('#option' + data.items[i].code);
							if (data.items[i].action == 'add') {
								addToCart(data.items[i].category, data.items[i]);
								fld.attr('checked', true);
								price = fld.closest('.line').addClass('active').find('.price');
								price.text(price.text().replace(/^[^\$]+(.+)$/, 'Added $1'));
							} else if (data.items[i].action == 'remove') {
								removeFromCart(data.items[i].category, data.items[i]);
								fld.attr('checked', false);
								price = fld.closest('.line').removeClass('active').find('.price');
								price.text(price.text().replace(/^[^\$]+(.+)$/, 'Add $1'));
							}
						}
					}
					$('#cart .price span').text('$' + data.price);
					showConflictMessages(data.solutions);
				} else if (data.failure) {
					//alert('Error');
					//handleErrors(obj, data.conflicts);
				}
			});
		} catch (e) {
			alert('Your request was unable to be processed. Please retry your selection.');
		}
	}
	function handleMoreInfo(obj) {
		var container = obj.closest('.line').append('<div class="preloader"></div>');
		var section = $('#wrapper1');
		section.find('#byoPopup').remove();
		var url = obj.attr('href');
		var utils = new CORE.Utils();
		utils.getJson({
			dataType: 'text',
			url: url
		}, function (data) {
			isPopOpen = true;
			container.find('.preloader').remove();
			var left = container.closest('.byoSection').offset().left;
			var top = container.offset().top;
			var content = $(data).css({left: left + 'px', top: top + 'px'}).hide();
			section.prepend(content);
			content.fadeIn(function () {
				content.find('.close').click(function (e) {
					e.preventDefault();
					$(this).unbind('click');
					content.fadeOut(function () {
						content.remove();
					});
				});
			});
		});
	}
	function wrapThings() {
		var obj;
		$('#byoPackages .line, #byoOptions .line').each(function () {
			obj = $(this).find('.price');
			if ($(this).hasClass('active')) {
				obj.prepend('Added ');
			} else {
				obj.prepend('Add ');
			}
		});
	}
	function addToCart(category, item) {
		var isStatic = false;
		if (category == 'validAccessories') {
			var container = $('#cart .accessories > span');
			item.description = '<span class="' + item.code + ' item">' + item.description + '</span>';
			container.append(item.description).find('.none').remove();
		} else if (category == 'validPackages') {
			var container = $('#cart .packages > span');
			item.description = '<span class="' + item.code + ' item">' + item.description + '</span>';
			container.append(item.description).find('.none').remove();
		} else if (category == 'validPaint') {
			var container = $('#cart .exterior span');
			container.html(item.description);
			isStatic = true;
		} else if (category == 'validMBTexUpholstery') {
			var container = $('#cart .interior span');
			container.html(item.description);
			isStatic = true;
		}
		var priceObj = container.closest('.line').find('i');
		updateCategoryPrice(priceObj, parseInt(item.price), isStatic);
	}
	function removeFromCart(category, item) {
		var container, html, opts;
		if (category == 'validAccessories') {
			//$('#' + item.code).removeClass('inactive').find('a').text('+');
			container = $('#cart .accessories > span');
		} else if (category == 'validPackages') {
			//$('#' + item.code).removeClass('inactive').find('a').text('+');
			container = $('#cart .packages > span');
		}
		if (container.length > 0) {
			container.find('.' + item.code).remove();
			if (container.find('span').length == 0) container.append('<span class="none item">None selected</span>');
		}
		var priceObj = container.closest('.line').find('i');
		updateCategoryPrice(priceObj, -parseInt(item.price), false);
	}
	function updateCategoryPrice(obj, itemPrice, isStatic) {
		var price;
		if (isStatic) {
			price = itemPrice;
		} else {
			price = parseInt(obj.text().replace(/[$,]/g, '')) + itemPrice;
		}
		obj.text('$' + formatCurrency(price));
	}
	function formatCurrency(amount) {
		var delimiter = ","; // replace comma if desired
		amount = new String(amount);
		var i = parseInt(amount);
		if (isNaN(i)) return '';
		var minus = '';
		if(i < 0) minus = '-';
		i = Math.abs(i);
		var n = new String(i);
		var a = [];
		while(n.length > 3) {
			var nn = n.substr(n.length-3);
			a.unshift(nn);
			n = n.substr(0,n.length-3);
		}
		if (n.length > 0) { a.unshift(n); }
		n = a.join(delimiter);
		amount = n;
		amount = minus + amount;
		return amount;
	}
	function makeSummaryHtml(item) {
		var html = '';
		var cssClass = 'line';
		item.code = (item.code) ? item.code + ' - ' : '';
		html += '<div class="line2">';
		html += '	<span class="title">' + item.code + item.title + '</span> ';
		html += '	<span class="price">$' + item.price + '</span>';
		html += '</div>';
		return html;
	}
	function getSummary() {
		var content = $('#byoSummary').empty();
		var utils = new CORE.Utils();
		preloadSummary();
		utils.getJson({
			dataType: 'text',
			data: 'action=summary',
			url: window.location.pathname
		}, function (data) {
			$('#byoSummary').find('.preloader').remove();
			$('#byoSummary').empty().append(data);
		});
	}
	function preloadSummary() {
		var selector = '#byoSummary';
		var content = $(selector);
		content.find('.summaryExterior, .summaryInterior, .summaryPackages, .summaryAccessories, .summaryVehicle, .summaryPrice').hide();
		content.append('<div class="preloader" style="clear: both">loading...</div>');
	}

	function showConflictMessages(solutions) {
		var obj, html, conflicts, i, j, arr, fld, name;
		for (var code in solutions) {
			obj = $('#' + code);
			obj.find('.note').remove();
			conflicts = solutions[code];
			html = '';
			if (conflicts.add || conflicts.remove) fld = $('#option' + code);
			if (conflicts.add) {
				arr = [];
				i = conflicts.add.length;
				while (i--) {
					arr.push(getName(conflicts.add[i]));
					//arr.push(getName(conflicts.add[i]) + ' (' + conflicts.add[i] + ')');
				}
				name = (/package/i.test(fld.attr('name'))) ? 'package' : 'option';
				html += '<div>By selecting this ' + name + ', ' + arr.join(', ') + ' will be selected automatically.</div>';
			}
			if (conflicts.remove) {
				arr = [];
				i = conflicts.remove.length;
				while (i--) {
					arr.push(getName(conflicts.remove[i]));
					//arr.push(getName(conflicts.remove[i]) + ' (' + conflicts.remove[i] + ')');
				}
				name = (/package/i.test(fld.attr('name'))) ? 'package' : 'option';
				html += '<div>By selecting this ' + name + ', ' + arr.join(', ') + ' will be unselected automatically.</div>';
			}
			if (html.length > 0) obj.find('.wrapper').append('<div class="note">' + html + '</div>');
		}
	}
	function getName(code) {
		return $('#' + code).find('.description').text();
	}
	init();
};

CORE.Popup = function (selector, isCloseOnClickOut, closeCallback) {
	var that = arguments.callee.prototype;
	var popID = 'popup';
	var overlayID = 'pageOverlay';
	var body = $('body');
	var pop, overlay;
	var transitionTime = 0.2; // secs
	init();
	function init() {
		$(selector).click(function (e) {
			e.preventDefault();
			that.open($(this).attr('href'));
		});
		$('#' + popID).find('.close').live('click', function (e) {
			e.preventDefault();
			that.close();
		});
		$(document).keyup(function(e) {
			if (e.keyCode == 27) { // esc
				that.close();
			}
		});
		$(window).bind('resize scroll', function () {
			position();
		});
	}
	function prepare() {
		$('#' + popID + ', #' + overlayID).remove();
		body.append('<div id="' + popID + '"></div><div id="' + overlayID + '"></div>');
		pop = $('#' + popID);
		overlay = $('#' + overlayID);
		overlay.css('opacity', 0.8);
		pop.hide();
		overlay.hide();
		overlay.click(function (e) {
			e.preventDefault();
			if (isCloseOnClickOut) that.close();
		});
	}
	function position() {
		if (pop) {
			var w = body.width();
			var h = $(document).height();
			var popW = pop.width();
			var popH = pop.height();
			pop.css({
				left: Math.floor($(window).scrollLeft() + ($(window).width() - popW) / 2) + 'px',
				top: Math.floor($(window).scrollTop() + ($(window).height() - popH) / 2) + 'px'
			});
			overlay.width(w);
			overlay.height(h);
		}
	}
	that.close = function () {
		pop = $('#' + popID);
		overlay = $('#' + overlayID);
		overlay.fadeOut(transitionTime * 1000);
		if (pop.find('object').length == 0) { // with plugins (flash, java)
			pop.fadeOut(transitionTime * 1000, function () {
				pop.remove();
				overlay.remove();
				if (closeCallback) closeCallback();
			});
		} else { // without plugins
			pop.remove();
			overlay.fadeOut(transitionTime * 1000, function () {
				overlay.remove();
				if (closeCallback) closeCallback();
			});
		}
	}
	that.open = function (url, callback) {
		prepare();
		position();
		overlay.fadeIn(transitionTime * 1000);
		pop.fadeIn(transitionTime * 1000);
		pop.append('<div class="preloader">loading...</div>');
		$.ajax({
			type: 'GET',
			url: url,
			data: 'ajax=1',
			error: function(xhr, status, error) {
				alert('Ajax error has occurred.');
				that.close();
			},
			success: function(data) {
				pop.html(data);
				var close = $(data).find('.close');
				if (close.length == 0) pop.append('<a href="" class="close"><span>Close</span></a>');
				position();
				if (callback) callback();
			},
			complete: function () {
				pop.find('.preloader').remove();
			}
		});
	}
};

CORE.FormHandler = function () {
	var that = arguments.callee.prototype;
	if (arguments.length == 0) return alert('No parameters specified.');
	var opts = {};
	if (arguments[0].constructor == Object) {
		opts = arguments[0];
	} else {
		opts.selector = arguments[0];
	}
	opts.buttonSelector = ':input[type=submit]';
	if (!opts.errorFieldSelector) opts.errorFieldSelector = '.errorFld';
	if (!opts.errorMsgSelector) opts.errorMsgSelector = '.errorMarker';
	if (!opts.errorSummarySelector) opts.errorSummarySelector = '.errorSummary';
	if (!opts.antirobotFieldSelector) opts.antirobotFieldSelector = '.noErrors';
	if (!opts.isHaltOnSuccess) opts.isHaltOnSuccess = false;
	if (!opts.isHideButton) opts.isHideButton = false;
	var isSubmitting = false;
	var xhr = null;
	init();
	function checkErrors (frm, fld, callback) {
		if (xhr) xhr.abort();
		var url = frm.attr('action');
		var utils = new CORE.Utils();
		var isSubmit = (fld) ? 0 : 1;
		if (!fld) { // submit button clicked
			clearErrors();
			if (opts.isHideButton) {
				frm.find(opts.buttonSelector).hide().after('<div id="processing">Please wait, processing...</div>');
			} else {
				utils.fixButton(false, frm.find(opts.buttonSelector));
			}
		} else { // field lost focus
			clearErrors(fld);
		}
		xhr = utils.getJson({
			url: frm.attr('action'),
			data: frm.serialize() + '&isSubmit=' + isSubmit,
			error: function () {
				if (callback) callback();
				$('#jsError').remove();
				var button = frm.find(opts.buttonSelector).after('<div id="jsError" class="error">Unexpected AJAX error occurred.</div>');
				utils.fixButton(true, button);
			}
		}, function (data) {
			if (data != true) { // got errors
				if (callback) callback();
				var errors = data;
				if (!fld) { // check all fields
					//summaryFld.html('<div class="one"><div class="two"><strong>Please fix the following errors:</strong><ul></ul></div></div>');
					for (var errorFieldName in errors) showError(errors, errorFieldName);
					if (opts.isHideButton) {
						$('#processing').remove();
						$(opts.buttonSelector).show();
					} else {
						utils.fixButton(true, frm.find(opts.buttonSelector));
					}
					isSubmitting = false;
				} else { // check one field
					showError(errors, fld.attr('name'));
				}
			} else { // no error
				if (!fld) {
					frm.append('<input type="hidden" name="jsSuccess" value="1" />');
					if (!opts.isHaltOnSuccess) {
						frm.submit();
					} else if (opts.callback) {
						opts.callback();
						//utils.fixButton(true, frm.find(opts.buttonSelector));
					}
				}
			}
		});
		function showError(errors, errorFieldName) {
			var error = errors[errorFieldName];
			if (error) {
				if (!error.length) { // error is object (zend way)
					for (var i in error) {};
					error = error[i];
				}
				if (errorFieldName != 'error') { // field error
					var fld = frm.find(':input[name=' + errorFieldName + ']').eq(0);
					if (fld) {
						if (!fld.is('[type=radio], [type=checkbox]')) fld.addClass(opts.errorFieldSelector.substr(1));
						fld.closest('.row').find(opts.errorMsgSelector).html(error);
					}
					//fld.after('<span class="' + opts.errorMsgSelector.substr(1) + '">' + error + '</span>');
				} else { // error summary
					frm.find(opts.errorSummarySelector).html(error);
				}
			}
		}
		function clearErrors(fld) {
			var msgObj;
			if (fld) {
				msgObj = fld.closest('.row').find(opts.errorMsgSelector);
			} else {
				fld = frm.find(opts.errorFieldSelector);
				msgObj = frm.find(opts.errorMsgSelector + ', ' + opts.errorSummarySelector);
			}
			msgObj.html('&nbsp;');
			fld.removeClass(opts.errorFieldSelector.substr(1));
		}
	}
	function init() {
		$(document).ready(function () {
			var utils = new CORE.Utils();
			var frm = $(opts.selector);
			frm.submit(function (e) {
				frm = $(this);
				var isValid = frm.find(':input[name=jsSuccess]').length;
				if (!isValid) { //frm.find(':input[name=' + opts.antirobotFieldSelector.substr(1) + ']').length == 0) {
					isSubmitting = true;
					e.preventDefault();
					checkErrors(frm, null);
				}
			});
			frm.find(':input[type!=submit]').not('.optional').blur(function (e) {
				if (!isSubmitting) {
					var fld = $(this);
					checkErrors(fld.closest('form'), fld);
				}
			});
			frm.append('<input type="hidden" name="' + opts.antirobotFieldSelector.substr(1) + '" value="secret" />');
		});
	}
};

CORE.FindDealerForm = function () {
	var that = arguments.callee.prototype;
	if (arguments.length == 0) return alert('No parameters specified.');
	var opts = {};
	if (arguments[0].constructor == Object) {
		opts = arguments[0];
	} else {
		opts.selector = arguments[0];
	}
	opts.buttonSelector = ':input[type=submit]';
	if (!opts.resultsSelector) resultsSelector = '.results';
	if (!opts.dealerSelector) opts.dealerSelector = '.dealerSelector';
	if (!opts.antirobotFieldSelector) opts.antirobotFieldSelector = '.noErrors';
	if (!opts.isHideButton) opts.isHideButton = false;
	var isSubmitting = false;
	init();
	function selectDealer(code, link) {
		var frm = $(opts.selector);
		var links = frm.find(opts.dealerSelector).show();
		if (link) link.hide();
		$('form').find(':input[name=dealerCode]').val(code);
	}
	function init() {
		$(document).ready(function () {
			var frm = $(opts.selector);
			frm.submit(function (e) {
				e.preventDefault();
				frm = $(this);
				var utils = new CORE.Utils();
				var button = frm.find(opts.buttonSelector);
				utils.fixButton(false, button);
				utils.getJson({
					url: frm.attr('action'),
					dataType: 'text',
					data: frm.serialize()
				}, function (data) {
					if (data) { // got errors
						frm.find(resultsSelector).html(data);
					} else { // no error
						
					}
					utils.fixButton(true, button);
					frm.find(opts.dealerSelector).click(function (e) {
						e.preventDefault();
						var obj = $(this);
						selectDealer(obj.attr('title'), obj);
					});
				});
			});
		});
	}
};

CORE.Uploader = function (props) {
// possible properties:
// file - css selector for file field
// button - css selector for button
// removeUrl - url at which uploaded image can be removed ()
// success - callback function called when file successfully uploaded
// complete - callback function called when file uploaded completed, no mater the result
	var that = arguments.callee;
	that.preloaderSelector = '.preloader'; // css selector for preload container
	that.removerSelector = '.uploadRemover'; // css selector for image remover
	init();
	function init() {
		//$(document).ready(function () {
			var file = $(props.file);
			var frm = file.closest('form').css({overflow: 'hidden', position: 'relative'});
			var button = $(props.button).click(function (e) {
				e.preventDefault();
			});
			file.change(function () {
				var file = $(this);
				uploadFile(file);
			}).css({
				opacity: 0,
				position: 'absolute',
				'z-index': 999
			});
			setupFileEvents(frm);
			frm.mousemove(function(e) {
				var file = $(this).find(getLastSelector(props.file));
				moveField(file, e);
			});
			frm.prepend('<a href="" class="' + getLastSelector(that.removerSelector).substr(1) + '" />').find(that.removerSelector).hide().click(function (e) {
				e.preventDefault();
				var frm = $(this).closest('form');
				removeFile(frm);
			});
			handlePrefilledItems(frm);
		//});
	}
	function getLastSelector(selector) {
	// convert string like "#idSelector .classSelectorFirst .classSelectorLast" to ".classSelectorLast"
		return selector.replace(/.* ([^ ]+)$/g, '$1');
	}
	function setupFileEvents(frm) {
		var file = frm.find(getLastSelector(props.file));
		file.show();
		file.unbind('click');
		file.bind('click', function (e) {
			// disable if clicked outside button
			var button = $(this).closest('form').find(getLastSelector(props.button));
			if (!isOverButton(button, e)) e.preventDefault();
		});
	}
	function setupRemoverEvents(frm) {
		if (props.removeUrl) {
			var file = frm.find(getLastSelector(props.file));
			file.hide();
			var remover = frm.find(that.removerSelector);
			remover.css({opacity: 0}).show();
			remover.bind('mouseover', function () {
				remover.css({opacity: '.9', visibility: 'visible'});
			}).bind('mouseout', function () {
				remover.css({opacity: 0});
			});
		}
	}
	function isOverButton(button, e) {
		//return true if mouse pointer is over button
		var position = button.offset();
		return e.pageX >= position.left && e.pageX <= (position.left + button.outerWidth()) &&
			e.pageY >= position.top && e.pageY <= (position.top + button.outerHeight());
	}
	function moveField(file, e) {
		var frm = file.closest('form');
		var button = frm.find(getLastSelector(props.button));
		var position = button.position();
		var offset = button.offset();
		var coord = e.pageX - (offset.left - position.left);
		if (e.pageX < offset.left) {
			coord = position.left;
		} else if (e.pageX > offset.left + button.outerWidth()) {
			coord = position.left + button.outerWidth();
		}
		var left = coord - file.width() + 10;
		coord = e.pageY - (offset.top - position.top);
		if (e.pageY < offset.top) {
			coord = position.top;
		} else if (e.pageY > offset.top + button.outerHeight()) {
			coord = position.top + button.outerHeight();
		}
		var top = coord - 10;
		file.css({left: left, top: top});
	}
	function uploadFile(file) {
		var frm = file.closest('form');
		var iframe = frm.find('iframe');
		var iframeDoc = $(window.frames[iframe.attr('name')].document);
		if (file.val()) {
			frm.append('<div class="' + getLastSelector(that.preloaderSelector).substr(1) + '"></div>');
			var defaultContent = iframeDoc.find('#info').html();
			iframe.unbind('load');
			iframe.load(function() {
				iframeDoc = $(window.frames[iframe.attr('name')].document);
				if (iframeDoc.find('img').length == 0) {
					alert('Error: ' + iframeDoc.find('#info').text());
					iframeDoc.find('#info').html(defaultContent);
				} else {
					setupRemoverEvents(frm);
					if (props.success) onSuccess(props.success, frm);
				}
				frm.find(that.preloaderSelector).remove();
				if (props.complete) onComplete(props.complete, frm);
			});
			frm.submit();
		}
	}
	function removeFile(frm) {
		frm.find(getLastSelector(props.file)).hide();
		if (props.removeUrl) {
			var remover = frm.find(that.removerSelector);
			remover.unbind('mouseover mouseout').css({opacity: 0});
			frm.append('<div class="' + getLastSelector(that.preloaderSelector).substr(1) + '"></div>');
			var utils = new CORE.Utils();
			utils.getJson({
				dataType: 'text',
				url: props.removeUrl,
				data: frm.attr('action').replace(/^[^?]+[?]?/, ''), // query from form action
				complete: function () {
					frm.find(that.preloaderSelector).remove();
				}
			}, function (data) {
				var iframe = frm.find('iframe');
				var iframeDoc = $(window.frames[iframe.attr('name')].document).find('#info').empty();
				setupFileEvents(frm);
			});
		}
	}
	function handlePrefilledItems(frm) {
		var iframe = frm.find('iframe');
		iframe.load(function () {
			iframe = $(this);
			var iframeDoc = $(window.frames[iframe.attr('name')].document);
			var hasImage = iframeDoc.find('#info').find('img').length;
			var frm = iframe.closest('form');
			//alert(frm.length);
			if (hasImage) setupRemoverEvents(frm);
		});
	}
	function onSuccess(func, frm) {
		func(frm);
	};
	function onComplete(func, frm) {
		//func(frm);
	};
	return that;
};

CORE.Specs = function () {
	var that = arguments.callee.prototype;
	init();
	function init() {
		$('#content').find('.dataTable tr:odd').addClass('interlaced');
		var specDd = $('#modelDropdown');
		var currentDd = specDd.val();
		specDd.change(function () {
			if ($(this).val() && $(this).val() != currentDd) {
				window.location.href = $(this).val();
			}
		});
		$(document).click(function (e) {
			var target = $(e.target);
			if (target.hasClass('seeAllFeaturesLink')) {
				e.preventDefault();
				var ul = target.closest('ul');
				if (!ul.hasClass('expanded')) {
					ul.find('.extra').show();
					ul.addClass('expanded');
					target.text('Hide');
				} else {
					ul.find('.extra').hide();
					ul.removeClass('expanded');
					target.text('Show All');
				}
			} else if (target.hasClass('showHideSection')) {
				e.preventDefault();
				var selector = target.attr('href');
				var container = $(selector);
				if (container.is(':visible')) {
					target.removeClass('active');
				} else {
					target.addClass('active');
				}
				container.toggle();
			}
		});
	}
};

CORE.Models = function () {
	var that = arguments.callee.prototype;
	that.selector = '#infoPopHolder';
	that.popSelector = '#infoPop';
	that.isOpen = false;
	that.currentIndex = 0;
	var currentDd = null;
	init();
	function init() {
		$(that.selector).show();
		setup();
		$(document).click(function (e) {
			var target = $(e.target);
			if (target.hasClass('close')) {
				e.preventDefault();
				close();
			} else if (target.hasClass('options')) {
				e.preventDefault();
				show(0);
			} else if (target.parent().hasClass('options')) {
				e.preventDefault();
				show(0);
			} else if (target.attr('id') == 'highlightsLink') {
				e.preventDefault();
				getFeatures(target);
			} else if (target.parent().attr('id') == 'highlightsLink') {
				e.preventDefault();
				getFeatures(target.parent());
			} else if (target.hasClass('hs')) {
				e.preventDefault();
				var index = target.attr('id').replace(/[^0-9]+/, '');
				show(index);
			} else if (target.parent().hasClass('section')) {
				e.preventDefault();
				toggleSection(target);
			}
		});
	}
	function setup() {
		var container = $('#content');
		container.append('<div id="' + that.selector.replace('#', '') + '"><div id="' + that.popSelector.replace('#', '') + '"><div class="content"><a href="" class="close"><span>Close</span></a></div></div><div class="bg"></div></div>');
		container.find('.hss > li').live('mouseenter', function () {
			$(this).find('a').show().css('display', 'block');
		}).live('mouseleave', function () {
			$(this).find('a').hide();
		});
	}
	function toggleSection(obj) {
		var container = $(obj.attr('href'));
		if (container.is(':visible')) {
			container.css('display', 'none');
			obj.removeClass('active');
		} else {
			container.css('display', 'table');
			obj.addClass('active');
		}
	}
	function getFeatures(obj) {
		if (!obj.hasClass('active')) {
			if ($('#content').find('.hss').length == 0) {
				var utils = new CORE.Utils();
				utils.getJson({
					dataType: 'text',
					url: obj.attr('href')
				}, function (data) {
					$('#content').append(data);
					showPointers();
				});
			} else {
				showPointers();
			}
			obj.addClass('active');
		} else {
			hidePointers();
			obj.removeClass('active');
		}
	}
	function showPointers() {
		var container = $('#content');
		var hotspots = container.find('.hss');
		if (hotspots.length > 0) {
			hotspots.each(function (i) {
				var obj = $(this);
				var delay = 200;
				setTimeout(function () {
					obj.fadeIn();
				}, (i) * delay);
			});
		}
	}
	function hidePointers() {
		var container = $('#content');
		var hotspots = container.find('.hss');
		if (hotspots.length > 0) {
			hotspots.each(function (i) {
				var obj = $(this);
				var delay = 200;
				setTimeout(function () {
					obj.fadeOut(function () {
						//$(this).remove();
					});
				}, (i) * delay);
			});
		}
	}
	function show(index) {
		var container = $(that.popSelector).find('.content');
		var close = container.find('.close');
		$(that.popSelector).find('.content').html($('#hotspot' + index).html()).append(close);
		that.currentIndex = index;
		open();
	}
	function open() {
		var container = $(that.selector);
		var obj = $(that.popSelector);
		var toY = 665 - obj.height();
		if (!that.isOpen) {
			//alert(toY);
			that.isOpen = true;
			shift(obj, toY, function () {
				
			});
		} else {
			obj.css('top', toY + 'px');
		}
	}
	function close() {
		if (that.isOpen) {
			var container = $(that.selector);
			var obj = $(that.popSelector);
			var toY = 680;
			//alert(toY);
			that.isOpen = false;
			shift(obj, toY, function () {
				
			});
		}
	}
	function shift(obj, toY, callback) {
		var time = 500;
		obj.animate({
			top: toY
		}, time, function() {
			if (callback) callback();
		});
	}
};

CORE.Comparison = function () {
	var that = arguments.callee.prototype;
	var opts = (arguments.length > 0 && arguments[0].constructor == Object) ? arguments[0] : {};
	if (!opts.selector) opts.selector = '#comparator';
	var baseUrl = window.location.pathname;
	var thumbUrls = [];
	init();
	function init() {
		var container = $(opts.selector);
		if (container.length > 0) {
			$(document).click(function (e) {
				var target = $(e.target);
				if (target.hasClass('compareNavLink')) {
					e.preventDefault();
					showSection(target);
				}
			});
			container.find('select').change(function () {
				var target = $(this);
				if (target.hasClass('makeID')) {
					getModels(target, target.val());
				} else if (target.hasClass('modelID')) {
					getTrims(target, target.val());
				} else if (target.hasClass('trimID')) {
					getData(target);
				}
			});
			container.find('.dataTable tr:even').addClass('interlaced');
			preselect();
		}
	}
	function showSection(obj) {
		obj.closest('ul').find('a').removeClass('active');
		obj.addClass('active');
		$('#data').find('.addition').css('display', 'none');
		$(obj.attr('href')).css('display', 'table');
	}
	function getModels(obj, makeID, callback) {
		if (makeID) {
			var index = $(opts.selector).find('.makeID').index(obj) + 1;
			var utils = new CORE.Utils();
			var dependentFld = $(opts.selector).find('.modelID').eq(index).empty().append('<option value="">loading...</option>');
			utils.getJson({
				url: baseUrl,
				data: 'makeID=' + makeID
			}, function (data) {
				if (data) {
					dependentFld.empty().append('<option value="">Select a Model</option>');
					for (var i in data) {
						dependentFld.append($('<option></option>').attr('value', i).text(data[i])); 
					}
					resetColumn(index);
					//dependentFld.trigger('change');
					if (callback) callback();
				}
			});
		}
	}
	function getTrims(obj, modelID, callback) {
		if (modelID) {
			var index = $(opts.selector).find('.modelID').index(obj);
			var utils = new CORE.Utils();
			var dependentFld = $(opts.selector).find('.trimID').eq(index).empty().append('<option value="">loading...</option>');
			utils.getJson({
				url: baseUrl,
				data: 'modelID=' + modelID
			}, function (data) {
				if (data) {
					dependentFld.empty();
					if (index > 0) dependentFld.append('<option value="">Select a Trim</option>');
					for (var i in data) {
						dependentFld.append('<option value="' + i + '" id="' + data[i].image + '">' + data[i].title + '</option>'); 
					}
					if (index == 0) $(opts.selector).find('.trimID').eq(index).trigger('change');
					if (callback) callback();
				}
			});
		}
	}
	function getData(obj) {
		if (obj.val()) {
			var container = $(opts.selector);
			var fields = container.find('.trimID');
			//if (fields.eq(0).val() == '') return alert("You must select trim for the first vehicle.");
			var dataContainer = $('#data').append('<div class="preloader"></div>');
			var index = fields.index(obj);
			var thumb = container.find('.thumb').eq(index).html('<img src="' + obj.find('option:selected').attr('id') + '" border="0" alt="" />');
			var query = '';
			var trimID;
			var trimIDs = [];
			fields.each(function () {
				trimID = $(this).val();
				trimIDs.push(trimID);
				//if (trimID) trimIDs.push(trimID);
			});
			query += 'trimIDs=' + trimIDs.join('|');
			var utils = new CORE.Utils();
			utils.getJson({
				dataType: 'text',
				url: baseUrl,
				data: query
			}, function (data) {
				var chars = Math.ceil(data.length / 2);
				dataContainer.html(data);
				showSection(container.find('.nav a').eq(0));
				container.find('.dataTable tr:even').addClass('interlaced');
			});
		}
	}
	function preselect() {
		var container = $(opts.selector);
		var index = 1; // second column
		var modelName = container.find('.modelID').eq(index).find('option:selected').text().toLowerCase();
		var trimID = container.find('.trimID').eq(index).val();
		var field = container.find('.makeID').eq(0);
		getModels(field, field.val(), function () {
			field = container.find('.modelID').eq(1);
			field.find('option').each(function () {
				if ($(this).text().toLowerCase() == modelName) {
					$(this).attr('selected', true);
					return;
				}
			});
			getTrims(field, field.val(), function () {
				field = container.find('.trimID').eq(1);
				field.find('option').each(function () {
					if ($(this).val() == trimID) {
						$(this).attr('selected', true);
						return;
					}
				});
				//field.trigger('change');
			});
		});
	}
	function reset() {
		var container = $(opts.selector);
		container.find('.thumb').each(function (i) {
			if (i != 0) $(this).empty();
		});
		container.find('.makeID').each(function (i) {
			$(this).find('option').eq(0).attr('selected', true);
		});
		container.find('.modelID').each(function (i) {
			if (i != 0) $(this).empty().append('<option value="">Select a Model</option>');
		});
		container.find('.trimID').each(function (i) {
			if (i != 0) $(this).empty().append('<option value="">Select a Trim</option>');
		});
	}
	function resetColumn(index) {
		var container = $(opts.selector);
		container.find('.thumb').eq(index).empty();
		container.find('.trimID').eq(index).empty().append('<option value="">Select a Trim</option>');
		container = $('#data').find('.dataTable').find('tr').each(function () {
			$(this).find('td').eq(index + 1).empty();
		});
	}
};

CORE.Rotate360 = function () {
	var that = arguments.callee.prototype;
	var opts = (arguments[0].constructor == Object) ? arguments[0] : {};
	if (!opts.selector) opts.selector = arguments[0];
	opts.path = '';
	opts.imgs = [];
	opts.delay = 100; // speed of swapping images
	opts.index = 1;
	opts.timer = null;

	that.init = function(color) {
		var container = $(opts.selector);
		if (color == undefined) color = '147';
		opts.index = 1;
		if (container.length > 0) {
			opts.path = container.find('img').attr('src').replace(/^(.*\/)[^\/]+$/, '$1');
			opts.path = opts.path.replace(/\d\d\d\/$/ ,'');
			opts.path = opts.path + color + '/';
			if (/minibus/.test(opts.path)) return false; // stop script if minibus
			opts.imgs = getImages();
			var preloader = container.append('<div class="preloader">loading...</div>').find('.preloader');
			preload(opts.imgs, function () {
				preloader.remove();
				setup();
			});
		}
	}
	that.init();
	function setup() {
		var container = $(opts.selector);
		if($('.rotation').length <= 0){
			var nav = container.append('<div class="rotation"><a href="" class="arrow left"></a><a href="" class="arrow right"></a></div>').find('.rotation').hide().fadeIn()
		}else{
			var nav = container;
		}
		nav.find('.arrow').mouseover(function (e) {
			e.stopPropagation();
			var target = $(e.target);
			if (target.hasClass('left')) {
				left();
			} else if (target.hasClass('right')) {
				right();
			}
			//alert('over');
		}).mouseout(function (e) {
			e.stopPropagation();
			stop();
		}).click(function (e) {
			e.preventDefault();
		});
	}
	function getImages() {
		var imgs = [];
		for (var i = 1; i <= 36; i++) {
			imgs.push(i + '.png?time=' + (new Date()).getTime());
		}
		return imgs;
	}
	function preload(imgs, callback) {
		var cache = [];
		load(1);
		function load(index) {
			if (imgs[index]) {
				var img = $(document.createElement('img'));
				img.src = '';
				var url = opts.path + imgs[index];
				img.attr('src', url).load(function () {
					cache.unshift(img);
					load(index + 1);
				});
			} else {
				if (callback) callback();
			}
		}
	}
	function left() {
		clearTimeout(opts.timer);
		opts.timer = setTimeout(function () {
			opts.index = (opts.imgs[opts.index - 1]) ? opts.index - 1 : opts.imgs.length - 1;
			var url = opts.path + opts.imgs[opts.index];
			$(opts.selector).find('img').attr('src', url);
			left();
		}, opts.delay);
	}
	function right() {
		clearTimeout(opts.timer);
		opts.timer = setTimeout(function () {
			opts.index = (opts.imgs[opts.index + 1]) ? opts.index + 1 : 1;
			var url = opts.path + opts.imgs[opts.index];
			$(opts.selector).find('img').attr('src', url);
			right();
		}, opts.delay);
	}
	function stop() {
		clearTimeout(opts.timer);
	}
};

CORE.Story = function () {
	var that = arguments.callee.prototype;
	var opts = {};
	opts.selector = '#content';
	opts.navSelector = '#sectionNav';
	opts.sliderSelector = '#dates';
	opts.togglerSelector = '#datesNav';
	opts.currentIndex = 0;
	var isOpen = false;
	var isMoving = false;
	init();
	function shift(obj, toY, callback) {
		var time = 500;
		obj.animate({
			top: toY
		}, time, function() {
			if (callback) callback();
		});
	}
	function toggle() {
		if (isOpen) {
			close();
		} else {
			open();
		}
	}
	function go(index) {
		if (!isMoving && opts.currentIndex != index) {
			var url = $(opts.navSelector).find('a').eq(index).attr('href');
			opts.currentIndex = index;
			isMoving = true;
			var wasOpen = isOpen;
			close();
			var utils = new CORE.Utils();
			var container = $(opts.selector);
			container.append('<div class="preloader"></div>');
			utils.getJson({
				dataType: 'text',
				url: url
			}, function (data) {
				var bgUrl = '/images/backgrounds/top/story.jpg';
				if (index == 1) {
					bgUrl = '/images/backgrounds/top/innovation.jpg';
				} else if (index == 2) {
					bgUrl = '/images/backgrounds/top/future.jpg';
				}
				bgUrl = CORE.wwwroot + bgUrl;
				bgUrl = preloadImg(bgUrl, function () {
					container.find('.preloader').remove();
					var newContainer = $(data).find(opts.selector);
					$(opts.navSelector).find('a').removeClass('active').eq(opts.currentIndex).addClass('active');
					$('.txtPromo').fadeOut(function () {
						$(this).replaceWith($(data).find('.txtPromo').hide().fadeIn());
						$('#wrapper1').css('background-image', 'url(' + bgUrl + ')');
					});
					var newTimeline = newContainer.find('.timeline');
					container.find('.timeline').fadeOut(function () {
						$(this).replaceWith(newTimeline.hide().fadeIn());
						var timeline = container.find('.timeline');
						var obj = $(opts.sliderSelector).html('');
						//alert( processData(timeline.html()) );
						obj.append(processData(timeline.html())).attr('class', newTimeline.attr('class').replace('timeline ', ''));
						setTimeout(function () {
							if (wasOpen) open();
						}, 500);
						isMoving = false;
					});
				});
			});
		}
	}
	function open() {
		var obj = $(opts.sliderSelector);
		if (!isOpen) {
			isMoving = true;
			shift(obj, obj.position().top - (obj.outerHeight() - 20), function () {
				isOpen = true;
				isMoving = false;
			});
			var toggler = $(opts.togglerSelector);
			if (opts.currentIndex == 0) {
				toggler.find('.datesNext').fadeIn();
			} else if (opts.currentIndex == 1) {
				toggler.find('.datesPrev, .datesNext').fadeIn();
			} else if (opts.currentIndex == 2) {
				toggler.find('.datesPrev').fadeIn();
			}
		}
	}
	function close() {
		var obj = $(opts.sliderSelector);
		if (isOpen) {
			isMoving = true;
			shift(obj, obj.position().top + (obj.outerHeight() - 20), function () {
				isOpen = false;
				isMoving = false;
			});
			$(opts.togglerSelector).find('.datesPrev, .datesNext').fadeOut();
		}
	}
	function processData(html) {
		var lines = $('<div>' + html + '</div>').find('.line');
		var obj = $(document.createElement('div'));
		var coords;
		lines.each(function () {
			coords = parseInt($(this).attr('coords'));
			if (coords) {
				try {
					obj.append($(this).css('padding-left', (coords - 10) + 'px').wrapInner('<div class="spot"></div>'))//.wrapInner('<a href="javascript:void(0);"></a>'));
				} catch(e) {
					//alert(e + ': ' + coords);
				}
			}
		});
		obj.html(obj.append(navHtml()).html().replace(/\> . \</gm, '><'));
		return obj.html();
	}
	function navHtml() {
		return '<div id="' + opts.togglerSelector.substr(1) + '"><a href="" class="datesPrev"></a><a href="" class="datesToggler"></a><a href="" class="datesNext"></a></div>';
	}
	function preloadImg(url, callback) {
		var img = new Image();
		img = $(img).css({position: 'absolute', width: '1px', height: '1px', opacity: '0'});
		url = url + '?random=' + (new Date()).getTime();
		$('body').append(img);
		img.attr('src', url).load(function () {
			$(img).remove();
			if (callback) callback();
		});
		return url;
	}
	function init() {
		var content = $(opts.selector);
		var timeline = content.find('.timeline');
		var dates = $('#wrapper3').append('<div id="' + opts.sliderSelector.replace('#', '') + '" class="' + timeline.attr('class') + '">' + processData(timeline.html()) + '</div><div class="holder"></div>').find('#dates').hide();
		opts.currentIndex = $(opts.navSelector).find('a').index($(opts.navSelector).find('a.active'));
		$(document).click(function (e) {
			var target = $(e.target);
			if (target.hasClass('sectionNavLink')) {
				e.preventDefault();
				var index = $(opts.navSelector).find('a').index(target);
				go(index);
			} else if (target.hasClass('sectionNavImg')) {
				e.preventDefault();
				target = target.parent();
				var index = $(opts.navSelector).find('a').index(target);
				go(index);
			} else if (target.hasClass('datesPrev')) {
				e.preventDefault();
				if (opts.currentIndex > 0) go(opts.currentIndex - 1);
			} else if (target.hasClass('datesNext')) {
				e.preventDefault();
				if (opts.currentIndex < 2) go(opts.currentIndex + 1);
			} else if (target.hasClass('datesToggler')) {
				e.preventDefault();
				toggle();
			}
		});
		var lines = $(opts.sliderSelector).find('.spot');
		lines.live('mouseenter', function () {
			var text = $(this).closest('.line').find('.description').html();
			var coords = $(this).offset();
			var hint = $('<div id="hint"><div class="hintWrapper">' + text + '</div><div class="hintTop"></div><div class="hintPointer"></div></div>');
			hint = $('body').append(hint).find('#hint');
			if ($(this).position().left + hint.width() < $(document).width()) {
				hint.css({left: (coords.left + $(this).innerWidth()) + 'px', top: (coords.top - hint.height() / 2 + 3) + 'px'});
			} else {
				hint.css({left: (coords.left - hint.width()) + 'px', top: (coords.top - hint.height() / 2 + 3) + 'px'}).addClass('reversed');
			}
			hint.find('.hintPointer').css('top', parseInt(hint.height() / 2 - 5) + 'px');
		});
		lines.live('mouseleave', function () {
			$('#hint').remove();
		});
		dates.fadeIn();
	}
};

CORE.OwnersStories = function () {
	var that = arguments.callee.prototype;
	var opts = (arguments.length > 0 && arguments[0].constructor == Object) ? arguments[0] : {};
	that.videoSelector = (opts.videoSelector) ? opts.videoSelector : '#storyVideo';
	that.isSupportVideo = isSupportVideo();
	that.currentMediaIndex = null;
	that.currentStoryID = (opts.currentStoryID) ? opts.currentStoryID : null;
	that.neededBuffer = 12;
	var isFirstLoad = true;
	var isShowingVideo = false;
	var isControlsRecognized = false;
	var timer = null;
	var testCounter = 0;
	init();
	function init() {
		var url = $('#slider').find('.content a').eq(0).attr('href');
		if (that.currentStoryID) url = url.replace(/[0-9]+$/, that.currentStoryID);
		var container = $(that.videoSelector).empty().after('<div class="storiesWrapper"></div><div id="videoControlls"><a href="" class="play"></a></div>');
		if (!that.isSupportVideo) { // supports video tag
			$.getScript(CORE.wwwroot + '/js/swfobject.js', function() {
				loadStory(url);
			});
		} else {
			loadStory(url);
		}
		$(document).click(function (e) {
			var video = document.getElementsByTagName('video')[0];
			var target = $(e.target);
			if (target.hasClass('paused')) {
				e.preventDefault();
				that.pauseVideo(true);
				target.removeClass('paused');
			} else if (target.hasClass('play')) {
				e.preventDefault();
				playVideo();
				isControlsRecognized = true;
				target.addClass('paused');
			} else if (target.hasClass('off')) {
				e.preventDefault();
				soundVideo();
				target.removeClass('off');
			} else if (target.hasClass('sound')) {
				e.preventDefault();
				muteVideo();
				target.addClass('off');
			} else if (target.parent().hasClass('sliderLink')) {
				e.preventDefault();
				target = target.parent();
				target.append('<span class="preloader"></span>');
				loadStory(target.attr('href'));
			} else if (target.hasClass('sliderLink')) {
				e.preventDefault();
				target.append('<span class="preloader"></span>');
				loadStory(target.attr('href'));
			} else if (target.hasClass('promoNavLink')) {
				e.preventDefault();
				var index = target.parent().find('a').index(target);
				show(index);
			}
		});
		var containerOffset = container.offset();
		$('body').mousemove(function(e) {
			if (isShowingVideo) {
				if (e.pageX >= containerOffset.left &&
					e.pageX <= containerOffset.left + container.width() &&
					e.pageY >= 0 &&
					e.pageY <= container.height() - 10) {
						$('#videoControlls, #topPromoNav').show();
				} else {
					var controls = $('#videoControlls');
					if (isControlsRecognized) {
						if (!controls.hasClass('loading')) controls.hide();
						var nav = $('#topPromoNav').hide();
					}
				}
			}
		});
		new CORE.Slider('#slider');
	}
	function loadStory(url) {
		var utils = new CORE.Utils();
		if (url.length > 0) {
			var storyID = url.replace(/^.*=([0-9]+)$/, '$1');
			if (that.currentStoryID != storyID || isFirstLoad) {
				var container = $(that.videoSelector);
				container.append('<div class="preloader"></div>');
				that.currentStoryID = storyID;
				utils.getJson({
					url: url,
					dataType: 'text',
					complete: function () {
						container.find('.preloader').remove();
						$('#slider').find('.preloader').remove();
					}
				}, function (data) {
					var data = $(data);
					container.find('.item').remove();
					var items = data.find(that.videoSelector).find('.item').hide();
					container.append(items);
					$('#topPromoNav').remove();
					if (items.length > 1) {
						var html = '<div id="topPromoNav"><div class="wrapper">';
						for (var i = 0; i < items.length; i++) {
							html += '<a href="" class="promoNavLink';
							if (i == 0) html += ' first active';
							html += '"></a>';
						}
						html += '</div></div>';
					}
					container.parent().append(html);
					var nav = $('#topPromoNav');
					nav.css('left', ((container.width() - nav.width()) / 2) + 'px');
					that.currentMediaIndex = null;
					show(0);

					if (isFirstLoad) {
						isFirstLoad = false; // don't change menu on first load
					} else {
						$('#sidebar').find('.promoMenuHolder').replaceWith(data.find('#sidebar').find('.promoMenuHolder').hide().fadeIn());
					}
				});
			} else {
				$('#slider').find('.preloader').remove();
			}
		}
	}
	function show(index) {
		if (timer) clearTimeout(timer);
		if (that.currentMediaIndex != index) {
			that.currentMediaIndex = index;
			var container = $(that.videoSelector);
			var item = container.find('.item').hide().eq(index).show();
			var nav = $('#topPromoNav').find('a').removeClass('active').eq(index).addClass('active');
			//return false;
			var vids = item.attr('videos');
			removeVideo();
			if (vids) {
				isShowingVideo = true;
				showControls();
				vids = vids.split(',');
				if (that.isSupportVideo) { // supports video tag
					var html = '<video width="1200" height="674" style="display: none;">';
					for (var i = 0; i < vids.length; i++) {
						html += '<source src="' + vids[i] + '"';
						if (/.mp4$/.test(vids[i])) {
							html += 'type="video/mp4"';
						} else if (/.ogv$/.test(vids[i])) {
							html += 'type="video/ogg"';
						} else if (/.webm$/.test(vids[i])) {
							html += 'type="video/webm"';
						}
						html += ' />';
					}
					html += '</video>';
					container.html(container.html() + html);
				} else { // does not support video tag
					container.prepend('<div id="myVideo"></div>');
					$.getScript(CORE.wwwroot + '/js/swfobject.js', function() {
						var flashvars = {
							movie: vids[vids.length - 1],
							autoplay: 'on',
							muteonly: 'false',
							volume: '0',
							accentcolor: '0x31b8e9'
						};
						var params = {
							menu: 'false',
							allowFullScreen: 'true',
							wmode: 'transparent'
						};
						swfobject.embedSWF(CORE.wwwroot + '/swfs/storyPlayer.swf', 'myVideo', '1200', '674', '9.0.0', CORE.wwwroot + '/swfs/expressInstall.swf', flashvars, params);
					});
				}
			} else {
				isShowingVideo = false;
				hideControls();
				item.fadeIn();
			}
			showSidebar();
		}
	}
	function hideControls() {
		$('#videoControlls').hide();
	}
	function showControls() {
		var container = $('#videoControlls');
		container.find('.play').removeClass('paused');
		container.find('.sound').removeClass('off');
		container.removeClass('loading').css('background', 'none').find('a').show();
		container.show();
	}
	function hideSidebar() {
		//$('#sidebar').show().find('.promoMenuHolder').show().fadeOut();
		$('#sidebar').find('.promoMenuHolder').fadeOut();
	}
	function showSidebar() {
		$('#sidebar').find('.promoMenuHolder').fadeIn();
	}
	function removeVideo() {
		var video = document.getElementsByTagName('video');
		if (video.length > 0) {
			if (timer) clearInterval(timer);
			video[0].pause();
			$(video).remove();
		} else {
			video = document.getElementById('myVideo');
			if (video) {
				video.pauseFlv();
				$(video).remove();
			}
		}
	}
	that.progress = function (percent) {
		var controls = $('#videoControlls');
		if (percent < 100) {
			var leftover = (percent % 5);
			if (leftover != 0) percent = percent - leftover;
			var offsetX = (percent - 5) / 5 * 70;
			//location.hash = percent + ' ' + offsetX;
			testCounter++;
			//location.hash = 'progress: ' + testCounter + ', ' + percent;
			controls.addClass('loading').css('background', 'url(' + CORE.wwwroot + '/images/backgrounds/video-loader.png) no-repeat -' + offsetX + 'px 0px').find('a').hide();
			if (timer) clearTimeout(timer);
			timer = setTimeout(function () {
				if (!that.isSupportVideo) {
					var video = document.getElementById('myVideo');
					video.isFlvPlaying();
					clearTimeout(timer);
				} else {
					checkVideoStatus();
				}
			}, 1000);
		} else {
			controls.removeClass('loading').css('background', 'none').find('a').show();
			controls.fadeOut();
		}
	}
	function playVideo() {
		var video;
		if (that.isSupportVideo) {
			video = document.getElementsByTagName('video')[0];
			video.play();
			if (!timer) checkVideoStatus();
			checkVideoStatus();
		} else {
			video = document.getElementById('myVideo');
			video.playFlv();
		}
		$('#videoControlls').find('.play').addClass('paused');
		$(video).show();
		hideSidebar();
	}
	that.pauseVideo = function (isWithBar) {
		var video;
		if (that.isSupportVideo) {
			video = document.getElementsByTagName('video')[0];
			video.pause();
			if (timer) {
				clearTimeout(timer);
				timer = null;
			}
		} else {
			video = document.getElementById('myVideo');
			video.pauseFlv();
		}
		$('#videoControlls').fadeIn().find('.play').removeClass('paused');
		if (isWithBar) {
			isControlsRecognized = false;
			showSidebar();
		}
	}
	function checkVideoStatus() {
		var video = document.getElementsByTagName('video')[0];
		var buffer = getVideoBuffer(video);
		if (timer) clearTimeout(timer);

		var timeLeft = video.duration - video.currentTime;
		if (timeLeft < 12) that.neededBuffer = timeLeft;
		//location.hash = 'preload ' + that.neededBuffer + ',' + buffer + ',' + testCounter + ',' + parseInt(buffer / that.neededBuffer * 100);

		if (buffer < that.neededBuffer) {
			if (that.neededBuffer == 3) that.neededBuffer = 12;
			if (!video.paused) that.pauseVideo(false);
			that.progress(parseInt(buffer / that.neededBuffer * 100));
		} else {
			if (video.ended) {
				that.pauseVideo(true);
				video.currentTime = 0;
				that.neededBuffer = 12;
			} else {
				if (video.paused) {
					playVideo();
					that.progress(100);
					that.neededBuffer = (that.neededBuffer == 3) ? 12 : 3;
				}
				timer = setTimeout(function () {
					checkVideoStatus();
				}, 1000);
			}
		}
	}
	function getVideoBuffer(video) {
		var buffer = 0;
		for (var i = 0; i < video.buffered.length; i++) {
			buffer = video.buffered.end(i) - video.currentTime;
			//location.hash = video.currentTime + ', ' + video.buffered.end(i) + ', ' + (video.buffered.end(i) * 100) + ', ' + video.paused;
			//location.hash = (video.buffered.start(i) / video.duration) + '/' + (video.buffered.end(i) / video.duration);
		}
		return buffer;
	}
	function soundVideo() {
		var video;
		if (that.isSupportVideo) {
			video = document.getElementsByTagName('video')[0];
			video.volume = 1;
		} else {
			video = document.getElementById('myVideo');
			video.soundFlv();
		}
	}
	function muteVideo() {
		var video;
		if (that.isSupportVideo) {
			video = document.getElementsByTagName('video')[0];
			video.volume = 0;
		} else {
			video = document.getElementById('myVideo');
			video.muteFlv();
		}
	}
	function isSupportVideo() {
		var result = false;
		if (isSupportH264()) {
			result = true;
		//} else if (isSupportOgg()) {
			//result = true;
		//} else if (isSupportWebm()) {
			//result = true;
		}
		if ($.browser.msie && $.browser.version > 8) result = false; // disable for IE9
		return result;
	}
	function isSupportH264() {
		var v = document.createElement('video');
		return v.canPlayType && v.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
	}
	function isSupportOgg() {
		var v = document.createElement('video');
		return v.canPlayType && v.canPlayType('video/ogg; codecs="theora, vorbis"');
	}
	function isSupportWebm() {
		var v = document.createElement('video');
		return v.canPlayType && v.canPlayType('video/webm; codecs="vp8, vorbis"');
	}
};
