﻿//*************************** RIO Tracking Manager *************************************
function RioTrackingManager() {
    // These variables will be set by code in the page
    this.guestCellCode = -1;
    this.wid = -1;
    this.vn = -1;
    this.fn = -1;
    this.uniqueActionTagCode = "null";
    this.isExtendedDataTag = true;
    this.testMode = false;

    // Flag for whether or not to update the WebTrends cookie
    this.isWtCookieSet = false;

    // Declare constants
    this.cellCodeCookieKey = "RioTracking.CellCode.ClientSide";
    this.permIdCookieKey = "RioTracking.PermId.ClientSide";
    this.wtCookieKey = "R";    
    
    this.baseAtlasUrlNotExtended = document.location.protocol + "//view.atdmt.com/jaction/{0}";
    this.baseAtlasUrl = document.location.protocol + "//view.atdmt.com/jaction/{0}/v3/ato.-1/atc1.{1}/atc2.{2}/atc3.{3}";

    this.baseCrsImpressionUrl = document.location.protocol + "//www.microsoft.com/click/services/Tracking/Impression.ashx";
    this.baseCrsClickUrl = document.location.protocol + "//www.microsoft.com/click/services/Tracking/Click.ashx";

    // Set the onload event
    this.AddHandler(window, "load", this.CreateDelegate(this, this.init));
}

RioTrackingManager.prototype.init = function() {
    this.setCellCode();
    this.setUserId();

    // If we don't have an Atlas Unique Action Tag Code then we're on a secondary page the doesn't fire any type of impression tag.
    if (this.uniqueActionTagCode == "null") { return; }

    // Read the query string parameters, and use default values if the parameters aren't available.
    this.wid = escape(this.queryStringParamSafeValue("wid", true, this.wid));
    this.vn = escape(this.queryStringParamSafeValue("vn", true, this.vn));
    this.fn = escape(this.queryStringParamSafeValue("fn", true, this.fn));

    this.fireImpressionTags();
}

RioTrackingManager.prototype.setCellCode = function() {
    this.crcc = escape(this.queryStringParamSafeValue("CR_CC", true, this.guestCellCode));

    // Check if a Cell Code was already passed in (crcc will be equal to the Guest Cell Code and the cookie will have a value)
    if (this.crcc == this.guestCellCode) {
        var currentCc = this.getCookie(this.cellCodeCookieKey + "." + this.guestCellCode);

        if ((currentCc != null) && (currentCc.toString().length > 0)) {
            this.crcc = parseInt(currentCc);
        }
    }

    // Make sure the cookie has the latest Cell Code
    document.cookie = this.cellCodeCookieKey + "." + this.guestCellCode + "=" + this.crcc;
}

RioTrackingManager.prototype.setUserId = function() {
    this.crid = escape(this.queryStringParamSafeValue("CR_ID", true, -1));
    if (this.crid == -1) {
        var currentId = this.getCookie(this.permIdCookieKey + "." + this.guestCellCode);
        if ((currentId != null) && (currentId.toString().length > 0)) {
            this.crid = currentId;
        }
    }

    // Make sure the cookie has the latest user ID.
    document.cookie = this.permIdCookieKey + "." + this.guestCellCode + "=" + this.crid;
}

/**********************/
/* Tracking Functions */
/**********************/

RioTrackingManager.prototype.fireImpressionTags = function() {
    this.fireAtlasImpressionTag();
    this.fireCrsImpressionTag();
}

RioTrackingManager.prototype.click = function(endActionCode, atlasTagCode) {
    this.fireAtlasClickTag(atlasTagCode, endActionCode);
    this.fireCrsClickTag(endActionCode);

    // Wait 0.5 seconds for tags to fire.
    var date = new Date();
    var curDate = null;

    do { curDate = new Date(); }
    while (curDate - date < 500);

    return true;
}

RioTrackingManager.prototype.clickNoWait = function(endActionCode, atlasTagCode) {
    this.fireAtlasClickTag(atlasTagCode, endActionCode);
    this.fireCrsClickTag(endActionCode);
}

/************************/
/* Tag Firing Functions */
/************************/

