function wafEval(str, obj) {
	var fn;
	if (typeof str == "string") {
		fn = eval(str);
		if (typeof fn == "function")
			fn.apply(obj);
	}
};


( function($) {
	$.widget("ui.wafMultiSelect", {
		_init : function() {
			var self = this;
			self.options = $.extend( {
				ajaxOptions : {},
				values : [],
				labels : {},
				blankValue : true,
				param : "data",
				params: {}
			}, self.options);
			
			if (self.options.values == null) {
				self.options.values = [];
			}
			if (self.options.params == null) {
				self.options.params = {};
			}
			/*if (typeof self.options.before == "string") {
				self.options.before = eval(self.options.before);
			}
			
			if (typeof self.options.after == "string") {
				self.options.after = eval(self.options.after);
			}*/
			
			var $select = this.element;

			if(self.options.blankValue) {
				$select.addOption("", "");
			}
			if (self.options.labels[self.options.values[0]] != undefined) {
				$select.addOption(self.options.values[0],
						self.options.labels[self.options.values[0]]);
				$select.one("click", function(event) {
					//if (typeof self.options.before == "function")
					//	self.options.before.apply(this);
					wafEval(self.options.before, this);
					self.options.params[self.options.param] = self.options.root;
                    self.options.params["_"] = (new Date()).getTime();
					$select.ajaxAddOption(self.options.url, self.options.params, false, function(val) {
						if ($(this).val() == "")
						{
							$(this).change();
						}
						//if (typeof self.options.after == "function")
						//	self.options.after.apply(this);
						wafEval(self.options.after, this);
					}, [ $select.val() ]);
				});
			} else {
				//if (typeof self.options.before == "function")
				//	self.options.before.apply($select.get(0));
				wafEval(self.options.before, $select.get(0));
				if (self.options.root != null)
				{
					self.options.params[self.options.param] = self.options.root;
                    self.options.params["_"] = (new Date()).getTime();
                    self.options.params["_depth"] = 1;
					$select.ajaxAddOption(self.options.url, self.options.params, false, function() {
						if (self.options.values != undefined && self.options.values != null
								&& self.options.values[0] != undefined) {
							$select.selectOptions(self.options.values[0], true);
						}
						//if (typeof self.options.after == "function")
						//	self.options.after.apply(this);
						wafEval(self.options.after, this);
					})
				};
			}

			var name = $select.attr("name");
			$select.attr("name", name + "[0]");

			self.selects = [];
			self.selects[0] = $select;
			if (self.options.values != undefined && self.options.values != null) {
				for(var i=0; i<self.options.values.length; i++){
				//for (i in self.options.values) {
					//if (i == 0|| i == 'remove' || i =='indexOf') {
					if (i == 0) {
						continue;
					}
					var $newSelect = $("<select />").attr("name",
							name + "[" + i + "]");	
					self.selects[i - 1].after("<br />").next().after($newSelect);
					self.selects[i] = $newSelect;
					if(self.options.blankValue) {
						$newSelect.addOption("", "");
					}
					if (self.options.labels[self.options.values[i]] != undefined) {
						$newSelect.addOption(self.options.values[i],
								self.options.labels[self.options.values[i]]);
						$newSelect.one("click", i, function(event) {
							//if (typeof self.options.before == "function")
							//	self.options.before.apply(this);
							wafEval(self.options.before, this);
							self.options.params[self.options.param] = self.options.values[event.data - 1];
                            self.options.params["_"] = (new Date()).getTime();
                            self.options.params["_depth"] = i;
							$(this).ajaxAddOption(self.options.url, self.options.params, false, function(val) {
								if ($(this).val() == "")
								{
									$(this).change();
								}
								//if (typeof self.options.after == "function")
								//	self.options.after.apply(this);
								wafEval(self.options.after, this);
							}, [ $(this).val() ]);
						});
					} else {
						//if (typeof self.options.before == "function")
						//	self.options.before.apply($newSelect.get(0));
						wafEval(self.options.before, $newSelect.get(0));
						self.options.params[self.options.param] = self.options.values[i - 1];
                        self.options.params["_"] = (new Date()).getTime();
                        self.options.params["_depth"] = i;
						$newSelect.ajaxAddOption(self.options.url, self.options.params, false, function(k) {
							$(this).selectOptions(self.options.values[k], true);
							//if (typeof self.options.after == "function")
							//	self.options.after.apply(this);
							wafEval(self.options.after, this);
						}, [ i ]);
					}
				}
			}
			var onchange = function(event) {
				for ( var j = self.selects.length - 1; j > event.data; j--) {
					self.selects[j].prev().remove().end().remove();
					self.selects.pop();
				}
				
				if ($(this).val() != "") {
					$newSelect = $("<select />").attr("name",
							name + "[" + (parseInt(event.data, 10) + 1) + "]");
					self.selects.push($newSelect);
					$(this).after("<br />").next().after($newSelect);
					//if (typeof self.options.before == "function")
					//	self.options.before.apply($newSelect.get(0));
					wafEval(self.options.before, $newSelect.get(0));
					self.options.params[self.options.param] = $(this).val();
                    self.options.params["_"] = (new Date()).getTime();
                    if(self.options.blankValue) {
						$newSelect.addOption("", "")
                    }
                    self.options.params["_depth"] = self.selects.length;
                    $newSelect.ajaxAddOption(
								self.options.url,
								self.options.params,
								false,
								function(el, k) {
									if ($(this).find("option").size() == 1)
									{
										$(this).next("br").andSelf().remove();
										self.selects.pop();
										//self.options.after.apply(this);
										wafEval(self.options.after, this);
										return false;
									}
									$(this).bind("change",
											parseInt(event.data, 10) + 1, onchange);
									//if (typeof self.options.after == "function")
									//	self.options.after.apply(this);
									wafEval(self.options.after, this);
								}, [ event.data ]);
                    
				}
			};
			for(var i=0; i<self.selects.length; i++){
			//for (i in self.selects) {
				//if( i != 'remove' && i != 'indexOf') {
					self.selects[i].bind("change", i, onchange);
				//}
			}
		},
		_setData: function(key, value) {
			if (key == 'root') {
				var self = this;
				self.options.root = value;
				self.selects[0].removeOption(/.*/);
				if(self.options.blankValue) {
					self.selects[0].addOption("", "");
				}
				//if (typeof self.options.before == "function")
				//	self.options.before.apply(self.selects[0].get(0));
				wafEval(self.options.before, self.selects[0].get(0));
				self.options.params["_"] = (new Date()).getTime();
				self.selects[0].ajaxAddOption(self.options.url, {
					data :self.options.root
				}, false, function() {
					self.selects[0].change();
					//if (typeof self.options.after == "function")
					//	self.options.after.apply(this);
					wafEval(self.options.after, this);
				});
			}
			else {
				this.options[key] = value;
			}
		},
		_getData: function(key) {
			if (key == "values") {
				var values = new Array();
				for(var i=0; i<this.selects.length; i++){
				//for (i in this.selects) {
					//if(i != 'remove' && i != 'indexOf') {
						values[i] = this.selects[i].val();
					//}
				}
				return values;
			} else {
				return this.options[key];
			}
		}
	});
})(jQuery);
