/*--------------------------------------------------------------------
Scripts for creating and manipulating custom menus based on standard <ul> markup
Version: 1.0, 01.18.2008

By: Maggie Costello Wachs (maggie@filamentgroup.com) and Scott Jehl (scott@filamentgroup.com)
	http://www.filamentgroup.com
	* reference article: http://www.filamentgroup.com/lab/jquery_ipod_style_drilldown_menu/

Copyright (c) 2008 Filament Group
Licensed under GPL (http://www.opensource.org/licenses/gpl-license.php)

Dependencies:
	jQuery library
	position.jQuery.js
	utilities.js
--------------------------------------------------------------------*/

/* Parameters:
@settings: see notes below
@positionOpts: // the orientation of the menu relative to the link that calls it
	posX: 'left',
	posY: 'bottom',
	offsetX: 0,
	offsetY: 0,
	directionH: 'right',
	directionV: 'down',
	detectH: true, // do horizontal collision detection
	detectV: true, // do vertical collision detection
	linkToFront: false // make the caller link appear over the menu (visual effect)
*/

function Menu(caller, settings) {
	var settings = jQuery.extend({
		content: null, // markup string to be inserted into the menu
		positionOpts: null, // see alternate options above -- must be passed in object notation, i.e., { offsetX: 10 }
		width: 160, // width of menu container
		maxHeight: 300, // max height of menu (if a drilldown: height does not include breadcrumb)
		showSpeed: 0, // show/hide speed in milliseconds
		callerOnState: 'btnMenuOn', // class to change the appearance of the link when the menu is showing
		itemHover: 'hover', // class for menu option hover state
		altClasses: null, // any additional classes for the menu container, separated by spaces
		crossSpeed: 300, // cross-fade speed for multi-level menus
		selectCategories: false, // false = selecting a category will navigate you to the next level until you reach a leaf node; true = each category is an accepted value in addition to leaf node
		parentSearch:false,
		nextMenuLink: 'nextLevel', // class to identify the link used in the multi-level menu to show the next level -- include the preceding "."
		topLinkText: 'All'
	}, settings);

	var menuLink = $(caller);
	var menu = $('<div class="menuContainer">'+settings.content+'</div>');
	var menuOpen = false;


	if (settings.selectCategories) {
		menu.find('li:has(ul)').each(function(){
			$(this).find('a:first').after('<a title="Раскрыть меню" rel="nofollow" href="#" class="'+settings.nextMenuLink+'">&nbsp;</a>');
		});
	};

	this.create = function(){
		if (settings.content) {

			menu.css({
				top: 0,
				left: '-9999px'
			});

			if (settings.altClasses) { menu.addClass(settings.altClasses); };
			if (menuLink.width() > menu.width()) { menu.css({ width: menuLink.width() }); };

			menu.appendTo('body').setRandomId({ attribute: 'menuid' }).css({ width: settings.width }).find('ul:first').addClass('menu').css({ position: 'relative' });

			// close all open menus
			$('*[menuid]').parent().trigger('click');

			if (settings.callerOnState) { menuLink.addClass(settings.callerOnState); };

			// if there are multiple levels, create a drilldown menu
			if (menu.children('ul').size() > 0) { this.drilldown(menu, settings); };

			menu.positionObject(menuLink, settings.positionOpts).hide().slideDown(settings.showSpeed).find('.menu:eq(0)').css({ visibility: 'visible' });

			menuOpen = true;

			// assign events to menu & child items
			menu.parent().click(this.kill);

			//click events when categories are accepted values
			var that = this;
			if (settings.selectCategories) {
				$('.ddMenu li a').not('.'+settings.nextMenuLink).click(function(){
					window.location = this.href;
					that.kill();
					return false;
					//other actions could go here
				});
			}
			else {
				$('.ddMenu li a').not('.menuIndicator').click(function(){
					window.location = this.href;
					that.kill();
					return false;
					//other actions could go here
				});
			};

		}; // end if (settings.content)
	}; // end this.create()

	this.kill = function(){
		menu.parent().remove();
		if (menuLink.is('.'+settings.callerOnState)) { menuLink.removeClass(settings.callerOnState); };
		menuOpen = false;
	};

	return this;
};


