/**
 * Package inviso.block
 *
 * This file contains functions and classes to work with inviso block objects
 *
 * @package inviso.block
 * @author  Lesley Wevers
 */

/**
 * BlockManager is a singleton object
 */
InvisoBlockManager = {
	blocks: $A(),
	initQueue: $A()

};

/**
 * Register a block to the blockmanager
 *
 * @param   mixed   object      The block object to register
 * @param   string  id          The id of the block
 * @param   string  widget_name The name of the block widget
 */
InvisoBlockManager.register = function(object, id, widget_name) {
   InvisoBlockManager.blocks.push({
       "object":object,
       "id":id,
       "widget_name":widget_name
   });
}

/**
* Gets a block by its id
*
* @param   string  id          The id of the block to get
* @return  mixed               If found the block, otherwise null
*/
InvisoBlockManager.get_block_by_id = function(id) {
	tmp = InvisoBlockManager.blocks.find(function(block) { return block.id == id })
	return tmp ? tmp.object : null;
}

/**
 * Initializes the given widget once the DOM is loaded. Will initialize immediately if the DOM is already loaded.
 * @param string widgetClass The class to instantiate, or a value that evaluates to false if no class should be instantiated. You may also pass a class object directly.
 * @param object options an object that will be passed to the constructor and/or initializer of the widget
 * @param initializer function (Optional) a function that will be called with the object handle and the options as parameters. If no class was given the object parameter is undefined.
 */
InvisoBlockManager.initialize = function (widgetClass, options, initializer) {
	initItem = {widgetClass: widgetClass, options: options, initializer: initializer};
	if (InvisoBlockManager.initQueue) {
		InvisoBlockManager.initQueue.push(initItem);
	} else {
		InvisoBlockManager.performInit(initItem);
	}
}

// Initialize all queued widgets when the DOM is loaded, and trigger the WidgetsInitialized event if the inviso.events module is loaded
document.observe('dom:loaded',function(){
	if (typeof(window['inviso_shared_ajax']) != "undefined") {
		// Start an ajax request so all initialization ajax requests that use inviso_shared_ajax() will be processed at once
		ajax = inviso_shared_ajax();
	}
	InvisoBlockManager.initQueue.map(InvisoBlockManager.performInit);
	InvisoBlockManager.initQueue = false;
	if (typeof(window['inviso_shared_ajax']) != "undefined") {
		// Send the ajax request before triggering the event
		ajax.send();
	}
	if (typeof(window['InvisoEventManager']) != "undefined") {
		tmp = InvisoEventManager.get('WidgetsInitialized');
		tmp.notify.bind(tmp).defer();
	}
});

// Internal function, do not call directly. 
InvisoBlockManager.performInit = function (initItem) {
	try { 
		if (initItem.widgetClass) {
			if (Object.isString(initItem.widgetClass)) {
				// Convert the name of the class to the class object itself
				initItem.widgetClass = eval(initItem.widgetClass);
			}
			// Instantiate the widget object
			obj = new initItem.widgetClass(initItem.options);
		}
		if (initItem.initializer) {
			initItem.initializer(obj, initItem.options);
		}
	} catch (ex) {
		// catch exceptions, so one failed initialization doesn't stop the rest
		if (typeof(window['console']) != "undefined") {
			console.info("Exception while initializing widget", ex, initItem);
		}
	}
}

/**
* Gets one block by its widget name
*
* @param   string  widget_name The name of the widget for which to get a block
* @return  mixed               A block
*/
InvisoBlockManager.get_block_by_widget_name = function(widget_name) {
	tmp = InvisoBlockManager.blocks.find(function(block) { return block.widget_name == widget_name })
	return tmp ? tmp.object : null;
}

/**
* Gets all blocks by a widget name
*
* @param   string  widget_name The name of the widget for which to get all blocks
* @return  array<mixed>        An array of blocks
*/
InvisoBlockManager.get_blocks_by_widget_name = function(widget_name) {
	return InvisoBlockManager.blocks.findAll(function(block) { return block.widget_name == widget_name }).pluck('object');
}

function $inviso(id) {
    return InvisoBlockManager.get_block_by_id(id);
}
