(function($){

$.browser.ie6 = $.browser.msie && parseInt($.browser.version) < 7;

var _st = window.setTimeout;
window.setTimeout = function(fRef, mDelay) {
	if(typeof fRef == 'function'){
		var argu = Array.prototype.slice.call(arguments,2);
		var f = (function(){ fRef.apply(null, argu); });
		return _st(f, mDelay);
	}
	return _st(fRef,mDelay);
};

jQuery.extend({

	overlay : function(options)
	{
		return $().overlay(options);
	},

	layer : function(o, cb, options)
	{
		return $().layer(o, cb, options);
	},

	lock : function(o, cb, options)
	{
		return $().lock(o, cb, options);
	},

	msg : function(str, cb, options)
	{
		return $().msg(str, cb, options);
	},

	quickMsg : function(str, cb, options)
	{
		return $().quickMsg(str, cb, options);
	},

	alert : function(str, cb, options)
	{
		return $().alert(str, cb, options);
	},

	confirm : function(str, submitHandler, cancelHandler, options)
	{
		return $().confirm(str, submitHandler, cancelHandler, options);
	},

	confirms : function(str, yesHandler, noHandler, cancelHandler, options)
	{
		return $().confirms(str, yesHandler, noHandler, cancelHandler, options);
	},

	'window' : function(o, options)
	{
		return $().window(o, options);
	},

	tip : function(str, options)
	{
		return $().tip(str, options);
	},

	dialog : function(url, options, cb)
	{
		return $().dialog(url, options, cb);
	},

	loadingMsg : function(str)
	{
		return $().loadingMsg(str);
	}
});

//global settings
$.overlay.settings = {
	backgroundColor	: '#000',
	opacity		: 0.27
};
$.overlay.resizeHandler = function(){};

$.layer.cache = null;
$.layer.timer = null;
$.layer.resizeHandler = function(){};
$.dialog.callback = function(){};



jQuery.fn.createIframe = function(id, options)
{
	if (!$.browser.ie6) return this;
	var full = this[0]==document;

	//settings
	var type = typeof options;
	if (type == 'number') {
		options = {opacity: options};
	} else if (type == 'string') {
		options = {backgroundColor: options};
	}

	var settings = $.extend({}, $.overlay.settings, options || {});

	var iframe = $('#'+id);
	if (iframe.length) {
		iframe.appendTo(full ? document.body : this);
	} else {
		var iframeHtml = "<iframe id=\"" + id + "\" name=\"" + id + "\""
				+ " style=\"border:0;padding:0;margin:0;overflow:hidden;z-index:1000\""
				+ " frameborder=\"0\" scrolling=\"no\""
				+ " src=\"about:blank\"><\/iframe>";
		iframe = $(iframeHtml).appendTo(full ? document.body : this);
		window.frames[id].document.write("<body><\/body>");
		window.frames[id].document.close();
	}

	iframe.css('opacity', settings.opacity);
	window.frames[id].document.body.style.backgroundColor = settings.backgroundColor;
	return this;
};

jQuery.fn.overlay = function(options)
{
	//full
	var full = this[0] == document;

	if (options === false) {
		$('#jqOverlay').length && $('#jqOverlay').remove();
		return this;
	}

	//settings
	var type = typeof options;
	if (type == 'number') {
		options = {opacity: options};
	} else if (type == 'string') {
		options = {backgroundColor: options};
	}

	var settings = $.extend({}, $.overlay.settings, options || {});

	if (!full && this.css('position')=='static') {
		this.css('position', 'relative');
	}

	if (full && !$.browser.ie6) {
		var style = {
			backgroundColor	: settings.backgroundColor,
			opacity		: settings.opacity,
			width		: '100%',
			height		: '100%',
			position	: 'fixed',
			zIndex		: 1000,
			left		: 0,
			top		: 0,
			drag		: false
		};
		var overlay = $('#jqOverlay');
		if (!overlay.length) {
			overlay = $('<div id="jqOverlay" class="jqOverlay"></div>');
		}

		overlay.appendTo(document.body).css(style);
		return this;
	}

	//width, height, left, top
	var width, height, left, top;

	if (full) { //ie6 and full
		var el = document.documentElement;

		width = el.scrollWidth;
		height = Math.max(el.scrollHeight, el.clientHeight);
		left = 0;
		top = 0;
	} else { // not full
		width = this[0].offsetWidth;
		height = this[0].offsetHeight;
		left = - parseInt(this[0].style.borderLeftWidth || 0);
		top = - parseInt(this[0].style.borderTopWidth || 0);
	}

	var style = {
		display		: 'block',
		backgroundColor	: settings.backgroundColor,
		opacity		: settings.opacity,
		width		: width,
		height		: height,
		position	: 'absolute',
		zIndex		: 1000,
		left		: left,
		top		: top
	};

	//create overlay && set style
	var overlay = $('#jqOverlay');
	if (overlay.length) {
		if ($.browser.ie6) {
			$(full ? document.body : this).createIframe('jqOverlay', {opacity: settings.opacity, backgroundColor: settings.backgroundColor});
			overlay.css(style);
		} else {
			overlay.appendTo(full ? document.body: this).css(style);
		}
	} else {
		if ($.browser.ie6) {
			$(full ? document.body : this).createIframe('jqOverlay', {opacity: settings.opacity, backgroundColor: settings.backgroundColor});
			overlay = $('#jqOverlay').addClass('jqOverlay').css(style);
		} else {
			overlay = $('<div id="jqOverlay" class="jqOverlay"></div>')
					.appendTo(full ? document.body : this)
					.css(style);
		}
	}

	//window.onresize (only IE6)
	if (full) {
		$(window).unbind('resize', $.overlay.resizeHandler);
		$.overlay.resizeHandler = function(){
			el = document.documentElement;
			setTimeout(function(){
				overlay.css({
					width : el.scrollWidth,
					height : Math.max(el.scrollHeight, el.clientHeight)
				});
			}, 0);
		};
		$(window).bind('resize', $.overlay.resizeHandler);
	}

	//return
	return this;
};


$.fn.layer = function(o, cb, options)
{
	if (!$.isFunction(cb) && options !== null) {
		options = cb;
		cb = function(){};
	}
	if (typeof options == 'number') {
		options = {speed: options};
	}

	//settings
	var settings = {
		speed		: 0,
		minWidth	: null,
		maxWidth	: null
	};
	$.extend(settings, options || {});

	var full = this[0] == document;

	if (!full && this.css('position')=='static') {
		this.css('position', 'relative');
	}

	clearTimeout($.layer.timer);

	$('#jqMsg').length && $('#jqMsg').remove();
	if ($.layer.cache) {
		$.layer.cache.appendTo(document.body);
		$.layer.cache = null;
	}

	if (typeof o == 'string') {
		o = $('<div id="jqMsg" class="clearfix" style="display:none">' + o + '</div>').appendTo(full ? document.body : this);
	} else {
		o = $('#' + o.attr('id')).css('float', 'left');
		$.layer.cache = o.clone();

		o = o.appendTo(full ? document.body : this).wrap('<div id="jqMsg" class="clearfix" style="display:none"></div>').show().parent();
	}
	o.css({
		position : (!full || $.browser.ie6) ? 'absolute' : 'fixed',
		zIndex : 1001,
		opacity: 0.01,
		display: 'block',
		float: 'left',
		left: 0,
		top: 0
	});


	var clientWidth = o.get(0).clientWidth;
	if (settings.minWidth && clientWidth < parseInt(settings.minWidth)) {
		clientWidth = parseInt(settings.minWidth);
	}
	if (settings.maxWidth && clientWidth > parseInt(settings.maxWidth)) {
		clientWidth = parseInt(settings.maxWidth);
	}
	o.css('width', clientWidth + 'px');


	if ($.browser.msie) {
		o.find('h2').css('zoom', 1);
	}

	var oWidth, oHeight, left, top;
	if (o.css('position') == 'fixed') {
		$(window).unbind('resize', $.layer.resizeHandler);
		$.layer.resizeHandler = function(s){
			oWidth = o[0].offsetWidth;
			oHeight = o[0].offsetHeight;

			//var doc = $.browser.opera ? document.body : document.documentElement;
			var doc = document.documentElement;
			left = (doc.clientWidth - oWidth) / 2;
			top = (doc.clientHeight - oHeight) / 2;

			if (s) o.css({left: left, top: top});
			else o.animate({left: left, top: top});
		};
		$.layer.resizeHandler(1);
		$(window).bind('resize', $.layer.resizeHandler);

	} else {
		if (full) {
			o[0].style.setExpression('left', 'document.documentElement.scrollLeft + parseInt((document.documentElement.clientWidth-this.offsetWidth)/2)');
			o[0].style.setExpression('top', 'document.documentElement.scrollTop + parseInt((document.documentElement.clientHeight - this.offsetHeight)/2)');
		} else {
			oWidth = o[0].offsetWidth;
			oHeight = o[0].offsetHeight;

			left = parseInt((this[0].offsetWidth - oWidth) / 2) - parseInt(this[0].style.borderLeftWidth || 0);
			top = parseInt((this[0].offsetHeight - oHeight) / 2) - parseInt(this[0].style.borderTopWidth || 0);
			o.css({left: left, top: top});
		}
	}

	o.css('opacity', 1);
	if (settings.speed) {
		o.hide().fadeIn(settings.speed, $.isFunction(cb) ? cb : function(){});
	} else {
		o.show();
		$.isFunction(cb) ? cb.call(o) : function(){};
	}

	//return
	return this;
};

$.fn.lock = function(o, cb, options)
{
	if (!$.isFunction(cb) && cb !== null) {
		options = cb;
		cb = function(){};
	}
	if (typeof options == 'number') {
		options = {speed: options};
	}
	var settings = {
		speed : 0,
		minWidth : null,
		maxWidth : null,
		backgroundColor	: $.overlay.settings.backgroundColor,
		opacity : $.overlay.settings.opacity
	};
	$.extend(settings, options || {});
	return this.overlay({backgroundColor: settings.backgroundColor, opacity: settings.opacity})
		.layer(o, cb, settings);
};

$.unlock = function(cb, speed)
{
	if (typeof speed != 'number') {
		speed = typeof cb == 'number' ? cb : 0;
	}
	if (!$.isFunction(cb)) {
		cb = function(){};
	}

	var jqMsg = $('#jqMsg');

	if (!jqMsg.length) {
		$('#jqOverlay').length && $('#jqOverlay').remove();
		return;
	}

	if ($.layer.cache) {
		var h = function(){
			$.layer.cache.appendTo(document.body);
			$.layer.cache = null;
			jqMsg.remove();
			$('#jqOverlay').length && $('#jqOverlay').remove();
			cb && cb.call();
		};
		speed ? jqMsg.fadeOut(speed, h) : h();
	} else {
		var h = function(){
			jqMsg.remove();
			$('#jqOverlay').length && $('#jqOverlay').remove();
			cb && cb.call();
		};
		speed ? jqMsg.fadeOut(speed, h) : h();
	}
};

$.fn.tip = function(str, options)
{
	var full = this[0]==document;

	if (typeof options == 'number') {
		options = {timeout: options};
	}
	var settings = {
		timeout	: 3000,
		speed1	: 200,
		speed2	: 300,
		opacity	: 1
	};
	$.extend(settings, options || {});

	if (!full && this.css('position')=='static') {
		this.css('position', 'relative');
	}

	var jqTips = $('#jqTips');
	if (jqTips.length && !$('#jqTips div').length) {
		jqTips.remove().length = 0;
	}
	if (!jqTips.length) {
		jqTips = $('<div id="jqTips"></div>')
				.appendTo(full ? document.body : this)
				. css({
					position	: full && !$.browser.ie6 ? 'fixed' : 'absolute',
					zIndex		: 1002,
					right		: '2px',
					top		: 0
//					opacity		: settings.opacity
				});

		if (full && $.browser.ie6) {
			jqTips[0].style.setExpression('top', 'parseInt(document.documentElement.scrollTop)');
		}
	}

	var tip = $('<div class="jqTip">' + str + '</div>').appendTo(jqTips)
		.css({float: 'right', clear: 'both'})
		.fadeIn(settings.speed1, function(){
			var _this = this;
			setTimeout(function(){
				$(_this).animate({
					height : 'hide',
					opacity : 'hide'
				}, settings.speed2, function(){
					$(this).remove();
				});
			}, settings.timeout);
		});

	//return
	return this;
};

$.fn.autoTip = function(str, options)
{
	if (this.width() < 350 || this.height() < 200) {
		$.tip(str, options);
	} else {
		this.tip(str, options);
	}

	return this;
};

$.fn.msg = function(str, cb, options)
{
	if (!$.isFunction(cb) && cb !== null) {
		options = cb;
		cb = function(){};
	}
	if (typeof options == 'number') {
		options = {speed: options};
	}
	var settings = {
		speed			: 100,
		minWidth		: null,
		maxWidth		: null,
		backgroundColor	: $.overlay.settings.backgroundColor,
		opacity			: $.overlay.settings.opacity
	};
	$.extend(settings, options || {});

	this.lock('<div class="jqMsg">' + str + '</div>', cb, settings);

	//return
	return this;
};

$.fn.quickMsg = function(str, cb, options)
{
	if (!$.isFunction(cb) && cb !== null) {
		options = cb;
		cb = function(){};
	}
	if (typeof options == 'number') {
		options = {timeout: options};
	}
	var settings = {
		timeout			: 500,
		speed1			: 100,
		speed2			: 300,
		backgroundColor	: $.overlay.settings.backgroundColor,
		opacity			: $.overlay.settings.opacity,
		minWidth		: null,
		maxWidth		: null
	};
	$.extend(settings, options || {});

	this.msg(str, null, {
			speed: settings.speed1,
			minWidth: settings.minWidth,
			maxWidth: settings.maxWidth,
			backgroundColor: settings.backgroundColor,
			opacity: settings.opacity});
	$.layer.timer = setTimeout($.unlock, settings.timeout, cb, settings.speed2);

	//return
	return this;
};

$.fn.loadingMsg = function(str)
{
	if (!str) str = 'Loading...';
	return this.msg('<div class="jqLoading">' + str + '</div>');
};

$.fn.alert = function(str, cb, options)
{
	var settings = {
		speed1		: 200,
		speed2		: 200,
		backgroundColor : $.overlay.settings.backgroundColor,
		opacity		: $.overlay.settings.opacity,
		title		: 'Notice',
		submit		: 'Ok',
		focus		: true,
		minWidth	: '220px',
		maxWidth	: '480px',
		drag		: true
	};
	$.extend(settings, options || {});

	this.lock('<div class="jqAlert">'
		+ '<div class="jqTopic"><a href="" class="jqClose">close</a><h2>' + settings.title + '</h2></div>'
		+ '<div class="jqBox">'
		+ '<div class="jqContent">' + str + '</div>'
		+ '<div class="jqBtns"><button type="button" class="jqSubmit">' + settings.submit + '</button></div>'
		+ '</div></div>',
		function(){
			if (settings.focus) {
				$('#jqMsg button').focus();
			}
		},
		{speed: settings.speed1, minWidth: settings.minWidth, maxWidth: settings.maxWidth,
			backgroundColor: settings.backgroundColor, opacity: settings.opacity});

	//setTimeout(, settings.speed1);
	$('#jqMsg a.jqClose').focus(function(){this.blur();}).click(function(){
		$.unlock(cb);
		return false;
	});
	$('#jqMsg button').click(function(){
		$.unlock(cb, settings.speed2);
	});

	//return
	return this;
};

$.fn.confirm = function(str, submitHandler, cancelHandler, options)
{
	var settings = {
		speed1		: 200,
		speed2		: 200,
		backgroundColor : $.overlay.settings.backgroundColor,
		opacity		: $.overlay.settings.opacity,
		title		: 'Notice',
		submit		: 'Ok',
		cancel		: 'Cancel',
		focus		: 'cancel',
		minWidth	: '220px',
		maxWidth	: '480px',
		drag		: true
	};
	$.extend(settings, options || {});

	this.lock('<div class="jqConfirm">'
		+ '<div class="jqTopic"><a href="" class="jqClose">close</a><h2>' + settings.title + '</h2></div>'
		+ '<div class="jqBox">'
		+ '<div class="jqContent">' + str + '</div>'
		+ '<div class="jqBtns">'
		+ '<button type="button" class="jqSubmit">' + settings.submit + '</button> '
		+ '<button type="button" class="jqCancel">' + settings.cancel + '</button></div>'
		+ '</div></div>',
		function(){
			if (settings.focus == 'cancel') {
				$('#jqMsg button.jqCancel').focus();
			} else if (settings.focus == 'submit') {
				$('#jqMsg button.jqSubmit').focus();
			}
		},
		{speed: settings.speed1, minWidth: settings.minWidth, maxWidth: settings.maxWidth,
			backgroundColor: settings.backgroundColor, opacity: settings.opacity, drag: settings.drag});

	$('#jqMsg a.jqClose').focus(function(){this.blur();}).click(function(){
		$.unlock(cancelHandler);
		return false;
	});
	$('#jqMsg button.jqCancel').click(function(){
		$.unlock(cancelHandler, settings.speed2);
	});
	$('#jqMsg button.jqSubmit').click(function(){
		$.unlock(submitHandler, settings.speed2);
	});

	//return
	return this;
};

$.fn.confirms = function(str, yesHandler, noHandler, cancelHandler, options)
{
	var settings = {
		speed1		: 200,
		speed2		: 200,
		backgroundColor : $.overlay.settings.backgroundColor,
		opacity		: $.overlay.settings.opacity,
		title		: 'Notice',
		yes		: 'Yes',
		no		: 'No',
		cancel		: 'Cancel',
		focus		: 'cancel',
		minWidth	: '250px',
		maxWidth	: '550px',
		drag		: true
	};
	$.extend(settings, options || {});

	this.lock('<div class="jqConfirms">'
		+ '<div class="jqTopic"><a href="" class="jqClose">close</a><h2>' + settings.title + '</h2></div>'
		+ '<div class="jqBox">'
		+ '<div class="jqContent">' + str + '</div>'
		+ '<div class="jqBtns">'
		+ '<button type="button" class="jqYes">' + settings.yes + '</button> '
		+ '<button type="button" class="jqNo">' + settings.no + '</button> '
		+ '<button type="button" class="jqCancel">' + settings.cancel + '</button></div>'
		+ '</div></div>',
		function(){
			if (settings.focus == 'yes') {
				$('#jqMsg button.jqYes').focus();
			} else if (settings.focus == 'no') {
				$('#jqMsg button.jqNo').focus();
			} else if (settings.focus == 'cancel') {
				$('#jqMsg button.jqCancel').focus();
			}
		},
		{speed: settings.speed1, minWidth: settings.minWidth, maxWidth: settings.maxWidth,
			backgroundColor: settings.backgroundColor, opacity: settings.opacity});

	$('#jqMsg a.jqClose').focus(function(){this.blur();}).click(function(){
		$.unlock(cancelHandler);
		return false;
	});
	$('#jqMsg button.jqCancel').click(function(){
		$.unlock(cancelHandler, settings.speed2);
	});
	$('#jqMsg button.jqYes').click(function(){
		$.unlock(yesHandler, settings.speed2);
	});
	$('#jqMsg button.jqNo').click(function(){
		$.unlock(noHandler, settings.speed2);
	});

	//return
	return this;
};

$.fn.window = function(o, options)
{
	var settings = {
		speed		: 200,
		title		: '',
		backgroundColor : $.overlay.settings.backgroundColor,
		opacity		: $.overlay.settings.opacity,
		minWidth	: '220px',
		maxWidth	: null,
		maxHeight	: null,
		drag		: true
	};
	if (typeof options == 'string') {
		options = {title: options};
	}
	$.extend(settings, options || {});


	if ($.className.has(o[0], 'jqContent')) {
		$.browser.msie && settings.maxHeight && o.cutInner().cutInner();
		p = o.parent().parent();
		p.find('div.jqTopic h2').html(settings.title + '&nbsp;');
	} else {
		p = o.addClass('jqContent').wrap('<div class="jqBox"></div>').show()
			.parent().wrap('<div class="jqWindow"></div>')
			.parent().attr('id', 'jq' + $.uid()).prepend('<div class="jqTopic"><a href="" class="jqClose">close</a><h2>' + settings.title + '&nbsp;</h2></div>').hide();
	}

	if (settings.maxHeight) {
		if ($.browser.msie) {
			o = $(o.wrapInner('<div class="jqInner"><div class="jqInner2"></div></div>').get(0).firstChild);
		}
		o.css('overflow', 'auto');

		if ($.browser.msie) {
			p.show();
			o.css('zoom', 1);
			if (o[0].clientHeight > parseInt(settings.maxHeight)) {
				o.css({
					height: settings.maxHeight,
					width: o[0].clientWidth
				});
				$(o[0].firstChild).css({
					width: parseInt(o[0].clientWidth) - 17 + 'px'
				});
			}
			p.hide();
		} else {
			o.css('maxHeight', settings.maxHeight);
		}
	}

	this.lock(p, settings);


	p.find('a.jqClose').focus(function(){this.blur();}).click(function(){
		$.unlock();
		return false;
	});

	if ($.browser.msie) {
		p.find('h2').css('zoom', 1);
	}

	//return
	return this;
};

$.fn.dialog = function(url, options, cb)
{
	var settings = {
		speed		: 0,
		title		: '',
		width		: '500px',
		height		: '350px',
		backgroundColor : $.overlay.settings.backgroundColor,
		opacity		: $.overlay.settings.opacity,
		name		: '',
		scroll		: false,
		drag		: true
	};
	$.extend(settings, options || {});

	var html = '<div class="jqDialog">'
				+ '<div class="jqTopic"><a href="" class="jqClose">close</a><h2>' + settings.title + '&nbsp;</h2></div>'
				+ '<div class="jqBox"><div class="jqContent">'
				+ '<iframe src="' + url + '" scrolling="' + (settings.scroll ? 'yes' : 'no') + '" frameborder="0" class="jqIframe"'
				+ (settings.name ? ' id="' + settings.name + '" name="' + settings.name + '"' : '')
				+ ' style="display:block; margin:0; border:0; width:' + settings.width + '; height:' + settings.height + '; margin:0; padding:0"></iframe>'
				+ '</div></div>'
				+ '</div>';
	this.lock(html, {speed: settings.speed, minWidth: null, maxWidth: null, backgroundColor: settings.backgroundColor, opacity: settings.opacity});

	var o = $('#jqMsg');
	o.find('a.jqClose').focus(function(){this.blur();}).click(function(){
		$.unlock();
		return false;
	});

	if ($.browser.msie) {
		o.find('h2').css('zoom', 1);
	}

	if ($.isFunction(cb)) {
		$.dialog.callback = cb;
	} else {
		$.dialog.callback = function(){};
	}

	return this;
};



$(document.body).keydown(function(e){
	if (e.keyCode == 27) {
		var jqMsg = $('#jqMsg a.jqClose');
		jqMsg.length && jqMsg.click();
	}
});

})(jQuery);
