/* Copyright 2009 Optify Inc. */
var _opt = new (function() {

	var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
	function generateUuid(len, radix) {
		var chars = CHARS, uuid = [], rnd = Math.random;
		radix = radix || chars.length;

		if (len) {
			// Compact form
			for ( var k = 0; k < len; k++) {
				uuid[k] = chars[0 | rnd() * radix];
			}
		} 
		else {
			var r;

			uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
			uuid[14] = '4';

			for ( var i = 0; i < 36; i++) {
				if (!uuid[i]) {
					r = 0 | rnd() * 16;
					uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r & 0xf];
				}
			}
		}
		return uuid.join('');
	}

	var cid = "";	//org JS token (corresponds to token column in organization table)
	
	var doc = document;
	var doc_title = doc.title;
	
	var serviceUrl = "service.optify.net";
	
	//can override the serviceUrl (useful in dev/test environments)
	try {
		if(window.serviceUrlOverride) {
			serviceUrl = window.serviceUrlOverride;
		}
	} catch(err) { }
	
	var pageProtocol = window.location.protocol + "//";
	var trackURL = pageProtocol + serviceUrl + "/visit/ping"; //URL to request tracking pixel
	var formURL = pageProtocol + serviceUrl + "/form/submit"; //URL to send form submission
	
	var visitorId;		//visitor id stored in visitorName cookie. unique per org. 
	var visitId;		//visit id stored in vtimedName cookie.

    // Names for our cookies.  They will be set in setCookieNames(), which is called by view().
	var visitorName = ""; 	//visitor cookie, long-lived (expires in 2020)
	var vsessionName = ""; 	//visit cookie, expires if browser is closed
	var vtimedName = ""; 	//visit cookie, expires after two hours of inactivity	
	
	var vtimed_time = 120; //visit cookie expires after 120 minutes (or if the browser is closed)

    //roll back form action change (if applied) if tracking pixel does not load
    function imgOnError() {
        var _forms = document.getElementsByTagName('form');
        for (var i = 0; i < _forms.length; i++) {
            var _form = _forms[i];
            var _originalActionElement = _form.elements["_orig_action"];
            
            if(_originalActionElement && _originalActionElement.value) {
                _form.action = _originalActionElement.value;
            }
        }
    }

	/* Public methods */
	this.getVisitId = function(){return visitId;}
	this.getVisitorId = function(){return visitorId;}
	this.getTitle = function(){return encodeURIComponent(doc_title);}
	this.getCid = function(){return cid;}
	this.getUrl = function(){return encodeURIComponent(document.location.href);}
	this.getQueryVar = function(variable){
		return getQueryVariable(variable);
	}
	
    this.view = function(c_token) {
		if (c_token === undefined || c_token === '') {
			return;
		}
	
		cid = c_token;			//customer JS token

        setCookieNames(c_token);  // VERY important to do this early!!!
		migrateCookies(visitorName);

		// if a visitorId does not already exist or if it is a broken 'foo' then generate a new one.
		visitorId = getCookie(visitorName);
		if (!visitorId || visitorId === "" || visitorId === "null" || visitorId === "foo") {
			visitorId = genCookieID();
		}
		
		//query parameters to tracking pixel
		var _ref = "&ref=" + getReferrer();									//referrer
		var _title = "&title=" + encodeURIComponent(doc_title);				//page title
		var _visitorId = "&visitorId=" + visitorId;							//visitor id
		var _url = "&url=" + encodeURIComponent(document.location.href);	//page url	
		var _cid = "?cId=" + cid;											//org token
		
		//custom "campaigns"
		var _optify_ref_old = getQueryVariable("optify_r");
		var _optify_ref_title_old = getQueryVariable("optify_rd");
		
		var _optify_ref_new = getQueryVariable("_opt_r");
		var _optify_ref_title_new = getQueryVariable("_opt_rd");
		var _optify_ref_title_id = getQueryVariable("_opt_rdid");
		
		var _optify_ref = (_optify_ref_new && _optify_ref_new !== "") ? _optify_ref_new : _optify_ref_old;
		var _optify_ref_title = (_optify_ref_title_new && _optify_ref_title_new !== "") ? _optify_ref_title_new : _optify_ref_title_old;
		
		trackURL += _cid + _visitorId + _ref + _title + _url + '&' + Math.random();		//Math.random() for busting browser caching

		if(_optify_ref && _optify_ref !== "") {
			trackURL += "&_opt_r=" + _optify_ref;
		}
		if(_optify_ref_title && _optify_ref_title !== "") {
			trackURL += "&_opt_rd=" + _optify_ref_title;
		}
		if (_optify_ref_title_id && _optify_ref_title_id !== ""){
			trackURL += "&_opt_rdid=" + _optify_ref_title_id;
		}
		
		setVisitorCookie();
	
		var vsession = getCookie(vsessionName);
		var vtimed = getCookie(vtimedName);
	
		visitId = vtimed;
	
		if(visitId === "foo") // for a week we had 'foo' values all over the place.  drop them.
		{
			vtimed = null;
		}
		
		if (!vsession || !vtimed) {
			visitId = generateUuid(10, 16);
			setVisitSessionCookie();
		}
	
		setVisitTimedCookie(visitId);
	
		trackURL += "&visitId=" + visitId;
	
		var trackingPixel = new Image(1,1);
		trackingPixel.src = trackURL;
		trackingPixel.onerror = imgOnError;

        modifyForms();
	};
	
    function setCookieNames(suffix) {
        // supports sub-site tracking by letting us have multiple cookie sets for a domain
		visitorName  = "_opt_vi_" + suffix;
		vsessionName = "_opt_vs_" + suffix;
		vtimedName   = "_opt_vt_" + suffix;
    }

	//with sub-site tracking we have new cookie names that include the customer token.
	//we want to copy over any existing cookies to the new system and then expire the old ones.
	function migrateCookies(newVisitorName) {
	    // if new style cookie names already exist then do not re-migrate
		var newVisitor = getCookie(newVisitorName);
		if(newVisitor)
			return;
		
		var oldVisitorName = "_opt_vi";
		var oldVsessionName = "_opt_vs";
		var oldVtimedName = "_opt_vt";
		
		var oldVtimed = getCookie(oldVtimedName);
		var oldVisitor = getCookie(oldVisitorName);
		
		//if old cookies are stored, migrate visitor and visit id 
		if(oldVisitor) {
			visitorId = oldVisitor;
			setVisitorCookie();
		}
		
		if(oldVtimed) {
			visitId = oldVtimed;
			setVisitSessionCookie();
			setVisitTimedCookie(visitId);
		}
		
		var date = new Date(2000, 1, 1);		//setting expiration date to past will erase cookie 
		setCookie(oldVisitorName, oldVisitor, date.toGMTString());
		setCookie(oldVsessionName, oldVtimed, date.toGMTString());
		setCookie(oldVtimedName, oldVtimed, date.toGMTString());
	}
	
	function getQueryVariable(variable) {
		var query = window.location.search.substring(1);
		var vars = query.split("&");
		for ( var i = 0; i < vars.length; i++) {
			var pair = vars[i].split("=");
			if (pair[0] == variable) {
				return pair[1];
			}
		}
	}
	
	function genCookieID() {
		return generateUuid();
	}
	
	function setCookie(name, value, expires, path) {
		var domain = getDomain();
	
		document.cookie = name + "=" + value + 
				((expires) ? ";expires=" + expires : "") + 
				((path) ? ";path=" + path : ";path=/") + 
				((domain) ? ";domain=." + domain : "");
	}
	
	function setVisitorCookie() {
		var date = new Date(2020, 1, 1);
		setCookie(visitorName, encodeURIComponent(visitorId), date.toGMTString());
	}
	
	function setVisitSessionCookie() {
		setCookie(vsessionName, encodeURIComponent(visitorId));
	}
	
	function setVisitTimedCookie(previousVisitId) {
		var date = new Date();
		date.setMinutes(date.getMinutes() + vtimed_time);
		setCookie(vtimedName, encodeURIComponent(previousVisitId), date.toGMTString());
	}
	
	function getCookie(name) {
		var dc = document.cookie;
		var prefix = name + "=";
		var begin = dc.indexOf("; " + prefix);
		if (begin == -1) {
			begin = dc.indexOf(prefix);
			if (begin !== 0) {
				return null;
			}
		} 
		else {
			begin += 2;
		}
		var end = dc.indexOf(";", begin);
		if (end == -1) {
			end = dc.length;
		}
		return decodeURIComponent(dc.substring(begin + prefix.length, end));
	}
	
	function getDomain() {
		var domainSuffixes = "aero;arpa;biz;cat;co;coop;com;edu;gov;info;int;jobs;mil;mobi;museum;name;net;org;pro;travel;";
		var domain = document.domain;
		var temp = domain.split('.');
		if ((/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/).test(domain)) {
			return domain;
		} else if (temp.length == 1) {
			return null;
		} else {
			var d = "";
			var i = 0;
			while (i < 2) {
				i++;
				var suffix = temp[temp.length - i];
				d = suffix + (i > 1 ? "." : "") + d;
				if (domainSuffixes.indexOf(suffix + ";") != -1) {
					d = temp[temp.length - i - 1] + "." + d;
					break;
				}
			}
			return d;
		}
	}
	
	function getReferrer() {
		var ref = encodeURIComponent(doc.referrer);
		if (ref === undefined || ref === '') {
			return '';
		}
		return ref;
	}
	
    function addHiddenField(_form, field_name, field_value) {
        var element  = null;
        var type = "input";

        // For the following see #1106 regarding dynamic naming of input elements, as well as
        //     http://www.thunderguy.com/semicolon/2005/05/23/setting-the-name-attribute-in-internet-explorer/

        // Attempt to create element using ghetto IE < 8 style
        try {
            element = document.createElement('<' + type + ' name="' + field_name + '" type="hidden"/>');
        } catch (e) {
        }

        // Normal browsers
        if (!element || element.nodeName != type.toUpperCase()) {
            element = document.createElement(type);
            element.type = 'hidden';
            element.name = field_name;
        }

        element.value = field_value;
        
        _form.appendChild(element);
    }


	// If modifyForms is exported to the world something will have be done to cleanly handle when
	// the tracker-receiver is down.  Extra pings will clean things up?
	function modifyForms() {
		var _forms = document.getElementsByTagName('form');
		for (var i = 0; i < _forms.length; i++) {
			var _form = _forms[i];
			
			var canModify = false;				//can we add hidden fields that track visitor id, visit id, page url, etc. 
			var canChangeAction = false;		//can we change the form action to point to our servers
			
	        var action = _form.getAttribute('action');
	        if(action == null || action == "")
	        	action = window.location.href;
	        var _optify_submit = _form.getAttribute('optify_submit');
	        var _optify_modify = _form.getAttribute('optify_modify');
   	        var _optify_target_token = _form.getAttribute('optify_target_token');
            var _preexistingCID = _form.elements['_opt_cid'];

            if (_preexistingCID) {
                continue; // something already touched this form.  bail.
            }

            if (_optify_target_token && _optify_target_token !== cid) {
	            continue; // this form is tagged for a different optify token, do not touch it!
	        }

	        if (action && action.indexOf && (action.indexOf('http://www.salesforce.com/servlet/servlet.WebToLead') != -1 ||
	        		      action.indexOf('https://www.salesforce.com/servlet/servlet.WebToLead') != -1)) {
	        	canModify = true;
	        	canChangeAction = true;
	        }
	        else if(_optify_submit && _optify_submit.toLowerCase() === "true") {
				canModify = true;
				canChangeAction = true;
			}
	        else if(_optify_modify && _optify_modify.toLowerCase() === "true") {
	            canModify = true;
	            canChangeAction = false;
	        }
	        
			for (var j = 0; j < _form.elements.length; j++) {
				var _element = _form.elements[j];
				var _elementClass = _element.className;
				//see http://wiki.optify.net/pages/viewpage.action?pageId=2884691 for explanation of optify_vid
				if(_elementClass && _elementClass === "optify_vid") {
					_element.value = visitorId;
					canModify = true;
					break;
				}
			}

			if(canModify) {
				addHiddenField(_form, "_orig_action", action);
				addHiddenField(_form, "_opt_vid", visitorId);
				addHiddenField(_form, "_opt_visit", visitId);
				addHiddenField(_form, "_opt_cid", cid);
				addHiddenField(_form, "_opt_url", document.location.href);
				addHiddenField(_form, "_opt_paget", document.title);
			}
			
			if(canChangeAction) {
			    _form.action = formURL;
			}
		}
	}
})();

