/** Track namespace declaration */
var Analytics = new Object();

/**
 * Google Analytics track object implementation.
 * Used to to track events and actions.
 * It uses Google's new feature "Events" to track different events
 *
 *   Warning:
 *      Shouldn't be instantiated directly. Use ImmoSolve.GoogleAnalyticsEventTrackObject.getTrackObject(...)
 *      as factory method.
 *
 * Options:
 *    name - event tracker name
 *    parentTracker - parent tracker object
 *    listeners - initially defined listeners
 *
 * Events:
 *    afterInit (source) - Just after full initialization
 *    trackEvent (source, eventName, label, param) - on track event
 *
 */
Analytics.GoogleAnalyticsEventTrackObject = function (options) {

	// -------------------------------------- Public API

	this.trackEvent = function (eventName, label, param) {
		if (!this._initialized) {
			this._init();
			if(!this._initialized) {
				return;
			}
		}

		this._fireEvent("trackEvent", {source: this, eventName: eventName, label: label, param: param});
		this._eventTracker._trackEvent(eventName, label, param);
	};

	this.addEventListener = function (eventName, handler) {
		var el = this._listeners[eventName];
		if (el == undefined) {
			el = new Array();
			this._listeners[eventName] = el;
		}

		el.push(handler);
	};

	// -------------------------------------- Private section

	this._init = function () {
		if (!this._tracker.isInitialized()) {
			return;
		}

		this._eventTracker = this._tracker.getPageTracker()._createEventTracker(this._name);
		this._fireEvent("afterInit", {source: this});
		this._initialized = true;
	};

	this._fireEvent = function (eventName, event) {
		if (this._listeners[eventName] != undefined) {
			for (i = 0; i < this._listeners[eventName].length; i++) {
				this._listeners[eventName][i](event);
			}
		}
	};


	// -------------------------------------- Constructor

	this._options = options;
	this._name = options.name;
	this._tracker = options.parentTracker;

	this._eventTracker;
	this._initialized = false;
	this._listeners = {};

	if (options.listeners != undefined) {
		for (l in options.listeners) {
			this.addEventListener(l, options.listeners[l]);
		}
	}

	this._init();
};

/**
 * Google Analytics track object implementation.
 * Used to to track events and actions.
 * It uses Google's trackPageview to track different events
 *
 *   Warning:
 *      Shouldn't be instantiated directly. Use ImmoSolve.GoogleAnalyticsEventTrackObject.getTrackObject(...)
 *      as factory method.
 *
 * Options:
 *    name - event tracker name
 *    parentTracker - parent tracker object
 *    listeners - initially defined listeners
 *
 * Events:
 *    afterInit (source) - Just after full initialization
 *    trackEvent (source, eventName, label, param) - on track event
 *
 */
Analytics.GoogleAnalyticsTrackPageviewTrackObject = function (options) {

	// -------------------------------------- Public API

	this.trackEvent = function (eventName, label, param) {
		if (!this._tracker.isInitialized()) {
			return;
		}

		this._fireEvent("trackEvent", {source: this, eventName: eventName, label: label, param: param});

		var page = "/Event/" + this._name + "/" + eventName;

		if (label != undefined) {
			page += "/" + label;
		}

		if (param != undefined) {
			page += "/" + param;
		}

		this._tracker.trackPageview(page);

		if (this._tracker._options.pageViewForEvent != undefined && this._tracker._options.pageViewForEvent != "") {
			this._tracker.trackPageview(this._tracker._options.pageViewForEvent);
		}
	};

	this.addEventListener = function (eventName, handler) {
		var el = this._listeners[eventName];
		if (el == undefined) {
			el = new Array();
			this._listeners[eventName] = el;
		}

		el.push(handler);
	};

	// -------------------------------------- Private section

	this._init = function () {
		this._fireEvent("afterInit", {source: this});
	};

	this._fireEvent = function (eventName, event) {
		if (this._listeners[eventName] != undefined) {
			for (i = 0; i < this._listeners[eventName].length; i++) {
				this._listeners[eventName][i](event);
			}
		}
	};


	// -------------------------------------- Constructor

	this._options = options;
	this._name = options.name;
	this._tracker = options.parentTracker;

	this._listeners = {};

	if (options.listeners != undefined) {
		for (l in options.listeners) {
			this.addEventListener(l, options.listeners[l]);
		}
	}

	this._init();
};

