<?php
/**
 * Theme Menuitem Extension
 * add icons and anchors to menu
 */
namespace Greyd\Navigation;

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

new Menu();
class Menu {

	/**
	 * Hodls the admin menu walker class. Can be modified using
	 * the @filter greyd_admin_menu_walker_class
	 */
	protected $menu_walker = '\Greyd\Navigation\Admin_Menu_Walker';

	/**
	 * Holds the custom menu fields arguments. Can be modified
	 * using the @filter greyd_admin_menu_fields
	 */
	protected $menu_fields = array();

	/**
	 * Constructor
	 */
	function __construct() {

		/**
		 * Filter the admin menu walker class.
		 * @since 1.4.5
		 * @filter greyd_admin_menu_walker_class
		 */
		$this->menu_walker = apply_filters( 'greyd_admin_menu_walker_class', $this->menu_walker );
		
		/**
		 * Filter the menu fields.
		 * @since 1.4.5
		 * @filter greyd_admin_menu_fields
		 */
		$this->menu_fields = apply_filters( 'greyd_admin_menu_fields', array(
			//'field-01' => array( 'label' => 'Custom Field #1', 'type' => 'text' ),
			'style'   => array(
				'label' => __('Darstellung', 'core'),
				'type' => 'style', 
				'width' => 'wide' 
			),
			'icon'    => array( 
				'label' => __('Icon', 'core'), 
				'type' => 'icon', 
				'width' => 'thin'
			),
			'iconpos' => array( 
				'label' => __('Icon Position',  'core'),
				'type' => 'radio', 
				'width' => 'thin' 
			),
			'image'   => array( 
				'label' => __('Bild', 'core'),
				'type' => 'file', 
				'width' => 'wide' 
			),
			'anchor'  => array( 
				'label' => __('Anker', 'core'), 
				'type' => 'select', 
				'width' => 'wide' 
			),
			'template'  => array( 
				'label' => __('Template Dropdown', 'core'), 
				'type' => 'template', 
				'width' => 'wide' 
			),
			'onclick'  => array( 
				'label' => __('Click Event', 'core'), 
				'type' => 'text', 
				'width' => 'wide', 
				'placeholder' => 'openGreydPopup( "contact" )', 
				'description' => __('Hier kannst du individuelle Javascript-Funktionen angeben, um z.B. Pop-ups zu öffnen.', 'core'), 
			),
			'leavehref'  => array( 
				'label' => __('In der Navigation: Link trotz Unterpunkten nicht entfernen.', 'core'), 
				'type' => 'checkbox', 
				'width' => 'wide', 
				'description' => __('Wenn ein Menüpunkt Untermenüpunkte hat, wird zum Auslösen des Dropdowns der Link entfernt. Durch diese Option kannst du dieses Verhalten verhindern.', 'core'), 
			),
		) );
		
		// frontend
		add_filter( 'wp_nav_menu_objects', array( $this, 'inject_objects' ), 10, 2 );
		add_filter( 'nav_menu_link_attributes', array( $this, 'render_menu' ), 10, 3 );
		
		// backend
		add_filter( 'wp_edit_nav_menu_walker', array( $this, 'filter_menu_walker' ), 99 );
		add_action( 'wp_nav_menu_item_fields', array( $this, 'filter_menu_fields' ), 10, 5 );
		add_filter( 'manage_nav-menus_columns', array( $this, 'filter_menu_columns' ), 99 );
		add_action( 'wp_update_nav_menu_item', array( $this, 'save_menu' ), 10, 3 );

	}

	/**
	 * =================================================================
	 *                          FRONTEND
	 * =================================================================
	 */

