/*
 * tripedia.org
 * 
 * (c) Jan Poeschko
 * 
 */

var ElementMethods = {
	setText: function(element, text) {
		element.deleteChildNodes();
		element.appendChild(document.createTextNode(text));
		return element;
	},
	
	deleteChildNodes: function(element) {
	  while (element.hasChildNodes())
	  	element.removeChild(element.lastChild);
	  return element;
	},
	
	setClassName: function(element, className, yesno) {
		if (yesno)
			element.addClassName(className);
		else
			element.removeClassName(className);
		return element;
	},
	
	isShown: function(element, recursionDepth) {
		return element.ancestors().invoke('visible').all();
	},
	
	tryFocus: function(element) {
		if (element.isShown()) {
			try {
				element.focus();
				return true;
			} catch (e) {
				return false;
			}
		} else
			return false;
	},
	
	deleteElement: function(element) {
		if (element.parentNode)
			element.parentNode.removeChild(element);
	},
	
	updateDOM: function(element, content) {
		var dom = stringToDOM(content);
		element.deleteChildNodes();
		element.appendChild(dom);
	},
	
	replaceDOM: function(element, content) {
		var dom = stringToDOM(content);
		element.parentNode.replaceChild(dom, element);
		
	},
	
	scrollIntoView: function(element) {
		var offset = element.cumulativeOffset(); 
		window.scrollTo(offset.left, offset.top);
	},
	
	setEnabled: function(element, enabled) {
		if (element.enable && element.disable) {
			if (enabled)
				element.enable();
			else
				element.disable();
		}
		if (enabled)
			element.removeClassName('disabled');
		else
			element.addClassName('disabled');
		element.childElements().each(function(child) {
			child.setEnabled(enabled);
		});
	}
};

Element.addMethods(ElementMethods);

Object.extend(Object, {
	isDOMElement: function(object) {
		return object && !!object.nodeType;
	}
});

// untested!
/*Object.extend(Function.prototype, {
	curryArray: function(args) {
		var that = this;
		return function() {
			return that.apply(this, args.concat($A(arguments)));
		}		
	},
	
	curryNamed: function(extra) {
		extra = $H(extra);
		var names = this.argumentNames();
		var args = names.map(function(element) {
			return extra.get(element);
		});
		return this.curryArray(args);
	}
});*/

var Publisher = Class.create({
	initialize: function() {
		this.events = $H();
	},
	
	fire: function(event) {
		var subscribers = this.events.get(event) || $A();
		var args = $A(arguments).slice(1);
		subscribers.each(function(subscriber) {
			subscriber.apply(this, args);
		}.bind(this));
	},
	
	observe: function(event, subscriber) {
		var existing = this.events.get(event);
		if (!existing)
			this.events.set(event, $A([subscriber]));
		else
			existing.push(subscriber);
	}
});

function exists(type) {
  return type != "undefined";
}

function dateToStr(date) {
	return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate(); 
}

function dateFromJSON(json) {
	if (json) {
		parts = json.split('-');
		return new Date(parts[0], parts[1] - 1, parts[2]);
	} else
		return null;
}

var lastCanceledLog = 0;

function log(message) {
	var now = new Date().getTime();
	if (now - lastCanceledLog < 100) {
		lastCanceledLog = new Date().getTime();
		return false;
	}
	message += '\n\n---\n' + 'Arguments: ' + Object.inspect($A(log.caller.arguments));
	if (!window.confirm(message))
		lastCanceledLog = new Date().getTime();
	return true;
}

function $E(tag, properties) {
	//log('$E');
	var children;
	if (Object.isDOMElement(properties)) {
		children = $A(arguments).slice(1);
		properties = {};
	} else
		children = $A(arguments).slice(2);
	if (tag == 'a' && properties.href == null)
		properties.href = 'javascript:;';
	var element = new Element(tag, properties);
	children.each(function(child) {
		if (child)
			element.appendChild(child);
	});
	return element;
}

function $T(text) {
	return document.createTextNode(text);
}
