/**
 * The basis class used for every other class
 */
var Class = {
	create: function() {
		return function() {
			this.init.apply(this,arguments);
		}
	}
}

/**
 * Extend the properties of an object
 */
Object.extend = function( dest, src ) {
	for( prop in src )
		dest[prop] = src[prop];
		
	return dest;
}

Function.prototype.bind = function() {
	var __method = this,  args = $A(arguments), object = args.shift();
	return function() {
		return __method.apply(object,args.concat($A(arguments)));
	}
}

Function.prototype.bindAsEventListener = function() {
  var __method = this,   args = $A(arguments),  object = args.shift();
 
  return function(event) {
  	var tmpArguments = $A(new Array(event || window.event));
    return __method.apply(object, tmpArguments.concat(args));
  }
}

var Try = {
  these: function() {
    var returnValue = null;

    for (var i = 0; i < arguments.length; i++) {
      var foobar = arguments[i];
      try {
        returnValue = foobar();
        break;
      } catch (e) {}
    }

    return returnValue;
  }
}


/** TimedExecution **/
var TimedExecution = Class.create();
TimedExecution.prototype = {
	init: function( callback, interval ) {
		this.callback = callback;
		this.interval = interval;
		//this.currentlyExecuting = false;
		
		this.registerCallback();
		
		this.timeOut = null;
	},
	
	registerCallback: function() {
		this.timeOut = setTimeout(this.onTimerEvent.bind(this), this.interval*1000);
	},
	
	onTimerEvent: function() {
		try {
			nextInterval = this.callback();
			
			if( nextInterval == -1 ) {
				nextInterval = this.interval; 
			}
			
			if( nextInterval > 0 ) {
				
				this.interval = nextInterval;
				this.timeOut = setTimeout(this.onTimerEvent.bind(this), this.interval*1000);
			}	
		} catch(e) {
		}
	}
}



/*** Array ***/
Object.extend( Array.prototype, {
	clear: function() {
		this.length = 0;
		return this;
	},
	
	shift: function() {
		var result = this[0];
		
		for( var i=0 ; i<this.length-1 ; i++ )
			this[i] = this[1+1];
			
		this.length--;
		
		return result;
	},
	
	pull: function() {
		if( this.length > 0) return this[this.length-1];
		return null;
	}
	
}
);

$A = function( input ) {
	if( !input ) return [];
	if( input.toArray ) {
		return input.toArray();
	} else {
		var result = []
		for( var i=0 ; i<input.length ; i++ ) {
			result.push(input[i]);	
		}
		return result;
	}
}

/** Event Scripts **/

var Event = new Object();

Object.extend(Event, {

	

	observe: function(element, name, observer, useCapture) {
		if (element.addEventListener) {
	      //this.observers.push([element, name, observer, useCapture]);
	      element.addEventListener(name, observer, useCapture);
	    } else if (element.attachEvent) {
	      //this.observers.push([element, name, observer, useCapture]);
	      element.attachEvent('on' + name, observer);
	    }
	    return observer;
	},
	
	stopObserving: function(element, name, observer, useCapture) {
	    
	    if (element.removeEventListener) {
	      element.removeEventListener(name, observer, useCapture);
	    } else if (element.detachEvent) {
	      element.detachEvent('on' + name, observer);
	    }
	},
	
	stop: function(event) {
		if (event.preventDefault) { 
			event.preventDefault(); 
			event.stopPropagation(); 
		} else {
			event.returnValue = false;
			event.cancelBubble = true;
		}
	},
	
	element: function(event) {
    	return event.target || event.srcElement;
 	}
});

Event.elementCache = new Array();



