/** public class CobaltPixelTag
 */
function CobaltPixelTag(pixelOptions){
    this.pixelOptions = (pixelOptions) ? pixelOptions : {};
    this.isSessionVerified = false;
    // set timestamp
    var d = new Date();
    this.timestamp = d.getTime();  
}

CobaltPixelTag.prototype.defaultParamSet = ['requestDomain', 'pageName', 'pageLabel', 'pageLayout', 'requestUri', 'referrerDomain', 'referrerUri', 'visitorId', 'eventId', 'sessionId', 'siteId', 'leadId', 'vin', 'promoName', 'pageLoadTime'];

CobaltPixelTag.prototype.writePixelTag = function(){
    if (!this.isSessionVerified) {
        // check session
        if (!this.isSessionExpired()) {
            this.isSessionVerified = true;
            this.writePixelTag();
        }
        else {
            // verify session ID
            this.verifySession();
        }
    }
    else {
        //
        var imgString = this.getPixelTag(this.pixelOptions);
        //
        this.firePixelTag(imgString);
        //
        // Perform callback if provided
        if (this.pixelOptions.callback) {
            this.pixelOptions.callback();
        }
    }
};
/**
 * 	Given a set of params, return a pixel tag URL string
 */
CobaltPixelTag.prototype.getPixelTag = function(pixelOptions){
    // Create a unique ID: concat Server-generated guid and 12-char suffix
    pixelOptions.eventId = ContextManager.getEventId() + ContextManager.generateEventIdSuffix();
    //
    var imgString = ContextManager.getTrafficServerUrl() + '?';
    // check for extra params
    var paramArray = (pixelOptions.paramSet) ? this.defaultParamSet.concat(pixelOptions.paramSet) : this.defaultParamSet;
    imgString += this.getPixelParameters(paramArray);
    // add extra queryString if present
    if (pixelOptions.queryString) {
        imgString += pixelOptions.queryString;
    }
    return imgString;
};
/**
 */
CobaltPixelTag.prototype.firePixelTag = function(imgString){
    var pt = new Image(1, 1);
    pt.src = imgString;
    // need this onload for consistent IE 6 performance, inspired by http://breckman.com/entry.php?id=30
    pt.onload = function(){
        pt.onload = null;
    }
};
//
CobaltPixelTag.prototype.verifySession = function(){
    // session expired, get new sessionID
    var _this = this; // use closure to maintain reference to this CobaltPixelTag
    jQuery.ajax({
        type: "GET",
        dataType: "html",
        url: "sessionInformation.ajax",
        success: function(data){
            newSessionId = jQuery.trim(data);
            if (newSessionId != ContextManager.getSessionId()) {
                // set new session
                ContextManager.updateProperties("sessionId=" + newSessionId);
            }
            // since we hit the backend, we must reset the session timer
            ContextManager.setSessionStartTime(_this.timestamp);
            _this.isSessionVerified = true;
            _this.writePixelTag();
        },
        error: function(oXHR, err, oExc){
            //alert(err);
        }
    });
};
//
CobaltPixelTag.prototype.isSessionExpired = function(){
    return ((this.timestamp - ContextManager.getSessionStartTime()) > ContextManager.getSessionDuration());
};
//
CobaltPixelTag.prototype.getPixelParameters = function(paramArray){
    var st = "";
    var key, val, param;
    var uniqueArray = [];
    // remove any duplicates from the array
    uniqueArray = this.removeDups(paramArray);
    var len = uniqueArray.length;
    for (i = 0; i < len; i++) {
        param = uniqueArray[i];
        // check for user-submitted override
        if (this.pixelOptions[param]) {
            val = this.pixelOptions[param];
        }
        else {
            // determine how to derive property value
            switch (param) {
                // handle unique cases 
                case 'pageLoadTime':
                    if (!ContextManager.getPageMonitoring()) {
                        continue;
                    }
                    val = this.appendPageMonitoringData();
                    break;
                case 'search':
                    val = this.getSearch();
                    break;
                case 'pageLabel':
                	val = ContextManager.URLEncode(ContextManager.getProperty('pageLabel'));
                	break;
                // ***********************************
                default:
                    // get value directly from ContextManager
                    val = ContextManager.getProperty(param);
            }
        }
        // skip null or undefined values
        if (val) {
            // get key from map
            key = this.getPixelKey(param);
            //
            st += key + '=' + val;
            st += '&';
        }
    }
    return st;
};

CobaltPixelTag.prototype.removeDups = function(a){
    var i, x, y;
    var r = [];
    var n = a.length;
    o: for (i = 0; i < n; i++) {
        y = r.length;
        for (x = 0; x < y; x++) {
            if (r[x] == a[i]) 
                continue o;
        }
        r[r.length] = a[i];
    }
    return r;
};

/*******************************************************************************/
/* 
 *	Evaluate ContextManager search array:
 *	Here is the rule to set search value, if search type is
 *	new -> ‘new’
 *	new + preowned/certified -> ‘All’
 *	preowned/certified -> ‘preowned’
 */
CobaltPixelTag.prototype.getSearch = function(){
    var ALL = "All";
    var NEW = "new";
    var PRE_OWNED = "preowned";
    var CERTIFIED = "certified";
    //
    var i;
    var searchValue = ALL;
    var searchArray = ContextManager.getSearch() || [];
    var len = searchArray.length;
    //
    for (i = 0; i < len; i++) {
        if (searchArray[i] == NEW) {
            if (searchValue == PRE_OWNED) {
                return ALL;
            }
            searchValue = NEW;
        }
        else 
            if ((searchArray[i] == PRE_OWNED) || (searchArray[i] == CERTIFIED)) {
                if (searchValue == NEW) {
                    return ALL;
                }
                searchValue = PRE_OWNED;
            }
    }
    return searchValue;
};


