/*jslint browser: true, forin: true, onevar: true, undef: true, nomen: true, eqeqeq: true, newcap: true, immed: true */
/*global window, $, CobaltPixelTag, s_gi, s, console, ContextManager */

(function()
{
	var domainMap = {
		"acc.cars.com": "cc",
		"accessories.bmwusa.com": "bmwa",
		"ads.autotrader.com": "at",
		"ads.cars.com": "cc",
		"adserving.autotrader.com": "at",
		"apps.gm.ca": "gcdl",
		"ask.cars.com": "cc",
		"auth.owners.lexus.com": "ld",
		"automobiles.honda.com": "ahmc",
		"autos.yahoo.com": "ya",
		"beta.cars.com": "cc",
		"blogs.cars.com": "cc",
		"bmwcpodealer.com": "bcpo",
		"bmwt2dealer.com": "bmwt2",
		"consumerguide.cars.com": "cc",
		"dealerlocator.saab-web.com": "sbus",
		"dealers.vw.com": "vwoa",
		"edmunds.autotrader.com": "at",
		"eshopping.honda.com": "ahmc",
		"extranet.cars.com": "cc",
		"gmaccessories.dealertrack.com": "gmch",
		"gmaccessorieszone.com": "gmaz",
		"gmownercenter.yahoo.com": "gmoc",
		"images.autotrader.com": "at",
		"inventory.autotrader.com": "at",
		"inventoryeditor.cars.com": "cc",
		"local.nissanusa.com": "nusa",
		"m.buick.com": "bmus",
		"m.cadillac.com": "camus",
		"m.chevrolet.com": "cvmus",
		"m.gm.com": "gmmus",
		"m.gmc.com": "gmcmus",
		"maps.google.com": "gm",
		"miniusa.com": "mu",
		"motors.shop.ebay.com": "e",
		"my.subaru.com": "mys",
		"newcars.cars.com": "cc",
		"nissan.nissan-dealer.com": "ndl",
		"nitra.bmwcpodealer.com": "bcpo",
		"offers.saturn.com": "snus",
		"owners.acura.com": "mya",
		"preview.autotrader.com": "at",
		"research.cars.com": "cc",
		"sitesearch.cars.com": "cc",
		"siy.cars.com": "cc",
		"vw.com": "vwoa",
		"vwcertified.vw.com": "vwcu",
		"web.vw.com": "vwoa",
		"ww.cars.com": "cc",
		"www.acura.com": "acus",
		"www.audi.ca": "auca",
		"www.audi.com": "aua",
		"www.audiusa.com": "aua",
		"www.automart.com": "amc",
		"www.autotrader.com": "at",
		"www.blackbookusa.com": "bbo",
		"www.bmwcpodealer.com": "bcpo",
		"www.bmwt2dealer.com": "bmwt2",
		"www.bmwusa.com": "bmwna",
		"www.bpgdealers.com": "bpgd",
		"www.buick.com": "bus",
		"www.buickdealer.com": "bt2",
		"www.cadillac.com": "caus",
		"www.cadillacdealer.com": "cat2",
		"www.carfax.com": "cfx",
		"www.cars.com": "cc",
		"www.chevrolet.com": "cvus",
		"www.chevydealer.com": "cvt2",
		"www.edmunds.com": "edc",
		"www.gm.ca": "gmcl",
		"www.gm.com": "gmcw",
		"www.gmaccessorieszone.com": "gmaz",
		"www.gmbuypower.com": "gbp",
		"www.gmc.com": "gmcus",
		"www.gmcdealer.com": "gmct2",
		"www.gmcertified.com": "gmcu",
		"www.gmfleet.com": "gmf",
		"www.gmgoodwrench.com": "gmgw",
		"www.goodwrench.com": "gw",
		"www.hummer.com": "hus",
		"www.hummerdealer.com": "ht2",
		"www.hyundaiusa.com": "hma",
		"www.hyunlslpdealer.com": "hyunt2",
		"www.infiniti.com": "icw",
		"www.infinitiusa.com": "ius",
		"www.kbb.com": "kbbw",
		"www.kia.com": "kia",
		"www.lcpo.com": "lcpo",
		"www.lexus.com": "lex",
		"www.miniusa.com": "mu",
		"www.mitsubishicars.com": "mmna",
		"www.nissanusa.com": "nusa",
		"www.onstar.com": "gmos",
		"www.owners.acura.com": "mya",
		"www.pontiac.com": "pus",
		"www.pontiacdealer.com": "pt2",
		"www.saabdealer.com": "sbt2",
		"www.saabusa.com": "sbus",
		"www.saturn.com": "snus",
		"www.saturndealer.com": "snt2",
		"www.scion.com": "sus",
		"www.spt.subaru.com": "spt",
		"www.subaru.com": "soa",
		"www.volvocars.com": "vus",
		"www.vw.ca": "vwca",
		"www.vw.com": "vwoa",
		"www.yourlexusdealer.com": "yld",
		"wwww23.pontiac.com": "pus"
	};
	
	/**
	 * Retrieves a parameter from the URL. 
	 * Borrowed from VW Tier3.
	 */
	function queryParm(parm) {
        if (!qParmArray) {
            var tmp = document.location.search.slice(1).split('&');
            qParmArray = [];
            for (var i=0,len=tmp.length; i<len; i++) {
                if (tmp[i].length > 0) qParmArray[i] = tmp[i].split('=');
            }
        }
        for (var i=0,len=qParmArray.length; i<len; i++) {
            if (qParmArray[i][0] === parm) {
                return decodeURIComponent(qParmArray[i][1]);
            }
        }
    }		
	
	/**
	 * Retrieves the campaign ID from the URL. 
	 * Borrowed from VW Tier3.
	 */
	function campaign() {
         var cs_a_or_ae = queryParm('cs:a') || queryParm('cs:a:e');
         if (cs_a_or_ae) {
             return [
                 cs_a_or_ae,
                 queryParm('cs:pro') || '',
                 queryParm('cs:e') || ''
             ].join(':').replace(/^::$/,''); // '::' shouldn't happen, but oh well
         }
         return null;
    }
	

	function getReferrerDomain() {
		var regExp = /https?:\/\/([^\/]+)/,
			match = regExp.exec(document.referrer);
		
		if(match) {
			return match[1];
		}
	};
	
	function getBiChannel() {
		var csE    = queryParm('cs:e'),
			gclid  = queryParm('gclid'),
			domain = getReferrerDomain();
	
		if(csE) {
			return csE;
		} else if(gclid) {
			return "g";
		} else if(domain) {
			return domainMap[domain]; // The domain or undefined
		}
	}
	
    var DART_TYPE_HOMEPAGE = "homepage",
        DART_TYPE_HANDOFF = "handoff",
        DART_TYPE_DEALER = "dealer",
        DART_TYPE_OFFER = "spcoffer",
        DART_TYPE_QUOTE = "reaquote",
        DART_SRC = "2617051",
        DART_SPECIAL_OFFER_CATEGORIES =
        {
            "default": "specoff",
            ":": "specoff",            
            cc: "spcoffcc",
            cpo: "spoffcpo",
            eos: "spoffeos",
            golf: "spoffglf",
            gti: "spoffgti",
            jetta: "spoffjet",
            jsw: "spojetsw",
            nb: "sponwbee",
            nbc: "spnbeecv",
            passat: "spcopass",
            passatwagon: "sopasswg",
            routan: "spcorout",
            tiguan: "spcoftig",
            touareg: "spotourg",
            beetle: "sponwbee"
        },
        DART_DEALER_HANDOFF_CATEGORIES = 
        {
            "default": "dealhand",
            cc: "hdoffcc",
            cpo: "hdoffcpo",
            eos: "hdoffeos",
            golf: "hdoffglf",
            gti: "hdoffgti",
            jetta: "hdoffjta",
            jsw: "hdoffjsw",
            nb: "hdoffnb",
            nbc: "hdoffnbc",
            passat: "hdoffpst",
            passatwagon: "hdoffpsw",
            routan: "hdoffrtn",
            tiguan: "hdofftgn",
            touareg: "hdofftrg",
            beetle: "hdoffnb"
        },
        DART_QUOTE_CATEGORIES =
        {
            "default": "requote",
            cc: "requotcc",
            cpo: "requocpo",
            eos: "requoeos",
            golf: "requoglf",
            gti: "requogti",
            jetta: "requojet",
            jsw: "reqjetsw",
            nb: "reqnwbee",
            nbc: "rqnbeecv",
            passat: "reqpasst",
            passatwagon: "reqpaswg",
            routan: "reaqrout",
            tiguan: "requotig",
            touareg: "reqtouar",
            beetle: "reqnwbee"
        },
        DEFAULT_OMNITURE_PROPERTIES =
        {    		
            prop5: ContextManager.getVisitorId(),
            prop6: ContextManager.getSessionId(),
            prop8: "DMAsite",
            eVar8: "DMAsite",
            server: window.location.href.split("/")[2],
            eVar12: queryParm('cs:pro'),
            eVar13: getBiChannel(),
            campaign: campaign(),
            eVar42: campaign(),
            eVar43: campaign(),
            eVar60: ContextManager.getSessionId()
        };
    
    
    /**
     * The PixelTagController listens for LSLP page events, and fires pixel tags in response.
     * @param eventController (EventController)
     */
    function Controller(eventController)
    {
        this.searchLocation = "map";
        
    	VWOmnitureConfig.init();
    	
        this.eventController = eventController;
        eventController.bind(this);
    }
    
    
    /**
     * Keeps track of the currently selected dealer group.
     * @param event (object)
     * @param dealerGroup (object) The current dealer group
     */
    Controller.prototype.onDealerGroupChanged = function(event, dealerGroup)
    {
        // TODO: In future pixel tag implementations, try to implement one event per tag.
        console.log("Event: dealerGroupChanged");
        
        var category,
        	s = {},
        	model;
        
    	this.searchLocation = this.listVisible && "list" || "map";
    	this.searchWidget = this.searchWidget || dealerGroup.searchWidget;
        this.searchType = this.searchType || dealerGroup.dealerName && "dealerName" || "zip";
        this.searchValue = this.searchValue || dealerGroup.dealerName || dealerGroup.zip;
        this.dealerGroup = dealerGroup;
        
        // Determine if the group was updated on the home page:
        if (dealerGroup.location === "DealerLocator")
        {
            s.pageName = "dmasite:homepage";
            s.channel = "homepage:dmasite";
            s.events = "event43";
        }
        else if (dealerGroup.location === "FinanceOffers")
        {        	
            s.pageName = "dmasite:homepage";
            s.channel = "homepage:dmasite";
            s.events = "event38";
        }
        else if (dealerGroup.location === "DealerLocatorPage")
        {
            s.pageName = "dmasite:dealerlocator:" + this.searchLocation + ":" + this.searchType;
            s.channel = "dealerLocator:dmasite";
            s.eVar33 = this.searchWidget;
        }
        else if (dealerGroup.location === "FinanceOffersPage")
        {
        	category = this.getDartCategory(DART_SPECIAL_OFFER_CATEGORIES);
        	
        	if (this.dealerGroup.model === ":")
        	{
        		model = "all";
        	}
        	else
        	{
        		model = $("#models option:selected").html();
        	}
        	
            s.pageName = "dmasite:specialoffers";
            s.channel = "specialoffers:dmasite";
            s.eVar1 = s.prop1 = model;
            s.eVar33 = this.searchWidget;
        }
            
        // If we're on the homepage, register the click of the "Go" button:
        if (s.pageName)
        {
            s.eVar4 = s.prop4 = dealerGroup.zip;
            s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
            this.fireOmniture(s, "dealerGroupChanged");
        }         
        
        if (category)
        {
        	this.fireDart(DART_TYPE_OFFER, category); 	
        }
        
        this.updateHandoffLinks();
    };
    
    
    /**
     * Keeps track of the any partially populated dealer group.
     * @param event (object)
     * @param dealerGroup (object) A partially populated dealer group
     */
    Controller.prototype.onDealerGroupNotDetermined = function(event, dealerGroup)
    {
        console.log("Event: dealerGroupNotDetermined");
        this.dealerGroup = dealerGroup;
    };
    
    
    
    // C O M M O N   E V E N T S
    
    
       
    /**
     * Invoked when the user opens vw.com.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI 
     */
    Controller.prototype.onVisitVw = function(event, data)
    {
        console.log("Event: visitVw");
        
        var s = {};
        
        s.pageName = "dmasite:homepage:lo:vw.com";
        s.channel = "homepage:dmasite";
        s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
        s.prop14 = $(data.element).html() + ":dmasite";
        
        this.fireDart(DART_TYPE_HANDOFF, "vwhand");
        this.fireOmniture(s, "visitVw");
    };
    

    /**
     * Invoked when the user opens vw.com.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI 
     */
    Controller.prototype.onContactUs = function(event, data)
    {
        console.log("Event: contactUs");
        
        var s = {};
        
        s.pageName = "dmasite:homepage:lo:contactUs";
        s.channel = "homepage:dmasite";
        s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
        s.prop14 = $(data.element).html() + ":dmasite";
        
        this.fireDart(DART_TYPE_HANDOFF, "vwhand");
        this.fireOmniture(s, "contactUs");
    };
    
    
    /**
     * Invoked when the user opens vw.com.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI 
     */
    Controller.prototype.onPrivacyPolicy = function(event, data)
    {
        console.log("Event: privacyPolicy");
        
        var s = {};
        
        s.pageName = "dmasite:homepage:lo:privacyPolicy";
        s.channel = "homepage:dmasite";
        s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
        s.prop14 = $(data.element).html() + ":dmasite";
        
        this.fireDart(DART_TYPE_HANDOFF, "vwhand");
        this.fireOmniture(s, "privacyPolicy");
    };    
       
    
    /**
     * Fired when the dealer group needs to be updated.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI 
     */
    Controller.prototype.onUpdateDealerGroup = function(event, dealerGroup)
    {
    	this.searchWidget = undefined;
        this.searchType = undefined;
        this.searchValue = undefined;
        this.searchLocation = undefined;
    };
    

    /**
     * Fired when the promo rotator opens in a new window.
     * @param event (object)
     * @param data (object)
     */
    Controller.prototype.onPromoExternalWindow = function(event, data)
    {
        console.log("Event: promoExternalWindow");       
        this.fireCobalt("com.cobaltgroup.ws.action.link", data);
    };

    
    // H O M E   P A G E
    
    
    
    /**
     * Fired when the home page loads.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onHomePageLoaded = function(event, data)
    {
        console.log("Event: homePageLoaded");
                
        var s = {},
        	referrer = this.findParameters();
        
        this.pageLoading = true;
        
        s.pageName = "dmasite:homepage";
        s.channel = "homepage:dmasite";
        s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
        s.eVar52 = !referrer.keyword && referrer.query || undefined; 
        s.eVar53 = referrer.keyword && referrer.query || undefined;
        s.eVar54 = referrer.keyword;
        
        this.fireDart(DART_TYPE_HOMEPAGE, "vwdealer");
        this.fireCobalt("com.cobaltgroup.ws.view.page");
        this.fireOmniture(s, "homePageLoaded");
        
        this.pageLoading = false;
    };
        
    
    
    // D E A L E R   P A G E 
    
    
    
    /**
     * Fired when the dealer locator page loads. 
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onDealerLocatorPageLoaded = function(event, data)
    {
        console.log("Event: dealerLocatorPageLoaded");
        
        var options = {},
            s = {},
            referrer = this.findParameters();
        
        this.pageLoading = true;
        
        options.zip = this.dealerGroup.zip;
        
        s.pageName = "dmasite:dealerlocator:map";
        s.channel = "dealerLocator:dmasite";
        s.prop2 = s.eVar2 = this.dealerGroup.dma;
        s.eVar4 = s.prop4 = this.dealerGroup.zip;
        s.eVar52 = !referrer.keyword && referrer.query || undefined; 
        s.eVar53 = referrer.keyword && referrer.query || undefined;
        s.eVar54 = referrer.keyword;

        
        this.fireDart(DART_TYPE_DEALER, "fad");
        this.fireCobalt("com.cobaltgroup.ws.view.page", options);
        this.fireOmniture(s, "dealerLocatorPageLoaded");
    };

    
    /**
     * Fired when a dealer list request is initiated.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onDealerGroupLoading = function(event, data)
    {
        console.log("Event: dealerGroupLoading");
        
        // Only fire this event when searching from the bottom:
        if (data.searchWidget !== "bottom") {return;}
        
        var s = {};
       
        s.pageName = "dmasite:dealerlocator:" + this.searchLocation + ":" + this.searchType;
        s.channel = "dealerLocator:dmasite";
        s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
        s.prop11 = data.zip || data.dealerName;
        s.eVar33 = this.searchWidget;
        s.events = "event40";

        this.fireOmniture(s, "dealerGroupLoading");
    };
    
    
    /**
     * Fired when a dealer list request is initiated.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onDealerGroupLoaded = function(event, data)
    {
        console.log("Event: dealerGroupLoaded");
                
        var s = {};
        
        this.firstDealer = true;
        
        s.pageName = "dmasite:dealerlocator:" + this.searchLocation + ":" + this.searchType;
        s.channel = "dealerLocator:dmasite";
        s.events = "event41";
        s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
        s.prop11 = this.searchValue;
        s.eVar4 = s.prop4 = this.dealerGroup.zip;

        this.fireOmniture(s, "dealerGroupLoaded");
    };
    
    
    /**
     * Fired when the user opens/closes the dealer list.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onToggleList = function(event, data)
    {
        console.log("Event: toggleList");
        
        var hidden = $("#dealerList").hasClass("hidden"),
            s = {};
        
        s.pageName = "dmasite:dealerlocator:list";
        s.channel = "dealerLocator:dmasite";
        s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
        
        this.listVisible = false;
        if(!hidden)
        {
            this.listVisible = true;
            this.fireOmniture(s, "toggleList");
        }
    };
    
        
    /**
     * Fired when the user selects a dealer to view in the map.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onDealerSelected = function(event, data)
    {
        console.log("Event: dealerSelected");
        
        var dealer,
            firstDealer = this.firstDealer && "D:" || "",
            location = this.listVisible && "list" || "map",
            s = {};
        
        dealer = data && (data.dealer || $(data.target).tmplItem().data); 
        
        if(dealer)
        {
            s.pageName = "dmasite:dealerlocator:" + location;
            s.channel = "dealerLocator:dmasite";
            s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
            s.eVar32 = firstDealer + dealer.webId;
            s.events = "event37";
        
            this.fireCobalt("com.cobaltgroup.ws.action.open.dealerLocator.dealerBubble", {pageLayout: "dealerlocator_dealerbubble"});
            this.fireOmniture(s, "dealerSelected");
            
            this.firstDealer = false;
            this.pageLoading = false;
        }

    };
    
    
    /**
     * Fired when a dealer is selected in the dealer list:
     */
    Controller.prototype.onSelectDealer = function(event, data)
    {        
        console.log("Event: selectDealer");
        
        var dealer = $(data.target).tmplItem().data,
            s = {};

        s.pageName = "dmasite:dealerlocator:list";
        s.channel = "dealerLocator:dmasite";
        s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
        s.eVar32 = dealer.webId;
        s.events = "event37";
        
        this.fireOmniture(s, "selectDealer");
    };
    
    
    /**
     * Fired when the user clicks on any "visit dealer" link.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onDealerHomePage = function(event, data)
    {
        console.log("Event: dealerHomePage");
        
        var s = {},
            source = data.source === "dealerbubble" ? "map" : "list";
        
        s.pageName = "dmasite:dealerlocator:" + source + ":lo:visitDealerWebsite";
        s.channel = "dealerLocator:dmasite";
        s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
        s.eVar31 = "Launch Dealer Site";
        s.events = "event1, event2:" + ContextManager.getSessionId();
        
        //this.fireDart(DART_TYPE_HANDOFF, "dealhand");
        this.fireDart(DART_TYPE_HANDOFF, "hdofffad");
        this.fireOmniture(s, "dealerHomePage");
    };
    
    
    /**
     * Fired when the user clicks on any "get directions" link.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onHoursAndDirections = function(event, data)
    {
        console.log("Event: hoursAndDirections");
        
        var s = {}, 
            source = data.source === "dealerbubble" ? "map" : "list";
       
        s.pageName = "dmasite:dealerlocator:" + source + ":lo:getDirections";
        s.channel = "dealerLocator:dmasite";
        s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
        s.eVar31 = "Hours and Directions";
        s.events = "event1, event2:" + ContextManager.getSessionId();
        
        //this.fireDart(DART_TYPE_HANDOFF, "dealhand");
        this.fireDart(DART_TYPE_HANDOFF, "hdoffdir");
        this.fireOmniture(s, "hoursAndDirections");
    };    
    
    
    /**
     * Fired when the user clicks on any "show on map" link.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onShowDealer = function(event, data)
    {
        console.log("Event: showDealer");
        
        // At this point, the list is no longer visible:
        this.listVisible = false;
        
        this.fireCobalt("com.cobaltgroup.ws.action.open.dealerLocator.dealerList", {pageLayout: "dealerlocator_showonmap"});
    };   
    
    
    /**
     * Fired when a dealer search returns no data.
     * @param event (object)    
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onDealerGroupNotLoaded = function(event, error)
    {
        console.log("Event: dealerGroupNotLoaded");
        
        // Only fire this event if zero results were returned:
        // TODO: Uncomment when back-end ca differentiate between errors and no results found.
        // if (error) {return;}
        
        var s = {},
            source = this.listVisible && "list" || "map",
            value = this.searchValue;
        
        s.pageName = "dmasite:dealerlocator:" + source + ":" + this.searchType + ":error";
        s.channel = "dealerLocator:dmasite";
        s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
        s.prop11 = this.searchValue;
        s.events = "event39, event42";
                
        this.fireOmniture(s, "dealerGroupNotLoaded");
    };
    
    
    
    // O F F E R   P A G E
    
    
    
    /**
     * Fired when the offer page loads.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onOfferPageLoaded = function(event, data)
    {
        console.log("Event: offerPageLoaded");
        
        var category = this.getDartCategory(DART_SPECIAL_OFFER_CATEGORIES),
            model,
            options = {},
            s = {},
            referrer = this.findParameters();
        
        this.pageLoading = true;
        
        options.zip = this.dealerGroup.zip;
        options["cs:i:v"] = "volkswagen:" + model + ":";
        options.paramSet = ["cs:i:v"];
        
    	if (!this.dealerGroup.model)
    	{
    		model = "all";
    	}
    	else
    	{
    		model = $("#models option:selected").html();
    	}
        
        s.pageName = "dmasite:specialoffers";
        s.channel = "specialoffers:dmasite";
        s.events = "event38";
        s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
        s.eVar1 = s.prop1 = model || "all";
        s.eVar4 = s.prop4 = this.dealerGroup.zip;
        s.eVar52 = !referrer.keyword && referrer.query || undefined; 
        s.eVar53 = referrer.keyword && referrer.query || undefined;
        s.eVar54 = referrer.keyword;

        
        this.fireDart(DART_TYPE_OFFER, category);
        this.fireCobalt("com.cobaltgroup.ws.view.page", options);
        this.fireOmniture(s, "offerPageLoaded");
    };
    
    
    /**
     * Resets the default offer flag.
     */
    Controller.prototype.onOffersLoaded = function(event, data)
    {
        this.firstOffer = true;
    };
    
    
    /**
     * Fired when an offer is selected in the list.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onOfferSelected = function(event, data)
    {
        console.log("Event: offerSelected");
        
        var offerElement = data.target && $(data.target),
            offer = data.offer || offerElement.tmplItem().data,
            s = {};
        
        s.pageName = "dmasite:specialoffers";
        s.channel = "specialoffers:dmasite";
        s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
        s.prop30 = s.eVar30 = offer.title;

        this.fireOmniture(s, "offerSelected");
        
        this.firstOffer = false;
        this.pageLoading = false;
    };
    
    
    /**
     * Fired when the legal disclaimer is displayed.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onShowLegal = function(event, data)
    {
        console.log("Event: showLegal");
    };
    
    
    /**
     * Fired when the legal disclaimer is hidden.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */    
    Controller.prototype.onHideLegal = function(event, data)
    {
        console.log("Event: hideLegal");
    };
        
    
    /**
     * Fired when the user navigates to the dealer home page.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onOfferHomePage = function(event, data)
    {
        console.log("Event: offerHomePage");
        
        // Determine the selected model (since it is no longer
        // stored in the cookie):
        this.dealerGroup.model = $("#models").val();
        if (this.dealerGroup.model === ":")
        {
        	this.dealerGroup.model = undefined;
        }
        
        var category = this.getDartCategory(DART_DEALER_HANDOFF_CATEGORIES),
        	s = {};
    
	    s.pageName = "dmasite:specialoffers:lo:searchInventory";
	    s.channel ="specialoffers:dmasite";
	    s.eVar31 = "Search Inventory";
	    s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
	    s.events = "event1, event2:" + ContextManager.getSessionId();

	    this.fireDart(DART_TYPE_HANDOFF, category);
	    this.fireOmniture(s, "searchInventory");
    };
    
    
    /**
     * Fired when the user navigates to the preferred dealer's quick quote page.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onQuickQuote = function(event, data)
    {
        console.log("Event: quickQuote");
        
        // Determine the selected model (since it is no longer
        // stored in the cookie):
        this.dealerGroup.model = $("#models").val();
        if (this.dealerGroup.model === ":")
        {
        	this.dealerGroup.model = undefined;
        }
        
        var category = this.getDartCategory(DART_QUOTE_CATEGORIES),
            s = {};
        
        s.pageName = "dmasite:specialoffers:lo:contactDealer";
        s.channel ="specialoffers:dmasite";
        s.eVar31 = "Contact Dealer";
        s.prop2 = s.eVar2 = this.dealerGroup && this.dealerGroup.dma || null;
        s.events = "event1, event2:" + ContextManager.getSessionId();

        this.fireDart(DART_TYPE_QUOTE, category);
        this.fireOmniture(s, "contactDealer");
    };
    
    
    /**
     * Fired when an offer search returns no data.
     * @param event (object)
     * @param data (object) Any additional data passed from data attributes in the UI
     */
    Controller.prototype.onOffersNotLoaded = function(event, error)
    {
        console.log("Event: offersNotLoaded");
        
        // TODO: Uncomment when back-end ca differentiate between errors and no results found.
        // if (error) {return;}
        
        var s = {};
        
        s.pageName = "dmasite:specialoffers:error";
        s.channel ="specialoffers:dmasite";
        s.events = "event39";
        s.prop11 = this.searchValue;

        this.fireDart(DART_TYPE_OFFER, "error");
        this.fireOmniture(s, "offersNotLoaded");
    };
    
    
    
    // P I X E L   T A G   I M P L E M E N T A T I O N S
    
    
    
    /**
     * Fires a Doubleclick pixel tag by appending an iFrame to the page.
     * @param type (string)
     * @param cat (string) 
     * @param src (string) 
     */
    Controller.prototype.fireDart = function(type, cat, src)
    {
        
        var val = Math.random() * 10000000000000,
        	ord = val,
        	num = "undefined";

        // Special offer tags have a different format (who knew?):
        if (type === DART_TYPE_OFFER || type === DART_TYPE_HOMEPAGE || type === DART_TYPE_DEALER)
        {
        	ord = 1;
        	num = val;
        	val = "1;num=" + val;
        }
        
        console.log("--> Dart: %s, %s (ord=%s, num=%s)", type, cat, ord, num);
        
        src = src || DART_SRC;
        
        $('<iframe src="http://fls.doubleclick.net/activityi;src=' + src + ';type=' + type + ';cat=' + cat + ';ord=' + val + '?" width="1" height="1" frameborder="0"></iframe>').appendTo("body");   
    };
        
    
    /**
     * Fires an Omniture pixel tag.
     * @param (data) The values to be copied into the Omniture pixel tag.
     */
    Controller.prototype.fireOmniture = function(data, eventName)
    {
        console.log("--> Omniture: %o", data || {});
        
        var key,
            eventType = this.pageLoading && "page load" || "user initiated";
        
        // Add the tag properties from the global Omniture 
        // object, and fire the pixel tag:
        data.eVar7 = data.prop7 = data.pageName;
        data.prop12 = eventName;
        data.prop13 = data.prop13 || eventType;
        $.extend(s, DEFAULT_OMNITURE_PROPERTIES, data);
        s.t();
        
        // Finally, clear out any old values:
        for (key in data)
        {
            delete s[key];
        }
    };
    
    
    /**
     * Writes a Cobalt pixel tag.
     * @param eventName (string)
     * @param data (object) An object containing the relevant pixel tag values.
     */
    Controller.prototype.fireCobalt = function(eventName, options)
    {
        console.log("--> Cobalt: %s, %o", eventName, options || {});
        
        var pixelTag = new CobaltPixelTag(options);
        pixelTag.writePixelTag();
    };
    
    
    /**
     * Gets a Dart model code for the given Coblat model code.
     * @param model (string) The Cobalt model code
     * @return (string) The Dart translation of the Cobalt model code
     */
    Controller.prototype.getDartCategory = function(categories)
    {
        return categories[this.dealerGroup.model || "default"];
    };
    
    
    /**
     * Adds the dealer group title to all VW handoff links.
     */
    Controller.prototype.updateHandoffLinks = function()
    {
    	var groupName = this.dealerGroup && this.dealerGroup.groupName || "";
    	
    	$(".footer_nav a").each(function()
    	{
    		var href = this.href, 
    			index = href.indexOf("=") + 1;
    		
   			href = href.substring(0, index) + "LMC-" + groupName;
   			this.href = href;    				
    	});
    };
    
    
    /**
     * Transforms the referrer into an object.
     * @return (object)
     */
    Controller.prototype.findParameters = function()
    {
    	var referrer = document.referrer,
    		url = window.location.href,
    		parameters,
    		result = {url: url, referrer: referrer};
    	
    	// Create an array of all referrer and url parameters:
    	referrer = this.parseUrlQueryString(referrer);
    	url = this.parseUrlQueryString(url);
    	parameters = referrer.concat(url);
    	
    	// Add each parameter in the referrer URL to the result:
    	jQuery(parameters).each(function()
    	{
    		var keyValue = this.split("="),
    			key = keyValue[0],
    			value = keyValue[1];
    		
    		// "p" or "q" represent the query string... 
    		if (key === "p" || key === "q")
    		{
    			key = "query";
    		}
    		
    		// ...and this is any keywords:
    		else if (key === "cs:kw")
    		{
    			key = "keyword";
    		}
    		
    		// Add the key/value pair to the result:
    		result[key] = value;
    	});
    	
    	return result;
    };
    
    
    /**
     * @param url (string) A url to parse
     * @return (array) An array of url parameters
     */
    Controller.prototype.parseUrlQueryString = function(url)
    {
    	var parameters;
    	
    	url = url || "";
    	parameters = url.split("?")[1];
    	if (parameters)
    	{
    		parameters = parameters.split("&");	
    	}
    	    	
    	return parameters || [];
    };

    
    // Make the controller available globally:
    window.PixelTagController = Controller;
    
}());


