

YAHOO.util.Event.onDOMReady(function(){MLPlugin.triggerPluginEvent("onLoad",{});});

MLPlugin = {};
MLPlugin.pluginMetadata = [

];

MLPlugin.registeredEventListeners = {};
/**
 * This function allows clients or internal components to programatically define
 * listeners for plugin system events.
 */
MLPlugin.registerEventListener = function (event, handler) {
	var handlers = MLPlugin.registeredEventListeners[event];
	if (handlers == undefined) {
		var handlers = [];	
		MLPlugin.registeredEventListeners[event] = handlers;
	}
	handlers.push(handler);
}

/**
 * This function defines the entry point for the event subs system of the plugin system
 * To add a client side event that any plugin can listen for call this function
 * event is a string that uniquely defines the event that happened.
 * params is a javascript object containing name value mappings of information relivant to the event.
 */
MLPlugin.triggerPluginEvent = function (event,params) {
	for(var i = 0; i < MLPlugin.pluginMetadata.length; i++){
        var plugin = MLPlugin.pluginMetadata[i];
        var eventHandler =  plugin.events[event];
        if(eventHandler != undefined){
        	MLPlugin.loadDependencies(plugin, function(){ 
            	eval(eventHandler+"(event,MLPlugin.copy(params,plugin));");
            });
        }
    }
	var handlers = MLPlugin.registeredEventListeners[event];
	if(handlers != undefined) {
		for(var i = 0; i < handlers.length; i++){
			var handler = handlers[i];
			handler(event,MLPlugin.copy(params));
		}
	}
};

/**
* utility function
* creates a copy of the pararms object and adds any gloabally relivant information
*/

MLPlugin.copy = function(params,plugin){
	var copy = {};
	for(key in params){
		var value = params[key];
		copy[key] = value;
	}
	if(plugin != undefined){
		for(key in plugin.extra){
			var value = plugin.extra[key];
			copy[key] = value;
		}
	}
	return copy;
};

/**
* utility function
* ensures that the dependencies for plugin (entry in the metadata table) are met and then calls the callback.
* the callback may or may not be called asynchronously
* TODO: (kluver) add error checking.
*/
MLPlugin.loadDependencies = function(plugin,callback){
	if(plugin.loaded == true){
		callback();
		return;
	}
    var successHandler = function(oData) {
        plugin.loaded = true;
        callback();
    };
    YAHOO.util.Get.script(plugin.dependencies, {onSuccess: successHandler});
 };

 /********
 *
 * Plugin API section
 *
 *********/
 
 MLPlugin.movies = {};//a space to cache retrived movies to avoid repeated fetching
 /**
  * retrives general information about a movie from movielens as would be presented to a user.
  * result object contains the following feilds: 
  *     starring
  *     directors
  *     Genres
  *     Language
  * 
  * callback should be a javascript function that gets called when the results are available.
  * the callback is NOT garunteed to be run asychronusly.
  * the callback will be ran with a value of null on error.
  */
 MLPlugin.getMovieData = function(movieURI, callback){
 	if(MLPlugin.movies[movieURI] != undefined){
 		callback(MLPlugin.movies[movieURI]);
 		return;
 	}
 	var uri = "/plugin/movieData?movieURI="+movieURI;
 	YAHOO.util.Connect.asyncRequest('GET', uri, {
 		success:function(o){
 			var movie = eval('(' + o.responseText + ')');
 			if(movie != null){
 				MLPlugin.movies[movieURI] = movie;
 			}
 			callback(movie);
 		},
 		
 		failure:function(o){
 			callback(null);
 		}
 	});
 };
 