/**	
	@author			nathaniel skulic <nate@skulic.name>
	@copyright 		Copyright 2007, Nathaniel Skulic. All Rights Reserved.
	@fileOverview	
	@name 			oil
*/

/** 
	@namespace The base oil namespace
	@property {Object} $elements All the nodes registered
	@property {Number} $element_count The sum of nodes registered
	@property {Object} $register_listeners functions to call when a nodeid is to be registered
*/
var oil = {
	$elements:{},
	$element_counter:0,
	$register_listeners:{},
	/** Register a element, but call any listeners beforehand 
		@param {oil.element} element The element to register
		@return {oil.element} the registered element
	*/
	register:function(node){
		var id = node.id;
		var element = node;
		
		if(!$defined(node)) 
			throw "Node not defined";
		
		if(oil.$register_listeners[id]){
			// call all register listeners deemed for this node
			for(var i=0; i<oil.$register_listeners[id].length; i++){
				oil.$register_listeners[id][i](node);
			}
			// remove so they dont get called again
			delete oil.$register_listeners[id];
		}
		
		return oil.$elements[id] = node;
	},
	unregister:function(element_id){
		// if the element has a container remove it
		// TODO: if the element has an array of containers remove them
		node = oil.$elements[element_id];
		
		if(node	&& node.container && node.container.parentNode){
			node.container.parentNode.removeChild(node.container);
		}
		
		if(node) delete oil.$elements[element_id];
		
		return true;
	},
	/** add a function to call when a nodeid gets registered */
	on_register:function(element_id, f){
		// if already registered run the function immediately
		if(oil.$elements[element_id]) return f(oil.$elements[element_id]);
		
		// check if we already have an array and push
		if(oil.$register_listeners[element_id])	oil.$register_listeners[element_id].push(f);
		// create a a new array for the listeners
		else oil.$register_listeners[element_id] = [f];
	},
	/* listen_register:function(element_id, f){
		oil.$register_listeners[element_id] = f;
	}, */
	/** fetch a registered node by id */
	node:function(element_id){
		return oil.$elements[element_id] || null;
	},
	/** check if a node exists */
	exists:function(element_id){
		return oil.$elements[element_id] == 'undefined'
	},
	initialize:function(){
		oil.$elements = {};
		oil.$element_counter = 0;
	}
};

oil.initialize();

oil.NODE_PREFIX = 'node-';
$node = function(element_id){
	return oil.node(element_id);
}
$unregister = function(element){
	return oil.unregister(element);
}

function find_or_create_id(e){
	 var name = (e.id != '') ? e.id : (e.name != '') ? e.name : false;
	 var retname = name;
		
	 // if we cant obtain an id, generate one
    if(!name){
		 // if a node with this id exists in GUI.nodes add a counter
		 if(oil.exists(name)){
			 retname = name+'-'+oil.$element_counter;
		 }
		 // else generate a standard name
		 else {
			 retname = oil.NODE_PREFIX+oil.$element_counter;
		 }
		 oil.$element_counter++;
		 // if an id is not set,
		 if(!e.id) {
			 e.id = retname;
		 }
    }
	
	 return retname;
}

$register = function(element){
	oil.register(element);
}
	/// browser detection and browser based history
	oil.browser = {};
	oil.browser.history = {};
	/// http remote requests
	oil.remote = {};
	/// date handling
	oil.date = {};
	/// debugging and assertions
	oil.debug = {};
	/// utility functions, things that dont belong ANYWHERE else
	oil.utlity = {};
	/// application space
	oil.application = {};
	/// bootstrapping
	oil.boot = {};
	
	oil.utilty = {};
