// JavaScript Document
(function($){
	$.extend({
		isString    : function(value){
			return !$.isNull(value) && value.constructor == String;
		},
		isArray     : function(value){
			return !$.isNull(value) && value.constructor == Array;
		},
		isBoolean   : function(value){
			return !$.isNull(value) && value.constructor == Boolean;
		},
		isNumber   : function(value){
			return !$.isNull(value) && value.constructor == Number;
		},
		isFunction  : function(value){
			return !$.isNull(value) && value.constructor == Function;
		},
		toFunction  : function(fun){
			try{
				return eval(fun);
			}catch(e){
				return null;
			}
		},
		isJSON      : function(value){
			return $.isObject(value) && typeof value.valueOf == 'function';
		},
		isObject    : function(value){
			return !$.isNull(value) && value.constructor == Object;
		},
		isNull      : function(value){
			return value == null
		},
		isEmpty     : function(value){
			var _value = String(value);
			return _value == 'null' || _value == 'undefined' || _value == '' || _value == 'NaN' || _value == 'unknown';
		}
	});
	$.JSON = {
		specialChar : {
			'\b': '\\b',
			'\t': '\\t',
			'\n': '\\n',
			'\f': '\\f',
			'\r': '\\r',
			'\\': '\\\\'
		},
		encodeString : function(s){
			if (/["\\\x00-\x1f]/.test(s)) {
				return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
					var c = this.specialChar[b];
					if(c){
						return c;
					}
					c = b.charCodeAt();
					return "\\u00" + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
				}) + '"';
			}
			return '"' + s + '"';
		},
		encode : function(value){
			var _ret = [];
			switch(typeof value){
				case 'date'     :return '\"'+(value)+'\"';break;
				case 'number'   :return value;break;
				case 'string'   :return $.JSON.encodeString(value);break;
				case 'boolean'  :return value;break;
				case 'function' :return value;break;
				case 'object'   :
					if($.isArray(value)){
						$.each(value,function(i,n){
							_ret.push($.JSON.encode(n));
						});
						return '['+_ret.join(',')+']';
					}else{
						$.each(value,function(i,n){
							_ret.push('\"'+i+'\":'+$.JSON.encode(n));
						});
						return '{'+_ret.join(',')+'}';
					}
				break;
				default : return '\"'+value+'\"';
			}
		},
		decode : function(value){
			return eval("(" + value + ')');
		},
		remove : function(value,name){
			var _re1 = new RegExp('{(?:.*?)(?:"name"\:([^,}]+))(?:.*?)\}',"ig");
			var _re2 = new RegExp(","+name+",","ig");
			do{
				var _ret = $.JSON.decode($.JSON.encode(value).replace(_re1,"$1"));
				var idx  = (","+_ret.toString()+",").replace(_re2,"|").replace(/[^,|]/g,"").indexOf("|");
				if(idx>-1) value.splice(idx,1);
			}while(idx>-1)
			return (value);
		}
	}
	$.fn.Ajax = function(options){
		var setting = $.extend({
			ajax   : 'ajax',
			url    : '../ajax/ajax.asp',
			refurbish  : function(data){
				if(!data.success) alert(data.msg);else location.reload();
			},
			validate:function(data){
				var _form = this.find('[@remote="true"]');
				if(!data.success){
					$.each(data.errors,function(i,n){
						var _obj = _form[i];
						if(!_obj.msg) _obj.msg=$('<span></span>').insertAfter(_obj);
						_obj.msg.removeClass(n.success?'wrong':'right');
						_obj.msg.addClass(n.success?'right':'wrong').attr('title',n.msg).html('&nbsp;');
						_obj.msg.html(n.msg);
					});
				}else{location.replace(_options.to);}
			}
		},options);
		function doAjax(options){
			$.ajax($.extend({
				dataType : 'json',
				url      : setting.url,
				type     : 'post',
				data     : {action:'list'},
				success  : function(data){
					setting.refurbish.apply(this,arguments);
				},
				error    : function(XMLHttpRequest,textStatus,errorThrown){//请求出错处理
					alert("Error");
				}
			},options));
		};
		function doAjaxSubmit(options){
			doAjax($.extend({
				success : function(){
					setting.refurbish.apply(this,arguments);
				}
			},options));
		};
		$.serializeArray = function(query){
			try{
				var data = query.match(/[^&?]+=[^&]+/g).toString().replace(/([^,]+)=([^,]+)/g,'{name:"$1",value:"$2"}');
				return eval('['+data+']');
			}catch(e){
				return [];
			}
		};
		this.filter('form[@'+setting.ajax+'][@bind!="true"]').attr('bind','true').submit(function(){
			var _obj = $(this);
			if(Validator.Validate(this,2)){
				var data = _obj.serializeArray();
				$.JSON.remove(data,'action');
				data.push({name:"action",value:_obj.attr(setting.ajax)});
				var fun = $.toFunction(_obj.attr('callback'));
				if($.isFunction(fun))
					var fn = {success:function(){fun.apply(_obj,arguments);}};
				else if(_obj.attr('validate')=="true")
					var fn = {success:function(data){setting.validate.apply(_obj,arguments);}};
				else
					var fn = null
				//alert($.JSON.encode(data))
				doAjaxSubmit($.extend({data:data},fn));
			}
			return false;
		});
		this.filter('input:text[@'+setting.ajax+'][@bind!="true"][@event]').attr('bind','true').each(function(){
			var _tmp = $(this);
			_tmp.bind(_tmp.attr('event'),function(){
				var _obj = $(this);
				var data = [];
				if(!$.isEmpty(this.form)) data = data.concat($(this.form).serializeArray());
				var _temp = _obj.attr("data");
				if(!$.isEmpty(_temp)) data = data.concat($.serializeArray(_temp));
				data.push({name:"value",value:_obj.val()});
				$.JSON.remove(data,'action');
				data.push({name:"action",value:_obj.attr(setting.ajax)});
				var fun = $.toFunction(_obj.attr('callback'))
				if($.isFunction(fun))
					var fn = {success:function(){fun.apply(_obj,arguments)}};
				else
					var fn = {success:function(){}};
				//alert($.JSON.encode(data))
				doAjax($.extend({data:data},fn));
				return false;
			});
		});
		this.filter('input:not(:text)[@'+setting.ajax+'][@bind!="true"]').attr('bind','true').click(function(){
			var _obj = $(this);
			var data = [];
			if(!$.isEmpty(this.form)) data = data.concat($(this.form).serializeArray());
			var _temp = _obj.attr("data");
			if(!$.isEmpty(_temp)) data = data.concat($.serializeArray(_temp));
			$.JSON.remove(data,'action');
			data.push({name:"action",value:_obj.attr(setting.ajax)});
			var fun = $.toFunction(_obj.attr('callback'))
			if($.isFunction(fun))
				var fn = {success:function(){fun.apply(_obj,arguments)}};
			else
				var fn = null;
			//alert($.JSON.encode(data))
			doAjax($.extend({data:data},fn));
			return false;
		});
		this.filter('a[@'+setting.ajax+'][@bind!="true"]').attr('bind','true').click(function(){
			var _obj = $(this);
			var data = [];
			var _temp = _obj.attr("href");
			if(!$.isEmpty(_temp)) data = data.concat($.serializeArray(_temp));
			var _temp = _obj.attr("data");
			if(!$.isEmpty(_temp)) data = data.concat($.serializeArray(_temp));
			$.JSON.remove(data,'action');
			data.push({name:"action",value:_obj.attr(setting.ajax)});
			var fun = $.toFunction(_obj.attr('callback'))
			if($.isFunction(fun))
				var fn = {success:function(){fun.apply(_obj,arguments)}};
			else
				var fn = null;
			//alert($.JSON.encode(data))
			doAjax($.extend({data:data},fn));
			return false;
		});
		this.filter('[@'+setting.ajax+'][@bind!="true"][@load="true"]').attr('bind','true').each(function(i,n){
			var _obj  = $(this);
			var _time = _obj.attr("time")=='true';
			if(_time) delay = _obj.attr("delay")||1;
			var data = [];
			var _temp = _obj.attr("data");
			if(!$.isEmpty(_temp)) data = data.concat($.serializeArray(_temp));
			$.JSON.remove(data,'action');
			data.push({name:"action",value:_obj.attr(setting.ajax)});
			var fun = $.toFunction(_obj.attr('callback'))
			if($.isFunction(fun))
				var fn = {success:function(){fun.apply(_obj,arguments)}};
			else
				var fn = null
			this.stop = function(){_time=false};
			args = $.extend({data:data},fn);
			function code(){
				doAjax(args);
				if(_time) window.setTimeout(code,delay);
			}
			code();
			return false;
		});
	}
})(jQuery);
jQuery(function(){
	jQuery('[@ajax]').Ajax();
});