/*jslint browser: true, forin: true, undef: true, nomen: true, eqeqeq: true, bitwise: true, newcap: true, immed: true */

/*global window, $, BasePageController, LslpController, EventController, HyundaiDealerListController, LslpDataService, OfferListController, ContextManager, DealerListController, google */

(function()
{
	"use strict";

	/**
	 * 
	 * @constructor
	 * 
	 */
	function Controller()
	{
		// Bind the controller:
		var eventController = this.eventController = new EventController("body");
		eventController.bind(this);
		
		this.pixelTagController = new PixelTagController(eventController);
		
		// Create the dealer UI and LSLP controllers:
		this.dealerListController = new DealerListController(eventController, "#dealerList ul", "#dealerMap");
		this.lslpController = new LslpController(eventController, {
			dealerService : new LslpDataService("/hyun/getDealers.ajax?format=json"),
			offerService : new LslpDataService("/hyun/getIncentives.ajax?format=json"),
			inventoryService: new LslpDataService("/hyun/getVirtualVehicles.ajax?format=json")
		});
		this.offerController = new OfferListController(eventController, "#specialOffersTab ul", "");
		this.inventoryController = new VirtualInventoryController(eventController, "#vehicleLineUpTab ul", "#trimDetailsTemplate" );
		$("div#requestAQuotePopUp").hide();
		this.init();
		if (navigator.userAgent.match(/like Mac OS X/i)) {
			this.dealerScroll = true;
			this.virtualInventoryScroll = true;
		}
		
	}

	Controller.prototype.init = function() {
		$('.tabWrapper').hide();
		$('.specialOffersTab, .mapTab').addClass('active');
		$('#specialOffersTab, #mapTab').show();
		
		$("a[href^='http://www.hyundaiusa.com']").each(function() {
			var url = window.location.hostname + window.location.pathname;
			this.href = this.href + '?referrer=' + url;
		});
		this.eventController.trigger("pageLoaded");
		this.lslpController.findVirtualVehicles();
		this.initSubmittableInputs();
	};
	
	Controller.prototype.onShowSpecialOffers = function(event, data) {
		if (!($('.specialOffersTab').hasClass('active'))) {
			$('.vehicleLineUpTab').removeClass('active');
			$('.specialOffersTab').addClass('active');
			$('#vehicleLineUpTab').hide();
			$('#specialOffersTab').fadeIn();
			this.eventController.trigger("specialOffersDisplayed", data);
		}
	};
	

	Controller.prototype.onShowVehicleLineUp = function(event, data) {
		if (!($('.vehicleLineUpTab').hasClass('active'))) {
			$('.specialOffersTab').removeClass('active');
			$('.vehicleLineUpTab').addClass('active');
			$('#specialOffersTab').hide();
			$('#vehicleLineUpTab').fadeIn();
			this.eventController.trigger("vehicleLineupDisplayed", data);
			if (navigator.userAgent.match(/like Mac OS X/i) && this.virtualInventoryScroll == true) {
				var Inventory = document.getElementById("virtualInventoryContainer");
				this.virtualInventoryScroll = false;
	            var virtualInventory = new TouchScroll(Inventory, {
	                elastic: true, // for bouncing effect
	                scrollevents: true // DOM scroll events should be fired virtualInventoryContainer
	            });
			}
		}
	};

	Controller.prototype.onShowMap = function(event, data) {
		if (!($('.mapTab').hasClass('active'))) {
			$('#dealerMap').focus();
			$('.dealerDirTab').removeClass('active');
			$('.mapTab').addClass('active');
			$('#dealerDirTab').hide();
			$('#mapTab').fadeIn();
			google.maps.event.trigger(this.dealerListController.map, "resize");
			this.eventController.trigger("mapDisplayed", data);
		}
	};

	Controller.prototype.onShowDealerDir = function(event, data) {
		if (!($('.dealerDirTab').hasClass('active'))) {
			$('.mapTab').removeClass('active');
			$('.dealerDirTab').addClass('active');
			$('#mapTab').hide();
			$('#dealerDirTab').fadeIn();
			this.eventController.trigger("dealerDirDisplayed", data);
			if (navigator.userAgent.match(/like Mac OS X/i) && this.dealerScroll == true) {
				var Dealers = document.getElementById("dealerListContainer");
				this.dealerScroll = false;
		        var myDealers = new TouchScroll(Dealers, {
		            elastic: true, // for bouncing effect
		            scrollevents: true // DOM scroll events should be fired 
		        });
			}
		}
	};

	Controller.prototype.initSubmittableInputs = function()
	{
		$("input").focus(function()
        {
            $(this).select();
        });
        
        $("body").delegate("input", "keypress", function(event)
        {
            // Don't bother checking if the keypress isn't an "enter":
            if (event.keyCode !== 13) {return;} 
            
            var target = $(this).blur().data().target;
            
            if(target)
            {
                $(target).click();
            }
        });        
	};
   
	Controller.prototype.onWrongInput = function(event, data)
	{
		var i,
        container = $(data),
        duration = 75,
        side = container.css("float") === "right" ? "margin-right" : "margin-left",
        margin = parseInt(container.css("margin-left"), 10) || 0, movement;
		  
		for(i = 0; i < 3; i++) 
		{
			movement = {};
			movement[side] = margin + 5;
			container.animate(movement, duration);
           
			movement = {};
			movement[side] = margin - 5;
			container.animate(movement, duration);
		}
       
		movement = {};
		movement[side] = margin;
		container.animate(movement, duration, function() {
			container.find("input").focus().select();
		});
	};

	Controller.prototype.onDealerGroupChanged = function(event, result)
	{
		if (result.groupName) {
			$("#dealerDirTab").show();
	   		$("#dealerListContainer").scrollTop(0,0);
	   		$("div#offersContainer").scrollTop(0);
	   		$("#dealerDirTab").hide();
	        $('#headerWrapper').html(result.groupName);
	        $('#dealerListHeader h4').html(result.groupName);
	        document.title = result.groupName;
	
	        this.setBackgroundImg(result.groupCode);            
	        this.updateSEOcell(result.groupCode);
		}    	
	   	if (result.zip != null) {       
	   		this.groupZipCode = result.zip;
	   	}
	};

	Controller.prototype.setBackgroundImg = function(groupCode) 
	{
		var imgBaseURL = ContextManager.getUrl();
		if (imgBaseURL) {
			if (imgBaseURL.charAt(imgBaseURL.length - 1) !== '/') {
				imgBaseURL = imgBaseURL + '/';
			}
			var newBkgdImg = new Image();
			var imgFolder = 'lslp_backgrounds/';
			var bkgdImgSrc = imgBaseURL + imgFolder + groupCode + '.jpg';
			var defaultBkgdImgSrc = imgBaseURL + imgFolder + 'default.jpg';

			$('body').css('background-image', 'url(' + bkgdImgSrc + ')');
	
			newBkgdImg.onerror = function() {				
                $('body').css('background-image','url(' + defaultBkgdImgSrc + ')');				
			};
			newBkgdImg.src = bkgdImgSrc;
		}
	};
		
	Controller.prototype.updateSEOcell = function(groupCode) 
	{
		var URL = document.location.protocol + '//' + document.location.host + '?cs:groupCode=' + groupCode;
		jQuery.ajax({
            dataType:'text'
           ,url:URL
           ,success:function(data,status,xhr) {
				var SEOcell = '#seo';
				var div = document.createElement('div');
				var html;
				div.innerHTML = data;
				html = jQuery(SEOcell,div).html();					
				jQuery(SEOcell,document).html(html);
           }
        });
	};
	
	Controller.prototype.onInvalidDealerGroup = function(event, data)
    {
		this.eventController.trigger("wrongInput", data.target);
    };
    
	Controller.prototype.prepareDealerList = function(dealerGroup)
	{   
		if (dealerGroup.dealers != undefined) {
			var  dealerListLength = dealerGroup.dealers.length;
			for ( var i = 0; i < dealerListLength; i++) {
				var thisDealer = dealerGroup.dealers[i];
				if (!thisDealer.thirdPartyUrl) {
					thisDealer.thirdPartyUrl = null;
				}
			}
		}
	};
	
	Controller.prototype.onDealerGroupLoaded = function(event, dealerGroup)
	{
		this.prepareDealerList(dealerGroup);
       
		// build the dealer list for incentives drop down
		if (dealerGroup.dealers != undefined) {
			var dealerNameList = "", 
				dealerListLength = dealerGroup.dealers.length;
			for ( var i = 0; i < dealerListLength; i++) {
				var thisDealer = dealerGroup.dealers[i];
				if (thisDealer.siteSubType == 'WEB') {
					dealerNameList += '<option value="'
							+ thisDealer.links.quick_quote.url
							+ '">' + thisDealer.dealerName
							+ '</option>';
				}
			}
			this.dealerNameList = dealerNameList;
			$('#requestAQuoteSelect select').html('<option value="">Select a dealership</option>'+dealerNameList);
			$('#dealerListContainer').show();
		}
	};   
    
	Controller.prototype.onShowOfferDetail = function(event, data) {
		if (this.dealerNameList != undefined 
								&& $(data.target).find('.dealerSelectionList option').length < 2) 
		{
			$('.dealerSelectionList').append(this.dealerNameList);
		}

		if (this.groupZipCode != false) 
		{
			$('.zipcodeValue').html(this.groupZipCode);
		}
		// individualOfferDetail
		
		var layoutWrapperPosition = $('#layoutWrapper').offset();
		$(data.target).css('left', layoutWrapperPosition.x);
		$(data.target).show();
		$('#overlayBG').show();
		
		if(navigator.userAgent.match(/like Mac OS X/i)) {
			$("body").append($(data.target));
			$("li div"+data.target).css("display", "none");
			$(data.target).show();
			$(data.target).css("margin-left", "30px");
			$('#overlayBG').show();
		}
	};
	
	Controller.prototype.onClosePopUp = function(event, data)
	{
		$(data.target).hide();
		$('#overlayBG').hide();	
	};

	Controller.prototype.onDealerGroupNotDetermined = function(event, result)
	{
		$('#zipPrompt, #overlayBG').show();
		
	};
		
	Controller.prototype.onDealerGroupNotLoaded = function(event, error)
	{
		this.groupZipCode = $("#getZip").val();
		this.radius = $("#getRadius option:selected").val();

		if(!this.groupZipCode){
			this.groupZipCode = $("#zip").val();
		}
		var html = "No participating Hyundai dealers within "+this.radius+" miles for the zip code "+this.groupZipCode;
		var defaultHeader = "Hyundai Dealers";
		$('#dealerList ul').html('<p class="noDealersMessage">'+html+'</p>');
		$('#dealerListHeader h4').html(defaultHeader);
		$('#headerWrapper').html(defaultHeader);
		document.title = defaultHeader;
		this.groupZipCode = "No dealers found";
		$('#requestAQuoteSelect select').html('<option value="">No dealers found</option>');
		this.dealerListController.init();
		this.setBackgroundImg(this.groupCode);
		this.eventController.trigger("showAlert", html);
	};
	
	Controller.prototype.onDealerGroupLoading = function(event, result)
	{
		$('#zipPrompt, #overlayBG').hide();
	};

	Controller.prototype.onGoToGaQonDealerSite = function(event, data)
	{	
		var source = data.source || "";
		var dealersite = $(data.target).val();
		var label = "";

		if (dealersite != "") 
		{
			if (source == "vehicleLineUp") {
				label = "vehiclelineup_requestaquote_";
			} else {
				label = "specialofferrequestaquote_";
			}
			var details = data.details || "";
			window.open(dealersite + "c&cs:a:i=" + label + details);
		}
		else
		{
			var errorMessage = "Please select a valid dealership in the required field and resend your request.";
			this.eventController.trigger("showAlert", errorMessage);
		}
	};
	
	
	Controller.prototype.formatCurrency = function(num)
	{
		num = num.toString();
		for ( var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++)
			num = num.substring(0, num.length - (4 * i + 3)) + ','
					+ num.substring(num.length - (4 * i + 3));
		return ('$' + num);
	};
	
    Controller.prototype.onTrimDetailsTab = function(event, data)
    {
    	$("ul#trimDetailsTabs li").removeClass("active");
    	var activeTab = "ul li#"+data.target;
    	var activeContent = "#trimTabContentWrapper div#"+data.target+"Div";
		$(activeTab).addClass("active");
    	$(".trimTabContent").hide(); 
    	$(activeContent).fadeIn();
		$(activeTab).fadeIn();
		return false;
    }; 
    
    Controller.prototype.onToggleTrimDetails = function(event, data)
    {
    	$("#"+data.target).slideToggle("fast");
    	if($("#"+data.target).prev().hasClass('active')){
    		$("#"+data.target).prev().removeClass('active');
    	}else{
    		$("#"+data.target).prev().addClass('active');
    	}

    };
    
    Controller.prototype.onShowRequestAQuote = function(event, data)
    {
		var year = data.year || "";
        var model = data.model || "";
        var locale = "en-US";
        model = model.replace(/ /g,"_").toLowerCase();
        $("div#requestAQuoteContent a#submitButton").attr('data-details',model + "-" + year + "-" + locale);
        
    	$("div#requestAQuotePopUp").show();
    	$('#overlayBG').show();
    	$('#requestAQuoteSelectOptions option:first').attr('selected', 'selected');
    	if (this.groupZipCode) 
		{
    		$('#presentZipCode').html(this.groupZipCode);
		}else {
			$('#presentZipCode').html($("input[name='defaultZipCode']").val());
		}	
    };
   
    Controller.prototype.onShowAlert = function(event, errorMessage) {
    	
    	$('#noDataAlert #alertMessageContainer').empty().append(errorMessage);
	    $("#noDataAlert").show();
	    $('#alertOverlayBG').show();
    };
    
    Controller.prototype.onCloseAlert = function(event, data)
	{
		$(data.target).hide();
		$('#alertOverlayBG').hide();
	};
	
	// Make the controller available globally:
	window.LslpPageController = Controller; 
})();

