/**
 * menu.renderer.js
 * 10.28.10
 * 
 * Used to render a Wendigo-managed menu.
 * 
 * Example usage:
 * 
 * var renderedMenu = ns.getRenderedMenu({
 * 		"id" : "menu1",
 * 		// either a single class, or an array of classes; the 
 * 		// index corresponds to the nest level of the menu
 * 		"menuClass" : ["_hopeMenu"],
 * 		// either a single class, or an array of classes; the 
 * 		// index corresponds to the nest level of the menu item
 * 		"menuItemClass" : null,
 * 		// either a single direction string, or an array of 
 * 		// direction strings; the index corresponds to the 
 * 		// nest level of the menu
 * 		"displayDirection" : "",
 * 		// either a single offset, or an array of offset; the 
 * 		// index corresponds to the nest level of the menu
 * 		"subOffset" : null,
 * 		// if creators are being used, the above 
 * 		// properties are ignored
 * 		// the following are either a single creator 
 * 		// functions, or an array of functions; the index 
 * 		// corresponds to the nest level of the menu
 * 		"menuCreator" : [
 * 			function() {
 * 				var html = jwyre.create("<ul class='menutop' style='overflow: visible'></ul>");
 * 				return html;
 * 			},
 * 			function() {
 * 				var html = jwyre.create("<ul style='overflow: hidden; margin-top: -2px;'></ul>");
 * 				return html;
 * 			}
 * 		],
 * 		"subMenuDisplayer" : [
 * 			function() {},
 * 			function(_init) {
 * 				var html = _init.html;
 * 				var x = _init.x;
 * 				var y = _init.y;
 * 				var mItem = _init.menuItem;
 * 		
 * 				var parent = jwyre.element("#" + mItem._id);
 * 				jwyre.append(parent, html);
 * 				var dims = jwyre.dimensions(html);
 * 				jwyre.style(html, "height", "0px");
 * 				grow();
 * 		
 * 				function grow() {
 * 		    		var ctr = 0;
 * 		    		var _id = window.setInterval(
 * 		        		function() {
 * 		            		if (ctr > dims.height) {
 * 		                		window.clearInterval(_id);
 * 		                		finish();
 *		 		                return;
 * 				            }
 * 		        		    jwyre.style(html, "height", ctr + "px");
 * 		            		ctr += 2;
 * 		        		},
 * 		        		1
 *		 		    );                                  
 * 				}
 * 				function finish() {
 * 		    		var ctr = 0;
 *		 		    var _id = window.setInterval(
 * 				        function() {
 * 		        		    if (ctr > 1) {
 * 		                		window.clearInterval(_id);
 *		 		                jwyre.style(html, "height", dims.height + "px");
 * 				                return;
 * 		        		    }
 *		 		            var h = dims.height + (Math.sin(ctr * Math.PI) * 10);    
 * 				            ctr += .03;                                         
 * 		        		    jwyre.style(html, "height", h + "px");
 *		 		        },
 * 				        2
 * 				    );                                    
 * 				}
 * 			}
 * 		],
 * 		"menuItemCreator" : 
 * 			function(_init) {
 * 				var html = jwyre.create(
 * 					"<li id='"+_init.id+"'>" +
 *		 			"<a href='"+_init.link+"'><span>"+_init.name+"</span></a>"+
 * 					"</li>");
 * 				return html;
 * 			}					
 * 		}); 
 *      wendigo.MenuLoader.getMenu("appId", function(menu) {
 *          renderedMenu.loadData(menu);
 *          jwyre.append(document.body, renderedMenu.getHtml());
 *      });
 * 
 * 
 * @author Ryan Hardy 
 * @version 1.0
 */
(function() {
	var ns = jwyre.module("wendigo.MenuBuilder");
	
	/**
	 * 
	 */
	ns.getRenderedMenu = function(initializer) {
		var renderedMenu = new RenderedMenu(initializer);
		
		return renderedMenu;
	};
	
	/*
	================================================================
	                   		Rendered menu code
	================================================================
	*/
	function RenderedMenu(initializer) {
		// used for testing
		this._properties = initializer;
		
	    var _menu;
	    
	    
	    // does a null-safe check for an array in the initializer object, obtaining
	    // the object at the given index, return null if not present
	    // if the property has a non-arrray value, that will be returned
	    function _safeGet(prop, index) {
	    	if (initializer[prop]) {
	    		var ary = initializer[prop];
	    		// items to be checked for will be either strings or functions,
	    		// so do type-checking first before assuming value is an array
	    		if (typeof ary == "string" || typeof ary == "function") {
	    			return ary;
	    		}
	    		if (ary.length > index) {
	    			return ary[index];
	    		}
	    	}
	    	return null;
	    }
	    
	    /**
	     *
	     * @param {string} name
	     * @param {integer} nest
	     */
	    function _getMenuObj(name, nest) {
	        var obj = {
	            "name": name,
	            "id": "menu_" + name.replace(/ /g, "") + jwyre.id(),
	            "tagClass" : _safeGet("menuClass", nest),
	            "subOffset": _safeGet("subOffset", nest),
	            "menuCreator" : _safeGet("menuCreator", nest),
	            "subMenuDisplayer" : _safeGet("subMenuDisplayer", nest)
	        };
	        return obj;
	    };
	    /**
	     *
	     * @param {string} name
	     * @param {function} action
	     * @param {integer} nest
	     */
	    function _getMenuItemObj(name, action, nest) {
	        var obj = {
	            "name": name,
	            "link" : action,
	            "id": "menuItem_" + name.replace(/ /g, "") + jwyre.id(),
	            "menuItemCreator" : _safeGet("menuItemCreator", nest)
	        };
	        return obj;
	    };
	    
	    function bldMenuItems(subs, parent, nest) {
	        for (var i in subs) {
	            var mObj = subs[i];
	            var mnu = parent.addMenuItem(
            		_getMenuItemObj(mObj.name, mObj.link, nest)
        		);
	            for (var i in mObj.subMenu) {
	                bldMenu(mObj.subMenu[i], mnu, nest + 1);
	            }
	        }
	    }
	    
	    function bldMenu(json, parent, nest) {
	        if (json.subMenu.length == 0) {
	            parent.addMenuItem(_getMenuItemObj(json.name, json.link, nest));
	        } else {
	            var sub = parent.addSubMenu(
            		_getMenuItemObj(json.name, json.link, nest), 
            		_getMenuObj(json.name, nest)
        		);
	            bldMenuItems(json.subMenu, sub, nest + 1);
	        }
	    }
	    /**
	     * 
	     * @return
	     */
	    this.getHtml = function() {
	        return _menu.getHtml();
	    };
	    	
	    /**
	     * 
	     * @param json
	     * @return
	     */
	    this.loadData = function(json) {
	        _menu = jwyre.menu({
	            "id": initializer.id,
	            "tagClass": _safeGet("menuClass", 0),
	            "makeContextMenu": false,
	            "subOffset": _safeGet("subOffset", 0),
	            "zIndex" : 10000,
	            "dispDirection": _safeGet("displayDirection", 0),
	            "menuCreator" : _safeGet("menuCreator", 0),
	            "subMenuDisplayer" : _safeGet("subMenuDisplayer", 0)
	        });
	        for (var i in json.subMenu) {
	            bldMenu(json.subMenu[i], _menu, 1);
	        }
	    };                  
	}
})();
