﻿var LoopDialog = Class.create();

LoopDialog.prototype = {
	initialize: function( id, title ) {
		this.id = id;
		this.title = title;
		this.bg = null;
		this.bgIframe = null;
		
		this.options = Object.extend({
				width: 300,
				height: 250,
				modal: true,
				effect: null,  // 'fade', turn off effect in ie because of PNG problem 
				hideEffect: null, // 'fade'
				bgFade: true,
				followScroll: false,
				bgColor: "black",
				bgOpacity: 0.4,
				focusElement: null,
				minBgWidth: 760,
				minBgHeight: 500,
				onShow: null,
				onHide: null,
				onContentUpdate: null
			}, arguments[2] || {});
	
		this.onScrollHandler = this.onScroll.bindAsEventListener(this);
		this.onResizeHandler = this.onResize.bindAsEventListener(this);
	
		this._createWindow();
	},
	
	_createWindow: function() {
		var div = this.htmlElement = document.createElement('div');
		div.className = 'dialog';
		
		var b = document.body;
		b.appendChild(div);
		
		var pngClass = '';
		if (document.all && navigator.userAgent.toLowerCase().indexOf("msie") != -1) {
			pngClass = ' class="trans_png"';
		}

		div.innerHTML = StringBuffer.concat(
			'<div class="zixun_tan_bor" >',
			'<div class="zixun_tan_bor_head" id="dialog_width_ctrl_' + this.id + '" style="cursor: move;">',
			'<div class="zixun_tan_bor_top" id="dialog_title_' + this.id + '"></div>',
			'<div id="dialog_close_btn_' + this.id + '" class="dialog-icon-close dialog-icon-normal"></div>',
			'</div>',
			'<div id="dialog_body_' + this.id + '"></div>',
			
			'<table border="0" cellspacing="0" cellpadding="0" style="padding: 0px;display:none;">',
				'<tr>',
					'<td width="9" height="9"><img src="images/dialog_header_lt.png" width="9" height="9" ' + pngClass + '\/><\/td>',
					'<td ><img src="images/dialog_header_center_top.png" width="100%" height="9" ' + pngClass + '\/><\/td>',
					'<td width="9" height="9"><img src="images/dialog_header_rt.png" width="9" height="9" ' + pngClass + '\/><\/td>',
				'</tr>',
				'<tr>',
					'<td height="20"><img src="images/dialog_header_lb.png" width="9" height="20" ' + pngClass + '\/><\/td>',
					'<td >',
						'<span  class="dialog-title">' + this.title + '<\/span>',
						'<div  class="dialog-icon-close dialog-icon-normal"><\/div>',
					'<\/td>',
					'<td height="20"><img src="images/dialog_header_rb.png" width="9" height="20" ' + pngClass + '\/><\/td>',
				'<\/tr>',
				'<tr>',
					'<td id="dialog_height_ctrl_l_' + this.id + '"><img src="images/dialog_body_left.png" height="100%" width="9" ' + pngClass + '\/><\/td>',
					'<td  class="dialog-body"><\/td>',
					'<td id="dialog_height_ctrl_r_' + this.id + '"><img src="images/dialog_body_right.png" height="100%" width="9" ' + pngClass + '\/><\/td>',
				'<\/tr>',
				'<tr>',
					'<td height="8"><img src="images/dialog_body_bottom_left.png" width="9" height="8" ' + pngClass + '\/><\/td>',
					'<td><img src="images/dialog_body_bottom_center.png" width="100%" height="8" ' + pngClass + '\/><\/td>',
					'<td><img src="images/dialog_body_bottom_right.png" width="9" height="8" ' + pngClass + '\/><\/td>',
				'<\/tr>',
			'<\/table>'
			);
	
		with(div.style) {
			left = "0"; 
			top = "0";
			width = this.options.width + "px";
			height = this.options.height + "px";
			position = "absolute";
			zIndex = 1009;
			display = "none";
		}

		this.titleBar = $('dialog_header_' + this.id);
		this.titleSpan = $('dialog_title_' + this.id);
		this.bodyDiv = $('dialog_body_' + this.id);
		this.closeBtn = $('dialog_close_btn_' + this.id);
		this.widthCtrl = $('dialog_width_ctrl_' + this.id);
		this.leftHeightCtrl = $('dialog_height_ctrl_l_' + this.id);
		this.rightHeightCtrl = $('dialog_height_ctrl_r_' + this.id);
		
		this.closeBtn.onmouseover = function() { this.className = "dialog-icon-close dialog-icon-hover";  }
		this.closeBtn.onmouseout = function() { this.className = "dialog-icon-close dialog-icon-normal"; }
		this.closeBtn.onmousedown = function() { this.className = "dialog-icon-close dialog-icon-pressed"; }
		this.closeBtn.onmouseup = function() { this.className = "dialog-icon-close dialog-icon-hover"; }
		var _this = this;
		this.closeBtn.onclick = function() { _this.hide(); }
		
		new Draggable(div, {handle:this.titleBar, starteffect:null, endeffect:null, zindex:1009});
		
		this.setWidth(this.options.width);
		this.setHeight(this.options.height);
		
		if (this.options.modal) {
			this.bgIframe = new BackgroundIframe();

			this.bg = document.createElement("div");
			this.bg.className = "DialogUnderlay";
			with(this.bg.style) {
				position = "absolute";
				left = top = "0px";
				zIndex = 1008;
				display = "none";
			}
			if (this.options.bgColor)
				this.setBackgroundColor(this.options.bgColor);
	
			b.appendChild(this.bg);
			this.bgIframe.setZIndex(this.bg);
		}
	},
	
	setWidth: function(w) {
		w = w - 18;
		if (w < 1) w = 1;
		this.widthCtrl.style.width = w + 'px';
		this.closeBtn.style.left = (w - 9) + 'px';
	},
	
	setHeight: function(h) {
		h = h - 37;
		if (h < 1) h = 1;
		this.leftHeightCtrl.style.height = h + 'px';
		this.rightHeightCtrl.style.height = h + 'px';
	},
	
	setTitle: function(title) {
		this.title = title;
		this.titleSpan.innerHTML = this.title;
	},
	
	setContent: function(content) {
		if ( typeof content == 'string') {
			this.bodyDiv.innerHTML = content;
		} else if(content.nodeType != undefined) {
			if (content.parentNode) {
				content.parentNode.removeChild(content);
			}
			if (Element.getStyle(content, 'position') != 'relative') {
				content.style.position = 'relative';
			}
			this.bodyDiv.appendChild(content);
			
			if (Element.getStyle(content, 'display') == 'none')
				content.style.display = 'block';
		}
		if (this.options.onContentUpdate) {
			this.options.onContentUpdate(this, content);
		}
	},
	
	setBackgroundColor: function(color) {
		if (!this.options.modal) return;
		
		this.bg.style.backgroundColor = color;
		return this.options.bgColor = color;
	},
	
	setBackgroundOpacity: function(op) {
		if (!this.options.modal || !this.options.bgColor) return;
		if(arguments.length == 0) { op = this.options.bgOpacity; }
		Element.setOpacity(this.bg, op);
		try {
			this.options.bgOpacity = Element.getOpacity(this.bg);
		} catch (e) {
			this.options.bgOpacity = op;
		}
		return this.options.bgOpacity;
	},

	sizeBackground: function() {
		if (!this.options.modal) return;
	
		if(this.options.bgOpacity > 0) {
			var h = document.documentElement.scrollHeight || document.body.scrollHeight;
			var w = Position.getViewportWidth();
			
			if (this.options.minBgWidth) {
				w = w < this.options.minBgWidth ? this.options.minBgWidth : w;
			}
			if (this.options.minBgHeight) {
				h = h < this.options.minBgHeight ? this.options.minBgHeight : h;
			}
			
			this.bg.style.width = w + "px";
			this.bg.style.height = h + "px";
			this.bgIframe.size([0, 0, w, h]);
		} else {
			this.bgIframe.size(this.htmlElement);
		}
	},

	showBackground: function() {
		if (!this.options.modal) return;
	
		this.sizeBackground();
		this.bgIframe.show();
		if(this.options.bgColor && this.options.bgOpacity > 0) {
			if (this.options.bgFade) {
				Element.setOpacity(this.bg, 0.0);
				new Effect.Fade(this.bg, { from: 0.0, to: this.options.bgOpacity });
			} else {
				Element.setOpacity(this.bg, this.options.bgOpacity);
			}
		}
		this.bg.style.display = "block";
	},

	placeDialog: function() {
		var scroll_offset = Position.getScrollOffset();
		var viewport_size = Position.getViewportSize();

		// find the size of the dialog
		this.htmlElement.style.display = "block";
		var w = this.htmlElement.offsetWidth;
		var h = this.htmlElement.offsetHeight;
		this.htmlElement.style.display = "none";

		var x = scroll_offset[0] + (viewport_size[0] - w)/2;
		var y = scroll_offset[1] + (viewport_size[1] - h)/2;

		with(this.htmlElement.style) {
			left = x + "px";
			top = y + "px";
		}

		// tied to domNode, so we need to update the position
		if(this.options.bgOpacity == 0) {
			this.bgIframe.size([x, y, w, h]);
		}
	},

	show: function() {
		this.setBackgroundOpacity();
		this.placeDialog();
		this.showBackground();
		
		switch((this.options.effect||"").toLowerCase()) {
			case "fade":
				var _this = this;
				
				if (this.anim && this.anim.state != 'finished') this.anim.cancel();
				
				Element.setOpacity(this.htmlElement, 0.0);
				this.htmlElement.style.display = "block";
				this.anim = new Effect.Fade(this.htmlElement, {
					from: 0.0,
					to: 1.0,
					onAfterFinish: function() { 
						if (_this.options.onShow) _this.options.onShow(_this); 
						_this.anim = null;
					}
				});
				break;
			default:
				this.htmlElement.style.display = "block";
				if(this.options.onShow) {
					this.options.onShow(this);
				}
				break;
		}
		
		if (this.options.focusElement) { 
			$(this.options.focusElement).focus(); 
		}

		// FIXME: moz doesn't generate onscroll events for mouse or key scrolling (wtf)
		// we should create a fake event by polling the scrolltop/scrollleft every X ms.
		// this smells like it should be a dojo feature rather than just for this widget.

		if (this.options.followScroll && !this._scrollConnected){
			this._scrollConnected = true;
			Event.observe(window, "scroll", this.onScrollHandler, false);
		}

		if(!this._resizeConnected) {
			this._resizeConnected = true;
			Event.observe(window, "resize", this.onResizeHandler, false);
		}
	},

	hide: function(){
		// workaround for FF focus going into outer space
		if (this.options.focusElement) { 
			$(this.options.focusElement).focus(); 
			$(this.options.focusElement).blur();
		}
		
		if (this.options.modal) {
			this.bg.style.display = "none";
			this.bgIframe.hide();		
		}
		if (this.options.hideEffect) {
			switch((this.options.hideEffect).toLowerCase()) {
				case "fade":
					var _this = this;
					if(this.anim && this.anim.state != 'finished'){ this.anim.cancel(); }
					
					this.anim = new Effect.Fade(this.htmlElement, {
						to: 0.0,
						onAfterFinish: function(effect) {
							_this.htmlElement.style.display = "none";
							if(_this.options.onHide) {
								_this.options.onHide(_this);
							}
							_this.anim = null;
						}
					});
					break;
				default:
					this.htmlElement.style.display = "none";
					if(this.options.onHide) {
						this.options.onHide(this);
					}
					break;
			}
		} else {
			this.htmlElement.style.display = "none";
			if(this.options.onHide) {
				this.options.onHide(this);
			}
		}

		if (this.bg)
			this.bg.style.width = this.bg.style.height = "1px";

		if (this._scrollConnected) {
			this._scrollConnected = false;
			Event.stopObserving(window, "scroll", this.onScrollHandler, false);
		}

		if(this._resizeConnected) {
			this._resizeConnected = false;
			Event.stopObserving(window, "resize", this.onResizeHandler, false);
		}
	},
	
	close: this.hide,

	setCloseControl: function(node) {
		Event.observe(node, "onclick", this.hide.bindAsEventListener(this));
	},

	setShowControl: function(node) {
		Event.observe(node, "onclick", this.show.bindAsEventListener(this));
	},

	onScroll: function(e) {
		this.placeDialog();
		this.htmlElement.style.display = "block";
	},

	onResize: function(e) {
		this.sizeBackground();
	}
}


