var SegmentationCounter = (function(){

	var teasersLoaded = 0, // number of teasers currently loaded
		teasersOnPage = null, // number of teasers on page (counted when onReady is called - assumes DOM is fully loaded)
		teasersReadyCallback = function(){}, // dummy empty callback (to be overridden with onReady)

		checkTeasersReady =  function() {
			if (teasersOnPage === null) {
				return false;
			} else {
				return teasersOnPage === teasersLoaded;
			}
		},
		
		checkTeasersReady = function() {
			return teasersOnPage === null ? false : teasersOnPage === teasersLoaded;
		},
		
		getElementsByClassName = function(parent, tagName, className) {
			// bulky code because of IE limitations
			var i = 0;
			var divs = parent.getElementsByTagName(tagName);
			var el;

			var result = [];

			while (el = divs[i++]) {
				if (el.className.indexOf(className) != -1) {
					result.push(el);
				}
			}

			return result;
		},
		
		api = {
			onTeaserLoaded: function(event) {
				teasersLoaded++;
				if (checkTeasersReady()) {
					teasersReadyCallback.call(null);
				}
			},
	
			onReady: function(callback) {
				teasersReadyCallback = callback;
				teasersOnPage = getElementsByClassName(document, 'div', 'campaign').length;
				if (checkTeasersReady()) {
					teasersReadyCallback.call(null);
				}
			}
	};
	
	return api;
})();

(function() {

	var PHP_USER_INFO = '/apps/user_info/index.html';
	var SCRIPT_REGEX = /<script[\s\S]*?>([\s\S]*?)<\/script>/gi;

	function getDataUrl() {
		var params = { cq_ck: (new Date()).valueOf() };
		return PHP_USER_INFO + "?" + CQ_Analytics.Utils.urlEncode(params);
	};

	function evaluate(response) {
		try {
			return eval('(' + response.responseText + ')');
		} catch (error) {
			if (console !== undefined) {
				console.warn('Cannot evaluate JSON: %s', error);
			}
			return {};
		}
	};

	function merge(obj1, obj2) {
		for (var p in obj2) {
			try {
				if (obj2[p].constructor == Object) {
					obj1[p] = merge(obj1[p], obj2[p]);
				} else {
					obj1[p] = obj2[p];
				}
			} catch(e) {
				obj1[p] = obj2[p];
			}
		}
		return obj1;
	};

	var session = new SessionPersistence();
	function isCookieStoreAvailable() {
		return session.get(ProfileDataManager.prototype.STOREKEY) != "" && session.get(SurferInfoManager.prototype.STOREKEY) != "";  
	};

	var setCookie = CQ_Analytics.Cookie.set;
	CQ_Analytics.Cookie.set = function(name, value, days) {
		setCookie.call(this, name, value); // makes the cookie session only, by not passing the date
	};

	// -------------------- overriding part responsible for getting user data  -----------------------

	ClickstreamcloudManager.prototype.loadConfig = function() {
		this.config = getPublishCloudstreamConfig();

		if (isCookieStoreAvailable()) {
			this.config.data = {};
			var thisScope = this;
			window.setTimeout(function() {
				initializeClickstreamCloudManager(thisScope);
			}, 1);
		} else {
			CQ_Analytics.Utils.load(getDataUrl(), function(response) {
				merge(this.config, evaluate(response));
				initializeClickstreamCloudManager(this);
			}, this);			
		}
	};

	function initializeClickstreamCloudManager(ccm) {
		ccm.isConfigLoaded = true;
		ccm.fireEvent('configloaded');
		ccm.fireEvent('storesloaded');
		ccm.areStoresLoaded = true;
		if (ccm.isMode(CQ_Analytics.CCM.POST_MODE_PAGELOAD)) {
			ccm.post();
		}
	};

	function getPublishCloudstreamConfig() {
		return {
			ui: {
				target: 'clickstreamcloud-gui',
				version: 'light'
			},
			configs: {
				surferinfo: {
					ui: {
						title: 'Surfer information',
						mode: 'textfield',
						"jcr:primaryType": 'nt:unstructured'
					},
					store: {
						excludedFromStats: [ 'mouse X', 'mouse Y' ],
						"jcr:primaryType": 'nt:unstructured'
					}
				},
				mouseposition: {
					store: {
						stats: 'false',
						"jcr:primaryType": 'nt:unstructured'
					}
				},
				segments: {
					ui: {
						title: 'Resolved segments',
						mode: 'link',
						"jcr:primaryType": 'nt:unstructured'
					}
				},
				pagedata: {
					ui: {
						title: 'Page data',
						mode: 'textfield',
						"jcr:primaryType": 'nt:unstructured'
					},
					store: {
						excludedFromStats: [ 'random' ],
						invisible: [ 'path' ],
						"jcr:primaryType": 'nt:unstructured'
					}
				},
				tagcloud: {
					ui: {
						title: 'Tag cloud',
						mode: 'textfield',
						"jcr:primaryType": 'nt:unstructured'
					}
				},
				profile: {
					ui: {
						title: 'Profile',
						mode: 'textfield',
						"jcr:primaryType": 'nt:unstructured'
					},
					store: {
						stats: 'false',
						"jcr:primaryType": 'nt:unstructured'
					}
				}
			}
		};
	};

	// -------------------- overriding part responsible for loading teasers -----------------------

	CQ_Analytics.Utils.loadElement = function(url, elemId) {
		CQ_Analytics.Utils.load(url, function(response) {
			var element = document.getElementById(elemId);
			element.innerHTML = response.responseText;

			// run all scripts embedded in fetched element, excluding CQ edit scripts
			var scripts = response.responseText.match(SCRIPT_REGEX);
			if (scripts != null) {
				for ( var i = 0; i < scripts.length; i++ ) {
					try {
						eval(scripts[i].replace(SCRIPT_REGEX, '$1'));
					} catch (error) {
						if (console !== undefined) {
							console.warn('Cannot evaluate script: %s\nError: %s', scripts[i], error);
						}
					}
				}
			}
			
			SegmentationCounter.onTeaserLoaded();
		});
	};
})();

