/**
 * A class to allow access to an API of a ResponseMX Flash Movie.
 * Handles the communication between JavaScript and Flash.
 *
 * Flash to JavaScript method execution (event dispatching)
 *   The Flash Movie will need to inform JavaScript when an event occurs that JavaScript must handle.
 *   Examples of events include: passing the return value of a method call in the Flash to JavaScript (setView -
 *   see below) and *real* events such as a new map loading (mapLoadComplete).
 *   When an event is dispatched all listeners registered for events of the given type will be called.
 *   The listeners are passed an event Object which has a type property (the event type),
 *   a target property (a reference to the RMXWrapper instance that dispatched the event) and properties to
 *   represent the data associated with the event (centerx, centery, zoomwidth for mapLoadComplete event).
 *
 * JavaScript to Flash method execution
 *   JavaScript calls a method in the Flash to do something (setView, setTool etc.) by calling the callMethod
 *   method defined on the RMXWrapper passing the method name as a String and the arguments to pass to the
 *   method as an Array.
 *   If there is a return value the Flash will dispatch an event as described above
 *   with the name of the method called as the event type and the return value as a named property.
 *
 */

/**
 * RMXWrapper constructor
 * @param id (String) The id of the Flash movie this instance is bound to
 */
function RMXWrapper(id) {
	// Set the id of the Flash movie we are bound to
	this.id = id;
	this.listeners = new Array();
}

/**
 * Allows a method to be called in the Flash Movie
 * @param name (String) The name of the method to call
 * @param args (Array) An Array of parameters to pass as arguments to the method
 */
RMXWrapper.prototype.callMethod = function(name, args) {
	//alert("RMXWrapper.callMethod")
	// alert("  name: " + name);
	// Create a new Array to hold the parameters
	var params = new Array();
	params.push("method=" + name);
	for (var i = 0; i < args.length; i++) {
		// escape the argument
		args[i] = escape(args[i]);
	}
	params.push("args=" + args.join(","));
	// Get a reference to the movie
	var movie = this.getMovie(this.id);
	// Build the command String to send to the Movie
	var qs = params.join("&");
	//alert(qs);
	// Set the rmx_method variable which is watched in the Movie
	movie.SetVariable("rmx_method", qs);
};

/**
 * Called by RMXController.onMovieEvent when the movie dispatches an event.
 * Dispatches the event to all listeners registered for events of the given type
 */
RMXWrapper.prototype.onMovieEvent = function(eventInfo) {
	//alert("onMovieEvent eventInfo: " + eventInfo);
	// Create an Array of the eventInfo String passed
	var params = eventInfo.split("&");
	var parts;
	// Create an event Object
	var eventObj = new Object();
	for (var p in params) {
		// Split the parameter into name, value
		parts = String(params[p]).split("=");
		if (parts[0] == "event") {
			// We've got the event type
			eventObj.type = parts[1];
		} else {
			// We've got an argument
			eventObj[parts[0]] = unescape(unescape(parts[1]));
		}
	}
	// Define the target of the event (this)
	eventObj.target = this;
	/*
	// Show the fields of the event Object
	for (var i in eventObj) {
		alert(i + ": " + eventObj[i]);	
	}
	*/
	// Loop through all listeners to find any for the current event
	//alert("  this.listeners.length: " + this.listeners.length);
	for (var i = 0; i < this.listeners.length; i++) {
		// Get the listener
		var listener = this.listeners[i];
		//alert("  listener.type: " + listener.type);
		// Test to see if the listeners type is the same as the event
		if (listener.type == eventObj.type) {
			// Call the listener
			listener.handler(eventObj);
		}
	}

}

/**
 * Adds a function as a listener for the given event
 * @param eventType (String) The type of the event to add a listener for e.g. "mapLoadComplete" or "getTool"
 * @param handlerFunction (Function) A reference to the function to call when the event is dispatched
 */
RMXWrapper.prototype.addEventListener = function (eventType, handlerFunction) {
	//alert("RMXWrapper.addEventListener eventType: " + eventType);
	this.listeners.push({type:eventType, handler:handlerFunction});
};

/**
 * Removes a listener for the given event
 * @param eventType (String) The type of the event to remove the listener for e.g. "mapLoadComplete" or "getTool"
 * @param handlerFunction (Function) A reference to the function to call when the event is dispatched
 */
RMXWrapper.prototype.removeEventListener = function (eventType, handlerFunction) {
	//alert("RMXWrapper.removeEventListener eventType: " + eventType);
	for (var i = 0; i < this.listeners.length; i++) {
		var listener = this.listeners[i];
		if (listener.type == eventType && listener.handler == handlerFunction) {
			this.listeners.splice(i, 1);	
		}
	}
};

/**
 * Returns a reference to the Flash Movie with the given id
 * @param id (String) The id of the Flash Movie on the page
 */
RMXWrapper.prototype.getMovie = function (id) {
	if ((window[id])) {
		// IE
		return window[id];
	} else {
		// Mozilla
		return document[id];
	}
};
