// define abc package
if (typeof com == "undefined") {
	com = {};
}
if (typeof com.abc == "undefined") {
	com.abc = {};
}

com.abc.DeepLink = {
	variables: {},
	qsParams: {},
	hash: '',
	options: null,
	timer: null,
	hashTimer: null,
	
	setOptions: function(options) {
		this.options = Object.extend({
			pollInterval: 500
		}, options || {});
	},
	
	initialize: function() {
		this.setOptions();
		
		this.parseVariables();
		
		this.startPolling();
		
		this.getQS();
	},
	
	parseVariables: function() {
		var key;
		var value;
		var pairs;
		var valuePairs;
		var hash;
		
		this.variables = {};
		
		if (window.location.hash.length) {
			this.hash = window.location.hash;
			if (this.hash) hash = this.hash.substring(1);
		
			var pairs = hash.split('&');
			
			for (var i=0; i<pairs.length; i++) {
				valuePairs = pairs[i].split('=');
				key = valuePairs[0];
				value = valuePairs[1];
				
				if (this.variables[key]) {
					if (typeof(this.variables[key]) == 'array') {
						this.variables[key].push(value);
					} else {
						tmp = this.variables[key];
						this.variables[key] = [tmp,value];
					}
				} else {
					this.variables[valuePairs[0]] = (valuePairs.length == 1) ? true : valuePairs[1];
				}
			}
		} else {
			this.hash = '';
			this.variables = {};
		}
	},
	
	hashChanged: function() {
		// inform deeplink listeners
		this.parseVariables();
		
		Event.broadcast(this,'hashChanged');
	},
	
	setVariable: function(key,value,addToExisting) {
		if (this.hashTimer) clearTimeout(this.hashTimer);
		this.stopPolling();
		
		if (!key) return;
		
		if (typeof value == 'undefined') value = true;
		
		if (!addToExisting) {
			this.variables[key] = value;
		} else {
			if (typeof this.variables[key] == 'array') {
				this.variables[key].push(value);
			} else if (this.variables[key]) {
				this.variables[key] = [this.variables[key],value];
			} else {
				this.variables[key] = value;
			}
		}
		
		// set a timeout for this so if they happen too fast we can queue them up and clear
		// out the ones that don't matter
		this.hashTimer = setTimeout(this.setHash.bind(this),500);
	},
	
	getVariable: function(key) {
		if (!key) return null;
		
		return this.variables[key];
	},
	
	setHash: function() {
		this.hashTimer = null;
		this.hash = '';
		var count = 0;
		
		for (var i in this.variables) {
			if (this.variables[i] === true) {
				if (count > 0) this.hash += '&';
				this.hash += i;
			} else if (this.variables[i] !== false && this.variables[i] != null) {
				if (count > 0) this.hash += '&';
				this.hash += i + '=';
				this.hash += this.variables[i];
			}
			
			count++;
		}
		
		window.location.hash = this.hash;
		this.startPolling();
	},
	
	poll: function() {
		if (window.location.hash != this.hash) {
			this.hashChanged();
		}
	},
	
	startPolling: function() {
		if (this.timer) this.stopPolling();
		
		this.timer = setInterval(this.poll.bind(this),this.options.pollInterval);
	},
	
	stopPolling: function() {
		clearInterval(this.timer);
	},
	
	getQS: function() {
		this.qsParams = {};
		
		var qs = window.location.search.substring(1);
		var tmp = qs.split('&');

		for (i=0;i<tmp.length;i++) {
			var pair = tmp[i].split('=');
			if (pair.length == 2) this.qsParams[pair[0]] = pair[1];
		}
	},
	
	getHardPath: function(vars) {
		var tmpVars = this.qsParams;
		var qs = '?';
		
		for (i in vars) {
			tmpVars[i] = vars[i];
		}
		
		var count = 0;
		
		for (var i in tmpVars) {
			if (count) qs += '&';
			qs += i + '=' + tmpVars[i];
			count++;
		}
	
		return window.location.pathname + qs;
	}

};

com.abc.DeepLink.initialize();