	/**
	 * Modify the menu items for the frontend.
	 */
	public function inject_objects( $items, $args ) {

		if ( empty($args->dropmenu) ) return $items;

		// holds the item keyed by ID.
		$items_keyed_by_id = [];

		foreach ( $items as $key => $item ) {
			// debug( $item );

			/**
			 * Add submenu
			 * @deprecated 1.3.6    Since Gutenberg Version 14.4.0 menu items do not
			 *                      necessarily have the class 'menu-item-has-children'
			 */
			// if ($item->menu_item_parent == 0 && in_array('menu-item-has-children', $item->classes)) {
			//     $item->sub_id = "dropmenu_".$item->ID;
			// }

			/**
			 * Add submenu to the referenced parent menu item.
			 * @since 1.3.6
			 */
			if ( $item->menu_item_parent !== 0 && isset( $items_keyed_by_id[ $item->menu_item_parent ] ) ) {
				$items_keyed_by_id[ $item->menu_item_parent ]->sub_id = "dropmenu_".$item->menu_item_parent;
			}

			/**
			 * Add template for template dropdowns.
			 */
			$template = get_post_meta( $item->ID, 'menu-item-template', true );
			if (!empty($template)) {
				$item->template = $template;
			}
			
			$items_keyed_by_id[ $item->ID ] = $item;
		}

		return array_values( $items_keyed_by_id );
	}

	/**
	 * Render the menu.
	 */
	public function render_menu( $atts, $item, $args ) {
		$classes = array();

		// add image
		$image = get_post_meta( $item->ID, 'menu-item-image', true );
		if ( !empty($image) ) {
			$attachment_url = wp_get_attachment_url( $image );
			if ( $attachment_url ) {
				$alt = \vc\helper::get_attachment_text( $image );
				$item->title = "<img title='{$item->title}' src='{$attachment_url}' alt='{$alt}'>";
			}
		}
		
		// add icon
		$icon = get_post_meta( $item->ID, 'menu-item-icon', true );
		if (!empty($icon)) {
			$iconpos = get_post_meta( $item->ID, 'menu-item-iconpos', true );
			if ($iconpos == 'right')
				$item->title = $item->title."<span aria-hidden='true' class='$icon' style='pointer-events:none;color:inherit;margin-left:5px'></span>";
			else
				$item->title = "<span aria-hidden='true' class='$icon' style='pointer-events:none;color:inherit;margin-right:5px'></span>".$item->title;
		}

		// add style
		$style = get_post_meta( $item->ID, 'menu-item-style', true );
		$style = explode('|', $style);
		// $atts['class'] = $style;
		$classes = array_merge($classes, array_filter($style));

		// add anchor
		$anchor = get_post_meta( $item->ID, 'menu-item-anchor', true );
		if (!empty($anchor)) {
			$classes[] = "anchor_item";
			$atts['href'] .= "#".$anchor;
		}

		// dropdowns
		if ( get_theme_mod('enable_headerconcept', false) ) {

			// element has a submenu
			if ( !empty($item->template) || !empty($item->sub_id) ) {

				// dropmode is enabled
				if (get_theme_mod('drop_mode', 'on') != 'none') {

					// only menu items on the first level
					if ( $item->menu_item_parent == 0 ) {

						$classes[] = "dropmenu_item";
						
						// check: leave href even though there are submenu-items?
						$leavehref = !empty($item->template) || !empty( get_post_meta( $item->ID, 'menu-item-leavehref', true ) );
						// check whether link is empty anyway
						$emptyhref = empty(trim($atts['href'])) || trim($atts['href']) == '#';

						if ( !$leavehref || $emptyhref ) {
							unset( $atts['href'] );
							$atts['tabindex'] = "0";
							$atts['role'] = "button";
							$atts['aria-expanded'] = "false";
							$atts['aria-controls'] = "submenu-{$item->ID}";
							$atts['aria-label'] = sprintf( __( "Zeige Menü-Unterpunkte von '%s'", "core" ), strip_tags( $item->title ) );
						} else {
							$item->title .= sprintf(
								'<a class="greyd_skip_link" tabindex="0" role="button" aria-expanded="false" aria-controls="submenu-%s">%s</a>',
								$item->ID,
								sprintf( __( "Zeige Menü-Unterpunkte von '%s'", "core" ), strip_tags( $item->title ) )
							);
						}
					}
				}
			}
		}

		// onclick
		$onclick = get_post_meta( $item->ID, 'menu-item-onclick', true );
		if ( $onclick && !empty($onclick) ) {
			$atts['onclick'] = esc_attr($onclick);
			$atts['tabindex'] = "0";
			$atts['role'] = "button";
			if (strpos($atts['onclick'], 'openGreydPopup') === 0) {
				$popup = str_replace(array('openGreydPopup(', ')'), "", $atts['onclick']);
				$popup = str_replace(array('&quot;', '&lsquo;', '&rsquo;', '&#039;'), "", $popup);

				if ( method_exists('\popup', 'add_popup_id') ) {
					\popup::add_popup_id($popup);
				}
				if ( method_exists('\Greyd\Popups\Render', 'add_popup_id') ) {
					\Greyd\Popups\Render::add_popup_id($popup);
				}

				$atts['aria-label'] = sprintf( __( "Zeige Popup '%s'", "core"), ucfirst(esc_attr($popup)) );
			}
		}

		if (count($classes) > 0) {
			$atts['class'] = implode(' ', array_unique($classes));
		}
		
		return $atts;
	}