RioTrackingManager.prototype.fireAtlasImpressionTag = function() {
    var atlasUrl;
    if (this.isExtendedDataTag) {
        atlasUrl = this.baseAtlasUrl.format(this.uniqueActionTagCode, this.crid, this.crcc, -1);
    }
    else {
        atlasUrl = this.baseAtlasUrlNotExtended.format(this.uniqueActionTagCode);
    }

    this.fireTag(atlasUrl, false);
}

RioTrackingManager.prototype.fireCrsImpressionTag = function() {
    var crsUrl = this.baseCrsImpressionUrl;

    // Check if it was a Form completion
    if ((this.vn != -1) && (this.fn != -1)) {
        crsUrl += "?vn=" + this.vn.toString() + "&fn=" + this.fn.toString();
    }
    // Check if it was a Wizard completion
    else if (this.wid != -1) {
        crsUrl += "?wid=" + this.wid.toString();
    }
    // Assume it was a standard impression
    else {
        crsUrl += "?cr_cc=" + this.crcc;

        // If we haven't already set the WebTrends cookie, do it now.
        if (!this.isWtCookieSet) {
            this.setWtCookie();
        }
    }

    // Append the Perm ID if available.
    if (this.crid != -1) {
        crsUrl += "&cr_id=" + this.crid.toString();
    }

    // If we're in test mode we need to tell the server-side web handler to put the data in the test database.
    if (this.testMode) {
        crsUrl += "&test=1";
    }

    // The wn parameter allows us to differentiate between sessions if the user has multiple browser windows open.
    crsUrl += "&wn=" + this.guestCellCode.toString();

    this.fireTag(crsUrl, false);
}

RioTrackingManager.prototype.fireAtlasClickTag = function(atlasUatc, endActionCode) {
    var atlasUrl = this.baseAtlasUrl.format(atlasUatc, this.crid, this.crcc, endActionCode);
    this.fireTag(atlasUrl, true);
}

RioTrackingManager.prototype.fireCrsClickTag = function(endActionCode) {
    var crsUrl = this.baseCrsClickUrl;
    crsUrl += "?cr_eac=" + endActionCode.toString();

    // If we're in test mode we need to tell the server-side web handler to put the data in the test database.
    if (this.testMode) {
        crsUrl += "&test=1";
    }

    // The wn parameter allows us to differentiate between sessions if the user has multiple browser windows open.
    crsUrl += "&wn=" + this.guestCellCode.toString();

    // Append a random number for "cache busting"
    var timestamp = new Date();
    crsUrl += "&r=" + Math.ceil(Math.random() * 99999999) + "" + timestamp.getUTCFullYear() + timestamp.getUTCMonth() + timestamp.getUTCDate() + timestamp.getUTCHours() + timestamp.getUTCMinutes() + timestamp.getUTCSeconds() + timestamp.getUTCMilliseconds();

    this.fireTag(crsUrl, true);
}


/*****************************/
/* WebTrends/RIO Integration */
/*****************************/

function wt_GetCurrentCellCode() {
    // If we don't have an Atlas Unique Action Tag Code then we're on a secondary page and don't want to write the Guest Cell Code to the WebTrends cookie.
    // We only want to set the WebTrends cookie on standard landing page impressions.
    // Also, if the Guest Cell Code hasn't been set we don't want to add it to the WebTrends cookie.

    var cookie = RioTracking.getCookie(RioTracking.wtCookieKey);
    var currentCellCode = escape(RioTracking.queryStringParamSafeValue("CR_CC", true, RioTracking.guestCellCode));

    if ((this.uniqueActionTagCode == "null") || (currentCellCode == -1) || (this.wid != -1) || ((this.vn != -1) && (this.fn != -1))) { return cookie; }

    return RioTracking.setWtCookie();
}

