/* var menu_links format:	
[{'display':'Link One','classes':'','newWindow':'','noFollow':'','href':'/#','children':[
	{'display':'Link One Child One','classes':'','newWindow':'','noFollow':'','href':'/#','children':[]},
	{'display':'Link One Child Two','classes':'','newWindow':'','noFollow':'','href':'/#','children':[]}]
},
{'display':'Link Two','classes':'','newWindow':'','noFollow':'','href':'/#','children':[
	{'display':'Link Two Child One','classes':'','newWindow':'','noFollow':'','href':'/#','children':[]},
	{'display':'Link Two Child Two','classes':'','newWindow':'','noFollow':'','href':'/#','children':[]}]
},
{'display':'Link Three','classes':'','newWindow':'','noFollow':'','href':'/#','children':[
	{'display':'Link Three Child One','classes':'','newWindow':'','noFollow':'','href':'/#','children':[]},
	{'display':'Link Three Child Two','classes':'','newWindow':'','noFollow':'','href':'/#','children':[]}]
}];
*/



var DynaMenu = Class.create();
DynaMenu.prototype = {
	initialize: function() {
		// class variables
		this.open_timer = null;
		this.close_timer = null;
		this.menu_timer = null;
		this.open_menus = [];
		this.curr_level = 1;
		this.curr_link = null;
		this.menu = '';
		this.menu_str = '';
		
		this.test = [];
		
		//ie browser check
		var nav_agent = navigator.userAgent;
		this.ie6 = window.showHelp;
		this.ie7 = nav_agent.indexOf("MSIE 7")+1;

		//option variables
		var data = $A(arguments);
		var options = (data[0]) ? data[0] : {};
		this.menu_id = (options.menu_id) ? options.menu_id : 'DynaMenu';
		this.menu_links = (options.menu_links) ? options.menu_links : [];
		this.menu_type = (options.menu_type) ? options.menu_type : 0; // 0=plain hierarchal : 1=mouseover link show subs : 2=click link shows subs
		this.menu_effect = (options.menu_effect && options.menu_effect != '') ? options.menu_effect : false;
		this.base_dir = (options.base_dir) ? options.base_dir : '';
		this.row_limit = (options.row_limit) ? options.row_limit : 0;
		this.menu_pad = (options.menu_pad) ? options.menu_pad : 0;
		this.col_width = (options.col_width) ? options.col_width : 0;
		this.menu_chrome = (options.menu_chrome && options.menu_chrome == true) ? true : false;
		this.test_mode = (options.test_mode && options.test_mode == true) ? true : false;
		
		//determine if sub menus need to be hidden
		this.hide_subs = (this.menu_type == 1 || this.menu_type == 2) ? true : false;
		
		//insert menu container into document if it doesn't exist
		if (!$(this.menu_id)) {
			var menu_container = document.createElement('div');
			menu_container.id = this.menu_id;
			document.body.appendChild(menu_container);
		}
		
		// build array from existing menu
		if ($(this.menu_id).immediateDescendants().length > 0) {
			this.crawlMenu($(this.menu_id).down('ul'));
			this.menu_str = '[' + this.menu_str + ']';
			this.menu_links = this.menu_str.evalJSON();
		}
		
		// build dynamic menu
		if (this.menu_links.length > 0) {
			this.buildMenu(this.menu_links);
		}
		
		this.loadMenu();
		
		//TESTING
		if (this.test_mode) {
			var test_box = '<div id="DynaMenuDebugger" style="width:300px;height:200px;background-color:#000;padding:10px;color:#fff;position:absolute;top:180px;right:10px;overflow:scroll;"></div>';
			new Insertion.Bottom($('wrapper'),test_box);
			//alert(this.menu);
			//alert(this.test.join(', '));
			//alert(this.curr_level);
		}
	},
	
	crawlMenu:function (list_el) {
		if (list_el != 'undefined' && list_el != null) {
			var self = this;
			var list_items = list_el.immediateDescendants();
			list_items.each(function(li_el,index) {
				
				var a_el = li_el.down('a');
				var child_list_el = li_el.down('ul');
				
				self.menu_str += "{\"display\":\"" + a_el.innerHTML + "\",\"classes\":\"" + a_el.className + "\",\"href\":\"" + a_el.readAttribute('href') + "\",\"children\":[";
				if (child_list_el != 'undefined' && child_list_el != null) { self.crawlMenu(child_list_el); }
				self.menu_str += ']}';
				if (index < (list_items.length - 1)) { self.menu_str += ','; }
			});
		}
	},
	
	buildMenu:function (links) {
		var cols = null;
		var last_col_rows = null;
		var curr_row = 1;
		var curr_col = 1;
		var total_links = links.length;
		if (this.row_limit > 0 && total_links > this.row_limit && this.curr_level > 1) {
			var modu = Math.ceil(total_links % this.row_limit);
			last_col_rows = (modu > 0) ? modu : this.row_limit;
			cols = Math.ceil(total_links / this.row_limit);
		}
		
		var div_styles = [];
		if (this.curr_level > 1 && this.hide_subs) { div_styles.push('display:none;'); }
		if (cols != null) { div_styles.push('width:' + ( (this.col_width * cols) + (this.menu_pad * 2) ) + 'px;'); }
		this.menu += '<div class="menu"';
		if (div_styles.length > 0) this.menu += ' style="' + div_styles.join('') + '"';
		this.menu += '>';
		
		if (this.menu_chrome) {
			this.menu += '<div class="menutop"><span><span></span></span></div>';
			this.menu += '<div class="menubody">';
		}
		
		var self = this;
		links.each(function(link,index) {
			if (curr_row == 1) {
				self.menu += (cols == null) ? '<ul>' : '<ul style="float:left;display:inline;width:' + self.col_width + 'px;">';
			}
			
			var li_classes = [];
			var a_classes = [];
			var has_children = (link.children.length > 0) ? true : false;
			if (index < 1) { li_classes.push('first');a_classes.push('first'); }
			if (index == (links.length - 1)) { li_classes.push('last');a_classes.push('last'); }
			li_classes.push('link_' + (index + 1));a_classes.push('link_' + (index + 1));
			if (has_children) { a_classes.push('parent'); }
			if (link.classes && link.classes != '') { li_classes.push(link.classes); a_classes.push(link.classes); }
			var li_class = (li_classes.length > 0) ? ' class="' + li_classes.join(' ') + '"' : '';
			var a_class = (a_classes.length > 0) ? ' class="' + a_classes.join(' ') + '"' : '';
			var a_target = (link.newWindow == 'Y') ? ' target="_blank"' : '';
			var a_rel = (link.noFollow == 'Y') ? ' rel="nofollow"' : '';
			var a_href = (link.href == 'index.html') ? '' : link.href;
			self.menu += '<li' + li_class + '><a href="' + (link.href.indexOf('http://') !== -1 ? link.href : self.base_dir + link.href) + '"' + a_rel + a_target + a_class + '>' + link.display + '</a>';
			if (has_children) {
				self.curr_level++;
				self.buildMenu(link.children);
			}
			
			self.menu += '</li>';
			
			if ( (curr_row == total_links && cols == null) || (curr_row == self.row_limit && cols != null) || (cols != null && curr_col == cols && curr_row == last_col_rows) ) {
				self.menu += '</ul>';
				
				if (cols != null) {
					if (curr_col == cols && curr_row == last_col_rows) {
						self.menu += '<div class="col_clear"></div>';
						curr_col = 1;
					} else {
						curr_col++;
					}
				}
				curr_row = 1;			
			} else {
				curr_row++;
			}
		});
		
		
		
		if (this.menu_chrome) {
			this.menu += '</div>';
			this.menu += '<div class="menubottom"><span><span></span></span></div>';
		}
		
		this.menu += '</div>';
	},
	
	loadMenu:function () {
		var menu_el = $(this.menu_id);
		menu_el.update(this.menu);
		
		// set events
		switch (this.menu_type) {
		case  0 :
			
			break;
		case  1 :
			Event.observe(menu_el,"mouseout",this.outEvent.bindAsEventListener(this));
			Event.observe(menu_el,"mouseover",this.overEvent.bindAsEventListener(this));
			break;
		case  2 :
			Event.observe(menu_el,"mouseup",this.upEvent.bindAsEventListener(this));
			break;
		}
	
	
		if (this.ie6 && !this.ie7) { this.ie_menuFix(); }
	},
	
	overEvent:function(e) {
		var self = this;
		var target_el = Event.element(e);
		if (this.curr_link != null && this.curr_link != target_el) { this.curr_link.removeClassName('hover'); }
		
		
		switch (this.menu_type) {
		case 1 :
			this.endCloseTimer();
			break;
		}

		
		if (this.test_mode) { new Insertion.Bottom($('DynaMenuDebugger'),'  el: ' + target_el.tagName + '<br />'); }
		
		switch (target_el.tagName) {
		case 'A' :
			if (this.curr_link != target_el) { 
				target_el.addClassName('hover');
				this.curr_link = target_el;
				
				switch (this.menu_type) {
				case 1 :
					this.startMenuTimer();
					this.closeMenus();
					this.endOpenTimer();
					if (target_el.hasClassName('parent')) {
						this.startOpenTimer(target_el);
					}
					break;
				}
			}
			break;
		}
	},
	
	outEvent:function(e) {
		var target_el = Event.element(e);
		var related_el = e.relatedTarget || e.toElement;
		while (related_el != target_el && related_el.nodeName != 'BODY') {
			related_el = related_el.parentNode;
		}
		if (related_el == target_el) return;
		
		this.curr_link = null;
		
		switch (this.menu_type) {
		case 1 :
			this.startCloseTimer();
			this.endOpenTimer();
			break;
		}
		
		switch (target_el.tagName) {
		case 'A' :
			target_el.removeClassName('hover');
			break;
		}
	},
	
	upEvent:function(e) {
		return true;
	},
	
	
	startCloseTimer:function () {
		var self = this;
		this.endCloseTimer();
		this.close_timer = new PeriodicalExecuter(function() {
			self.closeMenus(true);
			self.endCloseTimer();
		}, .01);
	},
	endCloseTimer:function () {
		if (this.close_timer != null) {
			this.close_timer.stop();
			this.close_timer = null;
		}
	},

	startMenuTimer:function () {
		var self = this;
		this.endMenuTimer();
		this.menu_timer = new PeriodicalExecuter(function() {
			self.closeMenus(true);
			self.endMenuTimer();
		}, 2);
	},
	endMenuTimer:function () {
		if (this.menu_timer != null) {
			this.menu_timer.stop();
			this.menu_timer = null;
		}
	},
	
	startOpenTimer:function (link_el) {
		var self = this;
		this.open_timer = new PeriodicalExecuter(function() {
			self.openMenu(link_el);
		}, .2);
	},
	endOpenTimer:function () {
		if (this.open_timer != null) {
			this.open_timer.stop();
			this.open_timer = null;
		}
	},
	
	
	
	
	
	openMenu:function(link_el) {
		link_el.addClassName('focus');
		var submenu_el = link_el.next(0); //div.menu
		
		if (this.menu_effect != false) {
			Effect.BlindDown(submenu_el);
		} else {
			submenu_el.show();
		}
				
		var vp_dims = document.viewport.getDimensions();
		var el_dims = submenu_el.getDimensions();
		var el_coords = new Position.cumulativeOffset(submenu_el);
						
		if ( (el_dims.width + el_coords[0]) > vp_dims.width ) {
			submenu_el.addClassName('reverse');
		}
		
	//	if (this.ie6 && !this.ie7) { this.ie_sizeIframe(submenu_el); }
		this.open_menus.push(link_el);
	},
	
	closeMenus:function (cmd) {
		if (this.open_menus.length > 0) {
			var self = this;
			if (cmd && cmd == true) {
				this.open_menus.each(function(open_anchor) {
					open_anchor.removeClassName('focus');
					open_anchor.removeClassName('hover');
					open_anchor.next(0).hide();
				});
				this.open_menus.clear();
			} else {
				this.open_menus.reverse(false).each(function(open_anchor) {
					var open_menu = open_anchor.next(0);
					if (!self.curr_link.descendantOf(open_menu)) {
						open_menu.hide();
						open_anchor.removeClassName('focus');
						open_anchor.removeClassName('hover');
						self.open_menus.pop();
					}
				});
			}
		}
	},
	
	
	
	
	
	
	ie_menuFix:function () {
		var fixmenus = $(this.menu_id).getElementsByClassName('menu');
		fixmenus.each(function(submenu,index) {
			submenu.insertAdjacentHTML("afterBegin","<iframe src='javascript:false;' style='display:block;z-index:-1;position:absolute;float:left;border-style:none;width:1px;height:1px;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);' frameborder='1'></iframe>");
		});
	},
	ie_sizeIframe:function (submenu_el) {
		var dims = submenu_el.getDimensions();
		var	sub_w = dims.width + 'px';
		var	sub_h = dims.height + 'px';
		var iframe_el = submenu_el.firstDescendant();
		$(iframe_el).setStyle({width:sub_w,height:sub_h});
	}
}
