function is_empty($value){
	return ($value ? false : true) || String($value) == 'undefined' || String($value) == 'NaN' || String($value) == 'unknown';
}
function is_string($value) {
	return !is_empty($value) && $value.constructor.toString().indexOf('String')>-1;
}
function is_number($value) {
	return !is_empty($value) && !isNaN($value) && isFinite($value) && $value.constructor.toString().indexOf('Number')>-1;
}
function is_boolean($value) {
	return ($value == true || $value == false) && $value.constructor.toString().indexOf('Boolean')>-1;
}
function is_array($value) {
	return !is_empty($value) && $value.constructor.toString().indexOf('Array')>-1;
}
function is_date($value) {
	if(is_string($value)){
		$value	= new Date($value.replace(/-/ig,'/'));
	}
	return !is_empty($value) && $value.constructor.toString().indexOf('Date')>-1;
}
function is_function($value) {
	return !is_empty($value) && $value.constructor.toString().indexOf('Function')>-1;
}
function is_object($value) {
	return !is_empty($value) && $value.constructor.toString().indexOf('Object')>-1;
}
function is_regexp($value) {
	return !is_empty($value) && $value.constructor.toString().indexOf('RegExp')>-1;
}
function serialize($value){
	$value				= serializeArray($value);
	return map($value,function(i,n){
		return n.name+'='+(is_array(n.value)?n.value.join('-'):n.value);
	}).join('&').replace(/%20/g,'+');
}
function serializeArray($value){
	if(is_array($value)) return $value;
	$value				= is_string($value)?unserialize($value):$value;
	var retsult			= [];
	for(var name in $value) {
		retsult.push({"name":name,"value":$value[name]});
	}
	return retsult;
}
function unserialize($value){
	var retsult			= {};
	$value				= $value.replace(/[^?]+\.php\/\w+\/\w+\//,'');
	var re				= /([^\/]+)\/([^\/]+)/g;
	//var re				= /([^&?]+)=([^&]+)/g;
	$value.replace(re,function(m,name,value){
		value			= /\-/.test(value)?value.split('-'):decodeURIComponent(value);
		retsult[name]	= is_empty(retsult[name])?value:is_array(retsult[name])?retsult[name].concat(value):[retsult[name]].concat(value);
	});
	return retsult;
}
function type($value){
	return is_empty($value)?'null':Object.prototype.toString.call($value).replace(/^\[\w+\W(\w+)\]$/,'$1').toLowerCase();
}
function map($value,$iterator){
	$iterator 			= $iterator || new Function("i","value","return value");
	var len 			= $value.length>>>0;
	var result			= Array(len);
	for(var i=0;i<len;i++){
		result[i]		= $iterator.apply($value,[i,$value[i],len]);
	}
	return result;
}
var JSON					= new (function(){
	var specialChar  		= {
		"\b": '\\b',
		"\t": '\\t',
		"\n": '\\n',
		"\f": '\\f',
		"\r": '\\r',
		'"' : '\\"',
		"\\": '\\\\'
	}
	var encodeString		= function(s){
		if (/["\\\x00-\x1f]/.test(s)) {
			return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
				var c = specialChar[b];
				if(c){
					return c;
				}
				c = b.charCodeAt();
				return "\\u00" + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
			}) + '"';
		}
		return '"' + s + '"';
	}
	this.encode				= function($value){
		switch(type($value)){
			case 'string'  	: return encodeString($value);
			case 'number'  	: return $value;
			case 'array'	:
				var ret		= [];
				var len 	= $value.length>>>0;
				for(var i=0;i<len;i++){
					ret.push(this.encode($value[i]));
				}
				return '['+ret.join(',')+']';
			case 'object':
				var ret = [];
				for(var o in $value) {
					ret.push('\"'+o+'\":'+this.encode($value[o]));
				}
				return '{'+ret.join(',')+'}';
		}
	}
	this.decode		= function($value){
		return eval("(" + $value + ')');
	}
});
(function($){
function num(px) {
	return parseInt(px,10)||0;
}
$.each([ "Height", "Width" ], function(i, name){
	var tl = i ? "Left"  : "Top",  // top or left
		br = i ? "Right" : "Bottom"; // bottom or right
	$.fn["px" + name] = function(){
		return num(this.css("padding" + tl))+num(this.css("padding" + br))+num(this.css("border" + tl + "Width"))+num(this.css("border" + br + "Width"));
	};	
});
$.fn.unselectable = function(){
	this.attr('unselectable','on');
	this.bind('selectstart',function(){return false});
	this.bind('select',function(){document.selection.empty();});
	this.bind('copy',function(){document.selection.empty();});
	this.bind('beforecopy',function(){return false});
	//this.bind('dragstart',function(){return false});
	this.css({'-moz-user-select':'none','-khtml-user-select':'none'});
	this.addClass("unselectable");
	return this;
}
String.prototype.format = function($value){
	if(typeof $value != 'object'){
		var args = Array.prototype.slice.call(arguments,0);
		return this.replace(/\{(\d+)\}/g,function(m,i){
			return args[i];
		});
	}else{
		return this.replace(/\{(\w+)\}/g,function(m,i){
			return $value[i];
		});
	}
}; 
var Dialogs					= new (function(){
	this.count				= 0;
	var dialogs				= {};
	var zIndex				= {};
	this.register			= function($key,$value,$index){
		dialogs[$key]		= $value;
		zIndex[$key]		= $index;
		this.count++;
		return this;
	}
	this.isRegistered		= function($key){
		return dialogs[$key]!=null;
	}
	this.registry			= function($key){
		return dialogs[$key];
	}
	this.zIndex				= function($key){
		$.each(dialogs,function(i,n){
			n.zIndex(zIndex[i]);
		});
		dialogs[$key].zIndex(zIndex[$key]+this.count+2);
	}
});
var Dialog					= function(options){
	var setting				= $.extend({
		'class'				: '',
		'title'				: '',
		'icon'				: 'plaint',
		'width'				: 'auto',
		'height'			: 'auto',
		'opacity'			: 0.4,
		'index'				: 2000000,
		'overlay'			: true,
		'drag'				: false,
		'animate'			: false,
		'action'			: false,
		'defaultbuttons'	: 'confirm&cannel',	
		'control'			: 'close',
		'confirm'			: null,
		'cannel'			: null,
		'before'			: null,
		'show'				: null,
		'complete'			: null,
		'success'			: null,
		'readerTo'			: 'body'
	},options);
	this.id					= new Date().getTime().toString(36);
	var screen 				= {
		width				: document.documentElement.clientWidth || document.body.clientWidth,
		height				: document.documentElement.clientHeight || document.body.clientHeight
	};
	var __this				= this;
	var __overlay			= null;
	var __dlg				= null;
	var __header			= null;
	var __content			= null;
	var __footer			= null;
	var __buttons			= {};
	var __loading			= null;
	var __url				= '';
	var __params			= {};
	
	var zIndex				= setting['index'];
	this.create				= function(){
		/* 创建遮罩 */
		if(setting['overlay']) this.createOverlay();
		/* 创建窗口 */
		this.createDialog();		// 创建窗口层
		this.createHeader();    	// 创建标题区
		this.createContent();   	// 创建内容区
		this.createFooter();  		// 创建控制区
		
		/* 创建默认按钮 */
		this.buttonAddDefault();
		
		/* 安装窗口拖动 */
		//if(setting['drag']) this.drag();
		this.drag();
		this.hide();
		
		if($.isFunction(setting['before'])) setting['before'].apply(__this,[__content,__footer]);
		/* 注册窗口到Dialogs集合 */
		zIndex	+= Dialogs.count+2
		Dialogs.register(this.id,this,zIndex);
		this.index			= Dialogs.count;
		this.zIndex(zIndex);
		
		__dlg.mousedown(function(){
			Dialogs.zIndex(__this.id);
		});
//		__dlg.bind('keypress',function(e){alert(e.keyCode)});
//		__dlg.blur(function(e){
//			//alert(e.target.tagName);
//			//if(!$(e.target).is('dl,dt,dd')||e.which==3) return false;
//			__dlg.focus();
//		});
		return this;
	}
	this.zIndex				= function($index){
		__dlg.css('z-index',$index);
		if(setting['overlay']) __overlay.css('z-index',$index-1);
	}
	this.createOverlay		= function(){
		__overlay			= $('<div class="dialog-overlay"></div>').css(screen).css({
			opacity			: setting['opacity'],
			zIndex			: zIndex+Dialogs.count+1
		}).appendTo(setting['readerTo']);
		__overlay.bind('contextmenu',function(){
			return false;
		});
	}
	this.createDialog		= function(){
		__dlg				= $('<div class="dialog"></div>').appendTo(setting['readerTo']);
		if(setting['class']) __dlg.addClass(setting['class']);
	}
	this.createHeader		= function(){
		__header			= $('<div class="dialog-header"><dl><dt></dt></dl></div>').appendTo(__dlg).find('dt');
		__header.bind('contextmenu',function(){
			return false;
		}).unselectable();
		this.title(setting['title'],setting['icon']);
		var operation		= {
			'close'			: function(){
				__this.hide();
			}
		};
		var __control		= $('<dd class="dialog-header-control"></dd>').appendTo(__header);
		$.each(setting['control'].split('&'),function(i,n){
			$('<button type="button" class="'+n+'" ></button>').bind('click',operation[n]||function(){}).appendTo(__control);
		})		
		__header.find('button').hover(function(){$(this).addClass('hover');},function(){$(this).removeClass('hover');});
	}
	this.title				= function($title,$icon){
		$icon 				= typeof($icon) == 'string' ? ('<dd class="icon '+ $icon +'"></dd>') : '';
		__header.html($icon+'<dd class="dialog-header-title">'+ $title +'</dd>');
	}
	this.createContent		= function(){
		__content			= $('<div class="dialog-content"></div>').appendTo(__dlg);
		this.width(setting['width']);
		this.height(setting['height']);
		__content.bind('contextmenu',function(){
			return true;
		});
		if(setting['action']){
			var __form		= $('<form method="post" action=""></form>').appendTo(__content);
			__form.submit(function(){
				return false;
			});
			__content		= __form;
		}
	}
	this.createFooter		= function(){
		__footer			= $('<div class="dialog-footer"><div class="dialog-buttons"></div></div>').appendTo(__dlg).find('.dialog-buttons');
		__footer.bind('contextmenu',function(){
			return false;
		}).unselectable();
	}
	this.createButton		= function(n){
		if(__buttons[n.id]) return ;
		var _button			= $('<button type="button">'+n.value+'</button>').hover(function(){
			$(this).addClass('hover');
		},function(){
			$(this).removeClass('hover');
		}).bind('click',function(){
			if($.isFunction(n.fn)) n.fn.call(__this);
		}).appendTo(__footer);
		if(n.id) _button.attr('id',n.id);
		__buttons[n.id]		= _button;
	}
	this.AddButton			= function(config){
		/* 创建按钮 */
		this.createButton({'id':config.id,'value':config.value,'fn':config.fn});
	}
	this.buttonAddDefault	= function(indexs){
		var btns			= (indexs||setting['defaultbuttons']).split('&');
		for(var i=0,j=btns.length; i < j; i++){
			if(btns[i] == 'refresh')	this.AddButton({'id':'refresh','value':'刷新','fn':this.refresh});
			if(btns[i] == 'confirm')	this.AddButton({'id':'confirm','value':'Confirm','fn':this.confirm});
			if(btns[i] == 'cannel')		this.AddButton({'id':'cannel','value':'Cannel','fn':this.cannel});
			if(btns[i] == 'close')		this.AddButton({'id':'close','value':'关闭','fn':this.cannel});
			if(btns[i] == 'submit')		this.AddButton({'id':'submit','value':'提交','fn':this.submit});
			if(btns[i] == 'reset')		this.AddButton({'id':'reset','value':'重置','fn':this.reset});
		}
	}
	this.buttonActive		= function(id,keypress){
		/* 键盘按下时处理函数 */
		__dlg.bind('keypress',function(e){alert(e.keyCode)});
		if(__buttons[id]&&typeof(keypress) == 'function' ){
			__dlg.bind('keypress',function(e){alert(e.keyCode)});
//			__dlg.bind('keypress',function(e){return keypress.apply(__this,[e])});
		}
	}
	this.on					= function($id,$fn){
		__buttons[$id].unbind('click').bind('click',function(){
			if($.isFunction($fn)) $fn.call(__this);
		});
	}
	this.createLoading		= function(){
		if(!__loading){
			__loading		= $('<dl class="dialog-loading"><dt></dt><dd></dd></dl>').appendTo(__dlg)
			__loading.find('dt').css({
				opacity			: setting['opacity'],
				backgroundColor	: '#000'
			});
		}	
		if(__dlg.css('position')!='fixed'){
			var dialog		= {
				width		: __dlg.outerWidth(),
				height		: __dlg.outerHeight()
			};
			__loading.css(dialog).find('dt,dd').css(dialog);
		}
		__loading.show();
	}
	
	this.html				= function(html){
		__content.html(html);
		if($.isFunction(setting.complete)) setting.complete.apply(__this,[__content]);
		__this.moved();
	}
	this.load				= function($url,$params){
		this.createLoading();
		__url				= $url;
		__params			= $params;
		$.ajaxSetup({
			global			: false,
			cache 			: false
		});
//		$.post($url,$params,function(o){
//			__content.html(o);
//			__this.moved();
//			__loading.hide();
//			var label			= __content.find('>dl>dt');
//			if(label.size()>1){
//				var ret			= [];
//				label.each(function(i,n){
//					ret.push($(this).width());
//				});
//				var w			= Math.max.apply(Math,ret);
//				label.width(w);
//			}
//		});
		__content.load($url,$params,function(o){
			__this.moved();
			__loading.hide();
			var label			= __content.find('>dl>dt');
			if(label.size()>1){
				var ret			= [];
				label.each(function(i,n){
					ret.push($(this).width());
				});
				var w			= Math.max.apply(Math,ret);
				label.width(w);
			}
			if($.isFunction(setting.complete)) setting.complete.apply(__this,[__content]);
		});
	}
	this.reload				= function(){
		this.load(__url,__params);
	}
	this.refresh			= function(){
		this.createLoading();
		this.load(__url,__params);
	}
	this.submit				= function(){
		this.createLoading();
		$.ajax({
			cache 			: false,
			url				: setting['action'],
			dataType 		: 'json',
			type			: 'post',
			data 			: __content.serializeArray(),
			success			: function(o){
				if($.isFunction(setting['success'])) setting['success'].call(__this,o);
			},
			complete		: function(){
				__loading.hide();
			}
		});
	}
	this.reset				= function(){
		__content[0].reset();
	}
	this.confirm			= function(){
		if($.isFunction(setting['confirm'])) setting['confirm'].apply(__this,[__content]);
	}
	this.cannel				= function(){
		this.hide();
		if($.isFunction(setting['cannel'])) setting['cannel'].apply(__this,[__content]);
	}
	this.width				= function(width){
		if(typeof(width)=='number') width += parseInt(__content.css("borderLeftWidth"))+parseInt(__content.css("borderRightWidth"));
		__dlg.css({width:width});
	}
	this.height				= function(height){
		if(typeof(height)=='number') height -= __content.pxHeight();
		__content.css({height:height});
	}
	this.moved				= function(x,y){
		var dialog			= {
			width			: __dlg.outerWidth(),
			height			: __dlg.outerHeight()
		};
		var point			= {
			top				: screen.height/2-dialog.height/2,
			left			: screen.width/2-dialog.width/2
		};
		__dlg.css(point);
		if(__dlg.css('position')!='fixed'){
			__dlg.css('top',point.top+$(window).scrollTop());
			__dlg[0].style.setExpression('top','eval(document.documentElement.scrollTop + '+point.top+')');
		}
	}
	this.drag				= function(){
		__header.bind("mousedown.draggable",{handle:__header,target:__dlg},function(e){
			if(!$(e.target).is('dl,dt,dd')||e.which==3) return false;
			//var pos 		= e.data.target.position();
			var pos 		= e.data.target.offset();
			var data 		= {
				x			: e.pageX - pos.left,
				y			: e.pageY - pos.top,
				move		: e.data.target.css('position')!='fixed'?'page':'client',
				target		: e.data.target,
				dragProxy	: e.data.target
			};
			var dialog		= {
				width		: e.data.target.outerWidth(),
				height		: e.data.target.outerHeight()
			};
			data['dragProxy']	= $('<div class="dialog-drag-mask"></div>').bind("selectstart",function(){return false;}).focus().css({
				width		: dialog.width-2,
				height		: dialog.height-2,
				opacity		: 0.4,
				zIndex		: zIndex+Dialogs.count+2,
				left		: e[data.move+'X'] - data.x,
				top			: e[data.move+'Y'] - data.y
			}).appendTo('body');
			data['minX']	= 0;
			data['minY']	= 0;
			data['maxX']	= $(window).width()  - dialog.width;
			data['maxY']	= $(window).height() - dialog.height;
			if(data.target.css('position')!='fixed'){
				data['minX']	= $(window).scrollLeft();
				data['minY']	= $(window).scrollTop();
				data['maxX']	= data['minX'] + screen.width   - dialog.width  - 1;
				data['maxY']	= data['minY'] + screen.height  - dialog.height;
			}else{
				data['minX']	= 0;
				data['minY']	= 0;
				data['maxX']	= screen.width   - dialog.width;
				data['maxY']	= screen.height  - dialog.height;
			}		
			
			$(document).bind("mousedown.draggable",data,function(e){
				//e.data.target.find('dialog-content');
			});
			$(document).bind("mousemove.draggable",data,function(e){
				var data 				= e.data;
				var x 					= e[data.move+'X'] - data.x;
				var y 					= e[data.move+'Y'] - data.y;
				
				if(data.minX||data.maxX)x = Math.min(Math.max(data.minX,x),data.maxX);
				if(data.minY||data.maxY)y = Math.min(Math.max(data.minY,y),data.maxY);
				
				var pos 				= {};
				switch(setting.axis){
					case 'x':pos.left 	= x;break;
					case 'y':pos.top	= y;break;
					default :pos		= {left:x,top:y};
				}
				e.data.dragProxy.css(pos);
			});
			$(document).bind("mouseup.draggable",data,function(e){
				var data 				= e.data;
				var x 					= e[data.move+'X'] - data.x;
				var y 					= e[data.move+'Y'] - data.y;
				
				if(data.minX||data.maxX)x = Math.min(Math.max(data.minX,x),data.maxX);
				if(data.minY||data.maxY)y = Math.min(Math.max(data.minY,y),data.maxY);
				
				var pos 				= {left:x,top:y};			
				if(setting['animate'])
					e.data.target.animate(pos);
				else
					e.data.target.css(pos);				
				if(e.data.target!==e.data.dragProxy) e.data.dragProxy.remove();
				if(e.data.target.css('position')!='fixed'){
					e.data.target[0].style.setExpression('top','eval(document.documentElement.scrollTop + '+(y-data.minY)+')');
				}
				$(document).unbind(".draggable");
			});
		});
	}
	this.show				= function(){
		this.moved();
		__dlg.show();
		if(setting['overlay']) __overlay.show();
		Dialogs.zIndex(__this.id);
		if($.isFunction(setting['show'])) setting['show'].apply(__this,[__content,__footer]);
		if(__buttons['confirm']) __buttons['confirm'].focus();
	}
	this.hide				= function(){
		__dlg.hide();
		if(setting['overlay']) __overlay.hide();
	}
}
Dialog.create 				= function(options,id){
	var setting				= $.extend({
		'id'				: null,
		'title'				: '',
		'width'				: 400,
		'height	'			: 'auto',
		'overlay'			: true,
		'drag'				: true,
		'animate'			: false,
		'action'			: false,
		'defaultbuttons'	: 'refresh&confirm&cannel',
		'before'			: null,
		'after'				: null,
		'confirm'			: null,
		'cannel'			: null,
		'complete'			: null
	},options);
	if(Dialogs.isRegistered(id||setting['id'])){
		var __dlg			= Dialogs.registry(id||setting['id']);
	}else{
		var __dlg			= new Dialog(setting);
		if(id) 	__dlg.id	= id;
		__dlg.create();
		__dlg.moved();
		if($.isFunction(setting.after)) setting.after.apply(__dlg);
	}
	return __dlg;
};
$.Dialog					= function(options,id){
	var setting				= $.extend({
		'class'				: '',
		title				: '',
		width				: 400,
		height				: 'auto',
		overlay				: true,
		action				: false,
		defaultbuttons		: 'confirm&cannel',
		href				: '',
		before				: null,
		show				: null,
		complete			: null,
		success				: null,
		callback			: null
	},options);
	var dlg				= Dialog.create({
		'class'			: setting['class'],
		id				: $.dialog_id,
		title			: setting.title,
		width			: setting.width,
		height			: setting.height,
		overlay			: setting.overlay,
		action			: setting.action,
		defaultbuttons	: setting.defaultbuttons,
		before			: function(o){
			if($.isFunction(setting.callback)) setting.callback.apply(this,[o]);
		},
		confirm			: function(o){
			this.submit();
			this.hide();
		},
		show			: function(o){
			if($.isFunction(setting.show)) setting.show.apply(this,[o]);
		},
		complete		: setting.complete,
		success			: function(o){
			if($.isFunction(setting.success)) setting.success.apply(this,[o]);
		}
	},id);
	$.dialog_id	= dlg.id;
	dlg.show();
	return dlg;
}
$.fn.Dialog					= function(options){
	var setting				= $.extend({
		'class'				: '',
		title				: '',
		width				: 400,
		height				: 'auto',
		overlay				: true,
		action				: false,
		defaultbuttons		: 'confirm&cannel',
		href				: '',
		before				: null,
		show				: null,
		complete			: null,
		success				: null,
		callback			: null
	},options);
	this.click(function(){try{
		var _this			= $(this);
		var dlg				= Dialog.create({
			'class'			: setting['class'],
			id				: _this.data('dialog'),
			title			: setting.title,
			width			: setting.width,
			height			: setting.height,
			overlay			: setting.overlay,
			action			: setting.action,
			defaultbuttons	: setting.defaultbuttons,
			before			: function(o){
				if($.isFunction(setting.callback)) setting.callback.apply(this,[o,_this]);
			},
			confirm			: function(o){
				this.submit();
				this.hide();
			},
			show			: function(o){
				if($.isFunction(setting.show)) setting.show.apply(this,[o,_this]);
			},
			complete: function(o){
				if($.isFunction(setting.complete)) setting.complete.apply(this,[o,_this]);
			},
			success			: function(o){
				if($.isFunction(setting.success)) setting.success.apply(this,[o,_this]);
			}
		});
		dlg.show();
		_this.data('dialog',dlg.id);}catch(e){alert(e.description)}
		return false;
	});
}
})(jQuery);