/**
 * For IE z-index schenanigans
 * See Dialog widget for sample use
 */
var BackgroundIframe = Class.create();

BackgroundIframe.prototype = {
	initialize: function() {
		this.ie = (navigator.userAgent.toLowerCase().indexOf("msie") != -1);
		this.iframe = null;
		this.visible = false;
		this.enabled = true;
		this.sizeNode = null;
		this.sizeCoords = null;
	
		if(this.ie) {
			this.iframe = document.createElement("<iframe frameborder='0' src='about:blank'>");
			var s = this.iframe.style;
			s.position = "absolute";
			s.left = s.top = "0px";
			s.zIndex = 2;
			s.display = "none";
			Element.setOpacity(this.iframe, 0.0);
			document.body.appendChild(this.iframe);
		} else {
			this.enabled = false;
		}
	},
	
	size: function(node /* or coords */) {
		if(!this.ie || !this.enabled) { return; }

		//if(dojo.dom.isNode(node)) {
			this.sizeNode = node;
		//} else if(arguments.length > 0) {
		//	this.sizeNode = null;
		//	this.sizeCoords = node;
		//}
		this.update();
	},

	update: function() {
		if(!this.ie || !this.enabled) { return; }

		if(this.sizeNode) {
			this.sizeCoords = Position.toCoordinateArray(this.sizeNode, true);
		} else if(this.sizeCoords) {
			this.sizeCoords = Position.toCoordinateArray(this.sizeCoords, true);
		} else {
			return;
		}

		var s = this.iframe.style;
		var dims = this.sizeCoords;
		s.width = dims.w + "px";
		s.height = dims.h + "px";
		s.left = dims.x + "px";
		s.top = dims.y + "px";
	},

	setZIndex: function(node /* or number */) {
		if(!this.ie || !this.enabled) { return; }

		if(isNaN(node)) {
			this.iframe.zIndex = Element.getStyle(node, "z-index") - 1;
		} else {
			this.iframe.zIndex = node;
		}
	},

	show: function(node /* or coords */) {
		if(!this.ie || !this.enabled) { return; }

		this.size(node);
		this.iframe.style.display = "block";
	},

	hide: function() {
		if(!this.ie) { return; }
		var s = this.iframe.style;
		s.display = "none";
		s.width = s.height = "1px";
	},

	remove: function() {
		document.body.removeChild(this.iframe);
	}	
}