
(function($){
$.dataSelect = {
	version: '1.0',
	author: 'liu.jb'
};

$.dataSelect.defaults = {
		cols : 5,
		clearName : "Çå³ýÑ¡Ôñ",
		fix:true,
		width:false,
		height:false,
		selectLeafOnly:false,
		vertical:false,
		beforeDisplay:null,
		onSelect:null,
		nameField:null,
		valueField:null,
		fillSelf:true,
		cellLength:10,
		events:"click focus dsRenderDataSelect"
};

$.dataSelect.renderDataSelect = function () {
	var $this = $(this);
	var wapper = $("#ds-wapper").empty();
	var table = $("<table cellspacing='0' cellpadding='0' border='0'></table>").appendTo(wapper);

	var data = $this.data("dsData");
	var setting = $this.data("dsSetting");

	if (!$.isArray(data)) {
		throw new Error("Illegal data format.");
		return false;
	}
	
	if (!setting) {
		throw new Error("Can not call RenderDateSelect method directly.");
		return;
	}
	
	wapper.data("dsFieldObject", $this);
	
	if (data.length == 0) {
		return false;
	}
	
	var complex = false;
	if (data[0].title) {
		complex = true;
	}
	
	$.extend(setting, {complex:complex});
	$this.data("dsSetting", setting);
	
	if (complex) {
		for (var i = 0; i < data.length; i++) {
			var title = data[i].title;
			var tableData = data[i].data;
			if (i > 0) {
				$("<tr></tr>").append($("<td></td>").attr("colspan", setting.cols).addClass("ds-top-line")).appendTo(table);
			}
			$("<tr></tr>").append($("<td></td>").attr("colspan", setting.cols).addClass("ds-complex-title").html(title)).appendTo(table);
			$("<tr></tr>").append($("<td></td>").attr("colspan", setting.cols).addClass("ds-top-line")).appendTo(table);
			
			$.dataSelect.renderCells.call(this, table, tableData, i);
		}
	} else {
		$.dataSelect.renderCells.call(this, table, data, 0);
	}
	
	try {
		wapper.locateTo(this, {x:"left", y:"bottom"}, {x:0, y:-1});
		wapper.bgIframe();
	} catch(e) {}
	
	wapper.show();
	
	if (setting.fix) {
		var w = $this.innerWidth() + parseInt($this.css("borderLeftWidth")) || 0 + parseInt($this.css("borderRightWidth")) || 0;
		var padding = parseInt(wapper.css("paddingLeft")) + parseInt(wapper.css("paddingRight"));
		var margin = parseInt(table.css("marginLeft")) + parseInt(table.css("marginRight"));
		var border = parseInt(wapper.css("borderLeftWidth")) || 0 + parseInt(wapper.css("borderRightWidth")) || 0;
		
		var fieldWidth = w - padding - margin - border;
		
		if (table.width() < fieldWidth) {
			table.width(fieldWidth);
		} 
	} else {
		table.css("width", setting.width || "auto");
	}
	
	if (setting.height) {
		wapper.css("height", setting.height);
		wapper.css("overflow-y", "auto");
		wapper.css("overflow-x", "hidden");
	} else {
		wapper.css("height", "auto");
		wapper.css("overflow-y", "hidden");
		wapper.css("overflow-x", "hidden");
	}
};

$.dataSelect.renderSubDataSelect = function (level, setting) {
	var $this = $("#ds-wapper").data("dsFieldObject");
	var cell = $(this);
	if (!level) {
		level = 1;
	}
	

	var data = cell.data("dsDataItem").subdata;


	if (!$.isArray(data)) {
		throw new Error("Illegal data format.");
		return false;
	}
	
	if (data.length == 0) {
		return false;
	}

	level++;
	var wapper = $("#ds-wapper-sub-" + level);
	
	if (wapper.size() == 0) {
		wapper = $("<div id='ds-wapper-sub-" + level + "'></div>").addClass("ds-wapper").addClass("ds-wapper-sub").css({display:"none", position:"absolute"}).data("level", level).bind("dsClose", function () {
			$("#ds-wapper-sub-" + (parseInt($(this).data("level")) + 1)).trigger("dsClose");
			$(this).empty().hide();
		}).appendTo("body");
	}
	
	var table = $("<table cellspacing='0' cellpadding='0' border='0'></table>").appendTo(wapper);
	var h = cell.outerHeight() - (parseInt(cell.css("borderTopWidth")) || 0) - (parseInt(cell.css("borderBottomWidth")) || 0);
	$("<div></div>").width(1).height(h).addClass("ds-wapper-spacer").appendTo(wapper);

	$.dataSelect.renderCells.call(this, table, data, 0, level);
	
	try {
		wapper.locateTo(this, {}, {x:-1, y:0}).bgIframe();
	} catch(e) {}
	
	wapper.show();
	
	/*
	var w = $this.innerWidth() + parseInt($this.css("borderLeftWidth")) || 0 + parseInt($this.css("borderRightWidth")) || 0;
	var padding = parseInt(wapper.css("paddingLeft")) + parseInt(wapper.css("paddingRight"));
	var margin = parseInt(table.css("marginLeft")) + parseInt(table.css("marginRight"));
	var border = parseInt(wapper.css("borderLeftWidth")) || 0 + parseInt(wapper.css("borderRightWidth")) || 0;
	*/
	var fieldWidth = $this.width();
	
	if (table.width() < fieldWidth) {
		table.width(fieldWidth);
	} 
}

$.dataSelect.renderCells= function (parent, data, group, level) {
	// var $this = $(this);
	var $this = $("#ds-wapper").data("dsFieldObject");
	
	if (!level) {
		level = 1;
	}

	var dss = $this.data("dsSetting");
	
	var setting = $.extend({}, dss);
	if (data[0] && data[0].subdata) {
		setting.subSelect = true;
		// $this.data("dsSetting", setting);
	} else {
		setting.subSelect = false;
	}
	
	var name = setting.nameField ? $(setting.nameField).val() : $this.val();

	var tr;
	for (var i = 0, j = 0; i < data.length; i++) {
		var c = $.extend(data[i], {group:group, level:level});
		
		if (j % setting.cols == 0 || setting.vertical || setting.subSelect) {
			if (!setting.vertical && !setting.subSelect && level == 1 && setting.complex == false && j > 0) {
				$("<tr></tr>").append($("<td></td>").attr("colspan", setting.cols).addClass("ds-top-line")).appendTo(parent);
			}
			tr = $("<tr></tr>").appendTo(parent);
		}

		var cell = $("<a></a>").append($("<span></span>").addClass("ds-item-float-left").html(c.name || '')).data("dsDataItem", c).bind("click", function (e) {
			//e.stopPropagation();
			//e.cancelBubble = true;
			var cellData = $(this).data("dsDataItem");
			var cellName = cellData.name;
			var cellValue = cellData.value;
			
			if (cellData.disabled || (setting.selectLeafOnly && cellData.subdata && cellData.subdata.length > 0)) {
				return false;
			}

			if (setting.clearName == cellName) {
				cellName = "";
				cellValue = "";
			}
			
			if (setting.fillSelf) {
				$this.val(cellName);
			}

			setting.nameField = setting.nameField ? $(setting.nameField) : null;
			setting.valueField = setting.valueField ? $(setting.valueField) : null;
			
			if (setting.nameField) {
				setting.nameField.val(cellName);
			}
			if (setting.valueField) {
				setting.valueField.val(cellValue);
			}
			$("#ds-wapper").trigger("dsClose");
			if (setting.onSelect && typeof setting.onSelect == "function" ) {
				setting.onSelect.call(this, cellData);
			}
			$this.trigger("change");
		}).bind("mouseover", function () {
			var subSelect = setting.subSelect;
			var cellData = $(this).data("dsDataItem");
			var subData = cellData.subdata || [];
			var subLevel = (cellData.level || 1);
			var $this = $(this);
			
			if (subSelect) {
				$("#ds-wapper-sub-" + (subLevel - 0 + 1)).trigger("dsClose");
				
				$(".ds-item-sub-hover").each(function () {
					
					if (subLevel == 1 || $(this).data("dsDataItem").level == subLevel) {				
						$(this).removeClass("ds-item-sub-hover").find(".ds-item-float-right").hide();
					}
				});
				
				if (subSelect && subData.length > 0) {
					$this.addClass("ds-item-sub-hover").find(".ds-item-float-right").show();
					$.dataSelect.renderSubDataSelect.call(this, subLevel);
				} else {
					$this.addClass("ds-item-hover");
				}
			} else {
				$this.addClass("ds-item-hover");				
			}
			
		}).bind("mouseout", function () {
			$(this).removeClass("ds-item-hover");
		});
		
		if (setting.subSelect) {
			$("<span></span>").addClass("ds-item-float-right").html(">").hide().appendTo(cell);
		}
		
		if (c.disabled) {
			cell.addClass("ds-cell-disabled");
		}
		
		var td = $("<td></td>").append(cell);
		

		var cellLength = $.dataSelect.realLength(c.name);
		if (cellLength > setting.cellLength && j < setting.cols - 1) {
			var colspan = parseInt(cellLength / setting.cellLength);
			var l = setting.cols - j - 1;
			if (colspan > l) {
				colspan = l;
			}
			td.attr("colspan", colspan + 1);
			j += colspan;
		}

		if (setting.vertical || setting.subSelect) {
			cell.css("display", "block");
		}
		
		if (c.name == name) {
				cell.addClass("ds-selected");
		}
		if (tr) {
			tr.append(td);
		}
		
		j++;
	}
}

$.dataSelect.realLength = function (str) {
	return str.replace(/[^\x00-\xff]/ig, "**").length; 
}

$.fn.extend({
	dataSelect : function (d, s) {
		if (typeof d == "string") {
			d = $.dataSelect.data[d];
		}
		
		$(this).each(function () {

			var field = $(this);
			
			var setting = $.extend({}, $.dataSelect.defaults, s);
			
			
			field.data("dsData", d);
			field.data("dsSetting", setting);
			/*
			field.data("dsWapper", wapper);
			*/
			if (setting.events) {
				field.bind(setting.events, function (e) {
					if (setting.beforeDisplay && typeof setting.beforeDisplay == "function") {
						if (!setting.beforeDisplay.call(this)) {
							return false;
						}
					}
					$.dataSelect.renderDataSelect.call(this);
				});
			}
			
			field.bind("dsCloseDataSelect", function (e) {
				$("div").filter(".ds-wapper").empty().hide();
			});
		});
		
	},
	
	dsSetData : function (data, rerender) {
		if (typeof data == "string") {
			data = $.dataSelect.data[data];
		}
		$(this).data("dsData", data);
		if (rerender) {
			$("#ds-wapper").trigger("dsClose");
			$.dataSelect.renderDataSelect.call(this);
		}
	}
});


$(function () {
	if ($("#ds-wapper").size() == 0) {
		$("<div id='ds-wapper'></div>").addClass("ds-wapper").css({display:"none", position:"absolute"}).bind("dsClose", function () {
			$("div").filter(".ds-wapper").empty().hide();
		}).appendTo("body");
	} 

	$(document).bind("mousedown.dsMouseDown", function (e) {
		var el = e.target;
		var flag = false;
		
		var wappers = [];

		$("div").filter(".ds-wapper").each(function () {
			
			wappers.push(this);
		});


		while (true){
			
			for (var i = 0; i < wappers.length; i++) {
				if (wappers[i] == el) {
					return true;
				}
			}
			
			if (!el || el == document || el == document.body) {
				$("#ds-wapper").trigger("dsClose");
				return true;
			} else {
				el = $(el).parent()[0];
			}
		}
	});
});

})(jQuery);
