(function($){
	$.fn.conditionsEditor = function(options) {
		var opts = $.extend({}, $.fn.conditionsEditor.defaults, options);
		return this.each(function(){
			var $this = $(this).addClass("conditionseditor");
			var o = $.meta ? $.extend({}, opts, $this.data()) : opts;
			$this.data("options", o);
			$("<div class='header ui-widget-header'></div>")
				.append($("<div class='fieldname'><div>").css({width:o.widths[0]+"px"}).text(o.label.fieldName))
				.append($("<div class='operator'><div>").css({width:o.widths[1]+"px"}).text(o.label.operator))
				.append($("<div class='mode'><div>").css({width:o.widths[2]+"px", display:(o.enableDisplayMode?"block":"none")}).text(o.label.mode))
				.append($("<div class='values'><div>").css({marginLeft:(o.widths[0]+o.widths[1]+o.widths[2]+16)+"px"}).text(o.label.values))
				.appendTo($this);
			var $conditions = $("<ul></ul>").addClass("conditions").appendTo($this);
			if (!o.readonly) {
				$conditions.sortable({
					placeholder: "ui-state-highlight"
				});
				var $trash = $("<ul></ul>").addClass("trash").css({display:"none"}).appendTo($this);
				$this.append($("<span class='addcondition'><span class='ui-icon ui-icon-newwin'></span>"+o.label.addCondition+"</span>").click(function(){
					addCondition(null);
				}));
				$this.append($("<span class='undoremove'>"+o.label.undoRemove+"</span>").click(function(){
					undoRemove();
				}));
			}
			for (var i=0; i<o.conditions.length; i++) {
				addCondition(o.conditions[i]);
			};
			
			function addCondition(condition) {
				var $condition = $("<li></li>").addClass("ui-state-default")
					.data("id",condition && condition.id ? condition.id : "")
					.data("fieldName",condition && condition.fieldName? condition.fieldName : o.fields[0].name)
					.data("operator",condition && condition.operator && condition.operator.value ? condition.operator.value : o.operators[0].value)
					.data("mode",condition && condition.mode && condition.mode.value ? condition.mode.value : o.modes[0].value)
					.data("values",condition && condition.values ? condition.values : null).appendTo($conditions);
					
				if (!o.readonly) {
					$condition.append($("<div class='deleteicon ui-icon ui-icon-trash'></div>").attr("title", o.label.removeCondition).click(function(){
						moveToTrash($(this).parent("li"));
					}));
				};
				$condition.append($("<div class='dragicon ui-icon ui-icon-arrowthick-2-n-s'></div>").attr("title",o.label.dragToOrder))
					.append($("<div class='fieldname'></div>").css({width:o.widths[0]+"px"}).append(getFieldList(condition && condition.fieldName? condition.fieldName : o.fields[0].name)))
					.append($("<div class='operator'></div>").css({width:o.widths[1]+"px"}).append(getOperatorList(condition && condition.operator && condition.operator.value ? condition.operator.value : o.operators[0].value)))
					.append($("<div class='mode'></div>").css({width:o.widths[2]+"px", display:(o.enableDisplayMode?"block":"none")}).append(getModeList(condition && condition.mode && condition.mode.value ? condition.mode.value : o.modes[0].value)))
					.append($("<div class='values'></div>").css({marginLeft:(o.widths[0]+o.widths[1]+o.widths[2]+16)+"px"}).append(getValuesList(condition && condition.values ? condition.values : null)))
					.show("highlight");
				
				if (!o.readonly) {
					if (o.lookupUrl != null && o.lookupUrl != "") {
						$condition.find("input").autocomplete({
							match:function(typed) {return true;},
							insertText:function(item){return item.label;},
							template:function(item){return "<li>"+item.value+"</li>";},
							ajax:o.lookupUrl+"?fieldName="+$condition.data("fieldName")
						});
					};
				}
			};
			
			function moveToTrash(conditionElement) {
				conditionElement.fadeOut("slow",function(){
					$(this).appendTo($trash);
				});
			};
			
			function undoRemove() {
				$trash.children(":last").appendTo($conditions).show("highlight");
			};
			
			function getFieldList(fieldName) {
				if (o.readonly) {
					var fieldLabel = fieldName;
					for (var i=0; i<o.fields.length; i++) {
						if (fieldName == o.fields[i].name) {
							fieldLabel = o.fields[i].label;
						}
					}
					return $("<span></span>").text(fieldLabel);
				} else {
					var fieldList = $("<select></select>");
					for (var i=0; i<o.fields.length; i++) {
						if (fieldName == o.fields[i].name) {
							fieldList.append($("<option></option>").text(o.fields[i].label).attr("value",o.fields[i].name).attr("selected","selected"));
						} else {
							fieldList.append($("<option></option>").text(o.fields[i].label).attr("value",o.fields[i].name));
						}
					}
					fieldList.change(function(){
						$(this).parents("li").data("fieldName", $(this).val());
						if (o.lookupUrl != null && o.lookupUrl != "") {
							$(this).parents("li").find("input").unbind();
							$(this).parents("li").find("input").autocomplete({
								match:function(typed) {return true;},
								insertText:function(item){return item.label;},
								template:function(item){return "<li>"+item.value+"</li>";},
								ajax:o.lookupUrl+"?fieldName="+$(this).parents("li").data("fieldName")
							});
						};
					});
					return fieldList;
				}
			};

			function getOperatorList(operator) {
				if (o.readonly) {
					var operatorLabel = operator;
					for (var i=0; i<o.operators.length; i++) {
						if (operator == o.operators[i].value) {
							operatorLabel = o.operators[i].label;
						}
					}
					return $("<span></span>").text(operatorLabel);
				} else {
					var operatorList = $("<select></select>");
					for (var i=0; i<o.operators.length; i++) {
						if (operator == o.operators[i].value) {
							operatorList.append($("<option></option>").text(o.operators[i].label).attr("value",o.operators[i].value).attr("selected","selected"));
						} else {
							operatorList.append($("<option></option>").text(o.operators[i].label).attr("value",o.operators[i].value));
						}
					}
					operatorList.change(function(){
						$(this).parents("li").data("operator", $(this).val());
					});
					return operatorList;
				}
			};
			
			function getModeList(mode) {
				if (o.readonly) {
					var modeLabel = mode;
					for (var i=0; i<o.modes.length; i++) {
						if (mode == o.modes[i].value) {
							modeLabel = o.modes[i].label;
						}
					}
					return $("<span></span>").text(modeLabel);
				} else {
					var modeList = $("<select></select>");
					for (var i=0; i<o.modes.length; i++) {
						if (mode == o.modes[i].value) {
							modeList.append($("<option></option>").text(o.modes[i].label).attr("value",o.modes[i].value).attr("selected","selected"));
						} else {
							modeList.append($("<option></option>").text(o.modes[i].label).attr("value",o.modes[i].value));
						}
					}
					modeList.change(function(){
						$(this).parents("li").data("mode", $(this).val());
					});
					return modeList;
				}
			};
			
			function getValuesList(values) {
				var returnList = $("<div></div>");
				if (!o.readonly) {
					returnList.append($("<div class='addvalue ui-icon ui-icon-circle-plus'></div>").attr("title",o.label.addValue).click(function(){
						addValue($(this).parent().find("input").val(), $(this).parent().find(".valuesList"));
						$(this).parent().find("input").val("");
					}));
				};
				returnList.append($("<div class='valuesList'></div>"));
				var valuesList = returnList.find(".valuesList");
				if (!o.readonly) {
					valuesList.append($("<input type='text'/>"));
				};
				if (values != null) {
					for (var i=0; i<values.length; i++) {
						addValue(values[i], valuesList);
					}
				}
				return returnList;
			};
			
			function addValue(value, valuesList) {
				if (value != null && value != "") {
					var $value = $("<div class='ui-priority-secondary'></div>");
					if (!o.readonly) {
						$value.mouseover(function(){ $(this).find(".removevalue").show();})
								.mouseout(function(){ $(this).find(".removevalue").hide();})
								.append($("<div class='removevalue ui-icon ui-icon-close'></div>").css({"display":"none"}).dblclick(function(){
									$(this).parent().remove();
									var values = [];
									valuesList.find(".conditionvalue").each(function(i,val){
										values.push($(this).text());
									});
									valuesList.parents("li").data("values",values);
								}));
					};
					$value.append($("<div class='conditionvalue'></div>").text(value)).appendTo(valuesList);
					var values = [];
					valuesList.find(".conditionvalue").each(function(i,val){
						values.push($(this).text());
					});
					valuesList.parents("li").data("values",values);
				}
			}
		});
	};
	$.fn.conditionsEditorToJSON = function() {
		var returnValue = [];
		if (this.length > 0) {
			var $this = $(this[0]);
			var o = $this.data("options");
			$this.find(".conditions li").each(function(i, conditionEle){
				/*if ($(conditionEle).find(".valuesList input").val() != "") {
					
					$(conditionEle).find(".addvalue").click();
					$(conditionEle).find(".valuesList input").val() = "";
												
					if ($(conditionEle).data("values") == null || $(conditionEle).data("values") == "") {
						
						alert("Value is required");
						throw "Value is required";
					}
				}*/
				if ($(conditionEle).find(".valuesList input").val() != "") {
					$(conditionEle).find(".addvalue").click();
					$(conditionEle).find(".valuesList input").val("");
				} 
	
				/*alert("o.validateValue = " + o.validateValue );*/
				
				if (o.validateValue) {	
					if ($(conditionEle).data("values") == null || $(conditionEle).data("values") == "") {
						alert("Value is required");						
						throw "Value is required";
					}
				}
				returnValue.push({
					id:$(conditionEle).data("id"),
					fieldName:$(conditionEle).data("fieldName"),
					operator:$(conditionEle).data("operator"),
					mode:$(conditionEle).data("mode"),
					values:$(conditionEle).data("values")
				});
				
				/*alert(JSON.stringify(returnValue));*/
			});
		}
		return JSON.stringify(returnValue);
	};
	$.fn.conditionsEditor.toJSON = function() {
		var returnValue = [];
		if (this.length > 0) {
			var $this = $(this[0]);
			var o = $this.data("options");
			$this.find(".conditions li").each(function(i, conditionEle){
				/*if ($(conditionEle).find(".valuesList input").val() != "") {
					$(conditionEle).find(".addvalue").click();
					$(conditionEle).find(".valuesList input").val("");
				} */
				returnValue.push({
					id:$(conditionEle).data("id"),
					fieldName:$(conditionEle).data("fieldName"),
					operator:$(conditionEle).data("operator"),
					mode:$(conditionEle).data("mode"),
					values:$(conditionEle).data("values")
				});
				/*alert(JSON.stringify(returnValue));*/
			});
		}
		return JSON.stringify(returnValue);
	};
	
	
	$.fn.conditionsEditor.defaults = {
		lookupUrl : eztrack.lookupUrl,
		readonly:false,
		enableDisplayMode:true,
		validateValue:false,
		widths:[200, 120, 100],
		label:{
			fieldName:"Field Name", operator:"Operator", mode:"Display", values:"Values",
			addCondition:"Add Condition",
			removeCondition:"Remove Condition",
			undoRemove:"Undo Remove",
			dragToOrder:"Drag to arrange the order of conditions",
			addValue:"Add Value"
		},
		conditions :[],
		fields : [],
		operators:[
			{value:"condition.equal",label:"equal"},
			{value:"condition.like",label:"like"},
			{value:"condition.greaterthan",label:"greaterthan"},
			{value:"condition.lessthan",label:"lessthan"},
			{value:"condition.in",label:"in"},
			{value:"condition.notequal",label:"notequal"}
		],
		modes:[{value:"hidden", label:"hidden"},{value:"readonly",label:"readonly"},{value:"editable",label:"editable"},{value:"required",label:"required"}]
	};
})(jQuery);

