/// <reference path="~/js/reference.js" />

$.createSingleton('X.Omniture',
// Constructor
function () {
	this.keyRE = /omnikey\-([^ ]+)/g;
	this.keyRE.compile(this.keyRE.source, this.keyRE.options);

	this._queue = []; // stores calls until the omniture object is ready
	this._defaults = {}; // stores data defaults for the page
	this._lastPropsSet = [];

	this._useIFrame = false;
	this._firstPageCall = true;
	this._forceQueuing = this._forceQueuingFlag = true;
	this.lastPageName = '';
	this.data = {};
},
// Prototype
{
// Called form page docuemnt ready event handler,
// Bind's click events to elements with omniture class
// Also sets the defaults
init: function () {
	$('.omniture,.omniture-page').each(function (idx) {
		X.Omniture._registerElm(this);
	});

	//window.setTimeout(X.Omniture.onExecuteQueue.delegate(X.Omniture), 10000);
},

onPageLoad: function () {
	if (this._forceQueuing) {
		setTimeout(this.onDelayedPageLoad.delegate(this), 100);
	}
	else {
		this.onDelayedPageLoad();
	}
},

onDelayedPageLoad: function () {
	if (!this._useIFrame) {
		$.console.log('begin loading s_code.js', 'loading_scode');
		$.ajax({
			type: "GET",
			url: "/js/s_code.js",
			success: function () { $.console.log('end loading s_code.js', 'loading_scode'); X.Omniture.onExecuteQueue(); },
			dataType: "script",
			cache: true
		});
	}
	else {
		$('<iframe src="/Omni.html" id="_omni_iframe_" name="_omni_iframe_" style="display:none;"></iframe>').appendTo($(document.body));
		this.onExecuteQueue();
	}
},

/*onPageUnload: function()
{
//if (!this._forceQueuingFlag) { return; }
this.onExecuteQueue();
},*/

// Set Ominture defaults
setDefaults: function (props) {
	props = this._getValidData(props);
	if (!props) { return; }
	for (var prop in props.data) {
		props.data[prop] = props.data[prop].toUpperCase();
	}
	this._defaults = props.data;
},

// Registers a set of omniture tags data
register: function (data) {
	if (!data) { return; }
	this.data = data;
},

// * Called via element click handler for element's with .omniture
// * class passing in the key (extracted from omnikey-XXX class)
// *  props.linkName
// *  props.key
// *  props.data
// *
trigger: function (props, obj, type, extendDefaults) {
	if (!props.linkName || props.linkName === '#') {
		props.linkName = location.href;
	}

	if (type == 'e' || type == 'd') {
		extendDefaults = false;
	}


	if (this.update(props, extendDefaults)) {
		var o = this._getObject();

		$.console.log('X.Omniture.trigger() - begin call');
		switch (type) {
			case 'e':
				if (obj) {
					o.tl(obj, type, props.data.prop25);
				}
				else if (props.data.url) // for flash which doesn't have an obj
				{
					o.tl(true, type, props.data.url.toLowerCase());
				}
				break;

			case 'd':
				o.tl(obj || true, type, props.data.fileName);
				break;

			default:
				o.tl(obj || true, 'o', props.data.prop16 || props.linkName);
				break;
		}

		$.console.log('X.Omniture.trigger() - end call');
	}
},

// Trigger's omniture's page load
triggerPageLoad: function (data) {
	var props = { data: data, pageLoad: true };
	if (this.update(props)) {

		var o = this._getObject();

		$.console.log('X.Omniture.triggerPageLoad() - begin call');
		var s_code = o.t(); //window.setTimeout(function() { o.t(); }, 0); // TODO - write response into document


		$.console.log('X.Omniture.triggerPageLoad() - end call');

		return s_code;
	}
	return '';
},

// Called via the trigger and triggerPageLoad methods,
// as well as in page after the X.Omniture.register() method
update: function (props, extendDefaults) {
	if (typeof (props) === 'string') {
		props = { key: props };
	}

	props = this._getValidData(props);

	if (!props || !props.data) { return false; }

	var propNames = [];

	// Ensure we have default values where the values do not exist
	if (extendDefaults || (extendDefaults === undefined)) {
		props.data = $.extend({}, this._defaults, props.data);
	}
	else {
		var clearData = {};
		for (var prop in this._defaults) {
			clearData[prop] = "";
		}

		props.data = $.extend({}, clearData, props.data);
	}

	if (props.data['prop16'] || props.data['prop25']) {
		if (this.lastPageName && !props.data['prop23']) props.data['prop23'] = this.lastPageName;
	}

	// reset the omniture object
	this._clearProps();

	if (props.pageLoad) {
		this.lastPageName = props.data.pageName || '';
		$.extend(props.data, { prop37: window.location.href });
	}

	if (window.dealerID) {

		$.extend(props.data, { prop38: window.dealerID, prop51: window.dealerID });

		if (window.websiteProvider) {
			$.extend(props.data, { prop39: window.websiteProvider });
		}
	}

	if (this._firstPageCall && props.pageLoad) {
		this._firstPageCall = false;

		var shareParam = $.query.get("from");
		var shareOmniture;
		var includePageName = false;

		if (shareParam && shareParam.length > 0) {

			if (shareParam.match(/^BRCE:.*/)) {
				shareOmniture = shareParam;
			}
			else {

				switch (shareParam) {

					case "fb":
						includePageName = true;
						shareOmniture = "FACEBOOK";
						break;
					case "mobile":
						shareOmniture = "ACURA MOBILE";
						break;
					case "MY ACURA WINTER SLS EVNT 1111":
						shareOmniture = "MY ACURA WINTER SLS EVNT 1111";
						break;
					case "EMAIL":
						shareOmniture = $.query.get("OFFERCODE");
						if (!shareOmniture || shareOmniture === true) {
							shareOmniture = "EMAIL";
						}
						break;

				}
			}

			if (shareOmniture) {
				if (includePageName) {
					$.extend(props.data, { prop29: shareOmniture + " " + props.data["pageName"] });
				}
				else {
					$.extend(props.data, { prop29: shareOmniture });
				}
			}

		}
	}



	// Uppercase the values
	for (var prop in props.data) {
		propNames[propNames.length] = prop;

		if (typeof (props.data[prop]) !== 'string' || prop === 'events') { continue; }
		props.data[prop] = props.data[prop].toUpperCase();
	}

	if ($.cookie('dealerinventory')) {
		for (var prop in props.data) {
			props.data[prop] = props.data[prop].replace("DEALER SEARCH", "INVNTRY SRCH");
			props.data[prop] = props.data[prop].replace("DEALER LOCATOR", "INVENTORY SEARCH");
			props.data[prop] = props.data[prop].replace("DL:", "INVLOC:");
		}
	}

	// Add the newly set prop to the last set props
	this._lastPropsSet = propNames;

	// If ominiture is not loaded, add the object to the queue, and exit
	if (!this._isOmnitureLoaded()) {
		this._queue[this._queue.length] = props;
		return false;
	}

	// Set all of our properties in the window.s object
	this._setObjProps(props.data);

	return true;
},

// Returns the Omniture object
_getObject: function () {
	if (this._forceQueuing) { return null; }

	if (this._useIFrame) {
		var iframeElm = $('#_omni_iframe_')[0];
		if (!iframeElm || !iframeElm.contentWindow) { return null; }
		iframeElm = iframeElm.contentWindow;
		return (iframeElm && iframeElm.s) ? iframeElm.s : null;
	}
	else {
		return window.s || null;
	}
},

// Determines if omniture has been loaded
_isOmnitureLoaded: function () {
	var o = this._getObject();
	return (o !== null);
},

// Set the actual Omniture object's properties
_setObjProps: function (data) {
	var o = this._getObject();
	for (var prop in data) {
		o[prop] = data[prop];
	}
},

// onExecuteQueue, loop through the queue of calls, and call them
// ONLY CALLED AFTER OMNITURE IS AVAILABLE IN THE PAGE
// ONLY GETS CALLED FROM window.onload
onExecuteQueue: function () {
	this._forceQueuing = false;

	if (!this._isOmnitureLoaded()) { return; }

	var len = this._queue.length;
	if (len === 0) { return; }

	// loop through each item in the queue, and call omniture
	for (var idx = 0, props; idx < len; idx++) {
		props = this._queue[idx];

		// Clear out the previously set props (if any)
		if (idx > 0) {
			this._clearProps();
		}

		// Get the names for the last call
		this._lastPropsSet = [];
		for (var prop in props.data) {
			this._lastPropsSet[this._lastPropsSet.length] = prop;
		}

		this._setObjProps(props.data);

		var o = this._getObject();
		if (props.pageLoad) {
			$.console.log('X.Omniture.onExecuteQueue() t() - begin call');
			o.t(); // TODO - write response into document
			$.console.log('X.Omniture.onExecuteQueue() t() - end call');
		}
		else {
			$.console.log('X.Omniture.onExecuteQueue() tl() - begin call');
			o.tl(true, 'o', props.linkName);
			$.console.log('X.Omniture.onExecuteQueue() tl() - end call');
		}
	}

	this._queue = [];

	//alert('end making queued calls');
},

// Clear out the Omniture object's last set properties
_clearProps: function () {
	if (!this._isOmnitureLoaded()) { return; }

	var len = this._lastPropsSet.length;
	if (len > 0) {
		var o = this._getObject();
		for (var idx = 0, prop; idx < len; idx++) {
			prop = this._lastPropsSet[idx];
			try {
				o[prop] = {};
				delete o[prop];
			}
			catch (ex) {
				o[prop] = '';
			}
		}
	}
	this._lastPropsSet = [];
},

// Checks to see if the props object passed in has a data prop, and if not
// sets it to the key
_getValidData: function (props) {
	// If we don't have data being passed in,
	// then look it up via the key
	// If there is no data for the key, then this is an invalid call, exit
	if (!props.data) {
		if (!props.key) { return null; }

		// 'k' is our key prefix
		props.data = this.data['k' + props.key];
		if (!props.data) { return null; }
	}
	return props;
},

// Register's an element's click event to the _handleEvent method
_registerElm: function (elm) {
	var matches = this.keyRE.exec(elm.className);
	this.keyRE.lastIndex = 0;
	if (!matches || matches.length < 2) { return; }

	var key = matches[1];
	$(elm).click(this._handleEvent.proxy(elm, key));
},

// Handles a omniture trackLink event
_handleEvent: function (evt, key) {
	if (!$(this).hasClass('omniture-page')) {
		X.Omniture.trigger({ linkName: this.href, key: key });
	}
	else {
		X.Omniture.triggerPageLoad($.extend(X.Omniture._getValidData({ key: key }).data, { prop37: this.href }));
	}
}
});

X.Omniture.init();

$(window)
    .load(X.Omniture.onPageLoad.delegate(X.Omniture))
    //.unload(X.Omniture.onPageUnload.delegate(X.Omniture));

