/**
 * @fileoverview This file contains the client-side functionality for the
 * navigation bars.
 * 
 * @requires jQuery jquery.js jQuery library
 * @requires Observable observable.js Functionality to make the model observable
 * @requires jQuery.dropshadow jquery.dropshadow.js Add drop-shadow to menu
 * @requires jQuery.bgiframe Fixes z-index form field glitch in IE6
 * @requires navigation.css Stylesheet for navigation bar
 */

/**
 * @namespace Holds functionality related to the navigation bar
 */
var Nav = {};

$('console.log').ready(function() {
	
	// initiate main structures
	Nav.Model = new Nav.ModelClass();
	Nav.View = new Nav.ViewClass(Nav.Model);
	Nav.Controller = new Nav.ControllerClass(Nav.Model, Nav.View);
	Nav.View.setBehavior();
});


/**
 * Model for Navigation handling data storage and retrieval
 * @class Model for Navigation
 * @extends Observable
 */
Nav.ModelClass = function() {

	Nav.ModelClass.baseConstructor.call(this);
	
	/**
	 * properties that point to variables that may not yet be defined when this
	 * code is run are set as strings to be executed later with eval
	 */
	this.properties = {
		timeOut: 500,
		closeTimer: 0
	};

};

OopExtend(Nav.ModelClass, Observable);

/**
 * Main View Class to handle all display functions. Constructor will set
 * default states of the UI elements.
 * @class View for Navigation
 */
Nav.ViewClass = function(model) {
	
	// set model and observe it
	this.model = model;
	Nav.Model.addObserver(this);
	
};

/**
 * Populate menu items in navigation bar
 */
Nav.ViewClass.prototype.setBehavior = function() {
	var context = this;
		
	// if browser is not IE6 or lower, set dropshadow for nav bar
	/*if (!($.browser.msie && $.browser.version < 7))
		$('.menu ul').dropShadow();*/
	
	// bind menus to drop-down functionality
	$('.menu > ul > li').bind('mouseover', function() {
		context._navOpen(this);
	});
	$('.menu > ul > li').bind('mouseout', function() {
		context._navTimer();
	});
	
	// remove right border from right-most menu item
	$('.menu > ul > li:last a').css('border-right', 'none');
};

/**
 * Closes navigation drop-down
 */
Nav.ViewClass.prototype.navClose = function() {
	if (this.model.properties.menuItem)
		this.model.properties.menuItem.css('visibility', 'hidden').removeShadow();
};

/**
 * Expands navigation drop-down
 * @param {Object} item Holds the element the user hovered over
 * @private
 */
Nav.ViewClass.prototype._navOpen = function(item) {
	this._navCancelTimer();
	this.navClose();
	this.model.properties.menuItem = $(item).find('ul').css('visibility', 'visible').bgiframe();
	// if browser is not IE6 or lower, set dropshadow for nav bar
	//if (!($.browser.msie && $.browser.version < 7)) {
	// TODO: for now, don't display drop-shadow for IE until we can troubleshoot the flickering
	if (!($.browser.msie)) {
		this.model.properties.menuItem.dropShadow({
			left: 2,
			top: 2,
			blur: 2,
			opacity: 0.2
		});
	}
};

/**
 * Set close navigation timer
 * @private
 */
Nav.ViewClass.prototype._navTimer = function() {
	var context = this;
	this.model.properties.closeTimer = window.setTimeout(function() {
		context.navClose();
	}, context.model.properties.timeOut);
};

/**
 * Clear close navigation timer
 * @private
 */
Nav.ViewClass.prototype._navCancelTimer = function() {
	var context = this;
	if (this.model.properties.closeTimer) {
		window.clearTimeout(context.model.properties.closeTimer);
		this.model.properties.closeTimer = null;
	}
};


/**
 * Main Controller to deal with all user interaction logic. Constructor sets
 * all user interaction functionality on the UI elements.
 * @class
 */
Nav.ControllerClass = function(model, view) {
	
	this.model = model;
	this.view = view;
	var context = this;
	
	this.bindNavEvent();
	
};

/**
 * Binds click event handler to nav menu links
 */
Nav.ControllerClass.prototype.bindNavEvent = function() {
	var context = this;
	$(document).click(function() {
		context.view.navClose();
	});
}

