function mouseCoords (ev) {
	ev = ev || window.event;
	if (ev.pageX || ev.pageY)
		return {x:ev.pageX, y:ev.pageY};
	return {
		x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
		y:ev.clientY + document.body.scrollTop - document.body.clientTop
	};
}

function associateObjectWithEvent(obj, method) {
	return (function(e) {
		e = e || window.event;
		return obj[method](e, this);
	});
}

function MouseDragging() {
	var dragObject = null;
	var prevObject = null;
	var dragObjectPrevIndex = '';
	var startMousePos = { x:0, y:0 };
	var startObjPos = { x:0, y:0 };

	document.onmousemove = null;
	document.onmouseup = function () {
		var self = mousedragging;
		document.onmousemove = null;
		self.dragObject = null;
	};

	this.moveObject = function (ev) {
		var self = mousedragging;
		if (self.dragObject == null) return;
		ev = ev || window.event;
		var pos = mouseCoords(ev);
		self.dragObject.style.top = Math.max(0,pos.y - self.startMousePos.y + self.startObjPos.y) + "px";
		self.dragObject.style.left = Math.max(0,pos.x - self.startMousePos.x + self.startObjPos.x) + "px";
		return false;
	}
	this.capture = function (ev, obj) {
		var self = mousedragging;
		ev = ev || window.event;
		self.startMousePos = mouseCoords(ev);
		obj.style.position = 'absolute';
		self.startObjPos = { x:parseInt(obj.style.left), y:parseInt(obj.style.top) };
		self.dragObject = obj;
		self.makeActive(obj);
		document.onmousemove = self.moveObject;
	}
	this.makeActive = function (obj) {
		var self = mousedragging;
		if (self.prevObject && self.prevObject != obj)
			removeClass(self.prevObject,'lastdragged');
		if (obj)
			addClass(obj,'lastdragged');
		self.prevObject = obj;
	}
	/*
		trigger: anklickbares Objekt, welches das Bewegen ausloest
		obj: zu bewegendes Objekt
	*/
	this.makeDraggable = function (trigger,obj) {
		if (!trigger) return;
		var self = mousedragging;
		if (!obj) obj = trigger;
		trigger.onmousedown = function (ev) {
			self.capture(ev,obj);
			return false;
		};
	}
}

mousedragging = new MouseDragging();

function WindowAction(id) {
	this.id = id;
	this.button = null;
	this.elem = document.getElementById(id);

	this.assignButton = function (obj) {
		this.clearButton();
		this.button = obj;
		if (this.button)
			addClass(this.button, 'active');
	};

	this.clearButton = function () {
		if (this.button)
			removeClass(this.button, 'active');
		this.button = null;
	}

	this.close = function () {
		this.elem.style.display = 'none';
		this.clearButton();
	}

	this.setTitle = function (txt) {
		setText(document.getElementById(this.id + '_windowbartitle'),txt);
	}

	this.showRelative_bis_20101022 = function (obj,xoff,yoff) {
		var pos = getNodeCoords(obj,true);
		var npos = {
			x:Math.max(0,pos.x + xoff),
			y:Math.max(0,pos.y + yoff)
		};
		this.elem.style.left = npos.x + "px";
		this.elem.style.top = npos.y + "px";
		this.elem.style.display = 'inline';
		// Fenster in den sichtbaren Bereich zurueckschieben, falls es unten/rechts herausragt
		var win = getWindowSize();
		var scroll = getWindowOffset();
		var out = {
			x:(npos.x + this.elem.clientWidth - scroll.x - win.x),
			y:(npos.y + this.elem.clientHeight - scroll.y - win.y)
		}
		if (out.x > 0)
			this.elem.style.left = Math.max(0,npos.x - out.x - 20) + "px"; // ein paar Pixel mehr fuer Scrollbalken
		if (out.y > 0)
			this.elem.style.top = Math.max(0,npos.y - out.y - 20) + "px"; // ein paar Pixel mehr fuer Scrollbalken
		mousedragging.makeActive(this.elem);
	}

	this.showRelative = function (obj,xoff,yoff) {
		// Position zuruecksetzen
		this.elem.style.left = "0px";
		this.elem.style.top = "0px";
		this.elem.style.display = 'inline';
		var pos = getNodeCoords(obj,false);
		var mypos = getNodeCoords(this.elem,false);
		var win = getWindowSize();
		var scroll = getWindowOffset();
		var npos = {
			x:pos.x + xoff,
			y:pos.y + yoff
		};
		// Fenster in den sichtbaren Bereich zurueckschieben, falls es unten/rechts herausragt
		var out = {
			x:(npos.x + this.elem.clientWidth - scroll.x - win.x),
			y:(npos.y + this.elem.clientHeight - scroll.y - win.y)
		}
		if (out.x > 0)
			npos.x -= out.x + 20; // ein paar Pixel mehr fuer Scrollbalken
		if (out.y > 0)
			npos.y -= out.y + 20; // ein paar Pixel mehr fuer Scrollbalken
		/*alert(dumpObject(pos));
		alert(dumpObject(mypos));
		alert(dumpObject(npos));*/
		// an ermittelte Position schieben, dabei aber niemals oben oder links aus den Fenster raus!
		this.elem.style.left = (Math.max(0,npos.x) - mypos.x) + "px";
		this.elem.style.top = (Math.max(0,npos.y) - mypos.y) + "px";
		mousedragging.makeActive(this.elem);
		if (this.elem.elements != null && this.elem.elements.length > 0 && this.elem.elements[0].focus) {
			try { // versuche in Formularen den Fokus auf das erste Element zu setzen
				this.elem.elements[0].focus();
			} catch (e) {}
		}
	}

	var tags = ['div','h1','button'];
	for (var t=0; t<tags.length; t++) {
		var div = this.elem.getElementsByTagName(tags[t]);
		for (var i=0; i<div.length; i++) {
			if (hasClass(div[i],'windowbartitle')) {
				mousedragging.makeDraggable(div[i], this.elem);
			} else if (hasClass(div[i],'windowbarclose')) {
				if (div[i].nodeName != null && div[i].nodeName.toLowerCase() == 'button') {
					div[i].onclick = associateObjectWithEvent(this,'close');
				} else {
					div[i].onmouseup = associateObjectWithEvent(this,'close');
				}
			}
		}
	}

	return this;
}

FloatingFormAction = WindowAction;

