/**
 * Copyright 2009 Great Wolf Lodge
 * Web Track module
 */
(function() {
    // Create the GWR namespace
    var GWR = window.GWR = window.GWR || {};
    var ns = GWR.WebTrack || {};

	ns.cookie = function(name, value, options) {
		if (typeof value != 'undefined') {
			options = options || {};
			if (value === null) {
				value = '';
				options.expires = -1;
			}
			var expires = '';
			if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
				var date;
				if (typeof options.expires == 'number') {
					date = new Date();
					date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
				} else {
					date = options.expires;
				}
				expires = '; expires=' + date.toUTCString();
			}
			var path = options.path ? '; path=' + (options.path) : '';
			var domain = options.domain ? '; domain=' + (options.domain) : '';
			var secure = options.secure ? '; secure' : '';
			document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
		} else {
			var cookieValue = null;
			if (document.cookie && document.cookie != '') {
				var cookies = document.cookie.split(';');
				for (var i = 0; i < cookies.length; i++) {
					var cookie = cookies[i];
					
					if(cookie[0] == " ") {
						cookie = cookie.substring(1);
					}
					
					if (cookie.substring(0, name.length + 1) == (name + '=')) {
						cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
						break;
					}
				}
			}
			return cookieValue;
		}
	};
	
	var loadScript = function(url, callback) {
		var f = arguments.callee;
		if (!("queue" in f))
			f.queue = {};
		var queue =  f.queue;
		if (url in queue) { // script is already in the document
			if (callback) {
				if (queue[url]) // still loading
					queue[url].push(callback);
				else // loaded
					callback();
			}
			return;
		}
		queue[url] = callback ? [callback] : [];
		var script = document.createElement("script");
		script.type = "text/javascript";
		script.onload = script.onreadystatechange = function() {
			if (script.readyState && script.readyState != "loaded" && script.readyState != "complete")
				return;
			script.onreadystatechange = script.onload = null;
			while (queue[url].length)
				queue[url].shift()();
			queue[url] = null;
		};
		script.src = url;
		document.getElementsByTagName("head")[0].appendChild(script);
	}
	
	var addEvent = function(el, ev, f) {
		if (el.addEventListener)
			return el.addEventListener(ev, f, true);
		if (el.attachEvent)
			return el.attachEvent("on"+ev, f);
	}
	
    function log(message) {
        if (GWR.Log) GWR.Log(message);
    }

    // Disables the initial tracking call
    GWR.disableInit = GWR.disableInit || false;
	
    // Default vocab and phrase collections in case dynamic script fails
    var defaultEventName = 'default';
    
	// Cookie handling for session based throttling
	var cookieOptions = {
		path: '/',
		domain: '.greatwolf.com',
		expires: 45,
		name: 'webtrack',
		enabled: '1',
		disabled: '0'
	}
	
	/**
	 * Gets the values of the trackers to determine if they are enabled or disabled
	 */
	var getTrackerValues = function() {
		var trackerValues = {};
		
		var cookieValue = ns.cookie(cookieOptions.name);
		
		log('WebTrack: Get cookie: ' + cookieValue);
		
		if(cookieValue && cookieValue != '') {
			var pairs = cookieValue.split(',');
			for(var i = 0; i < pairs.length; i++) {
				var pair = pairs[i];
				var keyValue = pair.split(':');
				if(keyValue && keyValue.length == 2) {
					var key = keyValue[0];
					var value = keyValue[1];
					trackerValues[key] = value;
				}
			}
		}
		
		return trackerValues;
	}
	
	var setTrackerValues = function(trackerValues) {
		var cookieValueList = [];
		
		for(var i in trackerValues) {
			var trackerValue = trackerValues[i];
			if(trackerValue != null) {
				cookieValueList.push(i + ':' + trackerValue);
			}
		}
		
		if(cookieValueList.length > 0) {
			var cookieValue = cookieValueList.join(',');
			ns.cookie(cookieOptions.Name, cookieValue, cookieOptions);
			log('WebTrack: set cookie: ' + cookieValue);
		}
	}
	
	/**
	 * Checks if a tracker is enabled or disabled based on a throttle percent
	 * omniture:0,google:1
	 */
	ns.TrackerEnabled = function(tracker, percent) {
		// get previous tracker values
		var trackerValues = getTrackerValues() || {};
		var trackerValue = trackerValues[tracker];
		
		// if no tracker value was set, determine a value based on percent
		if(trackerValue == null) {
			var percentage = parseInt(percent);
			
			// generate a number 1 - 100
			var randomnumber = Math.ceil(Math.random() * 100);
			
			// check random number against throttle percentage
			trackerValue = (randomnumber <= percentage) ? cookieOptions.enabled : cookieOptions.disabled;
			
			// set the new value in the container
			trackerValues[tracker] = trackerValue;
			
			// Save the tracker values in a cookie
			setTrackerValues(trackerValues);
		}
		
		return trackerValue == cookieOptions.enabled;
	}
	
	/** 
    * Evals script and logs script errors to avoid user alerts
    */
    ns.Eval = function(evalScript) {
        try {
            eval(evalScript);
			return true;
        }
        catch (ex) { }
		return false;
    }
	
	/**
	 * An array to keep track of track events
	 */
	ns.TrackQueue = [];
	
	ns.DefaultTrack = function() {
		if(ns.TrackQueue.length > 0) {
			for(var i = 0; i < ns.TrackQueue.length; i++) {
				GWR.Track.apply(this, ns.TrackQueue[i]);
			}
			ns.TrackQueue = [];
			return;
		}
		
		if(!GWR.disableInit) {
			GWR.Track();
		}
	}
	
    /**
    * Executes tracking for the default page or a specific event
    * This will be called on initial page load with null params
    * eventName - (optional) a string that specifies the event being tracked (default: "default")
    * params - {optional} an associative array that defines vocab name-value pairs for this track event
    */
    GWR.Track = function(eventName, params) {
		// Prevent double initialization
        GWR.disableInit = true;
	
		// Check if trackers have finished loading.
		// If not, queue the track event to execute after they have loaded.
		if(!trackersLoaded()) {
			log('WebTrack: Queueing Event: ' + eventName);
			ns.TrackQueue.push([eventName, params]);
			return;
		}
	
        // check if the default event is being called
        // modify the event name so the proper vocab array is used
        if (!eventName || eventName == '') {
            eventName = defaultEventName;
        }

        log('WebTrack: Track Event: ' + eventName);

        var eventsToRun = [defaultEventName];
        if (defaultEventName != eventName) {
            eventsToRun.push(eventName);
        }

        // run all phrases for default events, 
        // then run phrases for this specific event
        for (var i = 0; i < eventsToRun.length; i++) {
            var loopEventName = eventsToRun[i];
            var eventPhrases = ns.phrases[loopEventName];
            if (eventPhrases) {
                for (var j = 0; j < eventPhrases.length; j++) {
                    var code = eventPhrases[j];
                    if (code && code != '') {
                        code = replaceVocabs(code, params, eventName);
                        if (eventName != defaultEventName) {
                            code = replaceVocabs(code, params, defaultEventName);
                        }

						// execute code
                        if (!has_match(code) && ns.Eval(code)) {
							log('WebTrack: phrase(' + loopEventName + '): ' + code);
                        }
                    }
                }
            }
        }

        // run all code
        for (var name in ns.Trackers) {
			var tracker = ns.Trackers[name];
            var code = tracker.RunCode;
            if (code && code != '') {
                code = replaceVocabs(code, params, eventName);
                if (eventName != defaultEventName) {
                    code = replaceVocabs(code, params, defaultEventName);
                }

                if (!has_match(code) && ns.Eval(code)) {
					log("WebTrack: track: " + code);
                }
            }
        }
    }

    // Static regular expression used to detect vocab that have not been replaced
    var regex_phrase = /{\w+}/;

    /**
    * Returns true if all vocabs have been replaced in a phrase
    */
    var has_match = function(code) {
        return regex_phrase.test(code);
    }

    /** 
    * Attempts to replace all vocab tokens in a phrase string
    */
    var replaceVocabs = function(code, params, eventName) {
        // Replace vocab from arguments
        for (var vocab_name in params) {
            if (params[vocab_name]) {
                code = code.replace("{" + vocab_name + "}", params[vocab_name]);
            }
        }

        // get vocab associated with this event
        var eventVocab = ns.vocab[eventName];
        if (eventVocab) {
            for (var vocab_name in eventVocab) {
                if (eventVocab[vocab_name]) {
                    code = code.replace("{" + vocab_name + "}", eventVocab[vocab_name]);
                }
            }
        }

        return code;
    }
	
	var trackersLoaded = function() {
		return ns.NumTrackersLoaded > 0 && ns.NumTrackersLoaded >= ns.NumTrackers;
	}
	

	/**
	 * Import external scripts
	 */
	addEvent(window, 'load', function() {
		if(GWR.TrackData) {
			ns.Trackers = {};
			ns.NumTrackers = 0;
			ns.NumTrackersLoaded = 0;
			ns.vocab = GWR.TrackData.Vocab;
			ns.phrases = GWR.TrackData.Phrases;
			
			// Analyze trackers
			for(var name in GWR.TrackData.Trackers) {
				var tracker = GWR.TrackData.Trackers[name];
				var percent = tracker.Throttle;
				
				// check if throttling is enabled and if the throttling value has been previously determined
				if(percent && percent != "0") {
					// Check if throttleing is enabled
					if(percent == "100" || ns.TrackerEnabled(name, percent)) {
						++ns.NumTrackers;
						ns.Trackers[name] = tracker;
					}
				}
			}
			
			// Check for SSL
			var isSSL = window.location.href.indexOf('https') > -1;
			
			// Add tracker scripts
			for(var name in ns.Trackers) {
				var tracker = ns.Trackers[name];
				var url = isSSL ? tracker.ScriptUrlHttps : tracker.ScriptUrl;				
				log('WebTrack: Loading script: ' + url);
				loadScript(url, function() {
					tracker.IsLoaded = true;
					++ns.NumTrackersLoaded;
					if(trackersLoaded()) {
						ns.DefaultTrack();
					}
				});
			}
		}
	});
	
    /**
     * Decremented functions
     */
    GWR.AddScript = GWR.TrackDefault = function() {};
})();