/**
 * Google Analytics tracker implementation.
 * Used to to track page statistics.
 *
 * Options:
 *    authCode - implementation specific auth code
 *    trackObjectImplementation - track object implementation (Default: Analytics.GoogleAnalyticsTrackPageviewTrackObject)
 *    listeners - initially defined listeners
 *    pageViewForEvent - additional pageview that would be sent per each event
 *    domainName - domain name to track. By default all domain names are tracked ("none")
 *
 * Events:
 *    afterInit (source) - Just after full initialization
 *    newTrackObject (source, name, trackobject) - After creation of nre track object
 *    trackPageview (source, pageName) - on track page call
 *
 */
Analytics.GoogleAnalyticsTracker = function (options) {

	// -------------------------------------- Constants

	this.MAX_WAIT_ATTEMPTS = 30;
	this.WAIT_ATTEMPT_MS = 500;

	// -------------------------------------- Public API

	/**
	 * Track page view.
	 *
	 * @param name Optional param with page name
	 */
	this.trackPageview = function (name) {
		if(this.isInitialized()) {
			this._fireEvent("trackPageview", {source: this, pageName: name});

			if (name == undefined) {
				this._pageTracker._trackPageview();
			} else {
				this._pageTracker._trackPageview(name);
			}
		}
	};

	this.getTrackObject = function (name, liteners) {
		var to = this._trackObjects[name];
		if (to == undefined) {
			to  = new this._trackObjectImplementation({
				parentTracker: this,
				name: name,
				listeners: liteners
			});

			this._trackObjects[name] = to;
		}

		this._fireEvent("newTrackObject", {source: this, name: name, trackobject: to});

		return to;
	};

	this.addEventListener = function (eventName, handler) {
		var el = this._listeners[eventName];
		if (el == undefined) {
			el = new Array();
			this._listeners[eventName] = el;
		}

		el.push(handler);
	};

	this.isInitialized = function () {
		return this._initialized;
	};

	this.setInitialized = function (val) {
		this._initialized = val;
	};

	this.getPageTracker = function () {
		return this._pageTracker;
	};

	// -------------------------------------- Private section

	this._init = function() {
		var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");

		// This solution is not working in IE :(
		//var script = document.createElement("script");
		//script.type = "text/javascript";
		//script.src = gaJsHost + "google-analytics.com/ga.js";
		//alert(script.src);
		//document.body.appendChild(script);
		//document.write("sss");

		// This works everywhere
		document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));

		var meTracker = this;

		var waitForInit = function () {
			meTracker._waitAttempts ++;

			if (window._gat != undefined && _gat._getTracker != undefined) {
				meTracker._pageTracker = _gat._getTracker(meTracker._authCode);
                if (meTracker._domainName) {
                    meTracker._pageTracker._setDomainName(meTracker._domainName);
                }
				meTracker._pageTracker._initData();
				meTracker.setInitialized(true);

				meTracker._fireEvent("afterInit", {source: meTracker});
			} else if (meTracker._waitAttempts <= meTracker.MAX_WAIT_ATTEMPTS) {
				setTimeout(waitForInit, meTracker.WAIT_ATTEMPT_MS);
			}
		}

		waitForInit();
	};

	this._fireEvent = function(eventName, event) {
		if (this._listeners[eventName] != undefined) {
			for (i = 0; i < this._listeners[eventName].length; i++) {
				this._listeners[eventName][i](event);
			}
		}
	};

	// -------------------------------------- Constructor

	this._options = options;
	this._authCode = this._options.authCode;
	if (this._options.trackObjectImplementation != undefined) {
		this._trackObjectImplementation = this._options.trackObjectImplementation;
	} else {
		this._trackObjectImplementation = Analytics.GoogleAnalyticsTrackPageviewTrackObject;
	}

    this._domainName = "none"
    if (this._options.domainName) {
        this._domainName = this._options.domainName
    }

	this._pageTracker;
	this._initialized = false;
	this._waitAttempts = 0;
	this._trackObjects = {};
	this._listeners = {};

	if (options.listeners != undefined) {
		for (l in options.listeners) {
			this.addEventListener(l, options.listeners[l]);
		}
	}

	this._init();
};