/* Omniture Configuration
VW implementation
*/
var s, qParmArray;
//
if (!VWOmnitureConfig) {
	var VWOmnitureConfig = {
		doPluginsCalled : false,
		/**
		* Define Omniture account, set s properties
		*/
		init : function() {
			// Define account
			var s_account = "vwcimrdev";
			var subType = ContextManager.getSubType();
			var isProdSubType = ((subType == "WEB") || (subType == "INVENTORY"));
			if (ContextManager.isProd() && ContextManager.isLive() && isProdSubType) { 
			  s_account = "vwcimrprod";
			}
			s=s_gi(s_account);
			
			// ************************* CONFIG SECTION **************************

			// You may add or alter any code config here. 
			s.charSet="ISO-8859-1"
			s.currencyCode="USD";
			
			/* Link Tracking Config */
			s.trackDownloadLinks=true;
			s.trackExternalLinks=true;
			s.trackInlineStats=true;
			s.linkDownloadFileTypes="exe,zip,wav,mp3,mov,mpg,avi,wmv,doc,pdf,xls";
			s.linkInternalFilters="javascript:" + "," + ContextManager.getRequestDomain();
			s.linkLeaveQueryString=false;
			s.linkTrackVars="None";
			s.linkTrackEvents="None";
			
			/* Form Analysis Config */
			s.formList="frmQuickQuote,form_quickQuote";
			s.trackFormList=true;
			s.trackPageName=false;
			s.useCommerce=true;
			s.varUsed="eVar36";
			s.eventList="event17,event18,event19"; //Abandon,Success,Error
						
			/* WARNING: Changing any of the below variables will cause drastic
			changes to how your visitor data is collected.  Changes should only be
			made when instructed to do so by your account manager.*/
			s.visitorNamespace="volkswagen"
			s.trackingServer="volkswagen.122.2o7.net"
			s.dc="122";
			
			/* Plugin Config */
			s.usePlugins=true;
			s.doPlugins = VWOmnitureConfig.s_doPlugins;
			
			// ************************* PLUGINS SECTION ************************
			// You may insert any plugins you wish to use here.
			
			/*
			 * Plugin: getQueryParam 1.3 - Return query string parameter values
			 */
			s.getQueryParam=new Function("qp","d",""
			+"var s=this,v='',i,t;d=d?d:'';while(qp){i=qp.indexOf(',');i=i<0?qp.l"
			+"ength:i;t=s.gcgi(qp.substring(0,i));if(t)v+=v?d+t:t;qp=qp.substring"
			+"(i==qp.length?i:i+1)}return v");
			s.gcgi=new Function("k",""
			+"var v='',s=this;if(k&&s.wd.location.search){var q=s.wd.location.sea"
			+"rch.toLowerCase(),qq=q.indexOf('?');q=qq<0?q:q.substring(qq+1);v=s."
			+"pt(q,'&','cgif',k.toLowerCase())}return v");
			s.cgif=new Function("t","k",""
			+"if(t){var s=this,i=t.indexOf('='),sk=i<0?t:t.substring(0,i),sv=i<0?"
			+"'True':t.substring(i+1);if(sk.toLowerCase()==k)return s.epa(sv)}ret"
			+"urn ''");
			/*
			 * Plugin: getValOnce 0.2 - get a value once per session or number of days
			 */
			s.getValOnce=new Function("v","c","e",""
			+"var s=this,k=s.c_r(c),a=new Date;e=e?e:0;if(v){a.setTime(a.getTime("
			+")+e*86400000);s.c_w(c,v,e?a:0);}return v==k?'':v");
			/*
		 	* Plug-in: crossVisitParticipation v1.7 - stacks values from
		 	* specified variable in cookie and returns value
		 	*/
			s.crossVisitParticipation=new Function("v","cn","ex","ct","dl","ev","dv",""
			+"var s=this,ce;if(typeof(dv)==='undefined')dv=0;if(s.events&&ev){var"
			+" ay=s.split(ev,',');var ea=s.split(s.events,',');for(var u=0;u<ay.l"
			+"ength;u++){for(var x=0;x<ea.length;x++){if(ay[u]==ea[x]){ce=1;}}}}i"
			+"f(!v||v==''){if(ce){s.c_w(cn,'');return'';}else return'';}v=escape("
			+"v);var arry=new Array(),a=new Array(),c=s.c_r(cn),g=0,h=new Array()"
			+";if(c&&c!=''){arry=s.split(c,'],[');for(q=0;q<arry.length;q++){z=ar"
			+"ry[q];z=s.repl(z,'[','');z=s.repl(z,']','');z=s.repl(z,\"'\",'');arry"
			+"[q]=s.split(z,',')}}var e=new Date();e.setFullYear(e.getFullYear()+"
			+"5);if(dv==0&&arry.length>0&&arry[arry.length-1][0]==v)arry[arry.len"
			+"gth-1]=[v,new Date().getTime()];else arry[arry.length]=[v,new Date("
			+").getTime()];var start=arry.length-ct<0?0:arry.length-ct;var td=new"
			+" Date();for(var x=start;x<arry.length;x++){var diff=Math.round((td."
			+"getTime()-arry[x][1])/86400000);if(diff<ex){h[g]=unescape(arry[x][0"
			+"]);a[g]=[arry[x][0],arry[x][1]];g++;}}var data=s.join(a,{delim:',',"
			+"front:'[',back:']',wrap:\"'\"});s.c_w(cn,data,e);var r=s.join(h,{deli"
			+"m:dl});if(ce)s.c_w(cn,'');return r;");
			/*
			* Plugin Utility: Replace v1.0
			*/
			s.repl=new Function("x","o","n",""
			+"var i=x.indexOf(o),l=n.length;while(x&&i>=0){x=x.substring(0,i)+n+x."
			+"substring(i+o.length);i=x.indexOf(o,i+l)}return x");	
			/*
			 * s.join: 1.0 - s.join(v,p)
			 *
			 *  v - Array (may also be array of array)
			 *  p - formatting parameters (front, back, delim, wrap)
			 *
			 */
			s.join = new Function("v","p",""
			+"var s = this;var f,b,d,w;if(p){f=p.front?p.front:'';b=p.back?p.back"
			+":'';d=p.delim?p.delim:'';w=p.wrap?p.wrap:'';}var str='';for(var x=0"
			+";x<v.length;x++){if(typeof(v[x])=='object' )str+=s.join( v[x],p);el"
			+"se str+=w+v[x]+w;if(x<v.length-1)str+=d;}return f+str+b;");
			/*
			 * Utility Function: split v1.5 (JS 1.0 compatible)
			 */
			s.split=new Function("l","d",""
			+"var i,x=0,a=new Array;while(l){i=l.indexOf(d);i=i>-1?i:l.length;a[x"
			+"++]=l.substring(0,i);l=l.substring(i+d.length);}return a");
			/*
			 * Plugin: Form Analysis 2.1 (Success, Error, Abandonment)
			 */
			s.setupFormAnalysis=new Function(""
			+"var s=this;if(!s.fa){s.fa=new Object;var f=s.fa;f.ol=s.wd.onload;s."
			+"wd.onload=s.faol;f.uc=s.useCommerce;f.vu=s.varUsed;f.vl=f.uc?s.even"
			+"tList:'';f.tfl=s.trackFormList;f.fl=s.formList;f.va=new Array('',''"
			+",'','')}");
			s.sendFormEvent=new Function("t","pn","fn","en",""
			+"var s=this,f=s.fa;t=t=='s'?t:'e';f.va[0]=pn;f.va[1]=fn;f.va[3]=t=='"
			+"s'?'Success':en;s.fasl(t);f.va[1]='';f.va[3]='';");
			s.faol=new Function("e",""
			+"var s=s_c_il["+s._in+"],f=s.fa,r=true,fo,fn,i,en,t,tf;if(!e)e=s.wd."
			+"event;f.os=new Array;if(f.ol)r=f.ol(e);if(s.d.forms&&s.d.forms.leng"
			+"th>0){for(i=s.d.forms.length-1;i>=0;i--){fo=s.d.forms[i];fn=fo.name"
			+";tf=f.tfl&&s.pt(f.fl,',','ee',fn)||!f.tfl&&!s.pt(f.fl,',','ee',fn);"
			+"if(tf){f.os[fn]=fo.onsubmit;fo.onsubmit=s.faos;f.va[1]=fn;f.va[3]='"
			+"No Data Entered';for(en=0;en<fo.elements.length;en++){el=fo.element"
			+"s[en];t=el.type;if(t&&t.toUpperCase){t=t.toUpperCase();var md=el.on"
			+"mousedown,kd=el.onkeydown,omd=md?md.toString():'',okd=kd?kd.toStrin"
			+"g():'';if(omd.indexOf('.fam(')<0&&okd.indexOf('.fam(')<0){el.s_famd"
			+"=md;el.s_fakd=kd;el.onmousedown=s.fam;el.onkeydown=s.fam}}}}}f.ul=s"
			+".wd.onunload;s.wd.onunload=s.fasl;}return r;");
			s.faos=new Function("e",""
			+"var s=s_c_il["+s._in+"],f=s.fa,su;if(!e)e=s.wd.event;if(f.vu){s[f.v"
			+"u]='';f.va[1]='';f.va[3]='';}su=f.os[this.name];return su?su(e):tru"
			+"e;");
			s.fasl=new Function("e",""
			+"var s=s_c_il["+s._in+"],f=s.fa,a=f.va,l=s.wd.location,ip=s.trackPag"
			+"eName,p=s.pageName;if(a[1]!=''&&a[3]!=''){a[0]=!p&&ip?l.host+l.path"
			+"name:a[0]?a[0]:p;if(!f.uc&&a[3]!='No Data Entered'){if(e=='e')a[2]="
			+"'Error';else if(e=='s')a[2]='Success';else a[2]='Abandon'}else a[2]"
			+"='';var tp=ip?a[0]+':':'',t3=e!='s'?':('+a[3]+')':'',ym=!f.uc&&a[3]"
			+"!='No Data Entered'?tp+a[1]+':'+a[2]+t3:tp+a[1]+t3,ltv=s.linkTrackV"
			+"ars,lte=s.linkTrackEvents,up=s.usePlugins;if(f.uc){s.linkTrackVars="
			+"ltv=='None'?f.vu+',events':ltv+',events,'+f.vu;s.linkTrackEvents=lt"
			+"e=='None'?f.vl:lte+','+f.vl;f.cnt=-1;if(e=='e')s.events=s.pt(f.vl,'"
			+",','fage',2);else if(e=='s')s.events=s.pt(f.vl,',','fage',1);else s"
			+".events=s.pt(f.vl,',','fage',0)}else{s.linkTrackVars=ltv=='None'?f."
			+"vu:ltv+','+f.vu}s[f.vu]=ym;s.usePlugins=false;var faLink=new Object"
			+"();faLink.href='#';s.tl(faLink,'o','Form Analysis');s[f.vu]='';s.us"
			+"ePlugins=up}return f.ul&&e!='e'&&e!='s'?f.ul(e):true;");
			s.fam=new Function("e",""
			+"var s=s_c_il["+s._in+"],f=s.fa;if(!e) e=s.wd.event;var o=s.trackLas"
			+"tChanged,et=e.type.toUpperCase(),t=this.type.toUpperCase(),fn=this."
			+"form.name,en=this.name,sc=false;if(document.layers){kp=e.which;b=e."
			+"which}else{kp=e.keyCode;b=e.button}et=et=='MOUSEDOWN'?1:et=='KEYDOW"
			+"N'?2:et;if(f.ce!=en||f.cf!=fn){if(et==1&&b!=2&&'BUTTONSUBMITRESETIM"
			+"AGERADIOCHECKBOXSELECT-ONEFILE'.indexOf(t)>-1){f.va[1]=fn;f.va[3]=e"
			+"n;sc=true}else if(et==1&&b==2&&'TEXTAREAPASSWORDFILE'.indexOf(t)>-1"
			+"){f.va[1]=fn;f.va[3]=en;sc=true}else if(et==2&&kp!=9&&kp!=13){f.va["
			+"1]=fn;f.va[3]=en;sc=true}if(sc){nface=en;nfacf=fn}}if(et==1&&this.s"
			+"_famd)return this.s_famd(e);if(et==2&&this.s_fakd)return this.s_fak"
			+"d(e);");
			s.ee=new Function("e","n",""
			+"return n&&n.toLowerCase?e.toLowerCase()==n.toLowerCase():false;");
			s.fage=new Function("e","a",""
			+"var s=this,f=s.fa,x=f.cnt;x=x?x+1:1;f.cnt=x;return x==a?e:'';");
			/*
			 * END Form Analysis
			 */

			/************************** End PLUGINS SECTION *************************/
		},
		//
		s_doPlugins : function(s) {
			/* FORM ANALYSIS */
			s.setupFormAnalysis();
			/* Hack for IE issue - window.onload sometimes runs before doc.ready
				The setupFormAnalysis function assigns the window.onload to the s.faol function, then re-assigns the original window.onload to a variable.
				However, in IE we find that often the onload has already fired by the time we get to this point. 
				To ensure that the s.faol function gets called, we will check the document.readyState, and if needed, manually execute s.faol.
			*/
			if (!VWOmnitureConfig.doPluginsCalled) {
				if ((document.readyState == "complete") && (document.forms && document.forms.length > 0)) {
					// this means that onload has already fired, and we need to manually run faol
					if ((s.fa) && (s.fa.ol)) { 
						s.wd.onload = s.fa.ol; // restore the original window onload, just in case
						delete s.fa.ol;	// this stored the original document onload func, we don't want it to run again
					}
					s.faol();
				}
				VWOmnitureConfig.doPluginsCalled = true;
			}
			/* END FORM ANALYSIS */
		}
		
	};
}


/**
 * Correct IE's belief that an empty node is an empty string. 
 */
LslpController.prototype.getCookie = function()
{
	var cookie = document.cookie; 
    cookie = cookie.replace("<lslp:model></lslp:model>", "");
    return cookie;
};
