//= require <mootools-core-1.3-full-nocompat>
//= require <puremvc-mootools-port>
//= require <uiframework/URLUtil>
//= require <findsalons/ApplicationFacade>
var DeepLinkMediator = function()
{
	this.Extends = Mediator;

	/**
	 * The browserManager instance.
	 * 
	 * @type BrowserManager
	 */
	this.browserManager = null;
	this.currentHash = "";
	this.lastHash = "";

	this.initialize = function()
	{
		this.parent(DeepLinkMediator.NAME, new BrowserManager());
		this.browserManager = this.viewComponent;
	};

	/**
	 * Initializes the BrowserManager and initializes the history management
	 * system. The first URL_CHANGE event is triggered here containing the hash
	 * if one exists.
	 */
	this.onRegister = function()
	{
		this.parent();

		this.browserManager.addEventListener(BrowserManager.URL_CHANGE, this.browserManager_urlChangeHandler, false, 0, this);
		this.browserManager.historyInit();
	};

	this.listNotificationInterests = function()
	{
		return [ ApplicationFacade.SET_HASH, AsyncProxy.LOGOUT_RESULT ];
	};

	this.handleNotification = function(note /* Notification */)
	{
		switch (note.getName())
		{
			case ApplicationFacade.SET_HASH:
				this.setNewHash(note.getBody());
				break;
				
			case AsyncProxy.LOGOUT_RESULT:
				this.setNewHash({action:false});
				break;
		}
	};

	/**
	 * Sets a new hash in the browser address bar. Hash's are normalized and
	 * combined with changes being overwritten only when a new value exists. To
	 * remove a hash element, set it to false
	 * 
	 * @param value
	 *            mixed String or Object representing the new hash.
	 */
	this.setNewHash = function(value /* mixed String or Object */)
	{
		var newFragment = (typeof value == 'string') ? URLUtil.stringToObject(value) : value;
		// Normalizes the order of the fragments
		var existingFragment = URLUtil.stringToObject(this.browserManager.getCurrentHash());
		var existingFragString = URLUtil.objectToString(existingFragment);

		// Merge the fragments into the existing fragment object.
		for ( var key in newFragment)
		{
			if (newFragment[key] == false)
				delete existingFragment[key];
			else
				existingFragment[key] = newFragment[key];
		}

		var newFragString = URLUtil.objectToString(existingFragment);
		// Bail if the fragments are the same
		if (newFragString == existingFragString)
			return;

		this.browserManager.setUrlFragment(newFragString);
	};

	/**
	 * Notifies the system when the hash changes.
	 * 
	 * @param event
	 *            UICEvent containing the hash string in the data property.
	 */
	this.browserManager_urlChangeHandler = function(event)
	{
		var hash = event.data;
		if (this.currentHash != hash)
		{
			this.lastHash = this.currentHash;
			this.currentHash = hash;
			if (!hash && location.search)
				hash = URLUtil.searchStringToObject(location.search);
			else
				hash = URLUtil.stringToObject(hash);
			this.sendNotification(ApplicationFacade.URL_CHANGE, hash);
		}
	};

	/**
	 * Retrieves the current hash in the form of an object.
	 * 
	 * @return Object containing the current hash key => value pairs.
	 */
	this.getCurrentHash = function()
	{
		return URLUtil.stringToObject(this.currentHash);
	};
};
DeepLinkMediator = new Class(new DeepLinkMediator());
DeepLinkMediator.NAME = "DeepLinkMediator";