RioTrackingManager.prototype.setWtCookie = function() {
    // Set the WebTrends Cookie. The most recent Cell Code is in position 0. As new Cell Codes are added the oldest Cell Code is push out.

    var cookies = this.getCookie(this.wtCookieKey).split("|");
    var currentCellCode = escape(RioTracking.queryStringParamSafeValue("CR_CC", true, RioTracking.guestCellCode));
    var indexOfCellCode = cookies.IndexOf(currentCellCode);

    if (indexOfCellCode > -1) { cookies.splice(indexOfCellCode, 1); }

    var newCellCodeVal = currentCellCode + "-" + RioTracking.getCurrentDateTime();
    cookies.Add(0, newCellCodeVal);

    var newCookie = ((cookies.length > 1 ? cookies.Join(3, "|") : cookies));

    var exdate = new Date();
    exdate.setDate(exdate.getFullYear() + 20);

    var cookieVal = this.wtCookieKey + "=" + newCookie + ";expires=" + exdate.toGMTString() + ";domain=microsoft.com;path=/";
    document.cookie = cookieVal;

    this.isWtCookieSet = true;

    return cookieVal;
}


/*********************/
/* Support Functions */
/*********************/

RioTrackingManager.prototype.AddHandler = function(object, eventName, handler) {
    if (object.addEventListener) { object.addEventListener(eventName, handler, false); }
    else { object.attachEvent("on" + eventName, handler); }
}

// this function uses Closures and the Function.apply() method to achieve our goals
RioTrackingManager.prototype.CreateDelegate = function(object, method) {
    return (function() { return method.apply(object, arguments); })
}

RioTrackingManager.prototype.fireTag = function(tag, appendRandom) {
    var scriptObj = document.createElement("script");
    scriptObj.type = "text/javascript";
    scriptObj.src = tag;

    //document.body.appendChild(scriptObj);
    document.getElementsByTagName("head")[0].appendChild(scriptObj);
}

RioTrackingManager.prototype.queryStringParamSafeValue = function(name, caseInsensitive, defaultValueIfNull) {
    name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
    var r = "[?&]" + name + "=([^&#]*)";
    var rmod = ""
    if (caseInsensitive) rmod += "i";
    var s = new RegExp(r, rmod);
    var res = s.exec(window.location.href.toString());
    if (!res && defaultValueIfNull) return defaultValueIfNull;
    else if (!res) return null;
    else return res[1];
}

RioTrackingManager.prototype.getCookie = function(name) {
    var search = name + "="
    var returnvalue = "";

    if (document.cookie.length > 0) {
        offset = document.cookie.indexOf(search)
        // if cookie exists
        if (offset != -1) {
            offset += search.length
            // set index of beginning of value
            end = document.cookie.indexOf(";", offset);
            // set index of end of cookie value
            if (end == -1) {
                end = document.cookie.length;
            }

            returnvalue = unescape(document.cookie.substring(offset, end))
        }
    }

    return returnvalue;
}


/**********************************/
/* JavaScript Class Modifications */
/**********************************/

String.prototype.format = function() {
    var pattern = /\{\d+\}/g;
    var args = arguments;
    return this.replace(pattern, function(capture) { return args[capture.match(/\d+/)]; });
}

Array.prototype.IndexOf = function(obj) {

    var i = this.length;

    while (i--) {
        if (this[i].match(obj + "-")) {
            return i;
        }
    }

    return -1;
}

Array.prototype.Join = function(count, delimiter) {
    var _result = "";
    var _maxCellCodes = (count > this.length ? this.length : count);

    for (_index = 0; _index < _maxCellCodes; _index++) {

        _result += this[_index] + (_index < _maxCellCodes - 1 ? delimiter : "");
    }

    return _result;
}

Array.prototype.Add = function(addIndex, obj) {
    for (_index = this.length; _index > addIndex; _index--) {
        this[_index] = this[_index - 1];
    }

    this[addIndex] = obj;
}

RioTrackingManager.prototype.getCurrentDateTime = function() {
    var currentTime = new Date();

    var month = currentTime.getMonth() + 1;
    var day = currentTime.getDate();
    var year = currentTime.getFullYear();

    var hours = currentTime.getHours();
    var minutes = currentTime.getMinutes();
    var seconds = currentTime.getSeconds();
    if (minutes < 10) {
        minutes = "0" + minutes;
    }

    if (seconds < 10) {
        seconds = "0" + seconds;
    }

    return month + "/" + day + "/" + year + " " + hours + ":" + minutes + ":" + seconds;
}

// Instantiation of RIO Tracking Onject
var RioTracking = new RioTrackingManager();