LslpController.prototype.findVirtualVehicles = function(dealerGroup)
{
    if (this.inventoryService)
    {
        var me = this;
        
        dealerGroup = dealerGroup || this.dealerGroup;
    
       // this.eventController.trigger("offerGroupLoading", dealerGroup);
        this.inventoryService.find(dealerGroup, function(result, error)
        {
        	me.handleVirtualVehiclesLoaded(result, error);
        });
    }
};    

LslpController.prototype.handleVirtualVehiclesLoaded = function(result, error)
{
    var dealerGroup = this.dealerGroup = this.getDealerGroupFromCookie();
    if (error || !result || !result.vehicles || result.vehicles.length === 0)
    {
        this.eventController.trigger("offersNotLoaded", error);
    }
    else
    {
    	this.eventController.trigger("prepareVirtualInventory", [result]);
        this.eventController.trigger("inventoryLoaded");
    }
}; 



LslpController.prototype.handleOffersLoaded = function(result, error)
{
    var dealerGroup = this.dealerGroup = this.getDealerGroupFromCookie();
    if (error || !result || !result.incentives || result.incentives.length === 0)
    {
        this.eventController.trigger("offersNotLoaded", error);
    }
    else
    {
        dealerGroup = this.dealerGroup = this.getDealerGroupFromCookie();
        this.eventController.trigger("offersLoaded", [result]);
    }
};     
    
