(function ($) {
    $.analytics = function (settings, callback) {
        var pageView = {};
        var pageViewContext = {};
    	
        if(typeof(t) === "undefined"){
    		$.log("tracking: nothing to track.");
    		return;
    	}
        
        var defaultSettings = {
                siteCatalistPath: "/assets/js/tracking/s_code_gdyr.js",
                clickSelector: "a[rel^=t-], input[rel^=t-]",
                changeSelector: "select[rel^=t-]",
                extraEvent: "mouseenter",
                extraSelector: "",
                dartUrl: window.location.protocol + "//fls.doubleclick.net/activityi",
                domain: "GYTIRES"
            };
        var s = $.extend(defaultSettings, settings);

    	$.analytics.track = function(trackingValues, sender, callbacks){
            var relElements = trackingValues.split("|");
            var trackingCode = relElements[0];

            $.log("tracking:tracking code:", trackingCode);
            $.log("tracking:raw tracking values:", trackingValues);
            $.log("tracking:raw tracking definition:", t[trackingCode]);
            
            var definition = $.extend({}, t[trackingCode]);
            var pageDefinition = $.extend({}, pageView);

    		if(typeof(definition) !== "undefined"){
    			if(typeof(definition.cta) !== "undefined" && definition.cta !== "") {
    				delete pageDefinition.cta;
    			} else if(typeof(definition.od) !== "undefined" && definition.od !== "") {
    				delete pageDefinition.cta;
    				delete pageDefinition.od;
    			} else if(typeof(definition.sel) !== "undefined" && definition.sel !== "") {
    				delete pageDefinition.cta;
    				delete pageDefinition.od;
    				delete pageDefinition.sel;
    			} else if(typeof(definition.a) !== "undefined" && definition.a !== "") {
    				delete pageDefinition.cta;
    				delete pageDefinition.od;
    				delete pageDefinition.sel;
    				delete pageDefinition.a;
    			} else if(typeof(definition.sub) !== "undefined" && definition.sub !== "") {
    				delete pageDefinition.cta;
    				delete pageDefinition.od;
    				delete pageDefinition.sel;
    				delete pageDefinition.a;
    				delete pageDefinition.sub;
    			} else {
    				delete pageDefinition.cta;
    				delete pageDefinition.od;
    				delete pageDefinition.sel;
    				delete pageDefinition.a;
    				delete pageDefinition.sub;
    				delete pageDefinition.ss;
    			}
    			delete pageDefinition.source;
    			delete pageDefinition.type;
    			delete pageDefinition.cat;
    			delete pageDefinition.session;
    			delete pageDefinition.engagement;
    			delete pageDefinition.varyby;
    			delete pageDefinition.omniture;
    			delete pageDefinition.skip;
    		}
    		definition = $.extend({}, pageDefinition, definition);

    		var contextValues = {};
            if(relElements.length > 1) {
            	if(typeof(relElements[1]) === "string" && relElements[1] !== ""){
            		contextValues = JSON.parse(relElements[1].replace(/'/g,"\""));
            	}
            }
            
            contextValues = $.extend({}, pageViewContext, contextValues);
            $.log("tracking:adding context values", contextValues, "from", sender, "to", trackingCode);
            
            var hasVaryByParameters = typeof(definition.varyby) !== "undefined";
			for(property in contextValues){
				if(contextValues[property].indexOf("$") === 0 && contextValues[property].indexOf(".") > 0) {
					contextValues[property] = eval(String.format("$(\"#{0}\").{1}()",
							contextValues[property].split(".")[0].substring(1),
							contextValues[property].split(".")[1]
					));
				}
				
				for(definitionProperty in definition){
					if(definitionProperty !== "src" && definitionProperty !== "type" && definitionProperty !== "cat"){
						if(definition[definitionProperty] === property){
							$.log("tracking:found match for", definitionProperty, "with value", contextValues[property]);
							if(contextValues[property].indexOf("$") === 0) {
								definition[definitionProperty] = eval(String.format(
										"sender.{0}();", 
										contextValues[property].substring(1)
								));
							} else {
								if(contextValues[property].indexOf(".") > 0){
									var selectorElements = contextValues[property].split(".");
									if(selectorElements.length === 2) {
										definition[definitionProperty] = eval(String.format(
												"$('#{0}').{1}();", 
												selectorElements[0],
												selectorElements[1]
										));
									}
								} else {
									definition[definitionProperty] = contextValues[property];
								}
							}
						}
					}
				}
				
				if(hasVaryByParameters){
					if(definition.varyby.variable === property){
						for(varybyItem in definition.varyby.items){
							if(definition.varyby.items[varybyItem]["forItem"] === contextValues[property]){
								definition.cat = definition.varyby.items[varybyItem].cat;
								break;
							}
						}
					}
				}
			}

    		definition.domain = s.domain;
    		definition.id = trackingCode;
    		
    		for(service in $.analytics.services){
            	if(typeof(definition.engagement) !== "undefined"){
            		if(definition.engagement instanceof Array){
	            		for(engagement in definition.engagement){
	            			$.analytics.services[service].track($.extend(
            					definition.engagement[engagement],
            					{ id: trackingCode + " engagement" }
            				));
	            		}
            		} else {
            			$.analytics.services[service].track($.extend(
            				definition.engagement,
            				{ id: trackingCode + " engagement" }
            			));
            		}
            	}
    			
    			$.analytics.services[service].track(
        			definition,
        			$.extend({}, pageViewContext, contextValues),
        			sender,
        			function(){
        				if(arguments.length === 1){
        					for(callback in callbacks){
        						if($.isFunction(callbacks[callback])){
        							callbacks[callback](arguments[0]);
        						}
        					}
        				}
        			}
        		);
            }
        	
        	return contextValues;
        };
        
        //$.log("tracking:", t.size(), "definitions found.");
        $.log("tracking:binding events.");
        $(s.clickSelector).live("click.analytics", function (e) {
        	$.log("tracking:click");
        	var $this = $(this);
            var track = true;
        	
            if($this.attr("type") === "checkbox"){
            	track = $this.is(":checked");
            }

        	if(track) {
        		$.analytics.track($this.attr("rel").split(";")[0], $this);
        	}
        });
        $(s.changeSelector).live("change.analytics", function (e) {
            $.log("tracking:change");
            var $this = $(this);
            $.analytics.track($this.attr("rel"), $this);
        });
        if (s.extraSelector !== "") {
            $.log("tracking:found extra behaviour settings");
            $.log("tracking:binding ", s.extraEvent, " to ", s.extraSelector);
            $(s.extraSelector).live(s.extraEvent, function () {
                var $this = $(this);
                $.log("tracking:", s.extraEvent ,"on", $this);
                $.analytics.track($this.attr("rel").split(";")[0], $this);
            });
        }
        
        var lock = false;
        for(service in $.analytics.services){
        	$.analytics.services[service].init(s, function(){
        		if(!lock){
        			lock = true;
        			var ready = true;
        			for(service in $.analytics.services){
        				ready = ready && $.analytics.services[service].isready;
        			}
        			if(ready){
        				$.log("tracking:services ready.");
                		var $meta = $("meta[name=global]");
                		if($meta.length > 0){
                			var global = $meta.attr("content");
                			$.log("tracking:tracking global:", global);
                			$.analytics.track(global, "");
                		}

                		var pageViewCode = "";
                		var callbacks = [];
                		
                		if($.isFunction(callback)){
                			callbacks.push(callback);
                		}
                		
                		if(typeof(pageViewSettings) !== "undefined"){
                			pageViewCode = pageViewSettings.trackingCode;
                			if(typeof(pageViewSettings.callback) !== "undefined"){
                				callbacks.push(pageViewSettings.callback);
                			}
                		} else {
	                		$meta = $("meta[name=pageView]");
	                		if($meta.length > 0){
	                			var pageViewCode = $meta.attr("content");
	                		}
                		}
                		if(pageViewCode !== ""){
                			$.log("tracking:tracking pageview.");
                			pageViewContext = $.analytics.track(pageViewCode, {}, callbacks);
                			pageView = t[pageViewCode.split("|")[0]];
                		}
        			}
        		}
        		lock = false;
        	});
        }
    };
    $.analytics.services = {};
})(jQuery);
