//PDTS v1.3.1
//Added bing to the list of search sites.
//-- R. Seward 23 July 2009

//PDTS v1.3
//Improved classification of the linkType based on the LandingPage
// Reformated with http://jsbeautifier.org/
//-- R. Seward 3 July 2009

//PDTS v1.25
//Added Campaign and Medium Data
//-- D O'Neil 20 May 2008

//PDTS v1.2
//Major change to SetSubmitValues api; now set up as a hash array that will automatically search for
// and populate fields described in the user-defined values below

//pdts v1.1
// i. Corrected "direct tracking" bug 
//ii. simplified submission data set and separated into a specific function
//-- D O'Neil 16 May 2008

// pdts with google autotagging as well as general tagging capabilities.  
// installation of this script is a 3 step process:
// 1. 	Upload this script to the website and call it from EVERY page on the website.  
//		Sample installation code:  <script src="/scripts/PDTS.js"></script>

// 2.	In Salesforce, determine the form values mapping as assigned by the system.
//		Record those default mappings in the variables below: 							
var sfRefUrl = "00N3000000129K4"
var sfRefDomain = "00N3000000129N7"
var sfSearchTerms = "00N3000000129NH"
var sfLandingPage = "00N3000000129Mx"
var sfLinkType = "00N300000012Dky"
var sfMonthYear = "N/A"
var sfCampaign = "00N300000021Mss"
var sfMedium = "00N300000021Msx"

// 3.	Using the form values generated by Salesforce, add the appropriate hidden form fields to the website's form.  
//		Finally, call the function ParseSearchQuery as an onsubmit javascript action from your form(s).  This will properly
//		populate the hidden variables on your form as well as deleting the cookies. 

// 4.	If you want to track campaigns such as email campaigns, you can use the utm_medium and utm_source parameters
//		in the parameter. utm_medium will track the type of campaign (email, television, radio), and the 
//		utm_source will track the specific campaign (idaho email, for example). this will be put into the 
//		Campaign Channel and Web Campaign fields, respectively.

//5.	For Google, you're ready to go.  For any other paid search effort, a custom tag must be appended to the landing page URL
//		Currently, that tag is "paidSearch"  Both this tag and the native Google tag can be changed here:

var adwordsTag = "_kk";
var generalTag = "paidSearch";
var mailBlastTag = "utm_medium";

rawDate = Date()
splitDate = rawDate.split(" ")
monthYear = splitDate[1] + " " + splitDate[3]

SetRef();

function Map() {
    // members
    this.keyArray = new Array(); // Keys
    this.valArray = new Array(); // Values

    // methods
    this.put = put;
    this.get = get;
    this.size = size;
    this.clear = clear;
    this.keySet = keySet;
    this.valSet = valSet;
    this.showMe = showMe; // returns a string with all keys and values in map.
    this.findIt = findIt;
    this.remove = remove;
}

function put(key, val) {
    var elementIndex = this.findIt(key);

    if (elementIndex == ( - 1)) {
        this.keyArray.push(key);
        this.valArray.push(val);
    }
    else {
        this.valArray[elementIndex] = val;
    }
}

function get(key) {
    var result = null;
    var elementIndex = this.findIt(key);

    if (elementIndex != ( - 1)) {
        result = this.valArray[elementIndex];
    }
    return result;
}

function remove(key) {
    var result = null;
    var elementIndex = this.findIt(key);

    if (elementIndex != ( - 1)) {
        this.keyArray = this.keyArray.removeAt(elementIndex);
        this.valArray = this.valArray.removeAt(elementIndex);
    }
    return;
}

function size() {
    return (this.keyArray.length);
}

function clear() {
    for (var i = 0; i < this.keyArray.length; i++) {
        this.keyArray.pop();
        this.valArray.pop();
    }
}

function keySet() {
    return (this.keyArray);
}

function valSet() {
    return (this.valArray);
}

function showMe() {
    var result = "";

    for (var i = 0; i < this.keyArray.length; i++) {
        result += "Key: " + this.keyArray[i] + "\tValues: " + this.valArray[i] + "\n";
    }
    return result;
}

function findIt(key) {
    var result = ( - 1);

    for (var i = 0; i < this.keyArray.length; i++) {
        if (this.keyArray[i] == key) {
            result = i;
            break;
        }
    }
    return result;
}

function removeAt(index) {
    var part1 = this.slice(0, index);
    var part2 = this.slice(index + 1);

    return (part1.concat(part2));
}
Array.prototype.removeAt = removeAt;

