(function($){
	$.fn.dataLink = function(options) {
		var opts = $.extend({}, $.fn.dataLink.defaults, options);
		if (Calendar._SDN == null) {
			new Calendar();
		}
		return this.each(function(){
			var $this = $(this);
			var o = $.meta ? $.extend({}, opts, $this.data()) : opts;
			if (o.conditions != null && o.conditions.length > 0) {
				$this.addClass("datalink ui-widget-content");
				var $form = $("<form></form>").attr("action",o.formAction).attr("method",o.formMethod)
					.append($("<input type='hidden'/>").attr("name",o.viewIdParameterName).attr("id",o.viewIdParameterName).val(o.dataLinkViewId))
					.append($("<input type='hidden'/>").attr("name",o.valueParameterName).attr("id",o.valueParameterName))
					.appendTo($this);
				for (var i=0; i<o.conditions.length; i++) {
					var condition = o.conditions[i];
					if (condition.mode.value != 'hidden') {
						var conditionElement = $("<div class='condition'></div>")
							.data("id",condition && condition.id ? condition.id : "")
							.data("fieldName",condition && condition.fieldName ? condition.fieldName : "")
							.data("type",condition && condition.type ? condition.type.value : "")
							.data("operator",condition && condition.operator ? condition.operator.value : "")
							.data("mode",condition && condition.mode ? condition.mode.value : "")
							.data("values",condition && condition.values ? condition.values : null)
							.append($("<div></div>").addClass("fieldname").css({width:o.widths[0]+"px"}).text(condition.label))
							.append($("<div></div>").addClass("operator").css({width:o.widths[1]+"px"}).text(condition.operator.label))
							.append($("<div></div>").addClass("message"))
							.append($("<div></div>").addClass("values").css({marginLeft:(o.widths[0]+o.widths[1])+"px"}))
						.appendTo($form);
						
						var conditionValueElement = conditionElement.find(".values");
						if (condition.operator.value == "condition.in") {
							showValuesList(condition, conditionValueElement);
						} else if (condition.type.value == "text") {
							showTextValue(condition, conditionValueElement);
						} else if (condition.type.value == "number") {
							showTextValue(condition, conditionValueElement);
						} else if (condition.type.value == "date") {
							showDateValue(condition, conditionValueElement);
						};
						
						if (condition.mode.value == "required") {
							//conditionElement.find(".required").text(o.label.required);
							//conditionElement.find(".fieldname").text(condition.label + "*");
							conditionElement.find(".fieldname").append($("<div></div>").addClass("important").text("*"));							
						};
						
						conditionElement.find("input").blur(function(){
							var valid = validateConditionValueElement($(this).parents(".condition"));
							if ($this.find(".condition .ui-state-error").length > 0) {
								showError(o.label.invalidError);
							} else {
								hideError();
							}
						});
						
						if (o.lookupUrl != null && o.lookupUrl != "") {
							conditionElement.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="+conditionElement.data("fieldName")
							});
						};
						
					};
				};
				var controls = $("<div></div>").addClass("controls")
					.append($("<span></span>").addClass("control ui-state-default").click(function(){
						var dataLink = $(this).parents(".datalink");
						var valid = true;
						dataLink.find(".condition").each(function(){
							valid = valid && validateConditionValueElement($(this));
						});
						if (valid) {
							hideError();
							var position = $this.position();
							$this.append($("<div></div>").css({
								position:"absolute",
								top:position.top, 
								left:position.left, 
								width:$this.width(),
								height:$this.outerHeight()
							}).addClass("ui-widget-overlay"));
							
							$(this).parents("form").find(".loading").show();
							dataLink.find("#"+o.valueParameterName).val(dataLink.dataLink.toJSON());
							$(this).oneTime(1000, function(){
								$this.find("form").submit();
							});
						} else {
							showError(o.label.invalidError);
						}
					}).mouseover(function(){
						$(this).addClass("ui-state-hover");
					}).mouseout(function(){
						$(this).removeClass("ui-state-hover");
					})
						.append($("<span></span>").addClass("ui-icon ui-icon-search"))
						.append($("<span></span>").addClass("label").text(o.label.submittName)))
					.append($("<span></span>").addClass("loading ui-helper-hidden"))
					.appendTo($form);
			}
			
			function validateConditionValueElement(conditionValueElement) {
				if (conditionValueElement.data("mode") == "readonly") {
					return true;
				}
				
				var valid = true;
				conditionValueElement.find(".message").removeClass("ui-state-error").text("");
				
				//conditionValueElement.find(".required").removeClass("ui-state-error").text("");
				
				if (conditionValueElement.data("mode") == "required") {
					if (conditionValueElement.data("operator") == "condition.in") {
						valid = (conditionValueElement.data("values") != null && conditionValueElement.data("values").length > 0);
					} else {
						valid = (conditionValueElement.find("input").val() != "");
					};
					
					if (!valid) {
						conditionValueElement.find(".message").addClass("ui-state-error").text(o.label.requiredError).show("highlight");
						//alert (o.label.invalidError, o.label.requiredError);
						//conditionValueElement.find(".required").addClass("ui-state-error").text(o.label.requiredError).show("highlight");
					} 
					//else {hideError()};
				};
				
				if (conditionValueElement.find("input").val() != "") {
					if (conditionValueElement.data("type") == "date") {
						var parsedDate = Date.parseDate(conditionValueElement.find("input").val(), o.dateFormat);
						if (conditionValueElement.find("input").val() != parsedDate.print(o.dateFormat)) {
							valid = false;
							conditionValueElement.find(".message").addClass("ui-state-error").text(o.label.dateError).show("highlight");
							//conditionValueElement.find(".required").addClass("ui-state-error").text(o.label.dateError).show("highlight");
						}
					};
					
					if (conditionValueElement.data("type") == "number" && isNaN(conditionValueElement.find("input").val())) {
						valid = false;
						conditionValueElement.find(".message").addClass("ui-state-error").text(o.label.numberError).show("highlight");
						//conditionValueElement.find(".required").addClass("ui-state-error").text(o.label.numberError).show("highlight");
					};
				}
				
				return valid;
			}
			
			function showTextValue(condition, conditionValueElement) {
				var value = condition && condition.values ? condition.values[0]: "";
				if (condition.mode.value != "readonly" && condition.mode.value != "hidden") {
					conditionValueElement.append($("<div></div>")
						.append($("<div></div>").addClass("required"))
						.append($("<div></div>").addClass("valuespacer"))
						.append($("<input type='text'>").val(value).change(function(){
							if ($(this).val()=="") {
								$(this).parents(".condition").data("values",null);
							} else {
								$(this).parents(".condition").data("values",[$(this).val()]);
							}
						}))
					);
				} else {
					conditionValueElement.append($("<span></span>").text(value));
				}
			}
			

			
			
			function showDateValue(condition, conditionValueElement) {
				var value = "";
				if (condition && condition.values) {
					value = new Date();
					value.setTime(condition.values[0]);
					//value.setTime(condition.values, true);
				}
				if (condition.mode.value != "readonly" && condition.mode.value != "hidden") {
					conditionValueElement.append($("<div></div>").addClass("datetype")
						.append($("<div></div>").addClass("required"))
						.append($("<div></div>").addClass("timezone").html(o.timezone))
						.append($("<img />").addClass("calimg calendar").attr("id","dateValue"+condition.id+"_trigger"))
						.append($("<input type='text' />").attr("id", "dateValue"+condition.id).val(value!="" ? value.print(o.dateFormat):"").change(function(){
							if ($(this).val()=="") {
								$(this).parents(".condition").data("values",null);
							} else {
								$(this).parents(".condition").data("values",[Date.parseDate($(this).val(), o.dateFormat).getTime()]);
							}
						})));
					
					

                    Calendar.setup({
                        inputField     :    "dateValue"+condition.id,
                        defaultTimeZero	:	true,
                        //date		   :	startToday,
                        ifFormat       :    o.dateFormat,
                        daFormat       :    o.dateFormat,
                        showsTime      :    true,
                        button         :    "dateValue"+condition.id+"_trigger",
                        singleClick    :    true,
                        onUpdate       :    function(cal) {

                    	
							$(cal.params.inputField).change();
						}
                               
                    
                    });
				} else {
					conditionValueElement.append($("<span></span>").text(value!="" ? value.print(o.dateFormat):""));
				}
			}
			
			function showValuesList(condition, conditionValueElement) {
				var values = (condition && condition.values ? condition.values : null);
				var returnList = $("<div></div>").appendTo(conditionValueElement);
				var readonly = (condition.mode.value == "readonly" || condition.mode.value == "hidden"); 
				if (!readonly) {
					returnList.append($("<div></div>").addClass("required")).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"), false);
						$(this).parent().find("input").val("");
						$(this).parent().find("input").focus();
					}));
				};
				var valuesList = $("<div class='valuesList'></div>").appendTo(returnList);
				if (!readonly) {
					valuesList.append($("<input type='text'/>"));
				}
				
				if (values != null) {
					for (var i=0; i<values.length; i++) {
						addValue(values[i], valuesList, readonly);
					}
				}
			};
			
			function addValue(value, valuesList, readonly) {
				if (value != null && value != "") {
					var valueElement = $("<div class='ui-priority-secondary'></div>").appendTo(valuesList);
					if (!readonly) {
						valueElement.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(".condition").data("values",values);
									}));
					}
					valueElement.append($("<div class='conditionvalue'></div>").text(value));
					var values = [];
					valuesList.find(".conditionvalue").each(function(i,val){
						values.push($(this).text());
					});
					valuesList.parents(".condition").data("values",values);
				}
			}
		});
	};
	$.fn.dataLink.toJSON = function() {
		var returnValue = {};
		if (this.length > 0) {
			var $this = $(this[0]);
			$this.find(".condition").each(function(i, conditionEle){
				if ($(conditionEle).data("values") != null) {
					returnValue["value"+$(conditionEle).data("id")] = $(conditionEle).data("values");
				}
			});
		}
		return JSON.stringify(returnValue);
	};
	
	$.fn.dataLink.defaults = {
		widths : [200, 100],
		lookupUrl : eztrack.lookupUrl,
		label:{
			addValue:"Add Value",
			submittName:"Search",
			required:"Required",
			requiredError:"Please specify a value for this field.",
			dateError:"Please specify a valid date",
			invalidError:"Datalink input fields invalid",
			numberError:"Please specify a valid number"
		},
		timezone:"",
		formAction:"",
		formMethod:"POST",
		dataLinkViewId:"",
		viewIdParameterName:"viewId",
		valueParameterName:"valueJSON",
		conditions :[],
		dateFormat : "%d/%m/%Y %H:%M",
 
		
		operators:[
			{value:"condition.equal",label:"equals to"},
			{value:"condition.like",label:"like"},
			{value:"condition.greaterthan",label:"greater than"},
			{value:"condition.lessthan",label:"less than"},
			{value:"condition.in",label:"in list"},
			{value:"condition.notequal",label:"not equal to"}
		]
	};
})(jQuery);

