//=====================================================
// H G   M E N U
//=====================================================

//
// create closure
//
(function($) {

 	//=====================================================
 	// plugin definition
	//
	$.fn.hgMenu = function(options) {

		//debug(this.size());

		// build main options before element iteration
		//var opts = $.extend({}, $.fn.hgMenu.defaults, options);

		//=====================================================
		// iterate and reformat each matched element
		return this.each(function(i) {

			// build element specific options
			//var o = $.meta ? $.extend({}, opts, $this.data()) : opts;

			var $a;
			var mc		= this; // hgMenu main DOM element [DIV]
			var $mc		= $(this);

			// do not process menu that is already processed
			if (mc.hgMenu)
				return;

			//---------------------------
			// prepare menu properties
			var menuProps = {
				initItem: null,
				currItem: null,
				nextItem: null,
				timerId: null,
				menuNr: i,
				leftArr: { arr: null, vis: false },
				rightArr: { arr: null, vis: false }
			};

			// remember menuProps
			mc.hgMenu = { menuProps: menuProps };
			$mc.attr('hgMenuMain', "1" );
			//---------------------------
			// prepare submenu container
			//
			var $smc	= $('<div class="sub-menu-container"></div>');
			$smc.hover(
					   function(){ stopPending( mc ); },
					   function(){ startHiding( mc ); }
					);
			$smc.mouseover( function(){ stopPending( mc ); } );
			$mc.append( $smc );

			//---------------------------
			// prepare left scroller
			//
			$a = $('<div class="menu-scroller-left"></div>');
			$a.click( function(){ scrollSubMenu( mc, -1 ); } );
			$a.css( 'opacity', 0 );
			$smc.append( $a );
			menuProps.leftArr.arr = $a[0];

			//---------------------------
			// prepare right scroller
			//
			$a = $('<div class="menu-scroller-right"></div>');
			$a.click( function(){ scrollSubMenu( mc, +1 ); } );
			$a.css( 'opacity', 0 );
			$smc.append( $a );
			menuProps.rightArr.arr = $a[0];

			// wrap main manu with special div and iterate over main-menu list items
			$('ul.main-menu', $mc).wrap('<div class="main-menu"></div>').children().each( function()
			{
				var $this = $(this);
				var $submenu = $('<div class="sub-menu"></div>');

				if ( /current/.test($this.attr("class")) ) {
					menuProps.initItem	= this;
				}

				var submenuProps = {
					submenu: $submenu[0],
					showArr: false,
					innerW: 0,
					widths: new Array()
				};

				// remember submenuProps
				this.hgMenu = { submenuProps: submenuProps };

				//  wrap submenu list and move to submenu container div
				$submenu.append( $('ul', $this) );
				$smc.append( $submenu );

				// init mouse events
				$this.hover(
							function(){ startShowing( this, mc ); },
							function(){ startHiding( mc ); }
						);
			});

			/*
			// prepare all empty links
			$( 'a', mc ).each(
					function () {
						var $this = $(this);
						($.trim( $this.attr('href')) ) == '') ?  $this.addClass("no-link") : 0);
					});
			*/

			//--------------------------------------------
			// show initial menu
			$mc.css('visibility', 'visible');
			doHide( mc );

			//--------------------------------------------
			// scroll current submenu item into view
			var sbmIdx = 0;
			//debug( mc.hgMenu.menuProps.initItem.hgMenu.submenuProps.submenu );
			$( 'li', mc.hgMenu.menuProps.initItem.hgMenu.submenuProps.submenu ).each( function(i) {
					if ( /current/.test($(this).attr("class")) ) {
						sbmIdx = i;
						return false;
					}
				});
			//debug(sbmIdx);
			scrollSbmIntoView(mc, sbmIdx, 0);

		});

	};

	$.fn.hgMenu.setCurrItem = function(href) {
		$('[hgMenuMain]').each( function() { setCurrentHgMenu( href, this ); } );
	};

	//=====================================================
 	// plugin private methods definition
	//

	function setCurrentHgMenu( href, mc )
	{
		var mmItem2select = null;
		var sbmIdx = null;
		$('ul.main-menu li').each( function(){
				var mainLi = this;
				if ($('a', this).attr('href') == href) {
					mmItem2select = mainLi;
					$('.sub-menu-container li', mc).removeClass('current');
				}
				else
					$('li', mainLi.hgMenu.submenuProps.submenu).each(function( iSbmIdx ){
							//debug( $('a' this).text() );
							if ($('a', this).attr('href') == href) {
								mmItem2select	= mainLi;
								sbmIdx			= iSbmIdx;
								$('.sub-menu-container li', mc).removeClass('current');
								$(this).addClass('current');
								return false;
							}
					});
				return (mmItem2select == null);
			});
		if (mmItem2select != null)
		{
			//debug( $(mmItem2select).text() );
			stopPending( mc );
			mc.hgMenu.menuProps.nextItem = mc.hgMenu.menuProps.initItem = mmItem2select;
			doShow( mc );
			if (sbmIdx != null) scrollSbmIntoView(mc, sbmIdx);
		}
	}

	//
 	// startShowing
	//
	function startShowing( item, mc )
	{
		stopPending(mc);
		if (mc.hgMenu.menuProps.currItem != item)
		{
			mc.hgMenu.menuProps.nextItem	= item;
			mc.hgMenu.menuProps.timerId		= window.setTimeout( function(){ doShow(mc); } , 300);
		}
	}

	//
 	// startHiding
	//
	function startHiding( mc )
	{
		stopPending(mc);
		mc.hgMenu.menuProps.timerId		= window.setTimeout( function(){ doHide(mc); } , 400);
	}

	//
 	// stopPending operation
	//
	function stopPending( mc )
	{
		if (mc.hgMenu.menuProps.timerId)
			window.clearTimeout( mc.hgMenu.menuProps.timerId );
		mc.hgMenu.menuProps.timerId = null;
	}

	//
 	// doHide submenu and darken mainmenu item
	//
	function doHide( mc )
	{
		var mp = mc.hgMenu.menuProps;
		mp.timerId = null;
		if (mp.currItem != mp.initItem )
		{
			if (mp.currItem)
			{
				// hide current submenu
				$(mp.currItem).removeClass( "active" );
				doHideSubMenu( mc );
			}

			// set init to current
			mp.currItem = mp.initItem;

			// show current=init submenu
			$(mp.currItem).addClass("current");
			doShowSubMenu( mc );
		}
	}

	//
 	// doShow submenu and lighten mainmenu item
	//
	function doShow( mc )
	{
		var mp = mc.hgMenu.menuProps;
		var chSubMenus = (mp.currItem != mp.nextItem);
		mp.timerId = null;
		if (mp.currItem)
		{
			$(mp.currItem).removeClass( "current" ).removeClass( "active" );
			// hide current submenu
			(chSubMenus) ? doHideSubMenu( mc ) : 0;
		}

		// set next to current
		mp.currItem	= mp.nextItem;
		mp.nextItem	= null;

		// show current submenu
		$(mp.currItem).addClass( mp.currItem == mp.initItem ? "current" : "active" );
		doShowSubMenu( mc );
	}

	//
 	// positionSubMenuArrows
	//
	function positionSubMenuArrows( mc )
	{
		var $la 	= $(mc.hgMenu.menuProps.leftArr.arr);
		var $ra		= $(mc.hgMenu.menuProps.rightArr.arr);
		var $sm 	= $(mc.hgMenu.menuProps.currItem.hgMenu.submenuProps.submenu);
		var pos 	= $sm.offset();

		pos.right = pos.left + $sm.width() - $ra.width();
		$la.css( { top: pos.top, left: pos.left } );
		$ra.css( { top: pos.top, left: pos.right } );
	}

	//
 	// scrollSbmIntoView
	//
	function scrollSbmIntoView(mc, sbmIdx, speed )
	{
		scrollSubMenu( mc, sbmIdx, false, speed );
	}

	//
 	// scrollSubMenu
	//
	function scrollSubMenu( mc, dir, relative, speed )
	{
		var i, ds = -1;
		var mp	= mc.hgMenu.menuProps;
		var smp = mp.currItem.hgMenu.submenuProps;
		var $sm	= $(smp.submenu);

		relative = (relative == undefined) ?  true : (relative == true);

		speed = (speed == undefined) ?  500 : speed;

		var a = {
			scroll: $sm.scrollLeft(),
			mnWidth: smp.innerW,
			cntWidth: $sm.outerWidth()
		}

		if (!relative)
		{
			var ls, rs;
			i = Math.min( smp.widths.length-1, Math.max( 0, dir));
			ls = Math.max( ((i > 0) ? smp.widths[i-1] - $(mp.leftArr.arr).width() : 0), 0 );
			if (a.scroll > ls)
				ds = ls;
			else
			{
				rs = Math.min( (smp.widths[i] - a.cntWidth + $(mp.rightArr.arr).width()), a.mnWidth - a.cntWidth );
				if (a.scroll < rs)
					ds = rs;
				else if(a.scroll > a.mnWidth - a.cntWidth)
					ds = a.mnWidth - a.cntWidth;
			}
		}
		else
		{
			// find relative destination pos position
			if (dir == -1)
			{
				for(i = 0; (i < smp.widths.length-1) && (smp.widths[i] < a.scroll); i++);
				ds = Math.max( ((i > 0) ? smp.widths[i-1] - $(mp.leftArr.arr).width() : 0), 0 );
			}
			else if (dir == 1)
			{
				for(i = 0; (i < smp.widths.length-1) && (smp.widths[i] < a.scroll+a.cntWidth); i++);
				ds = Math.min( (smp.widths[i] - a.cntWidth + $(mp.rightArr.arr).width()), a.mnWidth - a.cntWidth );
			}
		}

		if (ds >= 0)
		{
			$sm.animate( { scrollLeft: ds }, speed );
			((ds > 0) ? showArrow(mp.leftArr) : hideArrow(mp.leftArr));
			((ds + a.cntWidth < a.mnWidth) ? showArrow(mp.rightArr) : hideArrow(mp.rightArr));
		}

	}


	//
 	// positionSubMenuArrows
	//
	function showSubMenuArrows( mc )
	{
		var mp 	= mc.hgMenu.menuProps;
		var smp = mp.currItem.hgMenu.submenuProps;

		if (smp.showArr)
		{
			var $sm = $(smp.submenu);
			var a = {
			scroll: $sm.scrollLeft(),
			mnWidth: smp.innerW,
			cntWidth: $sm.outerWidth()
			};
			//debug( a );
			((a.scroll > 0) ? showArrow(mp.leftArr) : hideArrow(mp.leftArr));
			((a.scroll + a.cntWidth < a.mnWidth) ? showArrow(mp.rightArr) : hideArrow(mp.rightArr));
		}
		else
		{
			hideArrow(mp.leftArr);
			hideArrow(mp.rightArr);
		}
	}

	//
 	// doShow Current SubMenu
	//
	function doShowSubMenu( mc )
	{
		//  submenu: $submenu[0],
		//	showArr: false,
		//	innerW:

		var smp			= mc.hgMenu.menuProps.currItem.hgMenu.submenuProps;
		var $submenu	= $(smp.submenu);
		var $li 		= $('li', smp.submenu );

		smp.showArr		= false;
		smp.innerW		= 0;

		//debug( 'pakaży: ' + $submenu.size() );
		if ( $submenu.css('visibility') != "visible" )
			$submenu.css( { visibility:"visible", display:"block", opacity:0.0 } );
		if ($li.size())
		{
			var w = 0;
			var $ul = $('ul', $submenu );
			$li.each( function(i) { smp.widths[i] = (w += $(this).outerWidth()); } );
			w += parseInt($ul.css( 'padding-right')) + parseInt($ul.css( 'padding-left'));
			$ul.width( w );
			smp.innerW		= w;
			smp.showArr		= ( w > $submenu.width() );
			positionSubMenuArrows( mc );
		}
		showSubMenuArrows( mc );
		$submenu.fadeTo("normal", 1);
	}

	//
 	// doHide Current SubMenu
	//
	function doHideSubMenu( mc )
	{
		$(mc.hgMenu.menuProps.currItem.hgMenu.submenuProps.submenu).fadeTo("fast", 0,
						function(){
							$(this).css( { visibility: "hidden", display:"none" } );
						}
					);
	}

	//
 	// showArrow
	//
	function showArrow(arrow)
	{
		if (! arrow.vis )
		{
			arrow.vis = true;
			$(arrow.arr).css( { visibility:"visible", diplay:"block" } ).fadeTo("normal", 1);
		}
	}

	//
 	// hideArrow
	//
	function hideArrow(arrow)
	{
		if ( arrow.vis )
		{
			arrow.vis = false;
			$(arrow.arr).fadeTo("normal", 0, function(){ $(this).css( {visibility: "hidden", diplay:"none"} ); });
		}
	}

 	//=====================================================
 	// private function for debugging
	//
	function debug(o, msg) {
		var s = '['+(typeof o) + "]:\n", v, skip;
		if (typeof o == 'object') {
			for( k in o ) {
				switch(typeof (o[k])) {
				case 'object':
				case 'function':
					v = '['+(typeof (o[k]))+']';
					skip = false;
					break;
				case 'string':
					v = o[k].length > 50 ? o[k].substr(0, 46) + ' ...' : o[k];
					skip = false;
					break;
				default:
					v = o[k];
					skip = false;
				}
				s += skip ? '' : k + ': ' + v + "\n";
			}
		}
		else
			s += o;

		alert( (msg ? msg + "\n" : '' ) + s );
	};

 	//
 	// plugin defaults
	//
	$.fn.hgMenu.defaults = {
		foreground: 'red',
		background: 'yellow'
	};

//
// end of closure
//
})(jQuery);


//
// run on document ready
//
jQuery(function($){
	   $('.hgMenu').hgMenu();
});


