//容器集合
var FixedMenu = function(containers, options) {
	this._timerContainer = null;//容器定时器
	this._timerMenu = null;//菜单定时器
	this._frag = document.createDocumentFragment();//碎片对象，保存菜单元素
	this._menus = {};//菜单对象
	
	this._containers = [];//容器集合
	
	this._setOptions(options);
	var opt = this.options;
	
	this._custommenu = opt.menu;
	
	this.css = opt.css;
	this.hover = opt.hover;
	this.active = opt.active;
	this.tag = opt.tag;
	this.html = opt.html;
	this.relContainer = opt.relContainer;
	this.relative = opt.relative;
	this.attribute = opt.attribute;
	this.property = opt.property;
	
	this.onBeforeShow = opt.onBeforeShow;
	
	this.delay = parseInt(opt.delay) || 0;
	
	//修正自定义容器
	$$A.forEach($$A.isArray(containers) ? containers : [containers], function(o, i){
		//自定义容器 id:定位元素 menu:插入菜单元素
		var pos, menu;
		if ( o.id ) {
			pos = o.id; menu = o.menu ? o.menu : pos;
		} else {
			pos = menu = o;
		};
		pos = $$(pos); menu = $$(menu);
		//容器对象 pos:定位元素 menu:插入菜单元素
		pos && menu && this._iniContainer( i, { "pos": pos, "menu": menu } );
	}, this);
	
	//初始化程序
	this._iniMenu();
};
FixedMenu.prototype = {
  //设置默认属性
  _setOptions: function(options) {
	this.options = {//默认值
		menu:			[],//自定义菜单集合
		delay:			200,//延迟值(微秒)
		tag:			"div",//默认生成标签
		css:			undefined,//默认样式
		hover:			undefined,//触发菜单样式
		active:			undefined,//显示下级菜单时显示样式
		html:			"",//菜单内容
		relContainer:	false,//是否相对容器定位（否则相对菜单）
		relative:		{ align: "clientleft", vAlign: "bottom" },//定位对象
		attribute:		{},//自定义attribute属性
		property:		{},//自定义property属性
		onBeforeShow:	function(){}//菜单显示时执行
	};
	$$.extend( this.options, options || {} );
  },
  //程序初始化
  _iniMenu: function() {
	this.hide();//隐藏菜单
	this._buildMenu();//生成菜单对象
	this._forEachContainer(this._resetContainer);//重置容器属性
	this._insertMenu(0, 0);//显示菜单
  },
  //根据自定义菜单对象生成程序菜单对象
  _buildMenu: function() {
	//清除旧菜单dom(包括自定义的)
	this._forEachMenu(function(o){
		var elem = o._elem;
		if ( elem ) {
			//防止dom内存泄漏
			$$E.removeEvent( elem, "mouseover", o._event );
			elem.parentNode.removeChild(elem);
			o._elem = o.elem = null;
		};
	});
	//设置菜单默认值
	var options = {
		id:				0,//id
		rank:			0,//排序
		elem:			"",//自定义元素
		tag:			this.tag,
		css:			this.css,
		hover:			this.hover,
		active:			this.active,
		html:			this.html,
		relContainer:	!!this.relContainer,
		relative:		this.relative,
		attribute:		this.attribute,
		property:		this.property
	};
	//先定义"0"顶级菜单
	this._menus = { "0": { "_children": [] } };
	//整理自定义菜单并插入到程序菜单对象
	$$A.forEach(this._custommenu, function(o) {
		//生成菜单对象(由于包含对象，要用深度扩展)
		var menu = $$.deepextend( $$.deepextend( {}, options ), o || {} );
		//去掉相同id菜单，同时排除了id为"0"的菜单
		if ( !!this._menus[ menu.id ] ) { return; };
		//重置属性
		menu._children = []; menu._index = -1;
		this._menus[menu.id] = menu;
	}, this);
	//建立树形结构
	this._forEachMenu(function( o, id, menus ) {
		if ( "0" === id ) { return; };//顶级没有父级菜单
		var parent = this._menus[o.parent];
		//父级菜单不存在或者父级是自己的话，当成一级菜单
		if ( !parent || parent === o ) { parent = menus[o.parent = "0"]; };
		//插入到父级菜单对象的_children中
		parent._children.push(o);
	});
	//整理菜单对象
	this._forEachMenu(function(o) {
		//如果有自定义元素的话先放到碎片文档中
		!!o.elem && ( o.elem = $$(o.elem) ) && this._frag.appendChild(o.elem);
		//修正样式,优先使用自定义元素的class
		if ( !!o.elem && o.elem.className ) {
			o.css = o.elem.className;
		} else if ( o.css === undefined ) { o.css = ""; };
		if ( o.hover === undefined ) { o.hover = o.css; };
		if ( o.active === undefined ) { o.active = o.hover; };
		//对菜单对象的_children集合排序(先按rank再按id排序)
		o._children.sort(function( x, y ) { return x.rank - y.rank || x.id - y.id; });
	});
  },
  //插入菜单
  _insertMenu: function(index, parent) {
	var container = this._containers[index];
	//如果是同一个父级菜单不用重复插入
	if ( container._parent === parent ) { return; };
	container._parent = parent;
	//把原有容器内菜单移到碎片对象中
	$$A.forEach( container._menus, function(o) { o._elem && this._frag.appendChild(o._elem); }, this );
	//重置子菜单对象集合
	container._menus = [];
	//把从父级菜单元素的子菜单对象集合获取的元素插入到容器
	$$A.forEach(this._menus[parent]._children, function( menu, i ){
		this._checkMenu( menu, index );//检查菜单
		container._menus.push(menu);//加入到容器的子菜单集合，方便调用
		container.menu.appendChild(menu._elem);//菜单元素插入到容器
	}, this);
  },
  //检查菜单
  _checkMenu: function(menu, index) {
	//索引保存到菜单对象属性中，方便调用
	menu._index = index;
	//如果菜单对象没有元素
	if ( !menu._elem ) {
		var elem = menu.elem;
		//如果没有自定义元素的话创建一个
		if ( !elem ) { elem = document.createElement(menu.tag); elem.innerHTML = menu.html; };
		//设置property
		$$.extend( elem, menu.property );
		//设置attribute
		var attribute = menu.attribute;
		for (var att in attribute) { elem.setAttribute( att, attribute[att] ); };
		//设置样式
		elem.className = menu.css;
		//设置事件
		menu._event = $$F.bindAsEventListener( this._hoverMenu, this, menu );//用于清除事件
		$$E.addEvent( elem, "mouseover", menu._event );
		//保存到菜单对象
		menu._elem = elem;
	};
  },
  //触发菜单
  _hoverMenu: function(e, menu) {
	var elem = menu._elem;
	//如果是内部元素触发直接返回
	if ( $$D.contains( elem, e.relatedTarget ) || elem === e.relatedTarget ) { return; };
	clearTimeout(this._timerMenu);
	//可能在多个容器间移动，所以全部容器都重新设置样式
	this._forEachContainer(function(o, i){
		if ( o.pos.visibility === "hidden" ) { return; };
		this._resetCss(o);
		//设置当前菜单为active样式
		var menu = o._active;
		if ( menu ) { menu._elem.className = menu.active; };
	});
	//设置当前菜单为触发样式
	if ( this._containers[menu._index]._active !== menu ) { elem.className = menu.hover; };
	//触发显示菜单
	this._timerMenu = setTimeout( $$F.bind( this._showMenu, this, menu ), this.delay );
  },
  //显示菜单
  _showMenu: function(menu) {
	var index = menu._index, container = this._containers[index], child = !!menu._children.length;
	//隐藏不需要的容器
	this._forEachContainer( function(o, i) { i > index && this._hideContainer(o); } );
	//重置当前容器_active
	container._active = null;
	//如果有子级菜单
	if ( child ) {
		//设置当前容器_active
		container._active = menu;
		//显示下一级容器
		index++;//设置索引
		this._checkContainer(index);//检查容器
		this._insertMenu(index, menu.id);//插入菜单
		this._showContainer(menu);//显示容器
	};
	//重置当前容器的css
	this._resetCss(container);
	//设置当前菜单样式
	menu._elem.className = child ? menu.active : menu.hover;
  },
  //初始化容器(索引, 容器元素)
  _iniContainer: function(index, container) {
	var oContainer = container.pos;
	//重置属性
	this._resetContainer(container);
	//添加事件
	$$E.addEvent(oContainer, "mouseover", $$F.bind(function(){ clearTimeout(this._timerContainer); }, this));
	$$E.addEvent(oContainer, "mouseout", $$F.bindAsEventListener(function(e){
		//先判断是否移出到所有容器之外
		var elem = e.relatedTarget,
			isOut = $$A.every(this._containers, function(o){ return  o.pos == elem || !($$D.contains(o.pos, elem)); });
		if ( isOut ) {
			//清除定时器并隐藏
			clearTimeout(this._timerContainer); clearTimeout(this._timerMenu);
			this._timerContainer = setTimeout( $$F.bind( this.hide, this ), this.delay );
		};
	}, this));
	//除了第一个容器外设置浮动样式
	if ( index ) {
		$$D.setStyle(container.pos, {
			position: "absolute", display: "block", margin: 0,
			zIndex: this._containers[index - 1].pos.style.zIndex + 1//要后面的覆盖前面的
		});
	};
	//ie6处理select
	if ( $$B.ie6 ) {
		var iframe = document.createElement("<iframe style='position:absolute;filter:alpha(opacity=0);display:none;'>");
		document.body.insertBefore(iframe, document.body.childNodes[0]);
		container._iframe = iframe;
	};
	//记录索引，方便调用
	container._index = index;
	//插入到容器集合
	this._containers[index] = container;
  },
  //检查容器
  _checkContainer: function(index) {
	if ( index > 0 && !this._containers[index] ) {
		//如果容器不存在，根据前一个容器复制成新容器，第一个容器必须自定义
		var pre = this._containers[index - 1].pos
		//用了新的添加事件方式，没有ie的cloneNode的bug
			,container = pre.parentNode.insertBefore( pre.cloneNode(false), pre );
		//清除id防止冲突
		container.id = "";
		//初始化容器
		this._iniContainer( index, { "pos": container, "menu": container } );
	};
  },
  //显示容器
  _showContainer: function(menu) {
	var index = menu._index
		,container = this._containers[index + 1].pos
		,elem = menu.relContainer ? this._containers[index].pos : menu._elem
		,pos = RelativePosition( elem, container, menu.relative );
	//执行显示前事件
	this.onBeforeShow(container, menu);
	//定位并显示容器
	$$D.setStyle(container, {
		left: pos.Left + "px", top: pos.Top + "px", visibility: "visible"
	});
	//ie6处理select
	if ( $$B.ie6 ) {
		$$D.setStyle(this._containers[index + 1]._iframe, {
			width: container.offsetWidth + "px",
			height: container.offsetHeight + "px",
			left: pos.Left + "px", top: pos.Top + "px",
			display: ""
		});
	};
  },
  //隐藏容器
  _hideContainer: function(container) {
	//设置隐藏
	$$D.setStyle( container.pos, { left: "-9999px", top: "-9999px", visibility: "hidden" } );
	//重置上一个菜单的触发菜单对象
	this._containers[container._index - 1]._active = null;
	//ie6处理select
	if ( $$B.ie6 ) { container._iframe.style.display = "none"; };
  },
  //重置容器对象属性
  _resetContainer: function(container) {
	container._active = null;//重置触发菜单
	container._menus = [];//重置子菜单对象集合
	container._parent = -1;//重置父级菜单id
  },
  //隐藏菜单
  hide: function() {
	this._forEachContainer(function(o, i){
		if ( i === 0 ) {
			//如果是第一个重设样式和_active
			this._resetCss(o);
		} else {//隐藏容器
			this._hideContainer(o);
		};
	});
  },
  //重设容器菜单样式
  _resetCss: function(container) {
	$$A.forEach( container._menus, function(o, i){ o._elem.className = o.css; }, this );
  },
  //历遍菜单对象集合
  _forEachMenu: function(callback) {
	for ( var id in this._menus ) { callback.call( this, this._menus[id], id, this._menus ); };
  },
  //历遍容器对象集合
  _forEachContainer: function(callback) {
	$$A.forEach( this._containers, callback, this );
  },
  //添加自定义菜单
  add: function(menu) {
	this._custommenu = this._custommenu.concat(menu);
	this._iniMenu();
  },
  //修改自定义菜单
  edit: function(menu) {
	$$A.forEach( $$A.isArray( menu ) ? menu : [ menu ], function(o){
		//如果对应id的菜单存在
		if ( o.id && this._menus[o.id] ) {
			//从自定义菜单中找出对应菜单,并修改
			$$A.every( this._custommenu, function(m, i){
				if ( m.id === o.id ) {
					this._custommenu[i] = $$.deepextend( m, o ); return false;
				};
				return true;
				//用every可以跳出循环
			}, this );
		};
	}, this );
	this._iniMenu();
  },
  //删除自定义菜单
  del: function() {
	var ids = Array.prototype.slice.call(arguments);
	this._custommenu = $$A.filter( this._custommenu, function(o){
		return $$A.indexOf(ids, o.id) === -1;
	});
	this._iniMenu();
  }
};