function GetCookie(check_name) {
    // first we'll split this cookie up into name/value pairs
    // note: document.cookie only returns name=value, not the other components
    var a_all_cookies = document.cookie.split(';');
    var a_temp_cookie = '';
    var cookie_name = '';
    var cookie_value = '';
    var b_cookie_found = false; // set boolean t/f default f

    for (i = 0; i < a_all_cookies.length; i++) {
        // now we'll split apart each name=value pair
        a_temp_cookie = a_all_cookies[i].split('=');

        // and trim left/right whitespace while we're at it
        cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');

        // if the extracted name matches passed check_name
        if (cookie_name == check_name) {
            b_cookie_found = true;
            // we need to handle case where cookie has no value but exists (no = sign, that is):
            if (a_temp_cookie.length > 1) {
                cookie_value = unescape(a_temp_cookie[1].replace(/^\s+|\s+$/g, ''));
            }
            // note that in cases where cookie is initialized but no value, null is returned
            return cookie_value;
            break;
        }
        a_temp_cookie = null;
        cookie_name = '';
    }
    if (!b_cookie_found) {
        return null;
    }
}

function DeleteCookie(name, path, domain) {
    // this deletes the cookie when called
    if (GetCookie(name)) {
		document.cookie = name + "=" +
		( ( path ) ? ";path=" + path : "") +
		( ( domain ) ? ";domain=" + domain : "" ) +
		";expires=Thu, 01-Jan-1970 00:00:01 GMT";
    }
}

function SetCookie(name, value, expiryInDays, path, domain, secure) {
    // set time, it's in milliseconds
    var today = new Date();

    today.setTime(today.getTime());
    /*
	if the expiryInDays variable is set, make the correct 
	expiryInDays time, the current script below will set 
	it for x number of days, to make it for hours, 
	delete * 24, for minutes, delete * 60 * 24
	*/

    if (expiryInDays) {
        expiryInDays = expiryInDays * 1000 * 60 * 60 * 24;
    }

    var expires_date = new Date(today.getTime() + (expiryInDays));
    document.cookie = name + "=" + escape(value) + ((expiryInDays) ? ";expires=" + expires_date.toGMTString() : "") + ((path) ? ";path=" + path: "") + ((domain) ? ";domain=" + domain: "") + ((secure) ? ";secure": "");
}

function GetDomain(url) {
    if (url) {
        var domain = url.match(/:\/\/(www\.)?([^\/:]+)/);
        domain = domain[2] ? domain[2] : '';
        return domain;
    }
}

function ShowCookies() {
    var PDTSref = GetCookie('PDTSref');
    var PDTSlanding = GetCookie('PDTSlanding');

    if (PDTSref) {
        //alert("PDTSref="+PDTSref);
        var debugNode = document.getElementById('PDTSref');
        if (debugNode) {
            debugNode.innerHTML = PDTSref;
        }
    }
    if (PDTSlanding) {
        //alert("PDTSlanding="+PDTSlanding);
        var debugNode = document.getElementById('PDTSlanding');
        if (debugNode) {
            debugNode.innerHTML = PDTSlanding;
        }
    }
}

function SetRef() {
    var ref = document.referrer;
    var doc = document.URL;

    //alert("ref="+ref+", doc="+doc);
    //alert("ref.domain="+GetDomain(ref)+", doc.domain="+GetDomain(doc));

    var PDTSref = GetCookie('PDTSref');
    var PDTSlanding = GetCookie('PDTSlanding');

    if (GetDomain(ref) != GetDomain(doc)) {
        //alert("PDTSref="+PDTSref+" "+GetDomain(ref));
        if (PDTSref == null) {
            SetCookie('PDTSref', ref, 365, "/", GetDomain(doc));
            //alert("PDTSref="+ref);
        }
        if (PDTSlanding == null) {
            SetCookie('PDTSlanding', doc, 365, "/", GetDomain(doc));
            //alert("PDTSlanding="+doc);
        }
    }

}

function GetQueryParams(urlString, resultHash) {
    var queryString;
    var pairs;
    var stringPairs;
    var keyval;

    //alert("refUrl is: " + urlString);
    if (urlString.indexOf("?") > -1) {

        //Get everything to the right of the "?"
        queryString = urlString.split("?")[1];

        // split the query string
        pairs = queryString.split("&");
        //alert ("pairlength: "+pairs.length);
        for (var i = 0; i <= (pairs.length - 1); i++) {
            //alert("count="+i+" val:"+pairs[i]);
            keyval = pairs[i].split("=");
            resultHash.put(keyval[0], keyval[1]);
        }
        //alert("pairsplit loop completed");
    }
    return resultHash;
}

function setWhenEmpty(theVar, newValue) {
    if (!theVar) {
        theVar = newValue;
    }
    return theVar;
}

