var DRAGWIN_G_ZINDEX = 500;// Global z-index for windows
var dragWinHash = $H();
/**
 * Window that can be draged and moved
 */
var DragWin = Class.create();
DragWin.prototype = {
	mainId:			"",
	// for apearence
	maxHeght:		300,// dragBody's max height 0==automatic
	// for ...
//	noChace:		true,
	disableZIndex:	false,
	// for drag & move
	canDrag:		false,
	mainX:			0,
	mainY:			0,
	mouseX:			0,
	mouseY:			0,
	/**
	 * Create a dragable window with some default features
	 * @param {Object} mainId
	 */
	initialize: function(mainId) {
		if(window.opera) {
			document.write("<input type='hidden' id='Q' value=' '>");
		}
		var idSuffix = Math.floor(Math.random() * 1000000);
		this.mainId = mainId ? mainId : "dragMain" + idSuffix;
		
		// main
		this.dragMain = document.createElement("div");
		this.dragMain.id = this.mainId;
		this.dragMain.className = "dragMain";
		this.dragMain.style.width = "400px";
		
		// dragHeader
		this.dragHeader = document.createElement("div");
		this.dragHeader.id = "dragHeader" + idSuffix;
		this.dragHeader.className = "dragHeader";
		this.dragMain.appendChild(this.dragHeader);
		
		// dragHeader ==  briefHead + optionHead
		var headerTbl = document.createElement("table");
		headerTbl.width = "100%";
		var oneRow = headerTbl.insertRow(-1);
		
		this.briefHead = oneRow.insertCell(-1);
		
		this.optionHead = oneRow.insertCell(-1);
		this.optionHead.align = "right";
		this.optionHead.width = 40;
		this.optionHead.className = "optionHead";
		
		this.closeLink = document.createElement("a");
		this.closeLink.innerHTML = "x";
		this.closeLink.href = "javascript: void(0);";
		this.closeLink.onclick = this.closeWin.bind(this);
		
		this.optionHead.appendChild(this.closeLink);
		
		this.dragHeader.appendChild(headerTbl);
		
		// body
		this.dragBody = document.createElement("div");
		this.dragBody.id = "dragBody" + idSuffix;
		this.dragBody.className = "dragBody";
		this.dragMain.appendChild(this.dragBody);
		
		// event handlers
		this.dragMain.onmousedown = this.topZIndex.bind(this);
		this.dragHeader.onmousedown = this.startDrag.bind(this);
		document.onmouseup = this.stopDrag.bind(this);
		
		dragWinHash[this.mainId] = this;
	},
	/**
	 * setters - or it seems
	 */
	setMaxHeight: function(maxHeght) {
		maxHeght = Math.floor(maxHeght);
		this.maxHeght = maxHeght ? maxHeght : 0;
	},
	/**
	 * Turn this on(true) so you can avoid some bug when you do something on select element
	 * @param {Object} bEnable
	 */
	setDisableZIndex: function(bDisabled) {
		this.disableZIndex = (bDisabled === true);
	},
	/**
	 * Set drag window's width, default 400px
	 * @param {Object} width
	 */
	setWidth: function(mainWidth) {
		mainWidth = Math.floor(mainWidth);
		this.dragMain.style.width = (mainWidth && mainWidth > 50) ? mainWidth + "px" : "400px";
	},
	/**
	 * Set drag head's innerHTML and align
	 * @param {Object} headInner
	 * @param {Object} headAlign
	 * @param {Object} headVAlign
	 */
	setHeaderInner: function(briefInner, briefAlign, briefVAlign) {
		this.briefHead.align = briefAlign ? briefAlign : "center";
		this.briefHead.valign = briefVAlign ? briefVAlign : "bottom";
		this.briefHead.innerHTML = briefInner ? briefInner : "";
	},
	/**
	 * Set the width of optionHead TD
	 * @param {Object} optionWidth
	 */
	setOptionWidth: function(optionWidth) {
		optionWidth = Math.floor(optionWidth);
		this.optionHead.width = (optionWidth && optionWidth > 0) ? optionWidth : 30;
	},
	/**
	 * Set the close link's innerHTML
	 * @param {Object} closeText
	 */
	setCloseInner: function(closeText) {
		this.closeLink.innerHTML = closeText ? closeText : "x";
	},
	/**
	 * Set the innerHTML of dragBody
	 * @param {Object} bodyInner
	 */
	setBodyInner: function(bodyInner) {
		this.dragBody.innerHTML = bodyInner ? bodyInner : "";
	},
	/**
	 * Show the window in document.body
	 */
	show: function(con) {
		con = $(con) || document.body;
		con.appendChild(this.dragMain);
		// locate the window to center of screen
		this.dragMain.style.left = (document.body.clientWidth - this.dragMain.offsetWidth)/2 + document.body.scrollLeft;
		this.dragMain.style.top = (window.screen.height - this.dragMain.offsetHeight)/2 -250 + document.body.scrollTop;
		this.dragMain.style.zIndex = DRAGWIN_G_ZINDEX++;
		this.adjustHeight();
	},
	/**
	 * Adjust dragBody's height according to this.maxHeight
	 * @private
	 */
	adjustHeight: function() {
		if(this.maxHeght > 0 && this.dragBody.offsetHeight > this.maxHeght) {
			this.dragBody.style.overflow = "auto";
			this.dragBody.style.height = this.maxHeght + "px";
		} else {
			this.dragBody.style.overflow = "hidden";
		}
	},
	/**
	 * 
	 * @param {Object} url
	 * @param {Object} param
	 */
	ajaxUpdateBodyInner: function(url, param) {
		var updater = new GlobalUpdater(this.dragBody, url, param);
		updater.setMsgInside(true);
		updater.setHintInside(true);
		updater.update();
		setTimeout(this.adjustHeight.bind(this), 500);
	},
	/**
	 * Close the whole window
	 */
	closeWin: function() {
		this.dragBody.innerHTML = "";
		this.dragMain.parentNode.removeChild(this.dragMain);
		dragWinHash[this.mainId] = null;
	},
	/**
	 * Make this window on top of any other widow
	 */
	topZIndex: function() {
		if(!this.disableZIndex) {
			this.dragMain.style.zIndex = DRAGWIN_G_ZINDEX++;
		}
	},
	/**
	 * When mousedown on dragHead, prepare for dragging
	 * @param {Object} e
	 */
	startDrag: function(ev) {
		if(!ev) {
			ev = window.event;
		}
		if (window.opera) {
			$("Q").focus();
		}
		this.canDrag = true;
		
		mainX = parseInt(this.getStyleValue(this.dragMain, "left")) | 0;
		mainY = parseInt(this.getStyleValue(this.dragMain, "top")) | 0;
		mouseX = ev.clientX;
		mouseY = ev.clientY;
		
		this.dragHeader.style.cursor = "move";
		this.briefHead.style.cursor = "move";
		
		document.onmousemove = this.moving.bind(this);
	},
	/**
	 * When mouseup on document
	 */
	stopDrag: function() {
		this.canDrag = false;
		this.dragHeader.style.cursor = "default";
		this.briefHead.style.cursor = "default";
		this.dragHeader.onmousemove = null;
	},
	/**
	 * Do when moving
	 * @param {Object} e
	 */
	moving: function(ev) {
		if(!ev) {
			ev = window.event;
		}
		if(this.canDrag) {
			this.dragMain.style.left = mainX + ev.clientX - mouseX + "px";
			this.dragMain.style.top  = mainY + ev.clientY - mouseY + "px";
			return false;
		}
	},
	/**
	 * Copied from web, don't quite understand it
	 * @param {Object} d
	 * @param {Object} a
	 */
	getStyleValue: function(elem, styleName) {
		if(elem.currentStyle) {
			return elem.currentStyle[styleName];
		} else {
			return document.defaultView.getComputedStyle(elem, null)[styleName];
		}
	}
};