/**
 *************************************************************************************
 * [标题：ExmayUI JQuery Selectable 插件]<br>
 *************************************************************************************
 * [描述：ExmayUI JQuery Selectable 插件]<br>
 *************************************************************************************
 * @author Exmay Team / 亿美团队
 *************************************************************************************
 * @version Version 1.0.1 Beta / v1.0.1 测试版
 *************************************************************************************
 */

/*
 * ***********************************************************************************
 * 版权：Copyright © 2012 Exmay Inc. All Rights Reserved. 长沙亿美软件有限公司　版权所有
 * ***********************************************************************************
 * 企业文化：专注　创新　分享　共赢
 * ***********************************************************************************
 * 官方网站：http://www.exmay.com
 * ***********************************************************************************
 * 官方邮箱：service@exmay.com
 * ***********************************************************************************
 */

(function($) {
	
	var itemClick = false;
	
	// 初始化
	function init(target) {
		var opts = $(target).data("exmaySelectable").options;
	};
	
	// 可选择事件绑定
	function bindExmaySelectableEvents($target){
		var opts = $target.data("exmaySelectable").options;
		var $selectableItems = $(opts.item, $target);
		var $lastSelectedItem = null;
		
		var $helper = $('<div class="exmayui-selectable-helper"></div>');
		$helper.appendTo($(opts.appendTo));
		
		// 鼠标事件
		$(document).bind("mousedown.toselect", function(event) {
			var data = {
				left: event.pageX, 
				top : event.pageY,
				ctrlKey : event.ctrlKey,
				shiftKey : event.shiftKey
			};
			disableBrowserDefaultSelect();
			$(document).bind("mousemove.exmaySelectable", data, doMove);
			$(document).bind("mouseup.exmaySelectable", data, doUp);
		}).bind("keydown.toselect", function(event) {
			var code = event.keyCode||event.which||event.charCode;
			if(code == 65 && event.ctrlKey) {
				if(event.altKey) {
					enableBrowserDefaultSelect();
				} else {
					disableBrowserDefaultSelect();
					exmaySelectedAll($target);
				}
			}
			if(code == 90 && event.ctrlKey) {
				if(event.altKey) {
					enableBrowserDefaultSelect();
				} else {
					disableBrowserDefaultSelect();
					exmayUnselectedAll($target);
				}
			}
		});
		
		var move = false;
		
		function doMove(event) {
			if(opts.checkbox) {
				return false;
			}
			move = true;
			var data = event.data;
			var left = data.left; 
			var top = data.top;
			var width = event.pageX;
			var height = event.pageY;
			if (left > width) { var tmp = width; width = left; left = tmp; }  
			if (top > height) { var tmp = height; height = top; top = tmp; }
			/*$("#left").html("left: " + left);
			$("#width").html("width: " + width);
			$("#lw").html(width - left);
			$("#top").html("top: " + top);
			$("#height").html("height: " + height);
			$("#th").html(height - top);*/
			
			if(!(data.ctrlKey || data.shiftKey)) {
				// 取消全部选择
				exmayUnselectedAll($target);
			}
			
			$helper.css({
				"left": left,
				"top": top,
				"width": width - left,
				"height": height - top
			}).show();
			
			//var date1=new Date();

			$selectableItems.each(function() { 
				
				var sleft = $(this).offset().left;
				var stop = $(this).offset().top;
				var sright = $(this).outerWidth() + sleft;
				var sbottom = $(this).outerHeight() + stop;
				
				/*$("#sleft").html("sleft：" + sleft);
				$("#sright").html("sright：" + sright);
				$("#stop").html("stop：" + stop);
				$("#sbottom").html("sbottom：" + sbottom);*/
				
				var flag = sright >= left && width >= sleft && top <= sbottom && height >= stop;
				if(flag) {
					//$("#hit").html("hit");
					//$(this).addClass("exmayui-selecting");
					//$(this).css({
					//	"background-color": "#FFFF99" 
					//});
					if(!$(this).hasClass("exmayui-selecting")) {
						$(this).addClass("exmayui-selecting");
					}
				} else {
					//$("#hit").html("no-hit");
					if($(this).hasClass("exmayui-selecting")) {
						$(this).removeClass("exmayui-selecting");
					}
				}	
				
				/*var flag = !(sleft > left + width || sright < left || sbottom < top || stop > top+height);
				if(flag) {
					$(this).addClass("exmayui-selecting");
				} else {
					$(this).removeClass("exmayui-selecting");
				}*/
			});	
			
			//var date2=new Date();
			//var haomiao=date2.getTime()-date1.getTime();
			//$("#exmay-debug").append(" @" + haomiao);
			
		};
		
		function doUp(event) {
			enableBrowserDefaultSelect();
			$helper.hide();
			$(document).unbind(".exmaySelectable");
			if(move) {
				return $selectableItems.each(function() { 
					if($(this).hasClass("exmayui-selecting")) {
						if(event.shiftKey) {
							//$(this).removeClass("exmayui-selecting").addClass("exmayui-selected");
							exmaySelected($target, $(this));
						} else {
							//$(this).removeClass("exmayui-selecting").toggleClass("exmayui-selected");
							selectedInvert($target, $(this));
						}
						move = false;
					}
				}); 
			}
		};
		
		// 全部取消事件
		$(document).bind("mousedown.toselect", function(event){
			
			if(event.altKey) {
				enableBrowserDefaultSelect();
//2011-12-29  				$(".exmayui-selectable").exmaySelectable({checkbox : true});
				return false;
			}
			//$("#tip").text(itemClick);
			if(!(event.ctrlKey || event.shiftKey)) {
					disableBrowserDefaultSelect();
				   if(!itemClick) {
					//$selectableItems.removeClass("exmayui-selected");
					exmayUnselectedAll($target);
					/*if($.fn.checkbox) {
						$(".exmayui-checkbox-all").checkbox("unchecked");
						$(".exmayui-checkbox-invert").checkbox("unchecked");
					}*/
					
				}
//				if(opts.onClick) {
//					opts.onClick.call();
//				}
			}
			itemClick = false;
		}, function(){
//2011-12-29  			$(".exmayui-selectable").exmaySelectable({checkbox : false});
		});
		
		bindItemEvents($target, $helper);
		
	};
	
	function bindItemEvents($target, $helper){
		var opts = $target.data("exmaySelectable").options;
		var $selectableItems = $(opts.item, $target);
		var $lastSelectedItem = null;
		$selectableItems.each(function() {
			
			// 单击右击事件
			$(this).bind("mousedown.toselect", function(event){
				itemClick = true;
				
				// 如果按住CTRL键，则交换选择状态；如果没有按CTRL键，则取消其他选中项
				if(event.ctrlKey) {
					selectedInvert($target, $(this));
				} else {
					if(!event.shiftKey) {
						//$selectableItems.removeClass("exmayui-selected");
						//$(this).addClass("exmayui-selected");
						//exmayUnselectedAll($target);
//						var isSelected = false;
//						if($(this).hasClass("exmayui-selected")) {
//							//exmayUnselected($target, $(this));
//							isSelected = true;
//						} else {
//							//exmaySelected($target, $(this));
//						}
//						if($(this).hasClass("exmayui-selected")) {
//							unselectedOthers($target, $(this));
//							if(selectedSize($target) == 1) {
//								exmayUnselected($target, $(this));
//							}
//						} else {
//							unselectedOthers($target, $(this));
//							exmaySelected($target, $(this));
//						}
						if(event.which != 3 || !$(this).hasClass("exmayui-selected")) { // 非右击
							exmayUnselectedAll($target);
							exmaySelected($target, $(this));
						}

					}
				}
					
				// 如果按住Shift键，则选择当前选择与上次选择之间的所有项
				if(event.shiftKey) {
					if($lastSelectedItem) {	
						// 选项是否连续
						// 反选

						var lastSelectedItemIndex = $selectableItems.index($lastSelectedItem);
						var thisIndex = $selectableItems.index($(this));
						
						// 向下
						if(lastSelectedItemIndex < thisIndex) {
							lastSelectedItemIndex = $selectableItems.index($(this).siblings(".exmayui-selected:first"));
						} else { // 向上
							lastSelectedItemIndex = $selectableItems.index($(this).siblings(".exmayui-selected:last"));
						}
						
						//$selectableItems.removeClass("exmayui-selected");
						exmayUnselectedAll($target);
						
						var startIndex = Math.min(lastSelectedItemIndex, thisIndex);
						var endIndex = Math.max(lastSelectedItemIndex, thisIndex);
						
						$("#last").html(lastSelectedItemIndex);
						$("#this").html(thisIndex);
						$("#start").html(startIndex);
						$("#end").html(endIndex);
						for(i = startIndex; i <= endIndex; i++) {
							exmaySelected($target, $selectableItems.eq(i))
						}
					}
				}
				
				$lastSelectedItem = $(this);
			
			}).hover(
				function(){
					if($helper.css("display") == "none") {
						$(this).addClass("exmayui-selecting");
					}
				},
				function(){
					if($helper.css("display") == "none") {
						$(this).removeClass("exmayui-selecting");
					}
				}
			);
		});
	}
	
	// 禁用浏览器默认选择
	function disableBrowserDefaultSelect() {
		//document.oncontextmenu=new Function("event.returnValue=false;"); //禁止右键功能,单击右键将无任何反应
		document.onselectstart=new Function("event.returnValue=false;"); //禁止先择,也就是无法复制
		$("*").css({"-moz-user-select":"none"});
	};
	
	// 禁用浏览器默认选择
	function enableBrowserDefaultSelect() {
		document.onselectstart=new Function("event.returnValue=true;");
		$("*").css({"-moz-user-select":""});
	}
	
	// 选择
	function exmaySelected($target, $data) {
		var opts = $target.data("exmaySelectable").options;
		if(opts.checkbox) return false;
		$($data[0], $target).removeClass("exmayui-selecting").addClass("exmayui-selected");
		/*if(opts.cc) {
			$("."+opts.cc, $data).exmayCheckbox("setChecked");
		}*/
		if(opts.onSelected) {
//			opts.onSelected.call($target[0], {item : $($data[0], $target)});
		}
	};
	
	// 取消选择
	function exmayUnselected($target, $data) {
		var opts = $target.data("exmaySelectable").options;
		if(opts.checkbox) return false;
		//$("#tip").append(" 测试 ")
		$($data[0], $target).removeClass("exmayui-selected");
		if(opts.cc) {
			$("."+opts.cc, $data).exmayCheckbox("unchecked");
		}
		if(opts.onUnselected) {
//			opts.onUnselected.call($target[0], {item : $($data[0], $target)});
		}
	};
	
	function selectedInvert($target, $data) {
		var opts = $target.data("exmaySelectable").options;
		if(opts.checkbox) return false;
		$($data[0], $target).each(function(){
			if($(this).hasClass("exmayui-selected")) {
				exmayUnselected($target, $(this));
			} else {
				exmaySelected($target , $(this));
			}
		});
	};
	
	function unselectedOthers($target,$data) {
		var opts = $target.data("exmaySelectable").options;
		if(opts.checkbox) return false;
		var $selectableItems = $(opts.item, $target);
		$selectableItems.each(function(){
			if($(this) != $data) {
				exmayUnselected($target, $(this));
			}
		});
		if(opts.onUnselectedAll) {
			opts.onUnselectedAll.call();
		}
	};
	
	// 全选
	function exmaySelectedAll($target) {
		var opts = $target.data("exmaySelectable").options;
		if(opts.checkbox) return false;
		var $selectableItems = $(opts.item, $target);
		$selectableItems.each(function(){
			exmaySelected($target, $(this));
		});
		if(opts.onSelectedAll) {
			opts.onSelectedAll.call();
		}
	};
	
	// 取消全选
	function exmayUnselectedAll($target) {
		var opts = $target.data("exmaySelectable").options;
		if(opts.checkbox) return false;
		var $selectableItems = $(opts.item, $target);
		$selectableItems.each(function(){
			if($(this).hasClass("exmayui-selected")) {
				exmayUnselected($target, $(this));
			}
		});
		if(opts.onUnselectedAll) {
			opts.onUnselectedAll.call();
		}
	};
	
	function selectedSize(target) {
		return exmayGetSelected(target).length;
	}
	
	function exmayGetSelected(target) {
		var ids = [];
		$(target).find(".exmayui-selected").each(function(){
			ids.push($(this).find(".exmay-ui-id").first().val());
		});
		return ids;
	};
	
	// 获取选中项目
	function exmayGetSelectedItems(target) {
		return $(target).find(".exmayui-selected");
	};
	
	function unbindEvents($target) {
		var opts = $target.data("exmaySelectable").options;
		var $selectableItems = $(opts.item, $target);
		$(document).unbind(".toselect");
		$(document).unbind(".selectable");
		$selectableItems.each(function() {
			$(this).unbind(".toselect");
		});
	}
	
	function unbindItemEvents($target) {
		var opts = $target.data("exmaySelectable").options;
		var $selectableItems = $(opts.item, $target);
		$selectableItems.each(function() {
			$(this).unbind(".toselect");
			$(this).unbind("mousedown.toselect");
		});
	}
	
	// 定义插件
	$.fn.exmaySelectable = function(options, data) {
		//$("#exmay-debug").append(" @你好");
        if (typeof options == "string") {
            return $.fn.exmaySelectable.methods[options](this, data);
        }

		this.each(function(){
			//$("#exmay-debug").append(" @初始化");
			var $this = $(this);
			var opts = null;
			var cache = $this.data("exmaySelectable");
			if(cache) {
				opts = $.extend(cache.options, options || {});
				cache.options = opts;
				unbindEvents($this);
				unbindItemEvents($this);
				
			} else {
				opts = $.extend( {}, $.fn.exmaySelectable.defaults, $.fn.exmaySelectable.parseOptions(this), options || {});
				$this.data("exmaySelectable", {
					options : opts
				});
			};
			bindExmaySelectableEvents($this);
		});
		
	};
	
	$.fn.exmaySelectable.methods = {
		setSelected : function(target, data) {
			return exmaySelected(target, data); // 选中
		},
		setUnselected : function(target, data) {
			return exmayUnselected(target, data); // 取消选中
		},
		selectedAll : function(target) {
			return exmaySelectedAll(target); // 全选
		},
		unselectedAll : function(target) {
			return exmayUnselectedAll(target); // 全选
		},
		getSelected : function(target) {
			return exmayGetSelected(target);//　获取选中
		},
		getSelectedItems : function(target) {
			return exmayGetSelectedItems(target);
		}
		//				case "bindEvents" : 
		//					bindExmaySelectableEvents($(this));
		//				case "unbindEvents" : 
		//					unbindEvents($(this));
		//				case "bindItemEvents" : 
		//					bindItemEvents($(this));
		//				case "unbindItemEvents" : 
		//					unbindItemEvents($(this));
	};
	
    $.fn.exmaySelectable.parseOptions = function(target) {
        var $target = $(target);
        return {
        	cc : $target.attr("cc")
        }
	};
	
	$.fn.exmaySelectable.defaults = {
		appendTo: 'body',
		autoRefresh: true,
		distance: 0,
		item : ".exmayui-selectable-item",
		filter: '*',
		tolerance: 'touch',
		sid: 1,
		checkbox : false,
		cc : null, // checkboxClass

		onClick : function(item) {},
		onSelected : function(item) {},
		onUnselected : function(item){},
		onSelectedAll : function(){},
		onunSelectedAll : function(){}
	};
	
})(jQuery);