DealerListController.prototype.updateMap = function(dealerGroup) {
	var dealers = dealerGroup && dealerGroup.dealers || [], bounds = new google.maps.LatLngBounds(), me = this;
	// Add a pin for each dealer
	this.removeAllPins();
	dealers = this.sortByRenderOrder(dealers);
	if(dealerGroup.zip == undefined){
			$(dealers).each(function() {
				me.addDealerPin(this);
				bounds.extend(this.marker.position);
			});
	}
	else
		{
			$(dealers).each(function() {
				if (this.dealerSearchResultType == "zip") {
					me.addDealerPin(this);
					bounds.extend(this.marker.position);
				}
			});
		
		}
	// Center the map on the dealer group:
	this.map.fitBounds(bounds);

	// Don't zoom in *too* far:
	if (this.map.zoom === 20) {
		this.map.setZoom(17);
	}
};

/* Overriding point to customize the dealer pin, ie Hyundai Pin */

DealerListController.prototype.addDealerPin = function(dealer) {

	var point = new google.maps.LatLng(dealer.latitude, dealer.longitude),
	options = {
		position : point,
		map : this.map,
		title : dealer.dealerName
	},
	marker = new google.maps.Marker(options),
	me = this,
	mapImgBaseURL = ContextManager.getUrl()+"mapIcons/";
	
	marker.setIcon(mapImgBaseURL+'hyundaiPin.png');
	marker.setShadow(mapImgBaseURL+'hyundaiPinShadow.png');
	this.markers.push(marker);
	dealer.marker = marker;
	// Delegate the pin's click event:
	google.maps.event.addListener(dealer.marker, 'click', function(event) {
		me.showPinDetails(event, dealer);
	});
};

