
function _bind(obj, method) {

	return function() {
		return method.apply(obj, arguments);
	};
}

function empty_function() {}

function _class(def) {

	var c = function() {
	
	    if(this.__ctors.length > 1) {
	        this.__parent = {
	            __construct: _bind(this, this.__ctors[this.__ctors.length - 2])
	        };
	    }

		if(this.__ctors) {
			if(arguments.length == 0) for(var i = 0; i < this.__ctors.length - 1; i++) _bind(this, this.__ctors[i])();
			this.__ctors[this.__ctors.length - 1].apply(this, arguments);
		}
	}

	if(def.inherits) {
		for(var i = 0; i < def.inherits.length; i++) {
			for(var j in def.inherits[i].prototype) {
				if(j == '__ctors') {
					if(!c.prototype.__ctors) c.prototype.__ctors = new Array;
					for(var k = 0; k < def.inherits[i].prototype.__ctors.length; k++) {
						c.prototype.__ctors.push(def.inherits[i].prototype.__ctors[k]);
					}
				} else if(j == '__dtors') {
					if(!c.prototype.__dtors) c.prototype.__dtors = new Array;
					for(var k = 0; k < def.inherits[i].prototype.__dtors.length; k++) {
						c.prototype.__dtors.push(def.inherits[i].prototype.__dtors[k]);
					}
				} else c.prototype[j] = def.inherits[i].prototype[j];
			}
		}
	}

	if(def.members) {
		for(i in def.members) {
			c.prototype[i] = def.members[i];
		}
	}

	if(def.methods) {
		for(var i in def.methods) {
			c.prototype[i] = def.methods[i];
		}
	}

	if(def.constructor) {
		if(!c.prototype.__ctors) c.prototype.__ctors = new Array;
		c.prototype.__ctors.push(def.constructor);
		c.prototype.__construct = c.prototype.__ctors[c.prototype.__ctors.length - 1];
	} else c.prototype.__construct = empty_function;

	if(def.destructor) {
		if(!c.prototype.__dtors) c.prototype.__dtors = new Array;
		c.prototype.__dtors.push(def.destructor);
	}

	if(c.prototype.__dtors) {
		c.prototype.__destroy = function() {
			for(var i = this.__dtors.length - 1; i >= 0 ; i--) {
				_bind(this, this.__dtors[i])();
			}
		}
	} else c.prototype.__destroy = empty_function;

	c.prototype.__attachTo = function(obj) {
		for(var m in this) obj[m] = this[m];
	};

	return c;
}

