/**
 * File navigation.js.
 *
 * Handles toggling the navigation menu for small screens and enables TAB key
 * navigation support for dropdown menus.
 */
(
	function () {
		var container, button, menu, links, i, len;

		container = document.getElementById( 'site-navigation' );
		if ( ! container ) {
			return;
		}

		menu = container.getElementsByTagName( 'ul' )[0];

		menu.setAttribute( 'aria-expanded', 'false' );
		if ( - 1 === menu.className.indexOf( 'nav-menu' ) ) {
			menu.className += ' nav-menu';
		}

		// Get all the link elements within the menu.
		links = menu.getElementsByTagName( 'a' );

		// Each time a menu link is focused or blurred, toggle focus.
		for ( i = 0, len = links.length; i < len; i ++ ) {
			links[i].addEventListener( 'focus', toggleFocus, true );
			links[i].addEventListener( 'blur', toggleFocus, true );
		}

		/**
		 * Sets or removes .focus class on an element.
		 */
		function toggleFocus() {
			var self = this;

			// Move up through the ancestors of the current link until we hit .nav-menu.
			while ( - 1 === self.className.indexOf( 'nav-menu' ) ) {

				// On li elements toggle the class .focus.
				if ( 'li' === self.tagName.toLowerCase() ) {
					if ( - 1 !== self.className.indexOf( 'focus' ) ) {
						self.className = self.className.replace( ' focus', '' );
					} else {
						self.className += ' focus';
					}
				}

				self = self.parentElement;
			}
		}

		/**
		 * Toggles `focus` class to allow submenu access on tablets.
		 */
		(
			function ( container ) {
				var touchStartFn, i,
				    parentLink = container.querySelectorAll( '.menu-item-has-children > a, .page_item_has_children > a' );

				if ( 'ontouchstart' in window ) {
					touchStartFn = function ( e ) {
						var menuItem = this.parentNode,
						    i;

						if ( ! menuItem.classList.contains( 'focus' ) ) {
							e.preventDefault();
							for ( i = 0; i < menuItem.parentNode.children.length; ++ i ) {
								if ( menuItem === menuItem.parentNode.children[i] ) {
									continue;
								}
								menuItem.parentNode.children[i].classList.remove( 'focus' );
							}
							menuItem.classList.add( 'focus' );
						} else {
							menuItem.classList.remove( 'focus' );
						}
					};

					for ( i = 0; i < parentLink.length; ++ i ) {
						parentLink[i].addEventListener( 'touchstart', touchStartFn, false );
					}
				}
			}( container )
		);
	}()
);


/**
 * Fixes menu out of viewport
 */
(
	function () {
		var i;

		var container      = document.getElementById( 'site-navigation' ),
		    elWithChildren = document.querySelectorAll( '.tg-primary-menu li.menu-item-has-children, .tg-primary-menu li.page_item_has_children' ),
		    elCount        = elWithChildren.length;

		/**
		 * @see https://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport/125106#125106
		 */
		function elementInViewport( el ) {
			var top    = el.offsetTop,
			    left   = el.offsetLeft,
			    width  = el.offsetWidth,
			    height = el.offsetHeight;

			while ( el.offsetParent ) {
				el = el.offsetParent;
				top += el.offsetTop;
				left += el.offsetLeft;
			}

			return (
				top >= window.pageYOffset &&
				left >= window.pageXOffset &&
				(
					top + height
				) <= (
					window.pageYOffset + window.innerHeight
				) &&
				(
					left + width
				) <= (
					window.pageXOffset + window.innerWidth
				)
			);
		} // End: function elementInViewport( el ) {

		// Loop through li having sub menu.
		for ( i = 0; i < elCount; i ++ ) {

			// On mouse enter.
			elWithChildren[i].addEventListener( 'mouseenter', function ( ev ) {
				var li = ev.currentTarget;

				if ( li ) {

					var subMenu = li.querySelectorAll( '.sub-menu, .children' )[0];

					if ( subMenu ) {

						var w = window,
						    d = document,
						    e = d.documentElement,
						    g = d.getElementsByTagName( 'body' )[0],
						    x = w.innerWidth || e.clientWidth || g.clientWidth,
						    y = w.innerHeight || e.clientHeight || g.clientHeight;

						if ( ! elementInViewport( subMenu ) ) {
							subMenu.classList.add( 'tg-edge' );
						}
					}
				}
			}, false );

			// On mouse leave.
			elWithChildren[i].addEventListener( 'mouseleave', function ( ev ) {
				var li = ev.currentTarget;

				if ( li ) {
					var sub = li.querySelectorAll( '.sub-menu, .children' )[0];

					sub.classList.remove( 'tg-edge' );

					if ( sub.classList.contains( 'tg-edge' ) ) {
						sub.classList.remove( 'tg-edge' );
					}
				}
			}, false );
		} // End: for ( i in elWithChildren ) {

	}
)();

/**
 * Keep menu items on one line.
 */
