var Window = Class.create();
Window.prototype = {
	URL : "content/jsp/dispatcher.jsp",
	params : "",
	onRequest : function() {},
	initialize : function(option) {
		this._initialize(option);
		if(this.parent) this.parent.child = this;
	},
	_initialize : function(option) {
		Object.extend(this, option);
		this.state = option.state || "window";
		this.createElement();
		this.contextMenuHandler = option.contextMenuHandler || function(){};
		this.subtract = {widths : [], heights : [$("javawideTaskManager"), $("copyright"), this.contentHeader, this.contentFooter]};
		this.fixed = {width: 0, height : 0};
		if(option.fixed) {
			var fixed = eval("["+option.fixed+"]");
			if(fixed[0]) {
				this.fixed = fixed[0];
			}
		}
		if(option.id) {
			if(!this.link)
				this.link = $(option.id).getAttribute("link");
			if(option.parentId) {
				this.parent = taskManager.find($(option.parentId).getAttribute("title"));
			}
			this.setTitle(option.title);
			if(this.link && !this.lazyLoad) {
				this.request();
			}
			this.popupCheck(option);
		}
		if(option.initCallback) {
			eval(option.initCallback);
		}
		this.enStyle();
	},
	hasParent : function() {
		if(!this.parent) {
			this.setContent("이 접근은 허용되지 않았습니다. 부모 창을 통해서 열어야 합니다.<br />" +
			"This access is not allowed because you have no parent window. You need to open this window using parent window.");
		}
		return this.parent;
	},
	buildElement : function(target, elementAttr, styles) {
		elementAttr = elementAttr || {};
		elementAttr.elementName = elementAttr.elementName || "div";
		var element = document.createElement(elementAttr.elementName);
		for(var attr in elementAttr) {
			if("elementName" == attr) continue;
			element.setAttribute(attr, elementAttr[attr]);
		}
		var eStyle = element.style;
		for(var style in styles) {
			eStyle[style] = styles[style];
		}
		target.appendChild(element);
		return $(element);
	},
	createExternalLink : function(name, link) {
		var url = document.createElement("a");
		url.setAttribute("href", link);
		url.setAttribute("target", "_blank");
		url.appendChild(document.createTextNode(name));
		return url;
	},
	popupCheck : function(option) {
		window.taskManager.addTask(this);
		if("popup" == option.state) {
			this.setPosition({x : (document.documentElement.clientWidth || document.body.clientWidth) - this.fixed.width, y: parseInt(this.element.style.top || "0")});
			Event.observe(window, "resize", function() {
				if(this.maximized) return;
				this.setPosition({x : (document.documentElement.clientWidth || document.body.clientWidth) - this.fixed.width, y : parseInt(this.element.style.top || "0")});
			}.bind(this));
		}
	},
	request : function() {
		new Ajax.Request(this.URL, {method: "post", parameters: "contentId=" + this.link + "&t=" + new Date().getTime() + this.params,
			onSuccess : function(response) {
				this.setContent(response.responseText);
				this.onRequest();
			}.bindAsEventListener(this),
			onFailure : function(response) {
				this.setContent("요청한 link가 없거나 서버 오류가 발생했습니다.");
			}.bindAsEventListener(this)}
		);
	},
	enStyle : function() {
		this.element.className = "JavawideWindow";
		this.titlebar.className = "JavawideWindow_TitleBar";
		this.titlearea.className = "JavawideWindow_TitleArea";
		this.contentHeader.className = "JavawideWindow_ContentHeader";
		this.content.className = "JavawideWindow_Content";
		this.contentFooter.className = "JavawideWindow_ContentFooter";
		this.statusbar.className = "JavawideWindow_StatusBar";
		this.statusmessage.className = "JavawideWindow_StatusMessage";
		this.statusprogress.className = "JavawideWindow_StatusProgress";
	},
	createElement : function() {
		this.element = this.buildElement(document.body, null, {width: "300px"});
		Event.observe(this.element, "contextmenu", function(event) {
			Event.stop(event);
			this.contextMenuHandler(event);
		}.bindAsEventListener(this));
		this.createTitleBar();
		this.addButtons();
		this.createContent();
		this.createStatusBar();
		this.createToolTip();
		Event.observe(this.titlebar, "click", function(event) {
			taskManager.setToFront(this);
		}.bindAsEventListener(this));
		Event.observe(this.statusbar, "click", function(event) {
			taskManager.setToFront(this);
		}.bindAsEventListener(this));
	},
	createTitleBar : function() {
		this.titlebar = this.buildElement(this.element, null, {height: "30px"});
		this.titlearea = this.buildElement(this.titlebar, null, {height: "30px"});
		new Dragger({src: this.titlearea, target: this});
	},
	createContent : function() {
		this.contentHeader = this.buildElement(this.element);
		this.content = this.buildElement(this.element);
		this.contentFooter = this.buildElement(this.element);
	},
	createStatusBar : function() {
		this.statusbar = this.buildElement(this.element, null, {height: "30px"});
		this.statusmessage = this.buildElement(this.statusbar, null, {height: "30px"});
		this.statusprogress = this.buildElement(this.statusbar, null, {width: "100px", height: "30px"});
		new Resizer({src : this.statusprogress, target : this});
	},
	setVisible : function(visible) {
		this.visible = visible ? "visible" : "hidden";
		this.element.style.visibility = this.visible;
		taskManager.setToFront(this);
	},
	toggle : function() {
		this.setVisible(("hidden" == this.visible));
	},
	setPosition : function(pos) {
		var style = this.element.style;
		style.position = "absolute";
		style.left = pos.x + "px";
		style.top = pos.y + "px";
	},
	setTitle : function(title) {
		if(title.length > 20) {
			this.resizeTo(640);
		}
		this.title = title;
		this.titlearea.innerHTML = title;
	},
	getTitle : function() {
		return this.title;
	},
	setContentHeader : function(header) {
		this.contentHeader.innerHTML = header;
	},
	addContentHeader : function(elem) {
		this.contentHeader.appendChild(elem);
	},
	setContent : function(content) {
		this.content.innerHTML = content;
		this.resizeToContent();
	},
	addContentElement : function(elem) {
		this.content.appendChild(elem);
		this.resizeToContent();
	},
	setContentFooter : function(footer) {
		this.contentFooter.innerHTML = footer;
	},
	addContentFooterElement : function(elem) {
		this.contentFooter.appendChild(elem);
	},
	log : function(data) {
		if(!window.debug) return;
		this.content.innerHTML += (""+data).escapeHTML();
		if(this.content.innerHTML.length > 1000) {
			this.content.style.height = "250px";
		}
		this.setStatusMessage("Content Length : " + this.content.innerHTML.length);
	},
	setStatusMessage : function(statusMessage) {
		this.statusmessage.innerHTML = statusMessage;
	},
	setProgressImageSrc : function(imageSrc) {
		if(null == this.progressImage) this.attachEmptyImageToProgress();
		this.progressImage.style.backgroundImage = "url("+imageSrc+")";
		this.progressImage.style.backgroundRepeat = "repeat-x";
	},
	setProcessed : function(processed) {
		if(null == this.progressImage) this.attachEmptyImageToProgress();
		this.progressImage.style.width = processed + "%";
	},
	attachEmptyImageToProgress : function() {
		this.progressImage = this.buildElement(this.statusprogress);
		this.progressImage.setStyle({ width : "0%", height: "100%", backgroundColor : "orange",
		float : "left"});
	},
	addButtons : function() {
		this.buttonarea = this.buildElement(this.titlebar, null, {width: "85px", height: "30px", cursor: "pointer"});
		this.buttonarea.className = "JavawideWindow_ButtonArea";
		this.minimizeImg = this.buildElement(this.buttonarea, {elementName: "img", src: "style/img/hide.png"}, {width: "25px", height: "25px"});
		Event.observe(this.minimizeImg, "click", function(event) {
			this.setVisible(false);
		}.bindAsEventListener(this));
		this.maximizeImg = this.buildElement(this.buttonarea, {elementName: "img", src: "style/img/maximize.png"}, {width: "25px", height: "25px"});
		this.maximizeHandler = function(event) {
			if(!this.maximized) {
				this.saveState();
				this.enlarge();
				this.maxEventHandler = function(event) {
					this.enlarge();
				}.bindAsEventListener(this);
				Event.observe(window, "resize", this.maxEventHandler);
			} else {
				this.restoreState();
				Event.stopObserving(window, "resize", this.maxEventHandler);
			}
		}.bindAsEventListener(this);
		Event.observe(this.maximizeImg, "click", this.maximizeHandler);
		this.closeImg = this.buildElement(this.buttonarea, {elementName: "img", src: "style/img/close.png"}, {width: "25px", height: "25px"});
		this.closeHandler = function(event) {
			window.taskManager.removeTask(this);
			if(this.userCloseHandler) {
				this.userCloseHandler();
			}
		}.bindAsEventListener(this);
		Event.observe(this.closeImg, "click", this.closeHandler);
	},
	saveState : function() {
		this.originalWidth = this.element.getWidth();
		this.originalHeight = this.element.getHeight();
		this.originalContentHeight = this.content.getHeight();
		this.originalLocation = {x: this.element.offsetLeft, y: this.element.offsetTop};
	},
	restoreState : function() {
		this.maximizeImg.setAttribute("src", "style/img/maximize.png");
		this.setPosition(this.originalLocation);
		this.resizeTo(this.originalWidth, this.originalHeight);
		this.content.style.height = this.originalContentHeight + "px";
		this.maximized = false;
	},
	enlarge : function() {
		this.maximizeImg.setAttribute("src", "style/img/minimize.png");
		var deskDim = { width: document.documentElement.clientWidth || document.body.clientWidth,
			height: document.documentElement.clientHeight || document.body.clientHeight };
		var taskDim = taskManager.element.getDimensions();
		var copyrightHeight = $("copyright").getHeight();
		var candidateWidth = deskDim.width;
		var candidateHeight = deskDim.height;
		this.subtract.widths.each(function(elem) {
			candidateWidth -= elem.getWidth();
		});
		this.subtract.heights.each(function(elem) {
			candidateHeight -= elem.getHeight();
		});
		this.resizeTo(candidateWidth, candidateHeight);
		this.content.style.width = "100%";
		this.content.style.height = (candidateHeight - $(this.buttonarea).getHeight() - $(this.statusbar).getHeight())+ "px";
		this.setPosition({ x: 0, y: taskDim.height});
		this.maximized = true;
	},
	resizeTo : function(width, height) {
		if(width) {
			this.element.style.width = width + "px";
		}
		if(height) {
			this.element.style.height = height + "px";
		}
	},
	resizeToContent : function() {
		if(this.maximized) return;
		var sumHeight = 0;
		var	maxWidth = 0;
		if(this.content.innerHTML.length <= 5000) {
			var childs = this.content.getElementsBySelector("*");
			var aChild = null;
			childs.each(function(child) {
				aChild = $(child);
				if(!aChild.visible()) return;
				var dim = aChild.getDimensions();
				maxWidth = Math.max(maxWidth, dim.width);
				sumHeight += dim.height;
				if(sumHeight > 599) {
					throw $break;
				}
			});
		} else {
			maxWidth = 800;
			sumHeight = 600;
		}
		maxWidth = Math.min(maxWidth, 800);
		sumHeight = Math.min(sumHeight, 600);
		var fixed = this.fixed;
		if(fixed.width)
			maxWidth = fixed.width;
		if(fixed.height)
			sumHeight = fixed.height;
		this.content.style.width = maxWidth + "px";
		this.content.style.height = sumHeight + "px";
		var maxWidth = Math.max(300, maxWidth);
		this.resizeTo(maxWidth, sumHeight);
		this.setStatusMessage("Content Length : " + this.content.innerHTML.length);
		if(this.titlebar.getWidth() - this.buttonarea.getWidth() - 5 > 0)
			this.titlearea.setStyle({width: this.titlebar.getWidth() - this.buttonarea.getWidth() - 5 + "px"});
	},
	cannotClose : function() {
		Event.stopObserving(this.closeImg, "click", this.closeHandler);
		$(this.closeImg).setStyle({display: "none"});
	},
	cannotMaximize : function() {
		Event.stopObserving(this.maximizeImg, "click", this.maximizeHandler);
		$(this.maximizeImg).hide();
	},
	createToolTip : function() {
		if(this.tooltipElem) return;
		this.tooltipElem = $(document.createElement("div"));
		this.tooltipElem.className = "JavawideWindow_ToolTip";
		this.tooltipElem.style.position = "absolute";
		this.tooltipElem.style.visibility = "hidden";
		document.body.appendChild(this.tooltipElem);
	},
	showToolTip : function(x, y) {
		if("visible" == this.tooltipElem.style.visibility) return;
		this.tooltipElem.style.visibility = "visible";
		this.tooltipElem.style.left = x;
		this.tooltipElem.style.top = y;
		this.tooltipElem.style.zIndex = "99999999";
		this.tooltipElem.innerHTML = this.tooltip || "This is Tool Tip";
	},
	hideToolTip : function() {
		this.tooltipElem.style.visibility = "hidden";
	},
	moveRight : function(px) {
		this.element.style.left = parseInt(this.element.style.left) + px + "px";
	},
	moveBottom : function(px) {
		this.element.style.top = parseInt(this.element.style.top) + px + "px";
	},
	close : function() {},
	wordwrap : function(str) {
		var tags = str.match(new RegExp("(<([^> ]*)([^>]*)>)([^<]*)(</\2>)*"));
		if(tags && tags[0] && tags[1])
			tags = tags[0].substring(tags[0].length - 1) == ">" ? tags[0] : tags[1];
		if(tags) return str;
		var len = str.length;
		var appender = "";
		var before = str;
		var after = str;
		for(var i=0; i< len; i+=10) {
			before = after.substring(0, 10);
			after = after.substring(10);
			appender += before + "<wbr />";
		}
		return appender;
	}
}