Dialog =
	function(title, win)
	{
		this.window = win || window;
		this.document = this.window.document;
		this.frame_elem = null;
		this.frame_obj = null;
		this.offset = new MochiKit.DOM.Coordinates(0,0);
		this.position = this.get_scroll_position();
		this.dragging = false;
		this.title = title;
		this.is_modal = false;
	}

Dialog.prototype.frame_create =
	function()
	{
		var n = this.window.frames.length;
		MochiKit.DOM.withDocument(this.document,
			MochiKit.Base.bind(
				function()
				{
					this.frame_elem = MochiKit.DOM.createDOM("IFRAME", 
						{"src": "/blank.html", 
						 "style": {
						 	"position": "absolute", 
						 	"visibility": "hidden", 
						 	"top": "0px", 
						 	"left": "0px", 
						 	"width": "250px", 
						 	"height": "150px", 
						 	"border": "2px solid gray", 
						 	"padding": "0px"
						 },
						 "scrolling": "no",
						 "frameBorder": "0",
						 "marginHeight": "0",
						 "marginWidth": "0"});
					MochiKit.DOM.appendChildNodes(currentDocument().body, this.frame_elem);
				}, this));
		if(this.window.frames.length==n+1) {
			this.frame_no = n;
		} else {
			alert("Error: no way to identify new frame");
			return;
		}
		this.frame_obj = this.window.frames[this.frame_no];
		this.frame_init();
	}

Dialog.prototype.frame_destroy =
	function()
	{
		_dm_.remove(this);
		MochiKit.DOM.withDocument(this.document,
			MochiKit.Base.bind(
				function()
				{
					MochiKit.DOM.removeElement(this.frame_elem);
				}, this));
	}

Dialog.prototype.frame_init =
	function()
	{
//		alert("Dialog.frame_init()");
		var doc = this.frame_obj.document;
		
		var frame_dim = MochiKit.DOM.elementDimensions(this.frame_elem);
		var title_height = 18;
		var main_height = frame_dim.h - title_height - 4;

		doc.open();
		doc.writeln('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">');
		doc.writeln('<html>');
		doc.writeln('<head>');
		doc.writeln('<style type="text/css">@import "/includes/stylesheets/Dialog.css";</style>');
		doc.writeln('</head>');
		doc.writeln('<body style="background-color: white">');
		doc.writeln('<div id="dialog-titlebar" style="width: 100%; height: ' + title_height + 'px; margin: 0px; background-color: darkblue; color: white; cursor: move;">');
		doc.writeln('<span id="dialog-title" style="float: left;"></span>');
		doc.writeln('<img id="dialog-close" src="/images/close-15x13.gif" style="float: right; margin: 2px; cursor: pointer;" />');
		doc.writeln('</div>');
		doc.writeln('<div id="dialog-main" style="width: 100%; height: ' + main_height + 'px; margin: 0px; overflow: scroll;"></div>');
		doc.writeln('</body>');
		doc.writeln('</html>');
		doc.close();

		this.set_title(this.title);

		this.add_handle(this.frame_obj.document.getElementById("dialog-titlebar"));
		connect(this.frame_obj.document, "onmouseup", this, this.stop_drag);
		connect(this.document, "onmousemove", MochiKit.Base.bind(this.follow_mouse, this, "document"));
		connect(this.frame_obj.document, "onmousemove", MochiKit.Base.bind(this.follow_mouse, this, "frame"));
		connect(this.frame_obj.document, "onmousedown", this, this.bring_to_front);
//		connect(this.document.body, "onscroll", this, this.follow_scroll);
		MochiKit.DOM.withDocument(this.frame_obj.document,
			MochiKit.Base.bind(
				function()
				{
					connect("dialog-close", "onclick", this, this.hide);
				}, this));
	}

Dialog.prototype.set_title =
	function(new_title)
	{
		this.title = new_title;
		MochiKit.DOM.withDocument(this.frame_obj.document,
			MochiKit.Base.bind(
				function()
				{
					MochiKit.DOM.replaceChildNodes($('dialog-title'), this.title);
				}, this));
	}

Dialog.prototype.show =
	function()
	{
		if(this.frame_elem) {
			_dm_.remove(this);
			_dm_.add(this);
			this.position = this.get_scroll_position();
			MochiKit.DOM.setElementPosition(this.frame_elem, this.position);
			this.frame_elem.style.visibility = "visible";
			this._paint();
			signal(this, "onopen");
		}
	}

Dialog.prototype.hide =
	function()
	{
		if(this.frame_elem) {
			_dm_.remove(this);
			this.frame_elem.style.visibility = "hidden";
			signal(this, "onclose");
		}
	}

Dialog.prototype.bring_to_front =
	function()
	{
		_dm_.bring_to_front(this);
	}

