﻿/// <reference path="Jquery-vsdoc.js"/>
// Common js lib by nicch.
// BY NC[fishcn@foxmail.com]


jQuery.fn["fadeInDown"] = function (offset, speed, easing, callback) {
	var handler = this;
	return this.animate({ "marginTop": "+=" + offset + "px", "opacity": "show" }, speed, easing, function () { try { callback && callback.call(handler); } catch (e) { } });
};
jQuery.fn["fadeOutDown"] = function (offset, speed, easing, callback) {
	var handler = this;
	return this.animate({ "marginTop": "+=" + offset + "px", "opacity": "hide" }, speed, easing, function () { try { callback && callback.call(handler); } catch (e) { } });
};
jQuery.fn["fadeOutUp"] = function (offset, speed, easing, callback) {
	var handler = this;
	return this.animate({ "marginTop": "-=" + offset + "px", "opacity": "hide" }, speed, easing, function () { try { callback && callback.call(handler); } catch (e) { } });
};


jQuery.extend({
	lang: {
		modifiedSave: "内容已修改，是否需要保存？"
	},
	enableAjaxDebug: function () {
		/// <summary>启用AjaxDebug</summary>
		$(document).ajaxError(function (a, b, c, d) {
			var v = self;
			v.document.open();
			v.document.write(b.responseText);
			v.document.close();
		});
	},
	quickEdit: function (p, callback, datavalider, event, ctx) {
		/// <summary>启用即时编辑</summary>
		/// <param name="p" type="String">要启用即时编辑的选择器.这里使用live绑定,所以支持动态添加的控件</param>
		/// <param name="callback" type="function">完成编辑后回调函数,传递三个参数,分别是原来的值,新的值,引发编辑的控件</param>
		/// <param name="datavalider" type="function">如果需要对填写的数据验证,在此添加.返回false将会导致编辑被取消.传递三个参数,分别是原来的值,新的值,引发编辑的控件</param>
		/// <param name="event" type="String">要绑定的编辑事件,默认是click</param>
		/// <param name="ctx" type="object">选择器上下文环境</param>

		event = event || 'click';
		$(p, ctx).live(event, function () {
			var obj = $(this);
			if (obj.attr("inedit") == "1") return;
			//取消编辑
			var cancelCallback = function (o, s) {
				var editobj = $(o);
				var parent = editobj.parent();
				parent.text(s ? editobj.val() : parent.attr("lastValue"));
				parent.attr({ inedit: 0 });
			};
			var endCallback = function (o) {
				var editobj = $(o);
				var parent = editobj.parent();
				if (editobj.val() != parent.attr("lastValue") && (datavalider == null || datavalider(parent.attr("lastValue"), editobj.val(), parent))) {
					if (callback != null) callback(parent.attr("lastValue"), editobj.val(), parent);
					cancelCallback(o, true);
				} else
					cancelCallback(o, false);
			};
			var blurCallback = function (o) {
				var editobj = $(o);
				var parent = editobj.parent();
				if (parent.attr("lastValue") != editobj.val()) {
					if (confirm($.lang["modifiedSave"])) endCallback(o);
					else cancelCallback(o);
				} else
					cancelCallback(o);
			};
			//当前是否有其它活动编辑
			$("#quickedit").blur();
			//保存当前内容
			var currentText = $.trim(obj.text());
			obj.attr({ lastValue: currentText });
			//看看应该用啥模式
			var edithtml;
			var ml = obj.attr("multiline") == "1";
			if (ml) {
				edithtml = $("<textarea id='quickedit' class='FormBase' ></textarea>");
			} else {
				edithtml = $("<input type='text' id='quickedit' class='FormFocus' value='' />");
			}
			//插入编辑框
			edithtml.keydown(function (e) {
				e = e ? e : window.event;
				if (e.keyCode == 27) cancelCallback(this);
				else if (e.keyCode == 13 && (!ml || e.ctrlKey)) endCallback(this);
			}).blur(function () { blurCallback(this); }).val(currentText);
			obj.empty();
			edithtml.appendTo(obj);
			edithtml.select();
			obj.attr({ inedit: 1 });
		});
	},
	showTip: function (msg, icon) { $.showMessageDialog(msg, icon || "block"); },
	createLoadingDialog: function (msg) {
		/// <summary>创建一个对话框</summary>
		/// <param name="msg" type="String">要显示的信息</param>
		var msg = $("<div class='loadingDialog' autoCreate='1'>" + (msg || "") + "</div>");
		return msg.appendTo("body");
	},
	createMessageDialog: function (msg, icon, parent) {
		/// <summary>创建一个对话框</summary>
		/// <param name="msg" type="String">要显示的信息</param>
		/// <param name="icon" type="String">要显示图标的样式</param>
		var msg = $("<div class='loadingDialog loadicon_" + (icon || "tip") + "' autoCreate='1'>" + (msg || "") + "</div>");
		return msg.appendTo(parent || "body");
	},
	showMessageDialog: function (msg, icon, parent) {
		/// <summary>显示一个自动关闭的对话框</summary>
		/// <param name="msg" type="String">要显示的信息</param>
		/// <param name="icon" type="String">要显示图标的样式</param>
		return $.createMessageDialog(msg, icon, parent).showDialog({ timeOut: 1500, parent: parent });
	}
});
$.fn.extend({
	resetClass: function () {
		/// <summary>重置表单属性</summary>
		return this.removeClass("FormError").removeClass("FormFocus");
	},
	addError: function () {
		/// <summary>为表单输入控件添加错误样式</summary>
		return this.removeClass("FormFocus").addClass("FormError");
	},
	reorderAble: function (options) { return new reorder(this, options); },
	setClass: function () {
		/// <summary>启用对指定控件的表单样式</summary>
		this.addClass('FormBase').focus(function () { $(this).addClass("FormFocus"); }).blur(function () { $(this).resetClass(); });
	},
	validateForm: function () {
		/// <summary>验证表单必填项,并重置默认项</summary>
		var ctx = this;
		var ok = true;
		$("input[required=1],select[required=1]", ctx).each(function () {
			if (!ok) return;
			if ($(this).val() == '') {
				ok = false;
				$.showTip($(this).addError().attr("message"));
			}
		});
		$("input[defaultValue]", ctx).each(function () { var obj = $(this); if (obj.val() == '') obj.val(obj.attr('defaultValue')); });
		return ok;
	},
	getSelectedText: function () {
		/// <summary>获得选中项的文本</summary>
		var obj = this[0];
		return (obj.options[obj.selectedIndex].text);
	},
	getTrimedText: function () {
		/// <summary>获得经过清理的文字</summary>
		return $.trim(this.text());
	},
	getTrimedValue: function () {
		/// <summary>获得经过整理的值</summary>
		return $.trim(this.val());
	},
	showDialog: function (opts) {
		/// <summary>显示对话框。其中带有 close_button 样式的控件会自动作为关闭按钮</summary>
		var dlg = this;
		this.options = $.extend({ parent: null, bindControl: null, removeDialog: this.attr("autoCreate") == "1", onClose: null, animationMove: 20, speed: "fast", fx: "linear", show: "fadeInDown", hide: "fadeOutUp", onShow: null, timeOut: 0 }, opts);
		var top = "50%";
		var left = "50%";
		dlg.data({ parent: dlg.parent() });
		if (this.options.parent) {
			if (this.options.parent.css("position") == "static") this.options.parent.css({ position: "releative" });
			//var offset = this.options.parent.offset();
			this.appendTo(this.options.parent);
			top = (this.options.parent.height() / 2/* + offset.top*/) + "px";
			left = (this.options.parent.width() / 2/* + offset.left*/) + "px";
		}
		dlg.css({
			"position": this.options.parent ? "absolute" : "fixed",
			"left": left,
			"top": top,
			"margin-left": "-" + (dlg.width() / 2) + "px",
			"margin-top": "-" + (dlg.height() / 2 + 20) + "px",
			"z-index": "9999"
		});
		if($.browser.msie&&$.browser.version<=6)
		{
			dlg.css({
				position: "absolute",
				top: (($(window).height()/2)+(document.body.scrollTop||document.documentElement.scrollTop)-dlg.height()/2)+"px"
			});
		}
		this.open = function () {
			if (this.options.bindControl) this.options.bindControl.disable();
			$.fn[this.options.show].call(this, this.options.animationMove, this.options.speed, this.options.fx, this.options.onShow);
		}
		this.close = function () {
			(function () {
				$.fn[this.options.hide].call(this, this.options.animationMove, this.options.speed, this.options.fx, function () {
					if (this.options.onClose) this.options.onClose();
					if (this.options.bindControl) this.options.bindControl.enable();
					if (this.options.removeDialog) this.remove();
					else {
						if (this.data["parent"]) this.appendTo(this.data["parent"]);
					}
				});
			}).call(dlg);
		}
		this.autoClose = function (timeout) {
			/// <summary>设置当前对话框在指定时间后自动关闭</summary>
			setTimeout(this.close, timeout || 1500);
		}
		$('.close_button').unbind("click").click(this.close);
		//auto close?
		if (this.options.timeOut > 0) {
			var handler = this.options.onShow;
			this.options.onShow = function () { this.autoClose(); if (handler != null) handler.call(this); }
		}
		//show it
		this.open.call(dlg);

		return this;
	},
	applyTip: function () {
		this.showTip = function () {
			var obj = $(this);
			var offset = obj.offset();
			var tipDiv = $("<div class=\"fishTipDiv\"></div>").appendTo("body");
			obj.data("tip", tipDiv);
			tipDiv.html(obj.attr("fishtip")).css({ left: (offset.left + 10) + "px", top: (offset.top + obj.height() + 10) + "px" }).fadeIn("fast");
		};
		this.closeTip = function () {
			var obj = $(this).data("tip");
			obj.fadeOut("fast", function () { obj.remove(); });
		};

		var tip = this;
		this.each(function () {
			with ($(this)) {
				attr({ "fishtip": attr("title"), title: "" }).hover(tip.showTip, tip.closeTip)
			};
		});

		return this;
	},
	enable: function () {
		this.attr({ disabled: false })
		var href = this.attr("hreforg");
		if (href && href != '') this.attr({ href: href });
		return this;
	},
	disable: function () {
		this.attr({ disabled: true })
		var href = this.attr("href");
		if (href && href != '') this.attr({ hreforg: href, href: "" });
		return this;
	},
	serializeForm: function () {
		/// <summary>序列化表单为对象</summary>
		var v = {};
		var o = this.serializeArray();
		for (var i in o) {
			if (typeof (v[o[i].name]) == 'undefined') v[o[i].name] = o[i].value;
			else v[o[i].name] += "," + o[i].value;
		}
		return v;
	},
	createMessageDialog: function (msg, icon) {
		/// <summary>创建一个对话框</summary>
		/// <param name="msg" type="String">要显示的信息</param>
		/// <param name="icon" type="String">要显示图标的样式</param>
		return $.createMessageDialog(msg, icon, this);
	},
	changeLoadingIcon: function (icon) {
		/// <summary>更改加载对话框的图标</summary>
		this.removeClass().addClass("loadingDialog loadicon_" + (icon || "tip"));
	},
	autoCloseDialog: function (timeout) {
		/// <summary>设置当前对话框在指定时间后自动关闭</summary>
		setTimeout(this.close, timeout || 2000);
	}

});

