// Copyright (c) 2005 Just Objects B.V. <just@justobjects.nl>
// Distributable under LGPL license. See terms of license at gnu.org.

/*
 * Widgets: some DHTML widgets.
 *
 * Selector: combo box
 * Panel: window
 * Menu: drop-down menu
 *
 * $Id: widget.js,v 1.21 2006-03-08 17:12:04 just Exp $
 */
var WG = {
	curZ: 10000,
	curOptionId: 1
}

function BBox(x, y, w, h) {
	this.x = x;
	this.y = y;
	this.w = w;
	this.h = h;
}

function Selector(title, id, callback) {
	this.id = id;
	this.callback = callback;

	var form = document.createElement('form');
	form.className = 'sel-form';
	form.id = form.className + id;
	var select = document.createElement('select');
	select.className = 'sel-select';
	select.id = select.className + id;
	form.appendChild(select);
	document.body.appendChild(form);
	this.form = form;
	this.select = select;
	this.title = title;

	this.addOption('title', this.title, this.title);
	var selector = this;

	this.onSelect = function(e) {

		var option = selector.select.options[selector.select.selectedIndex];

		// First is title
		if (selector.select.selectedIndex != 0) {
			selector.callback(option.name, option.childNodes.item(0).nodeValue, option.label);
		}

		DH.cancelEvent(e);
	}

	DH.addEvent(this.select, 'change', selector.onSelect, false);
}

// Setting the visibility to hidden
Selector.prototype.addOption = function(name, value, label) {
	var option = document.createElement('option');
	option.id = this.form.id + 'o' + WG.curOptionId++;
	option.name = name;
	option.label = label;
	var text = document.createTextNode(value);
	option.appendChild(text)
	this.select.appendChild(option);
}

// Cleart out all options
Selector.prototype.clear = function() {
	//var options = this.select.getElementsByTagName('option');
	//var count = options.length;
	while (this.select.hasChildNodes() == true) {
		this.select.removeChild(this.select.childNodes[0])
	}
	this.addOption('title', this.title, this.title);
}

// Cleart out all options
Selector.prototype.getBBox = function() {
	var form = this.form;
	return new BBox(DH.getObjectLeft(form), DH.getObjectTop(form), DH.getStyleObject(form).width, DH.getStyleObject(form).height);
}

// Setting the visibility to hidden
Selector.prototype.hide = function() {
	DH.hide(this.form);
}

// Set the callback function
Selector.prototype.setCallback = function(fun) {
	this.callback = fun;
}

// Set X,Y position
Selector.prototype.setWidth = function(w) {
	DH.getStyleObject(this.form).width = w;
}

// Set X,Y position
Selector.prototype.setXY = function(x, y) {
	DH.shiftTo(this.form, x, y);
}

// Setting the visibility to visible
Selector.prototype.show = function() {
	DH.show(this.form);
}

function Panel(id, bgColor, fgColor, onActivate, onClose) {
	var container = document.createElement('div');
	container.className = 'pn-container';
	container.id = container.className + id;

	var header = document.createElement('div');
	header.className = 'pn-header';
	header.id = header.className + id;

	var closer = document.createElement('div');
	closer.className = 'pn-closer';
	closer.id = closer.className + id;

	var content = document.createElement('div');
	content.className = 'pn-content';
	content.id = content.className + id;

	var footer = document.createElement('div');
	footer.className = 'pn-footer';
	footer.id = footer.className + id;

	var resizer = document.createElement('div');
	resizer.className = 'pn-resizer';
	resizer.id = resizer.className + id;


	container.appendChild(header);
	container.appendChild(content);
	container.appendChild(footer);
	container.appendChild(resizer);
	container.appendChild(closer);
	document.body.appendChild(container);

	this.container = container;
	this.header = header;

	this.closer = closer;
	this.resizer = resizer;
	this.content = content;
	this.footer = footer;
	this.onActivate = null;
	this.onClose = null;

	if (onActivate) {
		this.onActivate = onActivate;
	}

	if (onClose) {
		this.onClose = onClose;
	}

	// Damn, IE refuses overflow: auto !!
	if (DH.isIE == true) {
		DH.getStyleObject(container).overflow = 'hidden';
	}

	this.setXY((Math.round((Math.random() * 600) + 1)), 100 + (Math.round((Math.random() * 300) + 1)))
	this.setContent('');
	this.setBGColor(bgColor);
	this.setFGColor(fgColor);
	this.setTitle(id);

	var panel = this;

	this.onCloserClick = function(e) {
		panel.close();
		DH.cancelEvent(e);
	}

	this.onDragStart = function(target, x, y) {
		panel.activate();
	}

	this.onDrag = function(target, x, y, dx, dy) {
		if (target.className == 'pn-header' || target.className == 'pn-footer') {
			panel.setXY(panel.container.offsetLeft + dx, panel.container.offsetTop + dy);
		} else if (target.className == 'pn-resizer') {
			panel.setDimension(x - panel.container.offsetLeft, y - panel.container.offsetTop);
		}
	}

	DH.addEvent(this.closer, 'click', this.onCloserClick, true);
	DH.dragEnable(this.header, this.onDragStart, this.onDrag, null);
	DH.dragEnable(this.resizer, this.onDragStart, this.onDrag, null);
	DH.dragEnable(this.closer, this.onDragStart, this.onDrag, null);
	DH.dragEnable(this.footer, this.onDragStart, this.onDrag, null);
}