DealerListController.prototype.showPinDetails = function(event, dealer)
{
	var html;
	// Hide the zip code panel and any old overlay:
	$("#zipCodePanel").hide();
	if (this.infoWindow)
	{
		this.infoWindow.close();
	}
	// Render the popup and add it to the map:
	html = $("#dealerDetailsTemplate").tmpl(dealer);
	html = html.html();
	this.infoWindow = new google.maps.InfoWindow({
		maxWidth : 300,
		content : html
	});
	this.infoWindow.open(this.map, dealer.marker);
	// to keep the details centered):
	this.map.panTo(dealer.marker.getPosition());
	this.map.panBy(0, -100);
	this.eventController.trigger("mapPinDisplayed", dealer);
};

OfferListController.prototype.onOffersLoaded = function(event, result)
{
	var offers = this.offers = this.createOfferList(result),
	html;
	// Render the offer list:
	html = this.offerListTemplate.tmpl(offers);
	this.offerList.empty().append(html);
	// Display the number of offers found:
	this.offerList.find(".total").html(offers.length);
	$('div #offersHeader div.updated').html("Updated " + $("input[name='createdDate']").val());
	$("#offersContainer").scrollTop(0);
	// Select the first offer (if available):
	if (offers.length)
	{
		this.eventController.trigger("offerSelected", {
			offer : result.incentives[0]
		});
	}
};

