(function($){
	$.fn.listfield = function(options) {
		var opts = $.extend({}, $.fn.listfield.defaults, options);
		return this.each(function(){
			var $this = $(this).addClass("listfield");
			var o = $.meta ? $.extend({}, opts, $this.data()) : opts;
			$this.data("options", o);
			var $header = $("<div class='header ui-widget-header'></div>").appendTo($this);
			for (var i=0; i<o.columnNames.length; i++) {
				$header.append($("<div class='column "+o.columnNames[i]+"'><div>").css({width:o.columnWidths[i]+"px"}).text(o.columnLabels[i]))
			};
			$header.append($("<div></div>").css({clear:"both"}));
				
			var $listcontent = $("<ul></ul>").addClass("listcontent").appendTo($this);
			$listcontent.sortable({
				placeholder: "ui-state-highlight"
			});
			
			var $trash = $("<ul></ul>").addClass("trash").css({display:"none"}).appendTo($this);
			$this.append($("<span class='additem'><span class='ui-icon ui-icon-newwin'></span>"+o.label.addItem+"</span>").click(function(){
				addItem(null);
			}));
			$this.append($("<span class='undoremove'>"+o.label.undoRemove+"</span>").click(function(){
				undoRemove();
			}));
			for (var i=0; i<o.columnValues.length; i++) {
				addItem(o.columnValues[i]);
			};
			
			function addItem(item) {
				var $item = $("<li></li>").addClass("ui-state-default")
							.append($("<div class='deleteicon ui-icon ui-icon-trash'></div>").attr("title", o.label.removeItem).click(function(){
								moveToTrash($(this).parent("li"));
							}))
							.append($("<div class='dragicon ui-icon ui-icon-arrowthick-2-n-s'></div>").attr("title",o.label.dragToOrder))
							.appendTo($listcontent);
				for (var i=0; i<o.columnNames.length; i++) {
					var itemValue = "";
					if (item != null && item[o.columnNames[i]] != null) {
						itemValue = item[o.columnNames[i]];
					}
					$item.append(
						$("<div class='column'></div>").css({width:o.columnWidths[i]+"px"}).append(
							$("<input class='"+o.columnNames[i]+"' value='"+itemValue+"'/>").css({width:(o.columnWidths[i]-10)+"px"})));
				};
				$item.append($("<div></div>").css({clear:"both"}));
				$item.show("highlight");
				if (o.addItemHandler !=null && typeof(o.addItemHandler) == "function") {
					o.addItemHandler($item);
				}
			};
			
			function moveToTrash(itemElement) {
				itemElement.fadeOut("slow",function(){
					$(this).appendTo($trash);
				});
			};
			
			function undoRemove() {
				$trash.children(":last").appendTo($listcontent).show("highlight");
			};
		});
	};
	$.fn.listfieldValidate = function(){
		var valid = true;
		if (this.length > 0) {
			var $this = $(this[0]);
			$this.find(".listcontent li").each(function(i, itemEle){
				var item = {};
				var filledValueCount = 0;
				$(itemEle).find("input").each(function(j, inputEle){
					var itemValue = $(inputEle).val();
					if (itemValue != null && itemValue != "") {
						item[$(inputEle).attr("class")] = itemValue;
						filledValueCount++;
					};
				});
				
				if (filledValueCount != 0 && filledValueCount != $(itemEle).find("input").length) {
					valid = false;
				};
			});
		};
		return valid;
	};
	$.fn.listfieldToJSON = function() {
		var returnValue = [];
		if (this.length > 0) {
			var $this = $(this[0]);
			$this.find(".listcontent li").each(function(i, itemEle){
				var item = {};
				var filledValueCount = 0;
				$(itemEle).find("input").each(function(j, inputEle){
					var itemValue = $(inputEle).val();
					if (itemValue != null && itemValue != "") {
						item[$(inputEle).attr("class")] = itemValue;
						filledValueCount++;
					};
				});
				
				if (filledValueCount == $(itemEle).find("input").length) {
					returnValue.push(item);
				};
			});
		};
		return JSON.stringify(returnValue);
	};
	$.fn.listfield.defaults = {
		label:{
			addItem:"Add",
			removeItem:"Remove",
			undoRemove:"Undo Remove",
			dragToOrder:"Drag to arrange the order"
		},
		addItemHandler:null,
		columnWidths:[100,100],
		columnNames:["column1","column2"],
		columnLabels:["Column 1","Column 2"],
		columnValues:[]
	};
})(jQuery);

