<?php

namespace Greyd\Navigation;

if ( !defined( 'ABSPATH' ) ) exit;

class Header_Menu_Walker extends \Walker_Nav_Menu {

	/**
	 * Display an element
	 */
	public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
		if ( ! $element ) {
			return;
		}

		$id_field = $this->db_fields['id'];

		// display this element
		if ( is_array( $args[0] ) ) {
			$args[0]['has_children'] = ! empty( $children_elements[ $element->$id_field ] );
		}
		elseif ( is_object( $args[0] ) ) {
			$args[0]->has_children = ! empty( $children_elements[ $element->$id_field ] );
		}

		$cb_args = array_merge( array( &$output, $element, $depth ), $args );
		if ( is_array($cb_args[3]) ) {
			$cb_args[3] = (object) $cb_args[3];
		}
		call_user_func_array( array( &$this, 'start_el' ), $cb_args );

		$id = $element->$id_field;

		// descend only when the depth is right
		if ( $max_depth == 0 || $max_depth > $depth + 1 ) {

			// there are childrens for this element
			if ( isset( $children_elements[ $id ] ) ) {
				foreach ( $children_elements[ $id ] as $child ) {
	
					if ( ! isset( $newlevel ) ) {

						// only on first level
						if ( $depth === 0 ) {
							// add submenu id to arguments
							$args[0]->submenu_id = "submenu-{$element->ID}";
						}
	
						$newlevel = true;
	
						// start the child delimiter
						$cb_args = array_merge( array( &$output, $depth ), $args );
						call_user_func_array( array( &$this, 'start_lvl' ), $cb_args );
					}
					$this->display_element( $child, $children_elements, $max_depth, $depth + 1, $args, $output );
				}
				unset( $children_elements[ $id ] );
			}
			// this is a template dropdown
			else if ( isset( $element->template ) && !empty( $element->template ) ) {
				
				$args[0]->submenu_id = "submenu-{$element->ID}";
				$args[0]->template = $element->template;
	
				$cb_args = array_merge( array( &$output, $depth ), $args );
				call_user_func_array( array( &$this, 'render_template_dropdown' ), $cb_args );
			}

		}

		if ( isset( $newlevel ) && $newlevel ) {
			// end the child delimiter
			$cb_args = array_merge( array( &$output, $depth ), $args );
			call_user_func_array( array( &$this, 'end_lvl' ), $cb_args );
		}

		// end this element
		$cb_args = array_merge( array( &$output, $element, $depth ), $args );
		call_user_func_array( array( &$this, 'end_el' ), $cb_args );
	}

	/**
	 * Start new sublevel.
	 * 
	 * @param string $output
	 * @param int $depth
	 * @param object|array $args
	 */
	public function start_lvl( &$output, $depth = 0, $args = null ) {

		if ( $depth === 0 && isset( $args->submenu_id ) ) {
			$data = '';
			foreach ( array( 'trigger', 'anim', 'align' ) as $d ) {
				if ( isset($args->dropdown_args[$d]) ) {
					$data .= " data-{$d}='{$args->dropdown_args[$d]}'";
				}
			}
	
			$output .= sprintf(
				'<div id="%s" class="sub-menu dropmenu_content"%s>',
				esc_attr( $args->submenu_id ),
				$data
			);
	
			if ( isset($args->dropdown_args['tab']) ) {
				$output .= '<div class="dropmenu_tab '.$args->dropdown_args['tab'].'"></div>';
			}
		}

		$output .= '<ul class="submenu">';
	}

	/**
	 * End sublevel.
	 * 
	 * @param string $output
	 * @param int $depth
	 * @param object|array $args
	 */
	public function end_lvl( &$output, $depth = 0, $args = null ) {

		$output .= '</ul>';

		if ( $depth === 0 && isset( $args->submenu_id ) ) {
			$output .= '</div>';
		}
	}

	/**
	 * Render a template dropdown.
	 * 
	 * @param string $output
	 * @param int $depth
	 * @param object|array $args
	 */
	public function render_template_dropdown( &$output, $depth = 0, $args = null ) {

		if ( $depth !== 0 ) return;

		$data = '';
		foreach ( array( 'trigger', 'anim', 'align' ) as $d ) {
			if ( isset($args->dropdown_args[$d]) ) {
				$data .= " data-{$d}='{$args->dropdown_args[$d]}'";
			}
		}
		
		// parse template settings
		list( $template_id, $width, $custom_width ) = explode( '|', $args->template );

		if ( empty( $template_id ) ) return;

		// adjust width
		if ( $width == "" || $width == "auto" ) {
			$width = "";
		}
		else if ( $width == "full" ) {
			$width = "100vw";
		}
		else if ( $width == "custom" ) {
			$width = $custom_width;
			if ( strpos($width, '%') === false && strpos($width, 'px') === false ) {
				$width = ( (int) $width )."px";
			}
		}
		if ( !empty( $width ) ) {
			$data .= " style='width: {$width}'";
		}

		$output .= sprintf(
			'<div id="%s" class="sub-menu dropmenu_content template"%s>',
			esc_attr( $args->submenu_id ),
			$data
		);

		if ( isset($args->dropdown_args['tab']) ) {
			$output .= '<div class="dropmenu_tab '.$args->dropdown_args['tab'].'"></div>';
		}

		$output .= '<div class="dropmenu_template">'.do_shortcode( "[dynamic template='".$template_id."']" ).'</div>';

		$output .= '</div>';
	}
}
