/**
 * jQuery.dialog  0.6
 *
 * Copyright (c) 2008 Hudong.com
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 * author: panxuepeng
 * blog: http://dushii.blog.163.com
 * $Date: 2008-08-31 $
 * $Last: 2009-12-23 $
 */
 
 /*
 run:
 Firefox 2\3, IE 6\7\8, Chrome1.0, Safari3.2
 
 usage:
 $.dialog({
	id:'',
	title:'',
	content:''
 } );
 
 */

(function($){
	$._dialog = {version:0.6};
	
	var userAgent = navigator.userAgent;
	$.IE = $.browser.msie;
	$.IE6 = (function(){
		if (/MSIE [7891]\d?/.test(userAgent)) return false;
		if (/MSIE [56]/.test(userAgent)) return true;
		return false;
	})();

	$(document).ready(function(){
		$._dialog.scrollTop=$(document).scrollTop();
		$._dialog.bodyWidth=$('body').width();
		$._dialog.windowWidth=$(window).width();
		$._dialog.bodyPosition=$('body').css('position');
		$._dialog.bodyLeft=$('body').position().left;
	});
	
	$._dialog.list = []; // dialog object
	$._dialog.options = []; // dialog options
	$._dialog.parts = [];
	$._dialog.config = {
		lastid:'',
		id:'default',
		offsetClick:{},
		zIndex:2010
	};
	
	$._dialog.defaults = {
		id:'default',
		skin:'default',
		move:true,
		overlay:true,
		model:'default',//default  mini
		zIndex:2010,
		title:'',
		content:'',
		type:'',//img url iframe selector
		url:'',
		callback:null,
		position:'middle',
		fixed:false,
		effects:'',// fade  up down
		autoClose:0,
		height:240,
		width:350,
		align:'center',
		loadingImage:'<img src="style/default/indicator.gif" />'
	};
	
	$._dialog.open = function(options){
		if (typeof options != 'object'){
			alert('arguments must be a object, like {id:"id", title:"title"}.');
			return false;
		}
		
		var id = options.id;
		if (typeof id != 'string' && typeof id != 'number') {
			alert('the type of id must be string or number.');
			return false;
		}
		
		this.config.id = id;
		for (i in this.defaults){
			if (typeof options[i] == 'undefined'){
				options[i] = this.defaults[i];
			}
		}
		if (typeof options.position == "object"){
			options.fixed=false;
		}
		this.options[id] = options;
		if (options.overlay){
			this.setOverlay(id);
		}
		var dialog=this.list[id];
		if (!dialog){
			this.build(options);
		} else {
			this.config.lastid = this.config.id;
			this.parts[id].title.text(options.title);
			this.setOptions(options);
		}
		options['isLoad']=1;
		return this;
	};
	
	$._dialog.setContent = function(id, content){
		var self=this, dialog = self.list[id];
		if (!dialog){
			alert('dialog '+id+ ' is not exist.');
		}
		
		self.parts[id].content.html(content);
		self.show(id).show(id);
		return this;
	};
	
	$._dialog.setOptions = function(options){
		var id = options.id, content='', url='';
		var self=this, dialog = self.list[id];
		if (options.type == 'url'){
			url = options.url;
			if (this.config.url == url){
				this.show(id);
				return this;
			}
			this.config.url = url;
			this.setContent(id, options.loadingImage)
			$.get(url, function(data, state){
				if (state == 'success')	{
					self.setContent(id, data);
					if (typeof options.callback == 'function'){
						options.callback(data);
					}
				}else {
					self.setContent(id, "Loading failure!");
				}
			});
		}else if (options.type == 'img'){
			url = options.url;
			if (this.config.url == url){
				this.show(id);
				return this;
			}
			this.config.url = url;
			this.setContent(id, options.loadingImage);
			
			var img = new Image();
			img.onload = function(){
				width = img.width >950 ?950 : img.width;
				if (! $.IE){
					dialog.hide().fadeIn(300);
				}
				self.setContent(id, '<img src="'+url+'" width="'+width+'" />');
				if (typeof options.callback == 'function'){
					options.callback();
				}
			}
			img.onerror = function(){
				self.setContent(id, options.error);
			}
			img.src= url;
			
			self.parts[id].content.dblclick(function(){
				self.close(id);
			});

		}else if(options.type == 'iframe'){
			content = "<iframe border='0' src='"+options.url+"' width='100%' height='100%' frameborder='no' "
				+ " marginwidth='0' marginheight='0' scrolling='no' allowtransparency='yes'></iframe>";
			this.setContent(id, content);
			
		}else if(options.type == 'selector'){
			content = $(options.content).html();
			if(content) this.setContent(id, content);
			else self.show(id).show(id);
			if (typeof options.callback == 'function'){
				options.callback();
			}
		}else{
			this.setContent(id, options.content);
		}
		
		var part = this.parts[id];
		
		if (! options.move) {
			part.handle.css('cursor', 'default');
		}
		if (typeof options.align != 'undefined'){
			part.content.css('text-align', options.align);
		}
		if (typeof options.width != 'undefined'){
			part.table.width(options.width);
		}
		if (typeof options.height != 'undefined'){
			part.content.height(options.height - 25);
		}
		this.show(id).show(id);
		return this;
	};
	
	$._dialog.show = function(id){
		if (!id) id = this.config.id;
		var options = this.options[id], pos = this.getPosition(id);
		this.setPosition(id, pos);
		
		if(options.effects && typeof options['isLoad'] == 'undefined'){
			var dialog = this.list[id], top=pos.top, height=dialog.height();
			
			switch(options.effects){
				case 'down':
					dialog.css({left:pos.left, top:-1000}).animate({top:top},1000);
				break;
				case 'up':
					dialog.css({left:pos.left, 'top':top+height}).animate({top:top},1000);
				break;
				case 'fade':
					var duration = (typeof options.position == "object")?200:1500;
					dialog.css('opacity', 0.1).css(pos).animate({'opacity':1},duration);
					//dialog.css(pos).show();
				break;
			}
			
		}else if(options.effects){
			var dialog = this.list[id];
			
			dialog.animate({top:pos.top,left:pos.left}, 200);
		}
		
		return this;
	};
	
	$._dialog.skins = {
		'default':{
			'div':'border:1px solid #BFBFBF;',
			'table':'background-color:#FFFFFF;cursor:default;width:350px;',
			'handle':'height:25px;background:url(style/default/bg_box_hand.gif);cursor:move;'
				+'border-bottom:1px solid #E0E0E0;padding:2px;font-weight:bold;line-height:24px;-moz-user-select:none;',
			'title':'float:left; font-size:12px;margin-left:3px;',
			'content':'padding:10px;text-align:center;height:200px',
			'close':'display:block;float:right;cursor:pointer;width:22px;height:22px;'
				+'background:url(style/default/close.jpg)',
			'alphaDiv':'z-index:2001;cursor:default;background-color:#FFFFFF;'
				+'width:100%;height:100%;top:0px;left:0px;position:absolute;margin:0 auto;',
			'alphaOpacity':0.5
		},
		'lightbox':{
			'div':'border:1px solid #BFBFBF;',
			'table':'background-color:#FFFFFF;cursor:default;width:350px;'
				+'border-bottom:2px solid #666666;border:2px solid #666666;',
			'handle':'height:25px;background:url(style/default/bg_box_hand.gif);cursor:move;'
				+'border-bottom:1px solid #E0E0E0;padding:2px;font-weight:bold;line-height:24px;-moz-user-select:none;',
			'title':'float:left; font-size:12px;margin-left:3px;',
			'content':'padding:10px;text-align:center;height:200px',
			'close':'display:block;float:right;cursor:pointer;width:16px;height:16px;'
				+'background:url(style/default/icn_closew.gif)',
			'alphaDiv':'z-index:2001;cursor:default;background:url(style/default/overlay.png);'
				+'width:100%;height:100%;top:0px;left:0px;position:absolute;margin:0 auto;',
			'alphaOpacity':0.9
		}
	};
	
	$._dialog.build = function(options){
		var skin = $._dialog.skins[options.skin];
		var self = this, id = options.id,position='absolute';
		this.config.zIndex++;
		
		if(options.fixed){
			position='fixed !important;position:absolute;top:0;';
		}
		
		var html = '<div class="dialog" id="dialog_'+id+'" style="'+skin['div']+'width:'+ options.width +'px;'
		+ 'z-index:2010;position:'+position+';left:-10000px;top:-10000px;">'
		+ '<table class="dialog"  style="'+ skin['table']  +'" cellpadding="0" cellspacing="0">'
		+ '<tr><td name="handle"  style="'+ skin['handle'] +'">'
		+ '<span name="title"     style="'+ skin['title']  +'">'+options.title+'</span>'
		+ '<a name="close"        style="'+ skin['close']  +'"></a></td></tr>'
		+ '<tr><td name="content" style="'+ skin['content']+'"></td></tr></table>'
		+ '</div>';
		
		for(i in self.list){
			self.list[i].css('opacity', 0.8);
		}
		
		$('body').append(html);
		var dialog = $('#dialog_'+id);
		this.list[id] = dialog;
		this.parts[id] = {
			handle:dialog.find("td[name='handle']"),
			title:dialog.find("span[name='title']"),			
			close:dialog.find("a[name='close']"),
			content:dialog.find("td[name='content']"),
			table:dialog.find("table.dialog")
		};
		var part = this.parts[id];
		
		if (! options.move) {
			part.handle.css('cursor', 'default');
		}
		if (typeof options.align != 'undefined'){
			part.content.css('text-align', options.align);
		}
		if (typeof options.width != 'undefined'){
			part.table.width(options.width);
		}
		if (typeof options.height != 'undefined'){
			part.content.height(options.height - 25);
		}
		
		self.setOptions(options);
		//SET  EVENT
		
		//onclose
		part.close.click(function(){self.close(id);});
		
		//mousedown move
		part.handle.mousedown(function(e){
			e = e || event;
			if (self.config.id != id){
				self.config.lastid = self.config.id;
				self.config.id = id;
				for(i in self.list){
					self.list[i].css('opacity', 0.8);
				}
				dialog.css('opacity', 1).css('z-index', self.config.zIndex++);
			}

			if (! options.move) {
				return self;
			}
			var offset = dialog.offset();
			self.config.offsetClick = {
				width: e.pageX - offset.left,
				height:e.pageY - offset.top,
				startX:offset.left,
				startY:offset.top
			};
			
			$(document).mousemove(function(e){self.move(e, id);return false;}).bind("selectstart", function(){return false});
			
			$(document).mouseup(function(e){
				var oc = self.config.offsetClick;
				var pos = {left:oc.startX, top:oc.startY};
				
				if (e.clientY < 0 || e.clientX < 2 
					|| e.clientX > $(document).width() 
					|| e.clientY > $(window).height()
				){
					dialog.css(pos);
				}
				$(document).unbind("mousemove").unbind("selectstart").unbind("mouseup");
				return false;
			});
			
			return false;
		}).bind("dblclick", function(){
			if(options.model == 'mini'){
				var part = self.parts[id];
				part.content.toggle();
			}
			return false;
		}).bind("selectstart", function(){return false});
		
		var fn_clockScroll = function(e){
			if(options['clockScroll']) {
				clearTimeout(options['clockScroll']);
			}
			
			options['clockScroll']=setTimeout(function(){
				self.scrollTop = $(document).scrollTop();
				
				if($.IE6 && options.fixed){
					self.show(options.id);
					if(options.autoClose){fn_clockAutoClose();}
				}
			}, 200);
			return false;
		}
		
		$(window).scroll(fn_clockScroll);

		
		$(window).resize(function(){
			self.bodyWidth=$('body').width();
			self.windowWidth=$(window).width();
			self.bodyLeft=$('body').position().left;
			if (self.isShow(options.id)){
				self.show(options.id);
			}
			return false;
		});
		
		if(options.autoClose){
			options.autoClose = parseInt(options.autoClose);
			options.autoClose = isNaN(options.autoClose)?20:options.autoClose;

			function fn_clockAutoClose(){
				if(options['clockAutoClose']) {
					clearTimeout(options['clockAutoClose']);
				}
				options['clockAutoClose']=setTimeout(function(){
					self.close(options.id);
				}, options.autoClose);
				return false;
			}
			
			fn_clockAutoClose();
			
			dialog.mouseover(function(){
				clearTimeout(options['clockAutoClose']);
			}).mouseleave(function(e){
				fn_clockAutoClose();
			});
		}
		return this;
	};
	
	$._dialog.close = function(id){
		if (!id) id = this.list.length -1;
		if(typeof this.list[id] == 'undefined') return;
		var self=this,dialog = this.list[id], options = this.options[id], height=dialog.height(),pos=this.getPosition(id);
		if (dialog){		
			switch(options.effects){
				case 'down':
					dialog.animate({top:-1999},500);
				break;
				case 'up':
					dialog.animate({top:pos.top+height+100},{duration:1000, complete:function(){
						$(this).css({top:-1999});
					}});
				break;
				case 'fade':
					dialog.animate({'opacity':0.1},{duration:200, complete:function(){
						$(this).css({top:-1999, 'opacity':1});
					}});
				break;
				default:
					dialog.css({top:-1999});
			}
		}
		
		for(id in self.list){
			if (self.isShow(id)){
				return false;
			}
		}
		$("div.dialog_overlay").hide();
	};
	
	$._dialog.isShow = function(id){
		var offset = this.list[id].offset();
		return (offset.top>0 && offset.left>0);
	}
	
	$._dialog.pointer = function(e){
		var left, top;
		left = e.pageX||(e.clientX + $(document).scrollLeft());
		top = e.pageY||(e.clientY + $(document).scrollTop());
		return {"left":left, "top":top};
	};
	
	$._dialog.move = function(e, id){
		e = e || event;
		var self=this, dialog=this.list[id], options=this.options[id], pos=this.pointer(e), 
			x=this.config.offsetClick, left=pos.left-x.width, top=pos.top-x.height;
		self.bodyLeft=self.bodyLeft||$('body').position().left;
		
		if (options.fixed){
			if(!$.IE6){top -=$(document).scrollTop();}
		}else{
			left = parseInt(left-self.bodyLeft);
		}
		
		dialog.css({left:left, top:top});
		return false;
	};
	
	$._dialog.setPosition = function(id, pos){
		var dialog = this.list[id], options = this.options[id];
		if (typeof pos == 'object'){
			if(!options.effects){
				dialog.css(pos);
			}
		}
		var part = this.parts[id];
		var dW = part.table.width();
		//part.table.width(dW);
		//part.handle.width(dW);
		dialog.width(dW);
		var inputTexts = dialog.find(":text");
		if (inputTexts.length > 0) inputTexts.get(0).focus();
	};
	
	$._dialog.getPosition = function(id){
		var left=0, top=0, sL=$(document).scrollLeft(), sT = $(document).scrollTop();
		var self=this,dialog = this.list[id], options = this.options[id];
		var cW = (document.documentElement.clientWidth ||document.body.clientWidth );
		var cH = (document.documentElement.clientHeight||document.body.clientHeight);
		var dH = dialog.outerHeight(), dW = dialog.outerWidth();
		options.position = options.position || 'middle';
		switch(options.position){
			case 'center':
			case 'middle':
			case 'c':
			case 'm':
				left = (cW - dW)/2;
				top  = (cH - dH)/2;
				break;
			case 'rb':
			case 'rightBottom':
				left = cW - dW -4;
				top  = cH - dH;
				break;
			case 'rt':
			case 'rightTop':
				left = cW - dW -4;
				top  = 1;
				break;
			case 'lt':
			case 'leftTop':
				left = 1;
				top  = 1;
				break;
			case 'lb':
			case 'leftBottom':
				left = 1;
				top  = cH - dH;
				break;
			default:
				if (typeof options.position != "object") break;
				var E = $(options.position);
				
				if (! $.IE && E.find('img').length > 0){
					E = E.find('img');
				}
				
				var offset = E.offset(), eH = E.outerHeight(), eW = E.outerWidth();
				
				var w1, w2, h1, h2;
				w1 = offset.left - sL + eW;
				w2 = cW + sL - offset.left;
				h1 = offset.top - sT;
				h2 = cH + sT - offset.top - eH;
				if (w2 > dW && w1 > dW){
					left = (w2>w1) ? offset.left -3 : offset.left + eW - dW +3;
				}else if (w2 > dW){
					left = offset.left -3;
				}else if (w1 > dW){
					left = offset.left + eW - dW +3;
				}else {
					left = sL + (cW - dW)/2;
				}
				
				left = (dW < 700) ? left : sL + (cW - dW)/2;
				
				if (h2 > dH){
					top = (eH < 60) ? offset.top + eH : offset.top;
				}else if (h1 > dH){
					top = (eH < 60) ? offset.top - dH : offset.top -dH + eH;
				}else {
					top  = sT + (cH - dH)/2;
				}
				
				top = top > sT ? top : sT;
				top = (cH + sT > offset.top + eH) ? top: cH + sT - dH;
				
		}
		
		if (typeof options.position != "object"){
			left += sL;
			top  += sT;
		}
		
		top = top > 0 ? top : 0;
		
		if(!self.bodyLeft){
			self.windowWidth=self.windowWidth||$(window).width();
			self.bodyWidth=self.bodyWidth||$('body').width();
			self.bodyLeft = (self.windowWidth - self.bodyWidth)/2;
		}
		
		if (!options.fixed && $('body').css('position') == 'relative'){
			left = left - self.bodyLeft;
		}else if(options.fixed && $.IE6){
			left = left - self.bodyLeft;
		}
		
		return {"left":left, "top":top};
	};
	
	$._dialog.setOverlay = function(did){
		var self=this, id = 'dialog_overlay'+did, domH = $(document).height(), bodyW=self.bodyWidth||$('body').width();
		var overlay = $('div#'+id);
		var skin = this.skins[this.options[did].skin];
		
		if ($(".dialog_overlay:visible").length > 0){
			return this;
		}
		
		if (overlay.length > 0){
			overlay.show();
		}else{
			var s = skin['alphaDiv'];
			$('body').append('<div class="dialog_overlay" id="'+id+'" style="'+ s +'"></div>');
			overlay = $('div#'+id);
		}
		if (skin['alphaOpacity']){
			overlay.css('opacity', skin['alphaOpacity']);
		}

		if (domH > 600){
			overlay.height(domH);
		}
		if (bodyW > 1024){
			overlay.width(bodyW*0.97);
		}
		
		return this;
	};
	
	/*
	 * $.dialog
	 * 
	 */
	$.dialog = function(options){
		$._dialog.open(options);
	}
	
	$.extend($.dialog, {
	
		//compatible jquery.dialog 0.2
		box:function(id, title, content, position, callback){
			var options = {id:id, title:title, position:position, callback:callback};
			if (content.substr(0,4) == 'url:'){
				options.type = 'url';
				options.url = content.substr(4);
			}else if (content.substr(0,4) == 'img:'){
				options.type = 'img';
				options.url = content.substr(4);
			}else {
				options.type = 'html';
				options.content = content;
			}
			
			$._dialog.open(options);
		},
		
		close:function(id){
			$._dialog.close(id);
		},
		
		exist:function(id){
			return $._dialog.list[id];
		},
		
		setConfig:function(key, value){
			if (!key) return this;
			if (typeof key == 'string' && value !== null) {
				$._dialog.config[key] = value;
			}else if (typeof key == 'object') {
				$.extend($._dialog.config, key);
			}
			
			return this;
		},
		
		setDefaults:function(key, value){
			if (!key) return this;
			if (typeof key == 'string' && value !== null) {
				$._dialog.defaults[key] = value;
			}else if (typeof key == 'object') {
				$.extend($._dialog.defaults, key);
			}
			
			return this;
		},
		
		demo: function(){
			$.dialog({
				id:'demo',
				align:'left',
				position:'center',
				width:400,
				title:'Hi! This is a demo of the $.dialog',
				content:"$.dialog({<br>&nbsp;id:'demo',<br>&nbsp;align:'left',<br>&nbsp;width:400,<br>&nbsp;title:'Hi! This is a demo of the $.dialog',<br>&nbsp;content:'......'<br>});"
			});
		}
	});
	
})(jQuery);
