/**
 * Manage the dom of a list of trips given a datasource
 * 
 * @author Angelo Selvini <angelo@exmachina.ch>
 * @requires ch.exmachina.bravofly.utils
 */
if (!com)
	var com = {};
if (!com.bravofly)
	com.bravofly = {};
if (!com.bravofly.app)
	com.bravofly.app = {};


if(!ch){
	var ch = {};
}
if(!ch.exmachina){
	ch.exmachina = {};
}
if(!ch.exmachina.bravofly){
	ch.exmachina.bravofly = {};
}
if(!ch.exmachina.bravofly.controller){
	ch.exmachina.bravofly.controller = {};
}

ch.exmachina.bravofly.controller.Widgets = function(/* object */ctorArgs){
	if(!ctorArgs) ctorArgs = {};

	this.target  = ctorArgs.target || null;
	this.list    = [];
	this.refValidators      = [];
	this.refValidatorGroups = [];
};


ch.exmachina.bravofly.controller.Widgets.prototype = {
	type: "ch.exmachina.bravofly.controller.Widgets",
	// Default variables

	_isInit: false,

	_instance: null,
	listDOM  : null,
	listWGT  : null,

	wValidators : null,
	
	init: function(){
		this.listDOM = $$("*[bf:type]");
		this.listWGT = [];

		this.create();
		this.draw();

		this._isInit = true;
	},

	setParams: function(/* object */ p){
		Object.extend(this.params, p);
	},
	setOptions: function(/* object */ o){
		Object.extend(this.options, o);
	},
	// Prepare dom
	create: function(){
		var i, w, t, b, l,
			dl = this.listDOM,
			dw = this.listWGT
		;

		l = this._parseWidgets(dl);

		for (i=0;i<l.widgets.length;i++){
			w = l.widgets[i];
			if (w) {
				w.create();
				dw.push(w);
			}
		}

		this.populateValidatorGroup(l.validators, l.validatorGroups);
	},

	_parseWidgets: function(/* array */ dl){
		var i, w, t, b,
			lo = ch.exmachina.bravofly.utils.parseLocation(window.location),
			l       = [],
			vldGrps = [],
			vlds    = []
		;

		for (i=0;i<dl.length;i++){
			t = dl[i].getAttribute("bf:type");
			b = {target:dl[i]};

			// Try because not all classes could be loaded
			try {
				switch (t){

					case "Gatherer":
						w = new ch.exmachina.bravofly.ui.Gatherer(b);
						break;

					case "ValidatorGroup":
						w = new ch.exmachina.bravofly.manager.ValidatorGroup(b);
						vldGrps.push(w);
						break;

					case "Validator":
						w = new ch.exmachina.bravofly.ui.Validator(b);
						vlds.push(w);
						break;

					case "SelectExternal":
						w = new ch.exmachina.bravofly.ui.SelectExternal(b);
						break;

					case "Injector":
						w = new ch.exmachina.bravofly.ui.Injector(b);

						var p = this._parseParams(
							{ prefix: w.getName()
							, params:lo
							, avail: ["expanded","hideError"]
							}
						);

						if (p)
							w.setOptions(p);

						break;

					default:
						w = null;
						break;
				}
				l.push(w);
			} catch(err) {
				if (lo["debug"] == 1)
					alert("Error: "+err.message);
			}
		}
		return { widgets: l, validators: vlds, validatorGroups: vldGrps};
	},

	_findWidgetByDom: function(/* dom */ d,/* array */a){
		var i, w;
		for (i=0;i<a.length;i++){
			if (a[i] && a[i].getNode && a[i].getNode() == d) {
				w = a[i];
			}
		}
		return w;
	},

	getWidgetByName: function(/* string */ n){
		var w  = null,
			dw = this.listWGT
		;

		for (i=0;i<dw.length;i++){
			if ( dw[i] && dw[i].name && dw[i].name == n ){
				w = dw[i];
				break;
			}
		}
		
		return w;
	},

	handlerJSONP: function(/* object */ o){
		var w = this.getWidgetByName(o.name);

		if (w && w[ o.wgtMethod ])
			w[ o.wgtMethod ]( o.data );
	},

	populateValidatorGroup: function(vs, vgs, opts){
		// summary:
		/*
			add to validator group (VG) beneath validators objects
			+ get dom from VG
			+ select children bf:validators 
			+ compare bf:validator dom with the one from objecsts
			+ add list to current VG
		*/

		var i,d, w, k,
			o = opts
		;

		for (i=0;i<vs.length;i++){
			this.refValidators.push(vs[i]);
		}

		// iterate over validator groups
		for (i=0;i<vgs.length;i++){	

			this.refValidatorGroups.push(vgs[i]);

			d  = vgs[i].getNode();
			l = $(d).select("*[bf:type='Validator']");

			w = null;

			// Compare current node among validators
			for (k=0;k<l.length;k++){
				w = this._findWidgetByDom(l[k], vs);
				if (w){
					vgs[i].addValidator(w);
					if (o&&o.fields){
						vgs[i].setParams({fields:o.fields});
					}
					vgs[i].update();
				}
			}
		}
	},

	_parseParams: function(/* object */o){
		if (!o.prefix || !o.avail || !(o.avail instanceof Array) )
			return null;

		var p  = {}
			re = new RegExp("^"+o.prefix,"i");
		;

		// read params
		for (n in o.params){
			if (re.test(n)){
				// parameters are case insensitive
				// options are sensitive insted
				var oname = n.replace(re, "").toLowerCase();

				// verify params is among avaiables for the widget
				for (var i=0;i<o.avail.length;i++){
					if (o.avail[i].toLowerCase() == oname){
						p[ o.avail[i] ] = o.params[n];
						break;
					}
				}
				
			}
		}

		return p;
	},
	
	// Attach entries
	draw: function(){
		var i,
			dw = this.listWGT
		;
		for (i=0;i<dw.length;i++){
			dw[i].draw();
			dw[i].setListening(true);
		}
	},

	// Update data
	update: function( d,opts ){

		var i, w, t, b, l,
			dl = $(d).select("*[bf:type]"),
			dw = this.listWGT
		;

		l = this._parseWidgets(dl);

		for (i=0;i<l.widgets.length;i++){
			w = l.widgets[i];
			if (w){
				w.create();
				w.draw();
				w.setListening(true);

				dw.push(w);
			}
		}

		this.populateValidatorGroup(l.validators, l.validatorGroups, opts);
	},

	// Clean view
	clean: function(){
	},

	getType: function(){
		return this.type;
	},

	// Remove everything
	destroy: function(){
		this.clean();
	},

	//getDict: function(){return com.bravofly.dictionary;},
	hasParentNode: ch.exmachina.bravofly.utils.hasParentNode,
	delegate: ch.exmachina.bravofly.utils.delegate
};

ch.exmachina.bravofly.controller.Widgets.parseSelf = function(){
	var i,
		r = /.+?Widgets.js$/,
		s = document.getElementsByTagName("script")
	;
	for (i=0;i<s.length;i++){
		if (r.test(s[i].src)){

			var p;
			try {
				p = eval(s[i].getAttribute("params"));
			} catch (err) {
				throw new Error("Widgets broken: "+ err);
			}

			if (p == null || (typeof(p)=="object" && !p.autoLoad===false)){
				if (!com.bravofly.app.Widgets) {
					com.bravofly.app.Widgets = new ch.exmachina.bravofly.controller.Widgets();
					Event.observe(window, 'load', com.bravofly.app.Widgets.init.bindAsEventListener(com.bravofly.app.Widgets));
				}
			}

			break;
		}
	}
}

ch.exmachina.bravofly.controller.Widgets.parseSelf();