OfferListController.prototype.onOffersNotLoaded = function(event, error)
{
	var html = "<p class='noOffersMessage'>Please contact your local Hyundai dealer for current promotions while this page is being updated.</p>";
	this.offerList.empty().fadeIn("slow").append(html);
};

OfferListController.prototype.createOfferList = function(result)
{
	var offers = result.incentives || [],
	deal = [ offers[0] ];
	deal[deal.length - 1].offerDetails = [],
			deal[deal.length - 1].offerDetailsLong = [];
	for (i = 0; i < offers.length; i++)
	{
		var thisOffer = offers[i];
		deal.id = "offer" + i;
		thisOffer.cost = pageController.formatCurrency(thisOffer.cost);
		var length = deal.length;
		if (deal[length - 1].modelNameShort != thisOffer.modelNameShort
				|| deal[length - 1].modelYear != thisOffer.modelYear)
		{
			deal[length] = thisOffer;
			deal[length].id = length;
			deal[length].offerDetails = [ {
				name : thisOffer.name,
				type : thisOffer.type,
				descriptionLong : thisOffer.descriptionLong
			} ];
		}
		else
		{
			deal[length - 1].offerDetails.push({
				name : thisOffer.name,
				type : thisOffer.type,
				descriptionLong : thisOffer.descriptionLong
			});
		}
	}
	return deal;
};

