/**
 * FOX Tree
 *
 * @package FOX
 * @subpackage JavaScript Library
 */

if (typeof Fox == 'undefined') {
	Fox = {};
}

Fox.Control = Class.create({
	controlInitialize: function(options) {
		this.options = options;
		if (options.handlers) {
			this.handlers = options.handlers;
			delete options.pager;
		} else {
			this.handlers = {};
		}
		
		if (options.pager) {
			this.pager = options.pager;
			delete options.pager;
		}

		//states
		this.lazyloaded = false;
		this.loaded = false;

		this.options = {
			filter: $H({}),
			active: 1,
			canRedraw: 1
		};
		
		for (param in options) {
			if (options.hasOwnProperty(param)) {
				this.options[param] = options[param];
			}
		}
		
		this.options.filter = $H({});
		this.options.active = 1;
		
		this._templateOld = new Template('', /(^|.|\r|\n)(\$\{(.*?)\})/);
		this._template = new Template('', /(^|.|\r|\n)(\$\[(.*?)\])/);
		return this;
	},
	
	setOption: function(name, value) {
		this.options[name] = value;
		return this;
	},

	getOption: function(name) {
		return this.options[name];
	},
	
	dispatchEvent: function(event, params) {
		var result;
		//console.log('dipatched event', event, this.handlers)//, this.handlers[event]);
		try {
			if (this.handlers[event]) {
				//console.log('Event handler found', event, eval(this.handlers[event]));
				if (Object.isString(this.handlers[event])) {
					this.handlers[event] = eval(this.handlers[event]);
				}
				$A(this.handlers[event]).each(function(handler) {
					//console.log('Event handled', event);
					result = handler(this, params) && result;
				}.bind(this));
			}
			return result;
		} catch (e) {
			//console.log('Event Error', event);
			return result;
		}
	},
	
	setFilter: function(param, value, comparison) {
		if (typeof this.options.filter == 'undefined') {
			this.options.filter = $H({});
		}
		if (typeof comparison == 'undefined') {
			comparison = '';
		}
		if (value === '') {
			this.options.filter.unset(param + comparison);
		} else {
			this.options.filter.set(param + comparison, value);
		}
		return this;
	},

	deleteFilter: function(param, comparison, skipNavigator) {
		if (comparison == undefined) {
			comparison = '';
		}
		this.options.filter.unset(param + comparison);

		if (!skipNavigator) {
			if (typeof this.navigator != 'undefined') {
				Fox.Navigator.unset(this.navigator.get('filterPrefix') + '_' + param + comparison);
			}
		}
		return this;
	},
	
	clearFilter: function() {
		this.options.filter = $H({});
		if (typeof this.navigator != 'undefined') {
			Fox.Navigator.queryParams = $H({});
			Fox.Navigator.set({});
		}
		return this;
	},

	getFilter: function(param, comparison) {
		if (comparison == undefined) {
			comparison = '';
		}
		if (typeof this.options.filter.get(param) == 'object') {
			return this.options.filter.get(param + comparison)[2];
		}
		return this.options.filter.get(param + comparison);
	},
	
	_applyPatterns: function(root, data, paths, scope) {
		if (typeof root == 'string') {
			this._templateOld.template = root;
			this._template.template =  this._templateOld.evaluate(data);
			return this._template.evaluate(data);
		}
		$A(paths).each(function(place) {
			root.adjacent(place.path).each(function(node) {
				if (!node) {
					return;
				}
				if (!Object.isArray(place.prop)) {
					place.prop = [place.prop];
				}
				place.prop.each(function(prop) {
					if (prop == undefined || prop == 'innerHTML') {
						if (data._all_) {
							node.update(data._all_);
						} else {
							this._template.template = node.innerHTML;
							node.update(this._template.evaluate(data));
						}
					} else {
						if (this._template.template = unescape(node.getAttribute(prop))) {
							node.setAttribute(prop, this._template.evaluate(data));
						}
					}
				}.bind(scope || this));
			}.bind(scope || this));
		}.bind(scope || this));
		return this;
	},
	
	escapeHtml: function(data) {
		if (typeof data == 'string') {
			return data.escapeHTML();
		}
		
		if (typeof data != 'object') {
			return data;
		}
		
		// if (Object.isArray(data)) {
		// 	var clone = data.clone();
		// } else {
		// 	var clone = Object.clone(data);
		// }
		var clone = data;

		for (var prop in clone) {
			if (!clone.hasOwnProperty(prop)) {
				continue;
			}
			
			if (typeof clone[prop] == 'string') {
				clone[prop] = clone[prop].escapeHTML();
			} else if (typeof clone[prop] == 'object' && clone[prop] != null) {
				clone[prop] = this.escapeHtml(clone[prop]);
			}
		}
		
		return clone;
	},
	
	initNavigator: function(params) {
		if (typeof Fox.Navigator == 'undefined') {
			throw 'Include Fox.Navigator please';
		}
		this.navigator = this.defaultNavigatorParams.merge($H(params));
		var values = [];
		this.navigator.each(function(item) {
			if (item[0] == 'selector') {
				values.push(item[1]);
			} else {
				values.push([item[0], item[1]]);
			}
			
		});
		Fox.Navigator.handle(this.navigate.bind(this), values);
		return this;
	},
	
	setContainer: function(container) {
		this.options.container = $(container);

		if (!this.options.container) {
			throw 'Wrong container "' + container + '" for ' + this.options.name;
		}
		
		this.options.containerCloneX = this.options.container.cloneNode(true);
		
		if (this.options.container.down() && this.options.container.down().tagName == 'TBODY') {
			this.options.container = this.options.container.down();
			this.options.containerClone = this.options.containerCloneX.down();
		} else {
			this.options.containerClone = this.options.containerCloneX;
		}
		return this;
	}
});

