Object.extend(Class, {
	basePath: "",
	include: function(classPaths){
		
		if (typeof Class.includedScripts == "undefined"){
			Class.includedScripts = [];
		}
		
		$A(arguments).flatten().each(function(classPath){
			if (typeof classPath == "string"){
				classPath = classPath.replace("*", "_package");
				if (!Class.includedScripts.include(classPath)){
					Class.load(Class.basePath + classPath.replace(/\./g, "/") + '.js');
					Class.includedScripts.push(classPath);
				}
			}
		});
	},
	
	load: function(script){
		if (Class.domLoaded){
			$$("head").first().insert(new Element("script", {type: "text/javascript", src: script}));
		} else {
			document.write('<script src="' + script + '" type="text/javascript"><\/script>');
		}		
	},
	
	alias: function(alias, klass){
		if (typeof window[alias] != "undefined" && window[alias] != klass){
			throw new Error('Alias "' + alias + '" was already assigned to another class.');
		}
		window[alias] = klass;
	}
});

if (typeof Package == "undefined"){
	var Package = {};
}

Object.extend(Package, {
	create: function(packageName){
		var parts = packageName.split(".");
		var basePackage = window;
		for (var i=0; i<parts.length; i++){
			var part = parts[i];
			if (typeof basePackage[part] == "undefined"){
				basePackage[part] = {};
			}
			basePackage = basePackage[part];
		}
		
		return basePackage;
	},
	include: function(classes){
		$A(arguments).each(Class.include);
	}
});

var Core = {
	path: null,
	initialize: function(){
		var script = $$("script").findAll(function(script){
			return (script.src && script.src.match(/Core\.js(\?.*)?$/));
		})[0];
		if (script && script.src){
			Class.basePath = script.src.replace(/Core\.js(\?.*)?$/,'');
			var includes = script.src.match(/\?.*include=([a-zA-Z0-9,\.]*)/);
			if (includes){
				Class.include(includes[1].split(","));
			}
		}
	}	
};

Core.initialize();

Element.addMethods("A", {
    click: function(element, callback, passevent){
        element.observe("click", function(event){
            if (!passevent){
                event.stop();
            }
            event.target.blur();
            callback(event);
        });
    }
}); 

document.observe("dom:loaded", function(){
	Class.domLoaded = true;
});

Event.Dispatcher = {
	observe: function(eventName, observer){
		this._observers = this._observers || $H();
		var observers = this._observers.get(eventName) || this._observers.set(eventName,  $A());
		observers.push(observer);
		return this;
	},
	
	stopObserving: function(eventName, observer){
		this._observers.set(eventName, 
			observer ? this._observers.get(eventName).without(observer) : $A()
		);
		return this;
	},
	
	dispatch: function(eventName){
		var observers = (this._observers && this._observers.get(eventName)) || $A();
		if (observers){
			var args = $A(arguments).slice(1);
			observers.each(function(observer){
				observer.apply(this, args);
			});
		}
		return this;
	},
	
	pass: function(event, target){
		console.log(event, target);
		this.observe(event, function(){
			target.dispatch(event);
		});
		return this;
	}
};