Dialog.prototype.set_zindex =
	function(z)
	{
		if(this.frame_elem) {
			this.frame_elem.style.zIndex = z;
//			alert("Setting zIndex to " + z);
		}
	}

Dialog.prototype.resize =
	function(w, h)
	{
		this.frame_elem.style.width = w + "px";
		this.frame_elem.style.height = h + "px";
	}

Dialog.prototype.destroy =
	function()
	{
		MochiKit.DOM.withDocument(this.document,
			MochiKit.Base.bind(
				function()
				{
					MochiKit.DOM.removeElement(this.frame_elem);
				}, this));
	}

Dialog.prototype.repaint =
	function()
	{
		this._paint();
	}

Dialog.prototype._paint =
	function()
	{
		var MB = MochiKit.Base;
		var MD = MochiKit.DOM;
		MD.withDocument(this.frame_obj.document, 
			MB.bind(
				function()
				{
					MD.replaceChildNodes($("dialog-main"),
						this.paint());
				}, this));
	}

Dialog.prototype.paint =
	function()
	{
		return P(null, "Default dialog content");
	}

Dialog.prototype.set_relative_offset =
	function(e)
	{
		var pos = e.mouse().page;
		pos.x = -pos.x;
		pos.y = -pos.y;
//		this.offset = MochiKit.DOM.elementPosition(this.frame_elem, pos);
		this.offset = pos;
//		alert("pos=" + pos.toString() + "; offset=" + this.offset.toString());
	}

Dialog.prototype.follow_mouse =
	function(name, e)
	{
		if(this.dragging) {
			var px = e.mouse().page.x + this.offset.x;
			var py = e.mouse().page.y + this.offset.y;
			var pos;
			if(name=="frame") {
				pos = elementPosition(this.frame_elem);
			} else {
				pos = {"x": 0, "y": 0};
			}
			var spos = this.get_scroll_position();
			MochiKit.DOM.setElementPosition(this.frame_elem, 
				{"x": spos.x + pos.x + px, "y": spos.y + pos.y + py});
			e.stop();
		}
	}

Dialog.prototype.follow_scroll =
	function(e)
	{
		alert("scrolling");
		if(this.dragging)
			this.dragging = false;

		MochiKit.DOM.setElementPosition(this.frame_elem,
			{"x": this.position.x - this.offset.x, "y": this.position.y - this.offset.y});
	}

Dialog.prototype.start_drag =
	function(e)
	{
		this.set_relative_offset(e);
		this.dragging = true;
	}

Dialog.prototype.stop_drag =
	function(e)
	{
		this.dragging = false;
	}

Dialog.prototype.add_handle =
	function(elem)
	{
		connect(elem, "onmousedown", this, this.start_drag);
	}

Dialog.prototype.get_scroll_position =
	function()
	{
		var b = this.document.body;
		if(!b)
			return null;
		var p = new MochiKit.DOM.Coordinates(b.scrollLeft, b.scrollTop);
//		alert(p.toString());
		return p;
	}

Dialog.prototype.add_style =
	function(k, v)
	{
		var s = "#dialog-main " + k;
		var ss = this.frame_obj.document.styleSheets[0];
		if(ss && ss.addRule)
			ss.addRule(s, v);
	}

Dialog.prototype.add_stylesheet =
	function(s_url)
	{
		var ss = this.frame_obj.document.styleSheets[0];
		if(ss.addImport)
			ss.addImport(s_url);
		else if(ss.insertRule)
			ss.insertRule('@import url(' + s_url + ')', ss.cssRules.length);
	}

Dialog.prototype.get_element =
	function(s)
	{
		var o;
		MochiKit.DOM.withDocument(this.frame_obj.document, 
			MochiKit.Base.bind(
				function()
				{
					o = $(s);
				}, this));
		return o;
	}

/*** DialogManager ***/

DialogManager =
	function()
	{
		this.dialogs = [];
	}

DialogManager.prototype.add =
	function(d)
	{
		this.dialogs.push(d);
		d.set_zindex(this.dialogs.length);
	}

DialogManager.prototype.remove =
	function(d)
	{
		if(this.dialogs.length==0)
			return;
		var removed = false;
		for(var i=0; i<this.dialogs.length; ++i)
		{
			if(removed) {
				this.dialogs[i-1] = this.dialogs[i];
				this.dialogs[i-1].set_zindex(i);
			} else if(this.dialogs[i]==d) {
				removed = true;
			}
		}
		if(removed)
			--this.dialogs.length;
	}

DialogManager.prototype.bring_to_front =
	function(d)
	{
		var top = this.dialogs[this.dialogs.length-1];
		if(!top.is_modal && top!=d) {
			this.remove(d);
			this.add(d);
		}
	}

DialogManager.prototype.close_all =
	function()
	{
		while(this.dialogs.length>0)
			this.dialogs[0].hide();
	}

var _dm_ = new DialogManager;

