/*
* Copyright (c) 2008, Adam R. Smith.
* Version: v0.1
* Modified: 02/05/2008.
* License: New BSD License http://code.google.com/p/magic-classes/wiki/BsdLicense
* Some pieces taken from the Ext library 2.0.1 at http://www.extjs.com/
* Ext 2.0.1 and earlier used the LGPL license, which allows me to use the code.
* Has to use uppercase 'Class' instead of 'class' to avoid collision with the builtin keyword.
*/
if (typeof(com) == 'undefined') this.com = {};
if (typeof(com.magicClasses) == 'undefined') com.magicClasses = {};

if (typeof(com.magicClasses.GetNamespace) != 'function') com.magicClasses.GetNamespace = function(nsName, nsParent) {
	if (nsParent == null) nsParent = window;
	
	var nsPieces = nsName.split('.');
	var nsPath = '';
	var currNs = nsParent;
	for (var i = 0; i < nsPieces.length; ++i) {
		var localNs = nsPieces[i];
		if (currNs[localNs] == null) currNs[localNs] = {};
		if (typeof(currNs[localNs]) != 'function') {
			currNs[localNs]['Class'] = function(param1, param2, param3) {
				com.magicClasses['Class'](this, param1, param2, param3);
			};
		}
		currNs = currNs[localNs];
	}
	return currNs;
}

// Taken from the Ext library and maybe slightly modified.
if (com.magicClasses.extend == null) com.magicClasses.extend = function() {
	// inline overrides
	var io = function(o){
		for(var m in o){
			this[m] = o[m];
		}
	};
	return function(sb, sp, overrides){
		if(typeof sp == 'object'){
			overrides = sp;
			sp = sb;
			sb = function(){sp.apply(this, arguments);};
		}
		var F = function(){}, sbp, spp = sp.prototype;
		F.prototype = spp;
		sbp = sb.prototype = new F();
		sbp.constructor=sb;
		sb.superclass=spp;
		if(spp.constructor == Object.prototype.constructor){
			spp.constructor=sp;
		}
		sb.override = function(o){
			com.magicClasses.override(sb, o);
		};
		sbp.override = io;
		com.magicClasses.override(sb, overrides);
		
		return sb;
	};
}();

// Taken from the Ext library and maybe slightly modified.
if (com.magicClasses.override == null) com.magicClasses.override = function(origclass, overrides) {
	if(overrides){
		var p = origclass.prototype;
		for(var method in overrides){
			p[method] = overrides[method];
		}
	}
};
if (com.magicClasses['Class'] == null) com.magicClasses['Class'] = function(namespace, className, parentClassName, cfg) {
	// Wrap the custom/Ext stuff in a nice simple class declaration that will presume the com.magicClasses namespace.
	// Also improves constructor inheritance.
	// Makes a semi-convenient 'super()' function that calls the parent constructor, but it's still a bit cheesy.
			
	var parentObject = Object;
	if (typeof parentClassName == 'object') {
		cfg = parentClassName;
	} else {
		parentObject = com.magicClasses.GetNamespace(parentClassName, (parentClassName.indexOf('.') >= 0) ? window : namespace);
	}
	
	if (typeof cfg.construct == 'function') {
		namespace[className] = cfg.construct;
	} else if (typeof parentObject.prototype.construct == 'function') {
		namespace[className] = parentObject.prototype.construct;
	} else {
		namespace[className] = function() {};
	}
	
	cfg['super'] = function(param1, param2, param3, param4, param5) {
		namespace[className].superclass.constructor.call(this, param1, param2, param3, param4, param5);
	}

	com.magicClasses.extend(namespace[className], parentObject, cfg);
	/*
	com.magicClasses[className].prototype.super = function(cfg) {
		//var parentConstruct = com.magicClasses[className].superclass.constructor;
		var parentConstruct = parentObject.prototype.construct;
		var thisConstruct = com.magicClasses[className].prototype.constructor;
		alert('parent: ' + parentConstruct + ' this: ' + thisConstruct);
		if (parentConstruct != thisConstruct) {
			//com.magicClasses[className].superclass.constructor.call(this, cfg);
		}
	}
	*/
};