function ParseSearchQuery() {

    // 2-part activity
    // Step 1: parse between direct and referrer
    // Step 2: Get Seach terms if result is a search engine
    // additional var/value combinations from the url script
    // that don't require parsing are simply stored in the hashmap

    var refUrl
    var searchTerms
    var landingPage
    var linkType;
    var searchParam;
    var refDomain;
    var resultHash = new Map();

    landingPage = GetCookie('PDTSlanding');
    refUrl = GetCookie('PDTSref');

    //alert("landingPage= "+landingPage);	
    //alert("refUrl= "+refUrl);

    /*
	// test parameters
	landingPage = "www.purevisibility.com"; 
	refUrl = "http://www.google.com?utm_source=source&utm_medium=medium&q=findTHIS";
*/

    // Checking the landing page for obvious reasons for the visitor to be here
    if (landingPage) {
        if (landingPage.indexOf(adwordsTag) > -1) {
            linkType = setWhenEmpty(linkType, "Paid Search");
        }
        else if (landingPage.indexOf(generalTag) > -1) {
            linkType = setWhenEmpty(linkType, "Paid Search");
        }
        else if (landingPage.indexOf(mailBlastTag) > -1) {
            linkType = setWhenEmpty(linkType, "Email Blast");
        }
    }

    // Step 1. This check is for direct visits to the site
    // if it's a direct visit then load this list
    if (! (refUrl)) {
        refUrl = null;
        refDomain = "Direct";
        linkType = setWhenEmpty(linkType, "Direct");
        searchTerms = null;

        // otherwise it's a referrer, so we
        // 1) Need to parse the cookie data    
        // 2) need to get search engine data if need be
    } else {

        refDomain = GetDomain(refUrl);
        //alert("refDomain="+refDomain);

        // This check parses referrals from search engines
        // and defines the search as a search engine or a referral
        if (refDomain.indexOf("yahoo") > -1) {
            searchParam = "p";
        } else if (refDomain.indexOf("aol") > -1) {
            searchParam = "query";
        } else if (refDomain.indexOf("netscape") > -1) {
            searchParam = "query";
        } else if (refDomain.indexOf("google") > -1) {
            searchParam = "q";
        } else if (refDomain.indexOf("bing.com") > -1) {
            searchParam = "q";
        }

        // grab parameters from the referrer page and set search terms
        resultHash = GetQueryParams(refUrl, resultHash);
        searchTerms = resultHash.get(searchParam);

        // grab parameters from the landing page
        resultHash = GetQueryParams(landingPage, resultHash);

        //alert("searchParam="+searchParam);
        // This check identifies the referral linkType 
        if (searchParam) {
            // Earlier we should have identified the referral as a Paid Search
            // if linkType is empty then this a Natural Search
            linkType = setWhenEmpty(linkType, "Natural Search");
        } else {
            // This request has a referer but wasn't a search
            linkType = setWhenEmpty(linkType, "Referral");
        }
    }

    //alert("set hashmap results");
    // Set Result HashMap
    resultHash.put("refUrl", refUrl);
    resultHash.put("refDomain", refDomain);
    resultHash.put("searchTerms", searchTerms);
    resultHash.put("landingPage", landingPage);
    resultHash.put("linkType", linkType);

    /*
	alert(resultHash.size());  
	alert(resultHash.showMe());
*/

    // Submit Data Results	
    SetSubmitValues(resultHash);

    //delete cookie so that we can do this fun again!
    DeletePdtsCookies(GetDomain(landingPage));
}

function DeletePdtsCookies(domain) {
    DeleteCookie('PDTSref', "/", domain);
    DeleteCookie('PDTSlanding', "/", domain);
}

function SetSubmitValues(resultHash) {

    if (resultHash.get("refUrl")) {
        document.getElementById(sfRefUrl).value = resultHash.get("refUrl");
        //document.getElementById("refUrl").value = resultHash.get("refUrl");
    }

    if (resultHash.get("refDomain")) {
        document.getElementById(sfRefDomain).value = resultHash.get("refDomain");
    }

    if (resultHash.get("searchTerms")) {
        document.getElementById(sfSearchTerms).value = resultHash.get("searchTerms");
    }

    if (resultHash.get("landingPage")) {
        document.getElementById(sfLandingPage).value = resultHash.get("landingPage");
        //document.getElementById("landingPage").value = resultHash.get("landingPage");
    }

    if (resultHash.get("linkType")) {
        document.getElementById(sfLinkType).value = resultHash.get("linkType");
    }

    if (resultHash.get("monthYear")) {
        document.getElementById(sfMonthYear).value = resultHash.get("monthYear");
    }

    if (resultHash.get("utm_source")) {
        document.getElementById(sfCampaign).value = resultHash.get("utm_source");
    }

    if (resultHash.get("utm_medium")) {
        document.getElementById(sfMedium).value = resultHash.get("utm_medium");
    }

    //alert("results entered and submitted.");

}
