BLIP.Class.create("BLIP.Object", Object,
	// Constructor
	function() {},

	// Class
	{
		listeners: {},

		getCallback:function(f) {
			var self = this;

			return function() {
				f.apply(self,arguments);
			};
		},

		addEventListener:function(eventName, func, scope) {
			var eventListener = {
				fn : func,
				scope : scope
			};
			if (this.listeners[eventName]) {
				this.listeners[eventName].push(eventListener);
			}
			else {
				this.listeners[eventName] = [eventListener];
			}
			return eventListener;
		},

		removeEventListener : function(eventName, eventListener) {
			var i,
				len,
				listeners = this.listeners[eventName],
				sliceBeginning,
				sliceEnd;
			if(listeners) {
				for(i = 0, len = listeners.length; i < len; i++) {
					if(listeners[i] == eventListener) {
						sliceBeginning = listeners.slice(0, i);
						sliceEnd = listeners.slice(i+1);
						this.listeners[eventName] = sliceBeginning.concat(sliceEnd);
						return;
					}
				}
			}
			return;
		},

		fireEvent:function(eventName, args) {
			var handlers = this.listeners[eventName],
					i,
					r;

			if (handlers) {
				for (i = 0; i<handlers.length; i++) {
					try {
						r = handlers[i].fn.call(handlers[i].scope || this,args);
					} catch (x) {
						this.log(x);
					}
				}
			}
		},

		log:function() {
			try {
				console.log.apply( console, arguments );
			}
			catch(e) {
				try {
					opera.postError.apply( opera, arguments );
				}
				catch(e2) {}
			}
		},

		superCall:function(functionName, args) {
			return this.superClass.prototype[functionName].call(this,args);
		},

		superConstruct:function(args) {
			this.superClass.call(this,args);
		},

		concatArgs: function(args,dargs) {
			var result = [],
					i;

			for (i = 0; i<args.length; i++) {
				result.push(args[i]);
			}

			for (i = 1; i<dargs.length; i++) {
				result.push(dargs[i]);
			}

			return result;
		},

		delegate: function(func) {
			var self = this,
					dargs = arguments,
					f = function() { func.apply(self,self.concatArgs(arguments,dargs)); };

			return f;
		},

		is : function(mixin) {
			var thisContext = this;

			if (mixin === undefined) {
				throw "Mixin is undefined! Did you forget to include it?";
			}

			if(mixin.length > 0) {
				return function() {
					mixin.apply(thisContext, arguments);
				};
			}
			else {
				mixin.call(this);
				return this;
			}
		}
	}
);

BLIP.Class.createSingleton = function(name, superClass, cons, our) {
	var constructor = BLIP.Class.create(name, superClass, cons, our);
	eval(name + " = new constructor()");
};