/*

$("selector").reorderAble({headerItemCount:前面不允许调整的行数目,footerItemCount: 后面不允许调整的行数目, moveCallback: 函数回调});

函数回调原型:  moveCallback(options, applyCall)
options 包含:
tr			调整的行
rawIndex	调整的行原始索引
realIndex	调整的行真实索引
isUp		是否是向上移动
orderManager:	本类对象

如果有函数回调,需要最终调用 applyCall 来确认允许调整
applyCall 原型: applyCall(options)
options 包括:
succ		是否成功(1/0)
message		提示信息
*/
var reorder = function (parent, options) {
	var self = this;
	this.defaults = { headerItemCount: 2, footerItemCount: 0, moveCallback: null };
	this.options = $.extend(this.defaults, options); //组合选项
	//确认某项上移和下移可用
	this.ensureOrderAble = function (obj) {
		var count = $("tr", parent).length;
		var idx = obj.prevAll().length; //fix for juery-1.3.2, .index() only works with 1.4.2
		if (idx == self.options.headerItemCount) $(".moveup", obj).hide();
		else $(".moveup", obj).show();
		if (idx == count - self.options.footerItemCount - 1) $(".movedown", obj).hide();
		else $(".movedown", obj).show();
	}
	this.initList = function () {
		var list = $("tr", parent);
		var count = list.length;
		var startIndex = self.options.headerItemCount;
		var endIndex = count - self.options.footerItemCount - 1;

		if (startIndex <= endIndex) $(".moveup", list.eq(startIndex)).hide();
		if (endIndex >= startIndex) $(".movedown", list.eq(endIndex)).hide();
	}
	this.install = function () {
		$(".moveup", parent).live("click", this.moveupCall);
		$(".movedown", parent).live("click", this.moveDownCall);
		this.initList();
	}
	this.getCurrent = function (obj) {
		var _tr = $(obj).closest("tr");
		var _rawIndex = _tr.prevAll().length; //fix for juery-1.3.2, .index() works only with 1.4.2
		var _realIndex = _rawIndex - options.headerItemCount;

		return { tr: _tr, rawIndex: _rawIndex, realIndex: _realIndex };
	}
	this.moveupCall = function () {
		var c = $.extend(self.getCurrent(this), { isUp: true, orderManager: self });
		self.isup = true;
		self.movingTr = c.tr;
		//showBlock("上移中...", parent.attr("id"));
		parent.block({ message: "上移中..." });

		if (options.moveCallback == null) self.applyMoveCall({ success: 1, message: "操作成功" });
		else options.moveCallback(c, self.applyMoveCall);
	}
	this.moveDownCall = function () {
		var c = $.extend(self.getCurrent(this), { isUp: false });
		self.isup = false;
		self.movingTr = c.tr;
		//showBlock("下移中...", parent.attr("id"));
		parent.block({ message: "下移中..." });

		if (options.moveCallback == null) self.applyMoveCall({ success: 1, message: "操作成功" });
		else options.moveCallback(c, self.applyMoveCall);
	}
	this.isup = false;
	this.movingTr = null;
	this.applyMoveCall = function (d) {
		parent.unblock({ fadeOut: 0 });
		if (d.message) $.showMessageDialog(d.message, d.succ ? "ok" : "block", parent);
		if (d.succ) {
			if (self.isup) {
				var prev = self.movingTr.prev();
				self.movingTr.remove();
				prev.before(self.movingTr);

				self.ensureOrderAble(prev);
				self.ensureOrderAble(self.movingTr);

				self.movingTr = null;
			} else {
				var next = self.movingTr.next();
				self.movingTr.remove();
				next.after(self.movingTr);

				self.ensureOrderAble(self.movingTr);
				self.ensureOrderAble(next);

				self.movingTr = null;
			}
		}
	}

	this.install();

	return this;
};