Menu.prototype.drilldown = function(menu, settings) {
	var breadcrumb = $('<ul class="ddBreadcrumb clearfix" style="display: none;"></ul>');
	var ddmenu = $('<div class="ddMenu"></div>');

	menu.css({ overflow: 'hidden' }).children().eq(0).wrap(ddmenu);
	menu.prepend(breadcrumb);

	var listHeights = [];
	menu.find('.ddMenu').find('ul').each(function(i){
	 	listHeights[i] = $(this).height();
	 });
	listHeights.sort(sortBigToSmall);
	menu.find('.ddMenu').find('ul').css({ height: '330px' });

	// apply scrollbar to the menu if it exceeds max height
	if (listHeights[0] > settings.maxHeight) {
		menu.find('.ddMenu').addClass('scrollNeeded').css({ height: '330px', overflow: 'auto', 'overflow-x': 'hidden' }).find('ul').css({ width: ('180').pxToEm()});
	}
	else {
		menu.find('.ddMenu').css({ height: '330px' }).find('ul').css({ width: settings.width });
	};

	menu.find('.ddMenu li a').each(function(){
		if (!$(this).next().is('.'+settings.nextMenuLink)) {
			$(this).addClass('singleLink');
			/* autotitle
			var mTit = $(this).text();
			if($(this).attr('title') !== 'Раскрыть меню') {
            $(this).attr('title',mTit);
            }
            */
		};
	});

	var showNextLevel = function(el) {
		var thisLink = $(el);
		var thisList = $(el).parents('ul:eq(0)');
		var nextList = $(el).next();
		var thisListId = thisList.attr('id');

		//add all categories link
		if (breadcrumb.find('li').size()<1){
			var allCrumb = $('<li class="all"><a href="#">'+settings.topLinkText+'</a></li>');
			allCrumb.click(function(){
				menu.find('ul').not('ul.menu, .ddBreadcrumb').css({ visibility: 'hidden' });
				breadcrumb.empty().hide();
				return false;
			});
			breadcrumb.append(allCrumb);
		};

		var addNewCrumb = function() {
			var crumbText;
			var crumbLink;
			if (thisLink.prev().is('a')) { crumbText = thisLink.prev().html(); crumbLink = thisLink.prev().attr('href');}
			else { crumbText = thisLink.html(); crumbLink = thisLink.attr('href'); };

			var newCrumb = $('<li class="currentCrumb" style="display: none;"><a href="'+crumbLink+'" class="crumb">'+crumbText+'</a></li>');
			$('.currentCrumb').removeClass('currentCrumb');
			breadcrumb.append(newCrumb);
			newCrumb.show();

			newCrumb.find('a').click(function(){
				if($(this).parent().is('.currentCrumb')){
					window.location = this.href;
					//$('.menuBtn').children(':last').text($(this).text());
					menu.kill();
					//other actions could go here
					return false;
				}
				else {
					nextList.find('ul').css({ visibility: 'hidden' });
					$(this).parent().nextAll().css({ visibility: 'hidden' }).slideUp(settings.crossSpeed, function(){$(this).remove();});
					$(this).parent().addClass('currentCrumb');
					return false;
				}
			});
		};

		// if the breadcrumb container is hidden, show it and add the first crumb
		if (breadcrumb.css('display') == 'none') {
			breadcrumb.slideDown();
			addNewCrumb();
		}
		else { addNewCrumb(); };

		// show the next list
		nextList.css({
			visibility: 'visible',
			left: settings.width
		}).animate({ left: 0 }, settings.crossSpeed);
	};
	// end showNextLevel

	// when category links are not selectable (only link to next level)
	if (!settings.selectCategories) {
		menu.find('.ddMenu li a').each(function(){
			if ($(this).next().is('ul')) {
				$(this).addClass('menuIndicator').click(function(){
					showNextLevel(this);
					return false;
				});
			};
		});
	};


	menu.find('.'+settings.nextMenuLink).click(function(){
		showNextLevel(this);
		return false;
	});

	var url = window.location.href;
	var formedUrl = url.substr(19);

    if (settings.parentSearch) {
    menu.find('.ddMenu li a').each(function(){
    var links = $(this).attr('href');
    if (links == formedUrl) {
    $(this).addClass('mCurrent');
    $(this).parent().children('.nextLevel').click();
    $(this).parent().parent().parent().children('.nextLevel').click();
    }
    });
	}


};