	/**
	 * =================================================================
	 *                          BACKEND
	 * =================================================================
	 */
	
	/**
	 * extend menu walker
	 */
	public function filter_menu_walker( $walker ) {

		// include
		if ( !class_exists( $this->menu_walker ) ) {
			require_once __DIR__.'/admin-menu-walker.php';
		}

		// include successfull -> use it
		if ( class_exists( $this->menu_walker ) ) {
			return $this->menu_walker;
		}

		return $walker;
	}
	
	/**
	 * Save custom field values
	 */
	public function save_menu( $menu_id, $menu_item_db_id, $menu_item_args ) {
		if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
			return;
		}
		check_admin_referer( 'update-nav_menu', 'update-nav-menu-nonce' );
		foreach ( $this->menu_fields as $_key => $_val ) {
			$key = sprintf( 'menu-item-%s', $_key );
			// Sanitize
			if ( ! empty( $_POST[ $key ][ $menu_item_db_id ] ) ) {
				// Do some checks here...
				$value = $_POST[ $key ][ $menu_item_db_id ];
			} else {
				$value = null;
			}
			// Update
			if ( ! is_null( $value ) ) {
				update_post_meta( $menu_item_db_id, $key, $value );
			} else {
				delete_post_meta( $menu_item_db_id, $key );
			}
		}
	}
	
	/**
	 * print fields
	 */
	public function filter_menu_fields( $item_id, $item, $depth, $args, $id ) {
		//debug($item);
		foreach ( $this->menu_fields as $_key => $_val ) {
			$class = sprintf( 'field-%s', $_key );
			$key   = sprintf( 'menu-item-%s', $_key );
			$fid   = sprintf( 'edit-%s-%s', $key, $item->ID );
			$name  = sprintf( '%s[%s]', $key, $item->ID );
			$value = get_post_meta( $item->ID, $key, true );
			$label = __($_val['label'], 'core');
			$type  = $_val['type'];
			$width = $_val['width'];
			if ($type == 'select') {
				$show = true;
				$options = "";
				if ($_key == 'anchor') {
					// make anchor select
					if ($item->object == 'page') {
						$postid = $item->object_id;
						if ($postid > 0) {
							$post = get_post($postid); 
							$content = $post->post_content;
							$options = "<option value=''>"._x("Kein Anker", 'small', 'core')."</option>";
							// debug(htmlspecialchars($content));
							// search for anchor block
							preg_match_all('/(<!--\swp:greyd\/anchor\s(.+?)\s-->(\X+?)<!--\s\/wp:greyd\/anchor\s-->)/', $content, $matches);
							if (count($matches[0]) > 0) {
								// debug($matches);
								foreach ($matches[0] as $i => $match) {
									$atts = (array)json_decode($matches[2][$i]);
									// debug($atts);
									if (isset($atts["anchor"]) && $atts["anchor"] != "") {
										$option = $atts["anchor"];
										$sel = $value == $option ? "selected" : "";
										$options .= "<option value='".$option."' ".$sel.">".$option."</option>";
									}
								}
							}
							// deprecated search for vc_anchor
							$tmp = explode("vc_cbutton_anchor", $content);
							if (count($tmp) > 1) {
								$op = array();
								for ($i = 1; $i < count($tmp); $i++) {
									$tmp1 = explode('"]', $tmp[$i]);
									$op[] = str_replace(' anchor="', '', $tmp1[0]);
								}
								foreach ($op as $option) {
									$sel = $value == $option ? "selected" : "";
									$options .= "<option value='$option' $sel>$option</option>";
								}
							}
						}
						else
							$show = false;
					}
					else
						$show = false;
				}
				// render select
				if ($show) {
					echo "<p class='description description-$width ".$class."'>
							<label for='".$fid."'>".$label."</label>
							<select id='".$fid."' class='widefat ".$fid."' name='".$name."' value='".$value."'>
								".$options."
							</select>
						</p>";
				}
			}
			elseif ($type == 'radio') {
				$class = sprintf( 'field-%s', $_key );
				$key   = sprintf( 'menu-item-%s', $_key );
				$fid   = sprintf( 'edit-%s-%s', $key, $item->ID );
				$name  = sprintf( '%s[%s]', $key, $item->ID );
				$value = get_post_meta( $item->ID, $key, true );
				$value = $value !== 'right' ? 'left' : 'right';
				$label = $_val['label'];
				$type  = $_val['type'];
				$width = $_val['width'];
				$options = [];
				$inputs = '';
				
				if ($_key == 'iconpos') {
					$options = ['left' => _x("links", 'small', 'core'), 'right' => _x("rechts", 'small', 'core')];
				}
				
				// build input fields
				foreach( (array) $options as $k => $v ) {
					$sel = $value === $k ? "checked='checked'" : "";
					$id = $_key."_".$item->ID."_".$k;
					$inputs .= "<input type='radio' id='$id' name='$name' value='$k' $sel><label for='$id'>$v</label>";
				}
				echo "<div class='description description-$width ".$class."'>
						<label>".$label."</label>
						<fieldset id='".$fid."' class='greyd_radio widefat ".$fid."'>
							".$inputs."
						</fieldset>
					</div>";
			}
			elseif ($type == 'style') {
				$svalue = "";
				if ($value && $value != "") {
					$tmp = explode('|', $value);
					$value = $tmp[0];
					if (isset($tmp[1])) $svalue = $tmp[1];
				}
				// make style select
				$selsec = $value == 'sec' ? "selected='selected'" : "";
				$selbtn = $value == 'button' ? "selected='selected'" : "";
				$selbtnsec = $value == 'button sec' ? "selected='selected'" : "";
				$selbtntrd = $value == 'button trd' ? "selected='selected'" : "";
				if (get_theme_mod('enable_headerconcept', false)) {
					$options = "<option value=''>"._x("Standard Element", 'small', 'core')."</option>
								<option value='button' $selbtn>"._x("primärer Button", 'small', 'core')."</option>
								<option value='button sec' $selbtnsec>"._x("sekundärer Button", 'small', 'core')."</option>
								<option value='button trd' $selbtntrd>"._x("alternativer Button", 'small', 'core')."</option>";
					$selbtnbig = $svalue == 'big' ? "selected='selected'" : "";
					$selbtnsml = $svalue == 'small' ? "selected='selected'" : "";
					$options2 = "<option value=''>"._x("Standard Größe", 'small', 'core')."</option>
								<option value='big' $selbtnbig>"._x('groß', 'small', 'core')."</option>
								<option value='small' $selbtnsml>"._x("klein", 'small', 'core')."</option>";  
					echo "<p class='menu_style description description-$width ".$class."'>
							<input type='hidden' id='".$fid."' class='widefat menu_style_value ".$fid."' name='".$name."' value='".$value."|".$svalue."' />
							<label for='".$fid."'>".$label."</label><br>
							<select class='widefat menu_style_option' style='width:50%'>".$options."</select>
							<select class='widefat menu_size_option' style='".($value == "" ? "display:none;": "")."width:49%'>".$options2."</select>
						</p>";
				}
				else {
					$options = "<option value=''>"._x("Standard Element", 'small', 'core')."</option>
								<option value='sec' $selsec>"._x("sekundäres Element", 'small', 'core')."</option>
								<option value='button' $selbtn>"._x("primärer Button", 'small', 'core')."</option>
								<option value='button sec' $selbtnsec>"._x("sekundärer Button", 'small', 'core')."</option>
								<option value='button trd' $selbtntrd>"._x("alternativer Button", 'small', 'core')."</option>";
					echo "<p class='description description-$width ".$class."'>
							<label for='".$fid."'>".$label."</label>
							<select id='".$fid."' class='widefat ".$fid."' name='".$name."' value='".$value."'>
								".$options."
							</select>
						</p>";
				}
			}
			elseif ($type == 'icon') {
				// make iconpicker
				$options = "<option value=''>"._x("kein Icon", 'small', 'core')."</option>";
				foreach ( \vc\icons::$elegantIcons as $icon ) {
					foreach ( $icon as $icon_slug => $icon_title ) {
						$sel = $value == $icon_slug ? "selected" : "";
						$options .= "<option value='$icon_slug' $sel>$icon_slug</option>";
					}
				}
				echo "<p class='description description-$width ".$class."'>
						<label for='".$fid."'>".$label."</label>
						<span class='vc-icons-selector fip-vc-theme-grey'>
							<select id='".$fid."' class='iconselect widefat ".$fid."' name='".$name."' value='".$value."' >
								$options
							</select>
						</span>
					</p>";
			}
			elseif ($type == 'file') {
				$select_file_class = '';
				$remove_file_class = ' hidden';
				$attachment_url = wp_get_attachment_url( $value );
				// $attachment_title = get_the_title($value);
				if ( $attachment_url ) {
					$select_file_class = ' hidden';
					$remove_file_class = '';
				}

				// make preview
				// $filetype = json_encode(array( 'json', 'image' ));
				$filetype = json_encode(array( 'image' ));
				$preview = "<span class='image_grid'></span>";
				if (strpos($attachment_url, '.json')) {
					$icon_id = 'bm_'.uniqid();
					$preview .= "<span class='file_picker_anim bm_icon ".$remove_file_class."' id='".$icon_id."' data-src='".$attachment_url."' data-anim='auto' ></span>";
					$preview .= "<img class='file_picker_img hidden' src=''>";
				}
				else if (strpos($attachment_url, '.svg') ||
					strpos($attachment_url, '.png') ||
					strpos($attachment_url, '.jpg') ||
					strpos($attachment_url, '.gif')) {
					$preview .= "<span class='file_picker_anim bm_icon hidden' id='' data-src='' data-anim='auto' ></span>";
					$preview .= "<img class='file_picker_img ".$remove_file_class."' src='".$attachment_url."'>";
				}
				else {
					$preview .= "<span class='file_picker_anim bm_icon hidden' id='' data-src='' data-anim='auto' ></span>";
					$preview .= "<img class='file_picker_img hidden' src=''>";
				}
	
				echo "<p class='file_picker_block description description-".$width." ".$class."'>
						<label for='".$fid."'>".$label."</label><br>
						<input type='hidden' name='file_picker_type' class='file_picker_type' value='".$filetype."' />
						<input type='hidden' id='".$fid."' class='file_picker_input widefat ".$fid."' name='".$name."' value='".$value."' />
						<span class='file_picker_preview'>".$preview."</span>
						<span class='file_picker_url ".$remove_file_class."' style='padding-bottom:10px;'>".$attachment_url."<br></span>
						<button class='button file_picker_button ".$select_file_class."'>".__("Auswählen", 'core')."</button>
						<button class='button file_remover_button ".$remove_file_class."'>".__("Entfernen", 'core')."</button>
					</p>";
			}
			elseif ($type == 'template') {
				// debug($depth);
				if (!get_theme_mod('enable_headerconcept', false)) return;
				if ($depth > 0) return;
				// get values
				$template = array(
					'enabled' => false,
					'slug' => '',
					'width' => 'auto',
					'custom_width' => '100%',
				);
				if ($value && $value != "") {
					$t = explode('|', $value);
					$template = array(
						'enabled' => true,
						'slug' => $t[0],
						'width' => $t[1],
						'custom_width' => $t[2],
					);
				}
				// get templates
				$templates_array = \vc\helper::get_vc_templates();
				$templates = "";
				$tvalue = $template['slug'];
				if ($tvalue == "404" || !is_numeric($tvalue)) {
					$post = get_page_by_path($tvalue, OBJECT, 'dynamic_template');
					if ($post) $tvalue = $post->ID;
				}
				$toptions = $templates_array;
				if (count($toptions['default']) > 0) {
					foreach ($toptions['default'] as $title => $ovalue) {
						$templates .= "<option value='".$ovalue."' ".selected($ovalue, $tvalue, false).">".$title."</option>";
					}
				}
				unset($toptions['default']);
				if (count($toptions) > 0) {
					foreach ($toptions as $grouptitle => $groupoptions) {
						// $templates .= '<optgroup label="'.$grouptitle.'">';
						foreach ($groupoptions as $title => $ovalue) {
							$templates .= "<option value='".$ovalue."' ".selected($ovalue, $tvalue, false).">".$title."</option>";
						}
						// $templates .= "</optgroup>";
					}
				}

				// options
				$options_array = array(
					_x('an Inhalt anpassen', 'small', 'core') => 'auto',
					_x('volle Breite', 'small', 'core') => 'full',
					// 'innere Header-Breite' => 'header',
					// 'Row XL' => 'row_xxxl',
					// 'Row L' => 'row_xxl',
					// 'Row M' => 'row_xl',
					// 'Row S' => 'row_l',
					_x('individuelle Breite', 'small', 'core') => 'custom',
				);
				$options = "";
				foreach ($options_array as $k => $v)
					$options .= "<option value='".$v."' ".selected($template['width'], $v, false).">".$k."</option>";

				// render
				echo "<p class='template_menu description description-$width ".$class."'>
						<input type='hidden' id='".$fid."' class='widefat template_value ".$fid."' name='".$name."' value='".$value."' />
						<label style='display: inline-block; margin-top: 10px; margin-bottom: 10px;'>
						<input type='checkbox' class='widefat template_enable' ".($template['enabled'] ? 'checked' : '')."/>
							".$label."
						</label>
						<span style='display: ".($template['enabled'] ? 'block' : 'none')."; padding: 10px; background: #f8f8f8;'>
							<label>".__("Template Auswahl", 'core')."</label>
							<select class='widefat template_select'>
								".$templates."
							</select>
							<span class='template_width_wrap' ".($template['slug'] != '' ? "" : "style='display:none'")." >
								<label>".__("Breite", 'core')."</label>
								<select class='widefat template_width'>
									".$options."
								</select>
							</span>
							<span class='template_width_custom_wrap' ".($template['slug'] != '' && $template['width'] == 'custom' ? "" : "style='display:none'").">
								<label>".__("Breite in px oder %", 'core')."</label>
								<input type='text' class='widefat template_width_custom' value='".$template['custom_width']."' />
							</span>
							<span class='greyd_info_box info' style='display: block; margin-top: 20px; margin-bottom: 20px;'>
								<span class='dashicons dashicons-info'></span>
								<span>".__("Template-Dropdowns werden nur im Header dargestellt. Wenn der Menüpunkt Unterpunkte enthält, werden diese anstatt des Templates dargestellt.", 'core')."</span>
							</span>
						</span>
					</p>";
			}
			elseif ($type == 'checkbox') {
				$descr = isset($_val['description']) ? __( $_val['description'], 'core' ) : '';
				echo "<p class='description description-$width ".$class."' style='line-height:1.3; margin-bottom:10px;'>
						<label for='".$fid."' style='margin-bottom: 5px'>
							<input
								type='".$type."' id='".$fid."'
								class='widefat ".$fid."'
								name='".$name."' value='checked'
								".( empty($value) ? "" : "checked" )."
							/>&nbsp;$label
						</label>
						".( empty($descr) ? "" : "<br><small>$descr</small>" )."
					</p>";
			}
			else {
				$descr = isset($_val['description']) ? __( $_val['description'], 'core' ) : '';
				$place = isset($_val['placeholder']) ? $_val['placeholder'] : '';
				// default custom input field
				echo "<p class='description description-$width ".$class."' style='line-height:1.3; margin-bottom:10px;'>
						<label for='".$fid."'>".$label."</label>
						<input
							type='".$type."' id='".$fid."'
							class='widefat ".$fid."'
							name='".$name."' value='".esc_attr($value)."'
							placeholder='$place' style='margin-bottom: 5px'
						/>
						".( empty($descr) ? "" : "<br><small>$descr</small>" )."
					</p>";
			}
		}
	}
	
	/**
	 * add fields to screen options toggle
	 */
	public function filter_menu_columns( $columns ) {
		// $labels = array();
		// foreach ($this->menu_fields as $_key => $_val) { 
		//     $labels[$_key] = $_val['label']; 
		// }
		// $columns = array_merge( $columns, $labels );
		unset($columns['link-target']);
		return $columns;
	}

}