/**
 * Created by Aloyzas Rimeika on 2007-06-07.
 */

/**
 * Function.prototype.call and other IE 5.0 nonsense copy from base2.Legacy file or include one :)
 * http://base2.googlecode.com/svn/trunk/src/legacy.js
 */

function log() {
	if (window.console)
		window.console.log.apply(window.console, arguments);
	else
		alert(arguments[0]);
	return arguments[0];
}

function extend(target) {
	var obj, a = 1, i;
	while (obj = arguments[a++])
		for (i in obj) target[i] = obj[i];
	return target;
}

// Object to Array
function array(a) {
	var r = [], i = 0, l = a.length;
	try {
		r = r.slice.call(a, 0);
		if (r[0] == undefined) throw "";
	} catch (e) {
		for (; i < l; i++) r[i] = a[i];
	}
	return r;
}

// Dom manipulations
function dom(elem, name) {
	return !elem ? document : name
		? array(dom(elem).getElementsByTagName(name))
		: elem.constructor == String
			? dom().getElementById(elem)
			: elem;
}
extend(dom, {
	create: function(html) {
		var d = dom().createElement('div'), res;
		d.innerHTML = html;
		res = d.firstChild;
		d = null;
		return res;
	},

	before: function(elem, before) {
		before.parentNode.insertBefore(elem, before || null);
	},

	// get last of nodes with name
	last: function(elem, name) {
		var elems = dom(name ? elem : null).getElementsByTagName(name || elem);
		return elems[elems.length - 1];
	},
	
	addClass: function(elem, klass) {
		if (!this.hasClass(elem, klass)) {
			elem.className += (elem.className ? " " : "") + klass;
			return klass;
		}
	},

	hasClass: function(elem, klass) {
		var r = new RegExp("(^|\\s)" + klass + "(\\s|$)");
		return r.test(elem.className);
	},

	removeClass: function(elem, klass) {
		var r = new RegExp("(^|\\s)" + klass + "(\\s|$)");
		elem.className = elem.className.replace(r, "$2");
		return klass;
	},

	index: function(node) {
		var index = node.cellIndex, s = node;
		if (!index) while (node = node.previousSibling) if (node.nodeType == 1) index++;
		return index;
	},

	getByClass: function(klass, parent, tag) {
		var i = 0, parent = parent || document, tag = (tag || '*').toUpperCase(), result = [];
		if ((parent.getElementsByClassName) && (result = parent.getElementsByClassName(klass)) && tag != '*') { // FF 3, ... ?
			result = Array.filter(result, function(elem) { return elem.nodeName == tag });
		} else if (document.evaluate) { // FF <= 2, Opera, Safari
			var xpath = document.evaluate(".//" + tag + "[contains(concat(' ', @class, ' '), ' " + klass + " ')]", parent, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
			for (; (e = xpath.snapshotItem(i)); i++) result[result.length] = e;
		} else { // IE
			var regxp = new RegExp('(^|\\s)' + klass + '(\\s|$)');
			var elems = tag == '*' ? parent.all || dom(parent, tag) : dom(parent, tag);
			for (; (e = elems[i]); ++i) if (regxp.test(e.className)) result[result.length] = e;
		}
		return result.length != 0 ? result : false;
	},

	// event module
	event: {
		add: function(elem, type, handl) {
			if (!handl.$$guid) handl.$$guid = this.guid++;
			if (!elem.events) elem.events = {};

			var handlers = elem.events[type];
			if (!handlers) {
				handlers = elem.events[type] = {};
				if (elem["on" + type])
					handlers[0] = elem["on" + type];
			}

			handlers[handl.$$guid] = handl;
			elem["on" + type] = this.handle;
		},

		guid: 1,

		remove: function(elem, type, handl) {
			if (elem.events && elem.events[type])
				delete elem.events[type][handl.$$guid];
		},

		handle: function(e) {
			e = e || window.event;

			if (!e.target && e.srcElement)
				e.target = e.srcElement;

			if (!e.relatedTarget && e.toElement)
				e.relatedTarget = e.toElement == e.target
					? e.fromElement : e.toElement;

			if (!e.preventDefault)
				e.preventDefault = function() {
					this.returnValue = false;
				};

			if (!e.stopPropagation)
				e.stopPropagation = function() {
					this.cancelBubble = true;
				};

			var handlers = this.events[e.type];
			var result = true;
			for (var i in handlers) {
				this.$$handleEvent = handlers[i];
				this.$$handleEvent(e);
			}
		},
		// dom.event.hover(div, function(e){ ... mouse over element code ... }, function{ ... mouse out element code .... });
		hover: function(elem, over, out) {
			dom.event.add(elem, 'mouseover', function(e){
				if (!this.__hovered) {
					this.__hovered = true;
					return over.call(this, e);
				}
			});

			dom.event.add(elem, 'mouseout', function(e){
				var p = e.relatedTarget;
				while (p && p != document && p != this) p = p.parentNode;
				if (p != this) {
					this.__hovered = false;
					return out.call(this, e);
				}
			});
		}
	}
});

// force IE background cache
dom.event.add(window, 'load', function(){
	try { document.execCommand("BackgroundImageCache", false, true); } catch(e) {};
});

function sprintf(string) {
	var s = string.split('%s'), res = s[0], i = 1;
	for (; i < s.length; i++) res += (arguments[i] || '') + s[i];
	return res;
}

new function() {
	// Additional string methods
	var re = /([\/()[\]{}|*+-.,^$?\\])/g;
	extend(String.prototype, {
		stripTags: function(){
			return this.replace(/\s+/g, ' ').replace(/ *<br[^\/>]*\/?> */g, '\n').replace(/<[^>]+>/g, '');
		},
		rescape: function() {
			return this.replace(re, "\\$1");
		},
		trim: function() {
			return this.replace(/^\s+|\s+$/g, '');
		},
		toNumber: function(){
			return parseFloat(this
				.replace(/\s+/g, '')
				.replace(/[\,\.](?=.*[\,\.])/g, '')
				.replace(/[\,\.]/, '.')
				.replace(/^(?=-?)0*(?=\d)\.?/, ''), 10);
		}
	});
};