//检测是否是图片文件
function isImageFile(f) {
	/// <summary>检验一个选定文件路径是否是图片文件</summary>
	/// <param name="f" type="String">选定的文件路径</param>

	var ext = f.substring(f.lastIndexOf("."), f.length).toLowerCase();
	return ext == ".bmp" || ext == ".png" || ext == ".jpg" || ext == ".gif";
}

function isEmpty(obj, name, msg) {
	/// <summary>检测对应的选项是否填写</summary>
	/// <param name="obj" type="object">数据容器对象</param>
	/// <param name="name" type="String">数据项名称</param>
	/// <param name="msg" type="String">如果没有填写,显示的提示信息</param>


	if (!obj[name]) {
		with ($("#" + name).addError()) {
			if (length > 0) get(0).focus();
		}

		if (msg) $.showTip(msg);
		return true;
	}
	return false;
}

function checkNumber(v, min, max) {
	/// <summary>检测数字是否在指定的范围区间中</summary>
	/// <param name="v" type="object">要检测的值</param>
	/// <param name="min" type="object">允许的最小值,不传递或为null则不限制</param>
	/// <param name="max" type="object">允许的最大值,不传递或为null则不限制</param>

	v = parseFloat(v);
	return !isNaN(v) && (min == null || v >= min) && (max == null || v <= max);
}