CobaltPixelTag.prototype.appendPageMonitoringData = function(){
    ContextManager.setPageMonitoring(false)
    if (typeof pst == "undefined") 
        return (-1);
    var renderCompletedTime = new Date();
    return (renderCompletedTime.getTime() - pst.getTime());
};

/*******************************************************************************/

CobaltPixelTag.prototype.getPixelKey = function(prop){
    var key = this.pixelKeys[prop];
    // if undefined in key list, then use contextManager value
    return (key) ? key : prop;
};

CobaltPixelTag.prototype.pixelKeys = {
    dma: 'cs:dma',
    zip: 'cs:zip',
    radius: 'cs:sr',
    promoName: 'cs:a',
    webId: 'cs:s',
    make: 'inventory_make',
    model: 'inventory_model',
    trim: 'inventory_trim',
    series: 'inventory_series',
    search: 'inventory_search_type',
    locale: 'cs:loc',
    mileageRange: 'cs:i:mi',
    paymentRange: 'cs:i:pay',
    priceRange: 'cs:i:pr',
    bodyType: 'cs:i:vt',
    vin: 'cs:i:vin',
    yearRange: 'cs:i:y',
    requestDomain: 'header_request_domain',
    pageName: 'header_page_name',
    pageLabel: 'header_page_label',
    pageLayout: 'header_page_layout',
    requestUri: 'header_request_uri',
    referrerDomain: 'header_referrer_domain',
    referrerUri: 'header_referrer_uri',
    visitorId: 'header_visitor_id',
    eventId: 'header_event_id',
    sessionId: 'header_session_id',
    siteId: 'header_site_id',
    leadId: 'lead_id',
    linkoutLabel: 'cs:lo',
    pageLoadTime: 'cs:plt',
    latitude: 'cs:lat',
    longitude: 'cs:long',
    inventorydetails: 'cs:i:v' 
};

//***********************************************************************************************
// Linkout functionality
//		- providing static methods for this
//***********************************************************************************************
CobaltPixelTag.linkData = {};
CobaltPixelTag.pixelTagData = {};
/**
 *	linkout will perform specified tracking and perform external link
 *
 * 		linkData : This object will contain:
 *			url:			String: URL to link to
 *			target:			String: "_self" or "_top" to replace current, or "_blank" for new window
 *			windowParams:	A comma-delimited string specifying any properties of the new window.
 *		pixelTagData:	Provides any parameter overrides/additions for the pixel tag.
 */
CobaltPixelTag.linkout = function(linkData, pixelTagData){
    CobaltPixelTag.linkData = (linkData) ? linkData : {};
    CobaltPixelTag.pixelTagData = (pixelTagData) ? pixelTagData : {};
    // ensure valid URL
    if (CobaltPixelTag.isValidUrl(CobaltPixelTag.linkData.url)) {
        CobaltPixelTag.trackLinkout();
    }
};
/*
 * Checks whether this is a valid url format
 */
CobaltPixelTag.isValidUrl = function(urlString){
    if ((urlString.search(/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/) != -1) && (!CobaltPixelTag.isNull(urlString))) {
        return true;
    }
    else {
        return false;
    }
};
/*  
 * Returns true if the parameter is null
 */
CobaltPixelTag.isNull = function(param){
    if ((undefined == param) || (void 0 == param) || (param.length == 0)) {
        return true;
    }
    return false;
};
/**
 *	Fire a pixel tag before linking out.
 */
CobaltPixelTag.trackLinkout = function(){
    // add callback : execute the link when tracking is complete.
    CobaltPixelTag.pixelTagData.callback = CobaltPixelTag.doLink;
    //
    // Add linkoutLabel to extra params to track
    if (CobaltPixelTag.pixelTagData.paramSet) {
        // a paramSet has been specified, so add our linkoutLabel to it
        CobaltPixelTag.pixelTagData.paramSet.push('linkoutLabel');
    }
    else {
        CobaltPixelTag.pixelTagData.paramSet = ['linkoutLabel'];
    }
    var cobaltTag = new CobaltPixelTag(CobaltPixelTag.pixelTagData);
    // Callback will execute afterwards.
    cobaltTag.writePixelTag();
};
/**
 *	After linkout tracking is complete, execute the link
 */
CobaltPixelTag.doLink = function(){
    // First publish a linkout event for any potential third-party handlers
    // 		- Add cs:lo value to event name
    //		- Pass pixelTagData as publisherData
    var loLabel = (CobaltPixelTag.pixelTagData.linkoutLabel) ? "." + CobaltPixelTag.pixelTagData.linkoutLabel : "";
    var evName = 'com.cobaltgroup.ws.action.link' + loLabel;
    // Before passing along CobaltPixelTag.pixelTagData, first remove the callback, to avoid recursion.
    delete CobaltPixelTag.pixelTagData.callback;
    //
    EventManager.publish({
        eventName: evName,
        publisherData: CobaltPixelTag.pixelTagData
    });
    //
    if (!CobaltPixelTag.linkData.url)
    {
        return;
    }
    
    var tar = CobaltPixelTag.linkData.target;
    if (tar == "_self" || tar == "_top") {
        location.href = CobaltPixelTag.linkData.url;
    }
    else {
        var winParams = (CobaltPixelTag.linkData.windowParams) ? CobaltPixelTag.linkData.windowParams : "";
        var newWindow = window.open(CobaltPixelTag.linkData.url, "newWin", winParams);
        newWindow.focus();
    }
};