// Setting the visibility to hidden
Panel.prototype.activate = function() {
	this.setZ(WG.curZ++);
	this.show();
	if (this.onActivate != null && DH.isVisible(this.container) == true) {
		this.onActivate();
	}
}

// Setting the visibility to hidden
Panel.prototype.clear = function() {
	if (this.content) {
		// delete this.content;
	}
	this.content.innerHTML = ' ';
	//while(this.content.hasChildNodes() == true) {
	//  this.content.removeChild(this.content.childNodes[0])
	//}
}

// Setting the visibility to hidden
Panel.prototype.close = function() {
	this.clear();
	this.hide();
	if (this.onClose != null) {
		this.onClose();
	}
}

// Setting the visibility to hidden
Panel.prototype.hide = function() {
	DH.hide(this.container);
}

// No footer (resizer) to be shown
Panel.prototype.hideFooter = function() {
	DH.hide(this.footer);
	DH.hide(this.resizer);
}

// Set Panel color
Panel.prototype.loadContent = function(url) {
	this.clear();
	this.setContent('LOADING...');

	var panel = this;

	this.onLoadContent = function(cont) {
		panel.setContent(cont);
	}

	DH.getURL(url, this.onLoadContent);
}

// Set Panel color
Panel.prototype.setContent = function(cont) {
	this.clear();
	if (typeof cont == "string") {
		this.content.innerHTML = cont;
	} else {
		this.content.appendChild(cont);
	}
}

// Set Panel color
Panel.prototype.setTitle = function(title) {
	this.header.innerHTML = title;
}

// Set Panel color
Panel.prototype.setBGColor = function(color) {
	this.bgcolor = color;
	DH.setBGColor(this.header, color);
	DH.setBGColor(this.footer, color);
}

// Set Panel foreground (text) header/footer color
Panel.prototype.setFGColor = function(color) {
	this.fgcolor = color;
	DH.getStyleObject(this.header).color = color;
	DH.getStyleObject(this.footer).color = color;
}

// Set w/h
Panel.prototype.setDimension = function(w, h) {
	DH.getStyleObject(this.container).width = w + 'px';
	DH.getStyleObject(this.container).height = h + 'px';
}

// Set w/h
Panel.prototype.setOpacity = function(o) {
	DH.setOpacity(this.container, o);
}

// Set Panel color
Panel.prototype.setXY = function(x, y) {
	DH.shiftTo(this.container, x, y);
}

// Set Panel color
Panel.prototype.setZ = function(z) {
	DH.setZIndex(this.container, z);
}

// Setting the visibility to hidden
Panel.prototype.show = function() {
	DH.show(this.container);
}

/** Drop-down menu  */
function Menu(aCont) {
	this.container = DH.getObject(aCont);
	var links = this.container.getElementsByTagName('a');
	for (var i = 0; i < links.length; i++) {
		this._bindLink(links[i]);
	}

	// MS IE &$@%
	if (DH.isIE == true) {
		var sfEls = this.container.getElementsByTagName("LI");
		for (var i = 0; i < sfEls.length; i++) {
			this._fixIE(sfEls[i]);
		}
	}
}
/** Make invisible. */
Menu.prototype.hide = function() {
	DH.hide(this.container);
}

/** Get bounds */
Menu.prototype.getBBox = function() {
	var cont = this.container;
	return new BBox(DH.getObjectLeft(cont), DH.getObjectTop(cont), DH.getStyleObject(cont).width, DH.getStyleObject(cont).height);
}

/** Replace menu item. */
Menu.prototype.replaceItem = function(id, name, fn, arg) {
	var li = DH.getObject(id);
	if (!li) {
		return;
	}

	var a = li.getElementsByTagName('a')[0];
	a.innerHTML = name;
	if (fn) {
		a.setAttribute('fn', fn);
		if (arg) {
			a.setAttribute('arg', arg);
		}
	}
}

/** Replace menu item. */
Menu.prototype.removeItem = function(id) {
	var li = DH.getObject(id);
	if (!li) {
		return;
	}
	this._unbindLink(li.getElementsByTagName('a')[0]);
	li.parentNode.removeChild(li);
	delete li;
}

/** Make visible. */
Menu.prototype.show = function() {
	DH.show(this.container);
}

// Item in drop-down menu clicked
Menu.prototype._onSelect = function (e) {
	// Get callback function name
	var anchor = DH.getEventTarget(e);
	DH.cancelEvent(e);

	var fn = anchor.getAttribute('fn');
	if (fn) {
		var arg = anchor.getAttribute('arg');

		// Call handler function with/without arg
		if (!arg) {
			eval(fn + '()');
		} else {
			eval(fn + '("' + arg + '")');
		}
	}
}

/** Bind anchor to our select callback fun. */
Menu.prototype._bindLink = function(link) {
	var onSelect = this._onSelect;
	DH.addEvent(link, 'click', onSelect, false);
}

/** Bind anchor to our select callback fun. */
Menu.prototype._unbindLink = function(link) {
	var onSelect = this._onSelect;
	DH.removeEvent(link, 'click', onSelect);
}

/** Fix IE hover */
Menu.prototype._fixIE = function(li) {
	li.onmouseover = function() {
		this.className += " sfhover";
	}

	li.onmouseout = function() {
		this.className = this.className.replace(new RegExp(" sfhover\\b"), "");
	}
}