function convertNumberToString(num, digits) {
	/// <summary>转换数字为字符串</summary>
	/// <param name="num" type="int">要转换的数字</param>
	/// <param name="digits" type="int">数字的位数</param>

	num = '' + num;
	var ab = [];
	for (var i = 0; i < digits - num.length; i++) {
		ab.push("0");
	}

	return ab.join("") + num;
}

function convertDecimalToString(num, floatDigits) {
	/// <summary>转换浮点数为字符串</summary>
	/// <param name="num" type="float">要转换的数字</param>
	/// <param name="floatDigits" type="int">小数位数</param>

	num = '' + num;
	var fc = floatDigits;
	var idx = num.indexOf(".");
	if (idx != -1) fc = floatDigits - num.length - idx - 1;
	else num += ".";

	var ab = [];
	for (var i = 0; i < fc; i++) {
		ab.push("0");
	}

	return num + ab.join("");
}

function copyToClipboard(text) {
	/// <summary>复制到剪贴板</summary>

	return window.clipboardData.setData('text', text);
}


function addToFavorite(title, text) {
	/// <summary>添加到收藏夹</summary>

	window.external.addFavorite(text, title);
}

function isEmail(str) {
	/// <summary>测试一个字符串是否是电子邮件地址</summary>
	/// <param name="str" type="String">要测试的字符串</param>

	return /^\w+[\.\-_0-9a-z]+@[0-9a-z]+([\-_\.][0-9a-z]+)*\.(com|net|org|edu|cn)$/i.test(str);
}

function F(id) {
	/// <summary>获得指定ID的值</summary>
	return $("#" + id).val();
}

