﻿Object.extend = function(dest, source, allowOverwrite)
{
	for (var prop in source)
	{
		if (source.hasOwnProperty(prop) && (allowOverwrite || !dest.hasOwnProperty(prop)))
			dest[prop] = source[prop];
	}

	return dest;
}

Object.extend(Function.prototype,
{
	bind: function()
	{
		var handler = this, args = Array.slice(arguments, 0), obj = args.shift();

		return function()
		{
			return handler.apply(obj, args.concat(Array.slice(arguments, 0)));
		}
	}
});

Object.extend(Array.prototype,
{
	indexOf: function(searchElement, fromIndex)
	{
		var l = this.length, i = 0;
		if (fromIndex)
		{
			i = fromIndex;
			if (i < 0)
			{
				i += l;
				if (i < 0) i = 0;
			}
		}

		while (i < l)
		{
			if (this[i] === searchElement) return i;
			i++;
		}

		return -1;
	},
	forEach: function(func, obj)
	{
		for (var i = 0, l = this.length; i < l; i++)
		{
			if (i in this)
				func.call(obj, this[i], i, this);
		}
	},
	filter: function(func, obj)
	{
		var res = [], val;
		for (var i = 0, l = this.length; i < l; i++)
		{
			if (i in this)
			{
				val = this[i]; // in case func mutates this
			        if (func.call(obj, val, i, this))
					res.push(val);
			}
		}

		return res;
	}
});

// Generics
['forEach', 'filter', 'slice'].forEach(
	function(func)
	{
		if (!(func in Array))
		{
			Array[func] = function(obj)
			{
				return this.prototype[func].apply(obj, Array.prototype.slice.call(arguments, 1));
			}
		}
	}
);

function findObjectPosition(obj)
{
  var curleft = curtop = 0;
  if (obj.offsetParent) {
    curleft = obj.offsetLeft
    curtop = obj.offsetTop
    while (obj = obj.offsetParent) {
      curleft += obj.offsetLeft
      curtop += obj.offsetTop
    }
  }
  return [curleft,curtop];
}
    

// generic eventhandling
var addEvent = function()
{
	if (document.addEventListener)
	{
		return function(element, type, handler)
		{
			element.addEventListener(type, handler, false);
		}
	}
	else
	{
		function handleEvent(event)
		{
			event = event || fixEvent(window.event);

			var handlers = this.events[event.type], returnValue;
			for (var i in handlers)
			{
				if (handlers.hasOwnProperty(i) && handlers[i].call(this, event) === false)
					returnValue = false;
			}

			return returnValue;
		}
		function fixEvent(event)
		{
			event.preventDefault = preventDefault;
			event.stopPropagation = stopPropagation;
			event.target = event.srcElement;

			return event;
		}
		function preventDefault() { this.returnValue = false; }
		function stopPropagation() { this.cancelBubble = true; }
		function removeAllEvents()
		{
			while ((cachedEvent = eventCache.pop()))
				removeEvent(cachedEvent.element, cachedEvent.type, cachedEvent.handler);
		}

		var guid = 1;
		var eventCache = [];

		return function(element, type, handler)
		{
			if (!handler.$$guid) handler.$$guid = guid++;
			if (!element.events) element.events = {};
			if (!element.events[type])
			{
				element.events[type] = {};
				if (element['on' + type]) element.events[type][0] = element['on' + type];
				element['on' + type] = handleEvent;
			}

			element.events[type][handler.$$guid] = handler;

			if (type != 'unload')
			{
				if (!eventCache.length)
					//addEvent(window, 'unload', removeAllEvents);

				eventCache.push(
					{
						element: element,
						type: type,
						handler: handler
					}
				);
			}
		}
	}
}();

function displayElement(id)
{
    if (document.getElementById(id))
        document.getElementById(id).style.display = 'block';
}

function hideElement(id)
{
    if (document.getElementById(id))
        document.getElementById(id).style.display = 'none';
}