(
	function () {

		// Get required elements.
		var mainWrapper = document.querySelector( '.tg-site-header .tg-header-container' ),
		    branding    = document.querySelector( '.tg-site-header .site-branding' ),
		    navigation  = document.getElementById( 'site-navigation' ),
		    mainWidth   = mainWrapper.offsetWidth,
		    brandWidth  = branding.offsetWidth,
		    navWidth    = navigation.offsetWidth,
		    isExtra     = ( brandWidth + navWidth ) > mainWidth,
		    more        = navigation.getElementsByClassName( 'tg-menu-extras-wrap' )[0];

		// Return if no excess menu items.
		if ( ! navigation.classList.contains( 'tg-extra-menus' ) ) {
			return;
		}

		function Dimension( el ) {
			var elWidth;
			if ( document.all ) {// IE.
				elWidth = el.currentStyle.width + parseInt( el.currentStyle.marginLeft, 10 ) + parseInt( el.currentStyle.marginRight, 10 ) + parseInt( el.currentStyle.paddingLeft, 10 ) + parseInt( el.currentStyle.paddingRight, 10 );
			} else {
				elWidth = parseInt( document.defaultView.getComputedStyle( el, '' ).getPropertyValue( 'width' ) ) + parseInt( document.defaultView.getComputedStyle( el, '' ).getPropertyValue( 'margin-left' ) ) + parseInt( document.defaultView.getComputedStyle( el, '' ).getPropertyValue( 'padding-left' ) ) + parseInt( document.defaultView.getComputedStyle( el, '' ).getPropertyValue( 'padding-right' ) ) + parseInt( document.defaultView.getComputedStyle( el, '' ).getPropertyValue( 'margin-right' ) );
			}

			return elWidth;
		}

		// If menu excesses.
		if ( ! isExtra ) {
			more.parentNode.removeChild( more );
		} else {
			var widthToBe, search, cart, button, button2, searchWidth, cartWidth, buttonWidth, moreWidth;

			widthToBe   = mainWidth - brandWidth;
			search      = navigation.getElementsByClassName( 'tg-menu-item-search' )[0];
			cart        = navigation.getElementsByClassName( 'tg-menu-item-cart' )[0];
			button      = navigation.getElementsByClassName( 'tg-header-button-wrap' )[0];
			button2     = navigation.getElementsByClassName( 'tg-header-button-wrap' )[1];
			searchWidth = search ? Dimension( search ) : 0;
			cartWidth   = cart ? Dimension( cart ) : 0;
			buttonWidth = button ? Dimension( button ) : 0;
			buttonWidth += button2 ? Dimension( button2 ) : 0;
			moreWidth   = more ? Dimension( more ) : 0;
			newNavWidth = widthToBe - ( searchWidth + cartWidth + buttonWidth + moreWidth );

			navigation.style.visibility = 'none';
			navigation.style.width      = newNavWidth + 'px';

			// Returns first children of a node.
			function getChildNodes( node ) {
				var children = new Array();

				for ( var child in node.childNodes ) {
					if ( 1 === node.childNodes[child].nodeType ) {
						children.push( node.childNodes[child] );
					}
				}
				return children;
			}

			var navUl = navigation.getElementsByClassName( 'nav-menu' )[0],
			    navLi = getChildNodes( navUl ); // Get lis.

			function offset( el ) {
				var rect       = el.getBoundingClientRect(),
				    scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,
				    scrollTop  = window.pageYOffset || document.documentElement.scrollTop;

				return {top: rect.top + scrollTop, left: rect.left + scrollLeft}
			}

			var extraLi = [];

			for ( var liCount = 0; liCount < navLi.length; liCount ++ ) {
				var initialPos, li, posTop;

				li     = navLi[liCount];
				posTop = offset( li ).top;

				if ( 0 === liCount ) {
					initialPos = posTop;
				}

				if ( posTop > initialPos ) {
					if ( ! li.classList.contains( 'tg-menu-item-search' ) && ! li.classList.contains( 'tg-menu-item-cart' ) && ! li.classList.contains( 'tg-header-button-wrap' ) && ! li.classList.contains( 'tg-menu-extras-wrap' ) ) {
						extraLi.push( li );
					}
				}
			}

			var newNavWidth = newNavWidth + ( searchWidth + cartWidth + buttonWidth + moreWidth ) - 2,
			    extraWrap   = document.getElementById( 'tg-menu-extras' );

			navigation.style.width = newNavWidth + 'px';

			if ( null !== extraWrap ) {
				extraLi.forEach( function ( item, index, arr ) {
					extraWrap.appendChild( item );
				} );
			}

		}

	}()
);

/**
 * Close mobile menu on clicking menu items.
 */
(
	function () {
		var mobMenuItems = document.querySelectorAll( '#mobile-navigation li a' ),
		    toggleButton = document.querySelector( '.tg-mobile-toggle' ),
			item;

		for ( var i = 0; i < mobMenuItems.length; i++ ) {
			item = mobMenuItems[i];
			item.addEventListener( 'click', function ( event ) {
				toggleButton.click();
			} );
		}
	}()
);
