/**
 * File navigation.js.
 *
 * Handles toggling the navigation menu for small screens and enables TAB key
 * navigation support for dropdown menus.
 *
 * @package Zakra
 */

var ZakraNavHelper = {

	// Returns first children of a node.
	getChildNodes: function( node ) {
		var children = [],
			child;

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

		return children;
	},

	offset: function( 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};
	},


	// Calculate the dimension of an element with margin, padding and content.
	dimension: function( el ) {
		return 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' ) );
	},

	getOverflowItems: function( navLi ) {


		navigation.style.flex = '0 0 ' + navUlTempWidth + 'px';

		var extraLi = [];

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

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

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

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

		return extraLi;
	}
};

window.zakraNavHelper = ZakraNavHelper;

(
	function() {
		var container, menu, links, i, len;

		container = document.getElementById( 'zak-primary-nav' );

		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' ),
					supportsPassive = false;;
				try {
					var opts = Object.defineProperty( {}, 'passive', {
						get: function() {
							supportsPassive = true;
						}
					} );
					window.addEventListener( 'testPassive', null, opts );
					window.removeEventListener( 'testPassive', null, opts );
				} catch ( e ) {}

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

						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, supportsPassive ? { passive: true } : false );
					}
				}
			}( container )
		);
	}()
);


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

		var elWithChildren = document.querySelectorAll( '.zak-primary-nav li.menu-item-has-children, .zak-primary-nav li.page_item_has_children' ),
			elCount        = elWithChildren.length,
			elEvent        = isTouchDevice() ? 'touchstart' : 'mouseenter';

		/**
		 * @see https://stackoverflow.com/questions/123999/how-can-i-tell-if-a-dom-element-is-visible-in-the-current-viewport/7557433#7557433
		 */
		function isElementInViewport( el ) {
			var rect = el.getBoundingClientRect();

			return (
				0 <= rect.left &&
				rect.right <= (
					( window.innerWidth - 10 ) || ( document.documentElement.clientWidth - 10 )
				)
			);
		}

		// Checks whether user uses touch device or not.
		function isTouchDevice() {
			return 'ontouchstart' in window || navigator.maxTouchPoints;
		};

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

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

				if ( li ) {

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

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

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

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

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

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

	}
	() );

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

		// Get required elements.
		var more, search, cart, button, button2, searchWidth, cartWidth, buttonWidth, moreWidth, navUl, navLi,
			navLiWidth, extraWrap, navWrapWidth, overflowItems;

		navigation = document.getElementById( 'zak-primary-nav' );

		// Return if no navigation markup.

		if ( null === navigation ) {
			return;
		}

		// Return if `Keep Menu Items on One Line` customizer option is not enabled

		if ( ! navigation.classList.contains( 'zak-extra-menus' ) ) {
			return;
		}

		// Extra ellipsis icon added via PHP.
		more      = navigation.getElementsByClassName( 'zak-menu-extras-wrap' )[0];

		// Ul to append extra menu items.
		extraWrap = document.getElementById( 'zak-menu-extras' );

		// No primary menu assigned.
		if ( null === extraWrap ) {
			return;
		}

		navUl = navigation.getElementsByClassName( 'nav-menu' )[0];

		navLi = ZakraNavHelper.getChildNodes( navUl );

		navWrapWidth = navigation.offsetWidth;

		search      = navigation.getElementsByClassName( 'zak-header-search' )[0];
		cart        = navigation.getElementsByClassName( 'zak-menu-item-cart' )[0];
		button      = navigation.getElementsByClassName( 'zak-header-button-wrap' )[0];
		button2     = navigation.getElementsByClassName( 'zak-header-button-wrap' )[1];

		searchWidth = search ? ZakraNavHelper.dimension( search ) : 0;
		cartWidth   = cart ? ZakraNavHelper.dimension( cart ) : 0;
		buttonWidth = button ? ZakraNavHelper.dimension( button ) : 0;
		buttonWidth += button2 ? ZakraNavHelper.dimension( button2 ) : 0;
		moreWidth   = more ? ZakraNavHelper.dimension( more ) : 0;

		navUlTempWidth = navWrapWidth - ( searchWidth + cartWidth + buttonWidth + moreWidth );

		navLiWidth = 0;


		navLi.forEach( function( menuItem, index  ) {
			navLiWidth += ZakraNavHelper.dimension( menuItem );
		} );

		navWrapWidth = ( navLi.length - 1 ) * 24;

		// If overflow.
		if ( navLiWidth > navWrapWidth ) {

			overflowItems = ZakraNavHelper.getOverflowItems( navLi );

			overflowItems.forEach( function( item ) {
				extraWrap.appendChild( item );
			} );

		} else {

			// Remove ellipsis icon for more.
			more.parentNode.removeChild( more );
		}

		navigation.style.flex = '';
	}()
);

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

		for ( var i = 0; i < mobMenuItemsCount; i++ ) {
			item = mobMenuItems[i];

			item.addEventListener(
				'click',
				function() {
					toggleButton.click();
				}
			);
		}
	}()
);

