';
			while( $curr_level > $prev_level ){
				echo $piece;
				$prev_level++;
			}
		}
		foreach($menu_keys as $curr_key => $menu_key){
			echo "\n";
			$class			= '';
			$menu_value		= $menu_values[$curr_key];
			$curr_level		= $menu_value['level'];
			$next_level = 0;
			if( isset($menu_values[$curr_key+1]) ){
				$next_level = $menu_values[$curr_key+1]['level'];
				if( $next_level > $curr_level ){
					$class = 'haschildren';
				}
			}
			if( isset($this->hidden_levels[$menu_key]) ){
				$class .= ' hidechildren';
			}
			if( $curr_level >= $this->max_level_index){
				$class .= ' no-nest';
			}
			$class = \gp\admin\Menu\Tools::VisibilityClass($class, $menu_key);
			//layout
			$style = '';
			if( $this->is_main_menu ){
				if( isset($gp_titles[$menu_key]['gpLayout']) && isset($gpLayouts[$gp_titles[$menu_key]['gpLayout']]) ){
					$color = $gpLayouts[$gp_titles[$menu_key]['gpLayout']]['color'];
					$style = 'background-color:' . $color . ';';
				}
			}
			echo '- ';
			$this->ShowLevel($menu_key, $menu_value);
			$this->EqualizeLevels($curr_level, $next_level);
		}
	}
	/**
	 *
	 * @param int $curr_level
	 * @param int $next_level
	 */
	protected function EqualizeLevels($curr_level, $next_level){
		global $langmessage;
		if( $next_level > $curr_level ){
			$piece = '';
			while( $next_level > $curr_level ){
				echo $piece;
				$curr_level++;
				$piece = '- ';
			}
		}elseif( $next_level <= $curr_level ){
			while( $next_level < $curr_level ){
				echo ' 
 ';
				$curr_level--;
			}
			echo '
';
		}
		return $curr_level;
	}
	/**
	 * Check the curr_menu_array
	 * Remove missing titles
	 * Fill with new array if empty
	 *
	 */
	private function CurrMenuArray(){
		global $gp_titles;
		$menu_adjustments	= false;
		$array				= array();
		//get array of titles and levels
		foreach($this->curr_menu_array as $key => $info){
			if( !isset($info['level']) ){
				break;
			}
			//remove deleted titles
			if( !isset($gp_titles[$key]) && !isset($info['url']) && !isset($info['area']) ){
				$menu_adjustments = true;
				continue;
			}
			$array[$key] = $info;
		}
		//if the menu is empty (because all the files in it were deleted elsewhere), recreate it with the home page
		if( count($array) == 0 ){
			$array				= \gp\admin\Menu\Tools::AltMenu_New();
			$menu_adjustments	= true;
		}
		if( $menu_adjustments ){
			$this->curr_menu_array = $array;
			$this->SaveMenu(false);
		}
		return $array;
	}
	/**
	 * Output a piece of the editable menu
	 *
	 */
	public function ShowLevel($menu_key,$menu_value){
		global $gp_titles, $gpLayouts;
		$layout			= \gp\admin\Menu\Tools::CurrentLayout($menu_key);
		$layout_info	= $gpLayouts[$layout];
		echo '';
	}
	/**
	 * Show a menu entry if it's an Extra Content Area
	 *
	 */
	public function ShowLevel_Extra($menu_key, $menu_value){
		$data = array(
			'key'	=> $menu_key,
			'area'	=> $menu_value['area'],
			'label'	=> $menu_value['label'],
			'level'	=> $menu_value['level'],
		);
		if( strlen($data['label']) > 30 ){
			$data['title'] = substr($data['title'], 0, 30) . '...';
		}
		\gp\admin\Menu\Tools::MenuLink($data,'extra');
		echo \gp\tool::LabelSpecialChars($data['label']);
		echo '';
	}
	public function MenuSkeletonExtra(){
		global $langmessage;
		echo '' . $langmessage['options'] . '';
		echo '';
		$img	= '';
		$label = $langmessage['Menu Output'] . ' - ' . $langmessage['Classes'];
		$attrs	= array('title'=>$label, 'data-cmd'=>'gpabox');
		echo $this->Link(
			'Admin/Menu/Ajax',
			$img . $label,
			'cmd=ClassesForm&index=[key]&no_a_classes=1',
			$attrs
		);
		$img = '';
		echo $this->Link(
			'Admin/Menu/Ajax',
			$img . $langmessage['rm_from_menu'],
			'cmd=hide&index=[key]',
			array(
				'title'		=> $langmessage['rm_from_menu'],
				'data-cmd'	=> 'postlink',
				'class'		=> 'gpconfirm'
			)
		);
		echo '';
		$this->InsertLinks();
	}
	/**
	 * Show a menu entry if it's an external link
	 *
	 */
	public function ShowLevel_External($menu_key, $menu_value){
		$data = array(
			'key'		=>	$menu_key,
			'url'		=>	$menu_value['url'],
			'title'		=>	$menu_value['url'],
			'level'		=>	$menu_value['level']
		);
		if( strlen($data['title']) > 30 ){
			$data['title'] = substr($data['title'],0,30).'...';
		}
		\gp\admin\Menu\Tools::MenuLink($data,'external');
		echo \gp\tool::LabelSpecialChars($menu_value['label']);
		echo '';
	}
	public function MenuSkeletonExtern(){
		global $langmessage;
		echo ''.$langmessage['Target URL'].'';
		echo '';
		echo '[title]';
		echo '';
		echo '' . $langmessage['options'] . '';
		echo '';
		$img = '';
		echo $this->Link(
			'Admin/Menu/Ajax',
			$img . $langmessage['edit'],
			'cmd=EditExternal&key=[key]',
			array('title'=>$langmessage['edit'],'data-cmd'=>'gpabox')
		);
		$img	= '';
		$label	= $langmessage['Menu Output'] . ' - ' . $langmessage['Classes'];
		$attrs	= array(
			'title'		=> $label,
			'data-cmd'	=>'gpabox'
		);
		echo $this->Link(
			'Admin/Menu/Ajax',
			$img . $label,
			'cmd=ClassesForm&index=[key]',
			$attrs
		);
		$img = '';
		echo $this->Link(
			'Admin/Menu/Ajax',
			$img . $langmessage['rm_from_menu'],
			'cmd=hide&index=[key]',
			array(
				'title'		=> $langmessage['rm_from_menu'],
				'data-cmd'	=> 'postlink',
				'class'		=> 'gpconfirm'
			)
		);
		echo '';
		$this->InsertLinks();
	}
	/**
	 * Show a menu entry if it's an internal page
	 *
	 */
	public function ShowLevel_Title($menu_key, $menu_value, $layout_info){
		$title	= \gp\tool::IndexToTitle($menu_key);
		$data	= $this->GetReplaceData($title, $layout_info, $menu_key, $menu_value);
		$label	= \gp\tool::GetLabel($title);
		\gp\admin\Menu\Tools::MenuLink($data);
		echo \gp\tool::LabelSpecialChars($label);
		echo '';
	}
	/**
	 * Get the output formatting data for
	 *
	 */
	public function GetReplaceData($title, $layout_info, $menu_key, $menu_value=array() ){
		global $langmessage, $gp_titles;
		$isSpecialLink		= \gp\tool::SpecialOrAdmin($title);
		//get the data for this title
		$data = array(
			'key'			=>	$menu_key,
			'url'			=>	\gp\tool::GetUrl($title),
			'history'		=>	\gp\tool::GetUrl('Admin/Revisions/').$menu_key,
			'title'			=>	$title,
			'special'		=>	$isSpecialLink,
			'has_layout'	=>	!empty($gp_titles[$menu_key]['gpLayout']),
			'layout_color'	=>	$layout_info['color'],
			'layout_label'	=>	$layout_info['label'],
			'types'			=>	implode(', ', explode(',', $gp_titles[$menu_key]['type'])),
			'opts'			=>	'',
			'size'			=>	'',
			'mtime'			=>	'',
		);
		if( isset($menu_value['level']) ){
			$data['level'] = $menu_value['level'];
		}
		if( $isSpecialLink === false ){
			$file	= \gp\tool\Files::PageFile($title);
			$stats	= @stat($file);
			if( $stats ){
				$data['size']	= \gp\admin\Tools::FormatBytes($stats['size']);
				$data['time']	= \gp\tool::date($langmessage['strftime_datetime'], $stats['mtime']);
			}
		}
		ob_start();
		\gp\tool\Plugins::Action(
			'MenuPageOptions',
			array($title, $menu_key, $menu_value, $layout_info)
		);
		$menu_options = ob_get_clean();
		if( $menu_options ){
			$data['opts'] = $menu_options;
		}
		return $data;
	}
	/**
	 * Output html for the menu editing options displayed for selected titles
	 *
	 */
	public function MenuSkeleton(){
		global $langmessage;
		//page options
		echo '' . $langmessage['page_options'] . '';
		echo '';
		$img	= '';
		echo '';
		echo  $img . htmlspecialchars($langmessage['view/edit_page']);
		echo '';
		$img	= '';
		$attrs	= array(
			'title' => $langmessage['rename/details'],
			'data-cmd' => 'gpajax',
			'class' => 'not_multiple'
		);
		echo $this->Link(
			'Admin/Menu/Ajax',
			$img . $langmessage['rename/details'],
			'cmd=renameform&index=[key]',
			$attrs
		);
		$img	= '';
		$q		= 'cmd=ToggleVisibility&index=[key]';
		$label	= $langmessage['Visibility'] . ': ' . $langmessage['Private'];
		$attrs	= array(
			'title'		=> $label,
			'data-cmd'	=> 'postlink',
			'class'		=> 'vis_private'
		);
		echo $this->Link(
			'Admin/Menu/Ajax',
			$img . $label,
			$q,
			$attrs
		);
		$img	= '';
		$label	= $langmessage['Visibility'] . ': ' . $langmessage['Public'];
		$attrs	= array(
			'title'		=> $label,
			'data-cmd'	=> 'postlink',
			'class'		=> 'vis_public not_multiple'
		);
		$q		.= '&visibility=private';
		echo $this->Link(
			'Admin/Menu/Ajax',
			$img . $label,
			$q,
			$attrs
		);
		echo '';
		echo '';
		echo  htmlspecialchars($langmessage['Revision History']);
		echo '';
		$img	= '';
		$attrs	= array(
			'title'		=> $langmessage['Copy'],
			'data-cmd'	=> 'gpabox',
			'class'		=> 'not_multiple not_special'
		);
		echo $this->Link(
			'Admin/Menu/Ajax',
			$img . $langmessage['Copy'],
			'cmd=CopyForm&index=[key]',
			$attrs
		);
		if( \gp\admin\Tools::HasPermission('Admin_User') ){
			$img	= '';
			$attrs	= array(
				'title'		=> $langmessage['permissions'],
				'data-cmd'	=> 'gpabox'
			);
			echo $this->Link(
				'Admin/Permissions',
				$img . $langmessage['permissions'],
				'index=[key]',
				$attrs
			);
		}
		$img	= '';
		$label	= $langmessage['Menu Output'] . ' - ' . $langmessage['Classes'];
		$attrs	= array(
			'title'		=> $label,
			'data-cmd'	=> 'gpabox'
		);
		echo $this->Link(
			'Admin/Menu/Ajax',
			$img . $label,
			'cmd=ClassesForm&index=[key]',
			$attrs
		);
		$img	= '';
		$attrs	= array(
			'title'		=> $langmessage['rm_from_menu'],
			'data-cmd'	=> 'postlink',
			'class'		=> 'gpconfirm'
		);
		echo $this->Link(
			'Admin/Menu/Ajax',
			$img . $langmessage['rm_from_menu'],
			'cmd=hide&index=[key]',
			$attrs
		);
		$img	= '';
		$attrs	= array(
			'title'		=> $langmessage['delete_page'],
			'data-cmd'	=> 'postlink',
			'class'		=> 'gpconfirm not_special'
		);
		echo $this->Link(
			'Admin/Menu/Ajax',
			$img . $langmessage['delete'],
			'cmd=MoveToTrash&index=[key]',
			$attrs
		);
		echo '[opts]';	// replaced with the contents of
						// \gp\tool\Plugins::Action(
						//		'MenuPageOptions',
						//		array($title, $menu_key, $menu_value, $layout_info)
						// );
		echo '';
		//layout
		if( $this->is_main_menu ){
			echo '';
			echo '' . $langmessage['layout'] . '';
			echo '';
			//has_layout
			$img = '';
			echo $this->Link(
				'Admin/Menu',
				$img . '[layout_label]',
				'cmd=layout&index=[key]',
				array(
					'data-cmd'	=> 'gpabox',
					'title'		=> $langmessage['layout'],
					'class'		=> 'has_layout'
				)
			);
			$img = '';
			echo $this->Link(
				'Admin/Menu',
				$img . $langmessage['restore'],
				'cmd=restorelayout&index=[key]',
				array(
					'data-cmd'	=> 'postlink',
					'title'		=> $langmessage['restore'],
					'class'		=> 'has_layout'
				),
				'restore'
			);
			//no_layout
			$img = '';
			echo $this->Link(
				'Admin/Menu',
				$img . '[layout_label]',
				'cmd=layout&index=[key]',
				array(
					'data-cmd'	=> 'gpabox',
					'title'		=> $langmessage['layout'],
					'class'		=> 'no_layout'
				)
			);
			echo '';
			echo '
';
		}
		$this->InsertLinks();
		//file stats
		echo '';
	}
	/**
	 * Output Insert links displayed with page options
	 *
	 */
	public function InsertLinks(){
		global $langmessage;
		echo '';
		echo ''.$langmessage['insert_into_menu'].'';
		echo '';
		$img	= '';
		$query	= 'cmd=insert_before&insert_where=[key]';
		echo $this->Link(
			'Admin/Menu/Ajax',
			$img . $langmessage['insert_before'],
			$query,
			array(
				'title'		=> $langmessage['insert_before'],
				'data-cmd'	=> 'gpabox'
			)
		);
		$img	= '';
		$query	= 'cmd=insert_after&insert_where=[key]';
		echo $this->Link(
			'Admin/Menu/Ajax',
			$img . $langmessage['insert_after'],
			$query,
			array(
				'title'		=> $langmessage['insert_after'],
				'data-cmd'	=> 'gpabox'
			)
		);
		$img	= '';
		$query	= 'cmd=insert_child&insert_where=[key]';
		echo $this->Link(
			'Admin/Menu/Ajax',
			$img . $langmessage['insert_child'],
			$query,
			array(
				'title'		=> $langmessage['insert_child'],
				'data-cmd'	=> 'gpabox',
				'class'		=> 'insert_child'
			)
		);
		echo '';
		echo '
';
	}
	public function SearchDisplay(){
		global $langmessage, $gpLayouts, $gp_index, $gp_menu;
		$this->inherit_info = \gp\admin\Menu\Tools::Inheritance_Info();
		switch($this->curr_menu_id){
			case 'search':
				$show_list = $this->GetSearchList();
			break;
			case 'hidden':
				$show_list = \gp\admin\Menu\Tools::GetAvailable();
			break;
			case 'nomenus':
				$show_list = $this->GetNoMenus();
			break;
			default:
				$show_list = array_keys($gp_index);
			break;
		}
		$show_list	= array_values($show_list);		// to reset the keys
		$show_list	= array_reverse($show_list);	//show newest first
		$max 		= count($show_list);
		while( ($this->search_page * $this->search_max_per_page) > $max ){
			$this->search_page--;
		}
		$start	= $this->search_page * $this->search_max_per_page;
		$stop	= min(($this->search_page + 1) * $this->search_max_per_page, $max);
		ob_start();
		echo '';
		echo '';
		echo sprintf($langmessage['SHOWING'], ($start+1), $stop, $max);
		echo '';
		echo '';
		if( ($start !== 0) || ($stop < $max) ){
			for( $i = 0; ($i * $this->search_max_per_page) < $max; $i++ ){
				$class = '';
				if( $i == $this->search_page ){
					$class = ' class="current"';
				}
				echo $this->Link(
					'Admin/Menu',
					($i+1),
					'page=' . $i,
					'data-cmd="gpajax"' . $class
				);
			}
		}
		echo $this->Link(
			'Admin/Menu/Ajax',
			$langmessage['create_new_file'],
			'cmd=AddHidden',
			array(
				'title' => $langmessage['create_new_file'],
				'data-cmd' => 'gpabox'
			)
		);
		echo '';
		echo '
';
		$links = ob_get_clean();
		echo $links;
		echo '';
		echo '';
		echo '| ';
		echo $langmessage['file_name'];
		echo ' | ';
		echo $langmessage['Content Type'];
		echo ' | ';
		echo $langmessage['Child Pages'];
		echo ' | ';
		echo $langmessage['File Size'];
		echo ' | ';
		echo $langmessage['Modified'];
		echo ' | 
|---|
';
		echo '';
		echo '';
		if( count($show_list) > 0 ){
			for( $i = $start; $i < $stop; $i++ ){
				$title = $show_list[$i];
				$this->SearchDisplayRow($title);
			}
		}
		echo '';
		echo '
';
		if( count($show_list) == 0 ){
			echo '';
			echo $langmessage['Empty'];
			echo '
';
		}
		echo '
';
		echo $links;
	}
	/**
	 * Get a list of titles matching the search criteria
	 *
	 */
	public function GetSearchList(){
		global $gp_index;
		$key =& $_REQUEST['q'];
		if( empty($key) ){
			return array();
		}
		$key = strtolower($key);
		$show_list = array();
		foreach($gp_index as $title => $index ){
			if( strpos(strtolower($title),$key) !== false ){
				$show_list[$index] = $title;
				continue;
			}
			$label = \gp\tool::GetLabelIndex($index);
			if( strpos(strtolower($label),$key) !== false ){
				$show_list[$index] = $title;
				continue;
			}
		}
		return $show_list;
	}
	/**
	 * Get an array of titles that is not represented in any of the menus
	 *
	 */
	public function GetNoMenus(){
		global $gp_index;
		//first get all titles in a menu
		$menus = $this->GetAvailMenus('menu');
		$all_keys = array();
		foreach($menus as $menu_id => $label){
			$menu_array = \gp\tool\Output\Menu::GetMenuArray($menu_id);
			$keys = array_keys($menu_array);
			$all_keys = array_merge($all_keys,$keys);
		}
		$all_keys = array_unique($all_keys);
		//then check $gp_index agains $all_keys
		$avail = array();
		foreach( $gp_index as $title => $index ){
			if( in_array($index, $all_keys) ){
				continue;
			}
			$avail[] = $title;
		}
		return $avail;
	}
	/**
	 * Display row
	 *
	 */
	public function SearchDisplayRow($title){
		global $langmessage, $gpLayouts, $gp_index, $gp_menu, $gp_titles;
		$menu_key		= $gp_index[$title];
		$layout			= \gp\admin\Menu\Tools::CurrentLayout($menu_key);
		$layout_info	= $gpLayouts[$layout];
		$label			= \gp\tool::GetLabel($title);
		$data			= $this->GetReplaceData($title, $layout_info, $menu_key);
		echo '| ';
		echo \gp\tool::Link($title,\gp\tool::LabelSpecialChars($label));
		//area only display on mouseover
		echo ' ';
		//types
		echo '';
		echo $this->Link(
			'Admin/Menu/Ajax',
			$langmessage['rename/details'],
			'cmd=renameform&index=' . urlencode($menu_key),
			array(
				'title'		=> $langmessage['rename/details'],
				'data-cmd'	=> 'gpajax'
			)
		);
		$label	= $langmessage['Visibility'] . ': ' . $langmessage['Private'];
		$q		= 'cmd=ToggleVisibility&index=' . urlencode($menu_key);
		if( !isset($gp_titles[$menu_key]['vis']) ){
			$label	= $langmessage['Visibility'] . ': ' . $langmessage['Public'];
			$q		.= '&visibility=private';
		}
		$attrs = array(
			'title'		=> $label,
			'data-cmd'	=> 'postlink',   // ######################## <<<<---- ########################
			// 'class'		=> 'vis_private'
		);
		echo $this->Link(
			'Admin/Menu/Ajax',
			$label,
			$q,
			$attrs
		);
		if( $data['special'] === false ){
			echo \gp\tool::Link(
				'Admin/Revisions/'.$menu_key,
				$langmessage['Revision History'],
				'cmd=ViewHistory',
				'class="view_edit_link not_multiple"'
			);
			echo $this->Link(
				'Admin/Menu/Ajax',
				$langmessage['Copy'],
				'cmd=CopyForm&index=' . urlencode($menu_key),
				array(
					'title' => $langmessage['Copy'],
					'data-cmd' => 'gpabox'
				)
			);
		}
		echo '';
		echo $langmessage['layout'].': ';
		echo $this->Link(
			'Admin/Menu',
			$layout_info['label'],
			'cmd=layout&index=' . urlencode($menu_key),
			array(
				'title' => $langmessage['layout'],
				'data-cmd' => 'gpabox'
			)
		);
		echo '';
		if( $data['special'] === false ){
			echo $this->Link(
				'Admin/Menu/Ajax',
				$langmessage['delete'],
				'cmd=MoveToTrash&index=' . urlencode($menu_key),
				array(
					'title' => $langmessage['delete_page'],
					'data-cmd' => 'postlink',
					'class' => 'gpconfirm'
				)
			  );
		}
		echo $data['opts'];
		//stats
		if( gpdebug ){
			echo 'Data Index: '.$menu_key.'';
		}
		echo ' | ';
		$this->TitleTypes($menu_key);
		//children
		echo ' | ';
		if( isset($this->inherit_info[$menu_key]) && isset($this->inherit_info[$menu_key]['children']) ){
			echo $this->inherit_info[$menu_key]['children'];
		}elseif( isset($gp_menu[$menu_key]) ){
			echo '0';
		}else{
			echo $langmessage['Not In Main Menu'];
		}
		//size, modified
		echo ' | ';
		echo $data['size'];
		echo ' | ';
		echo $data['mtime'];
		echo ' | 
';
	}
	/**
	 * List section types
	 *
	 */
	public function TitleTypes($title_index){
		global $gp_titles;
		$types		= explode(',',$gp_titles[$title_index]['type']);
		$types		= array_filter($types);
		$types		= array_unique($types);
		foreach( $types as $i => $type ){
			if( isset($this->section_types[$type]) && isset($this->section_types[$type]['label']) ){
				$types[$i] = $this->section_types[$type]['label'];
			}
		}
		echo implode(', ', $types);
	}
	/**
	 * Get a list of pages that are not in the current menu array
	 * @return array
	 */
	protected function GetAvail_Current(){
		global $gp_index;
		if( $this->is_main_menu ){
			return \gp\admin\Menu\Tools::GetAvailable();
		}
		$avail = array();
		foreach( $gp_index as $title => $index ){
			if( !isset($this->curr_menu_array[$index]) ){
				$avail[$index] = $title;
			}
		}
		return $avail;
	}
	/**
	 * Save changes to the current menu array after a drag event occurs
	 * @return bool
	 */
	public function SaveDrag(){
		global $langmessage;
		$this->CacheSettings();
		if( is_null($this->curr_menu_array) ){
			msg($langmessage['OOPS'].'(1)');
			return false;
		}
		$key = $_POST['drag_key'];
		if( !isset($this->curr_menu_array[$key]) ){
			msg($langmessage['OOPS'].' (Unknown menu key)');
			return false;
		}
		$moved = $this->RmMoved($key);
		if( !$moved ){
			msg($langmessage['OOPS'].'(3)');
			return false;
		}
		// if prev (sibling) set
		if( !empty($_POST['prev']) ){
			$inserted = $this->MenuInsert_After( $moved, $_POST['prev']);
		// if parent is set
		}elseif( !empty($_POST['parent']) ){
			$inserted = $this->MenuInsert_Child( $moved, $_POST['parent']);
		// if no siblings, no parent then it's the root
		}else{
			$inserted = $this->MenuInsert_Before( $moved, false);
		}
		if( !$inserted ){
			$this->RestoreSettings();
			msg($langmessage['OOPS'].'(4)');
			return;
		}
		if( !$this->SaveMenu(false) ){
			$this->RestoreSettings();
			\gp\tool::AjaxWarning();
			return false;
		}
	}
	/**
	 * Get portion of menu that was moved
	 */
	public function RmMoved($key){
		if( !isset($this->curr_menu_array[$key]) ){
			return false;
		}
		$old_level = false;
		$moved = array();
		foreach($this->curr_menu_array as $menu_key => $info){
			if( !isset($info['level']) ){
				break;
			}
			$level = $info['level'];
			if( $old_level === false ){
				if( $menu_key != $key ){
					continue;
				}
				$old_level = $level;
				$moved[$menu_key] = $info;
				unset($this->curr_menu_array[$menu_key]);
				continue;
			}
			if( $level <= $old_level ){
				break;
			}
			$moved[$menu_key] = $info;
			unset($this->curr_menu_array[$menu_key]);
		}
		return $moved;
	}
	/**
	 * Remove key from curr_menu_array
	 * Adjust children levels if necessary
	 *
	 */
	protected function RmFromMenu($search_key,$curr_menu=true){
		global $gp_menu;
		if( $curr_menu ){
			$keys = array_keys($this->curr_menu_array);
			$values = array_values($this->curr_menu_array);
		}else{
			$keys = array_keys($gp_menu);
			$values = array_values($gp_menu);
		}
		$insert_key = array_search($search_key,$keys);
		if( ($insert_key === null) || ($insert_key === false) ){
			return false;
		}
		unset($keys[$insert_key]);
		$keys = array_values($keys);
		unset($values[$insert_key]);
		$values = array_values($values);
		//adjust levels of children
		$prev_level = -1;
		if( isset($values[$insert_key-1]) ){
			$prev_level = $values[$insert_key-1]['level'];
		}
		do{
			$moved_one = false;
			if( isset($values[$insert_key]) ){
				$curr_level = $values[$insert_key]['level'];
				if( ($prev_level+1) < $curr_level ){
					$values[$insert_key]['level']--;
					$prev_level = $values[$insert_key]['level'];
					$moved_one = true;
					$insert_key++;
				}
			}
		}while($moved_one);
		//shouldn't happen
		if( count($keys) == 0 ){
			return false;
		}
		//rebuild
		if( $curr_menu ){
			$this->curr_menu_array = array_combine($keys, $values);
		}else{
			$gp_menu = array_combine($keys, $values);
		}
		return true;
	}
	/**
	 * Insert titles into menu
	 *
	 */
	protected function MenuInsert_Before($titles,$sibling){
		$old_level = \gp\admin\Menu\Tools::GetRootLevel($titles);
		//root install
		if( $sibling === false ){
			$level_adjustment = 0 - $old_level;
			$titles = $this->AdjustMovedLevel($titles,$level_adjustment);
			$this->curr_menu_array = $titles + $this->curr_menu_array;
			return true;
		}
		//before sibling
		if( !isset($this->curr_menu_array[$sibling]) || !isset($this->curr_menu_array[$sibling]['level']) ){
			return false;
		}
		$sibling_level = $this->curr_menu_array[$sibling]['level'];
		$level_adjustment = $sibling_level - $old_level;
		$titles = $this->AdjustMovedLevel($titles,$level_adjustment);
		$new_menu = array();
		foreach($this->curr_menu_array as $menu_key => $menu_info ){
			if( $menu_key == $sibling ){
				foreach($titles as $titles_key => $titles_info){
					$new_menu[$titles_key] = $titles_info;
				}
			}
			$new_menu[$menu_key] = $menu_info;
		}
		$this->curr_menu_array = $new_menu;
		return true;
	}
	/*
	 * Insert $titles into $menu as siblings of $sibling
	 * Place
	 *
	 */
	protected function MenuInsert_After($titles,$sibling,$level_adjustment=0){
		if( !isset($this->curr_menu_array[$sibling]) || !isset($this->curr_menu_array[$sibling]['level']) ){
			return false;
		}
		$sibling_level = $this->curr_menu_array[$sibling]['level'];
		//level adjustment
		$old_level			= \gp\admin\Menu\Tools::GetRootLevel($titles);
		$level_adjustment	+= $sibling_level - $old_level;
		$titles				= $this->AdjustMovedLevel($titles,$level_adjustment);
		// rebuild menu
		// insert $titles after sibling and it's children
		$new_menu = array();
		$found_sibling = false;
		foreach($this->curr_menu_array as $menu_key => $menu_info){
			$menu_level = 0;
			if( isset($menu_info['level']) ){
				$menu_level = $menu_info['level'];
			}
			if( $found_sibling && ($menu_level <= $sibling_level) ){
				foreach($titles as $titles_key => $titles_info){
					$new_menu[$titles_key] = $titles_info;
				}
				$found_sibling = false; //prevent multiple insertions
			}
			$new_menu[$menu_key] = $menu_info;
			if( $menu_key == $sibling ){
				$found_sibling = true;
			}
		}
		//if it's added to the end
		if( $found_sibling ){
			foreach($titles as $titles_key => $titles_info){
				$new_menu[$titles_key] = $titles_info;
			}
		}
		$this->curr_menu_array = $new_menu;
		return true;
	}
	/*
	 * Insert $titles into $menu as children of $parent
	 *
	 */
	protected function MenuInsert_Child($titles,$parent){
		if( !isset($this->curr_menu_array[$parent]) || !isset($this->curr_menu_array[$parent]['level']) ){
			return false;
		}
		$parent_level = $this->curr_menu_array[$parent]['level'];
		//level adjustment
		$old_level			= \gp\admin\Menu\Tools::GetRootLevel($titles);
		$level_adjustment	= $parent_level - $old_level + 1;
		$titles				= $this->AdjustMovedLevel($titles,$level_adjustment);
		//rebuild menu
		//	insert $titles after parent
		$new_menu = array();
		foreach($this->curr_menu_array as $menu_title => $menu_info){
			$new_menu[$menu_title] = $menu_info;
			if( $menu_title == $parent ){
				foreach($titles as $titles_title => $titles_info){
					$new_menu[$titles_title] = $titles_info;
				}
			}
		}
		$this->curr_menu_array = $new_menu;
		return true;
	}
	protected function AdjustMovedLevel($titles,$level_adjustment){
		foreach($titles as $title => $info){
			$level = 0;
			if( isset($info['level']) ){
				$level = $info['level'];
			}
			$titles[$title]['level'] = min($this->max_level_index,$level + $level_adjustment);
		}
		return $titles;
	}
	/**
	 * Display the current homepage setting
	 *
	 */
	public function HomepageDisplay(){
		global $langmessage, $config;
		if( \gp\admin\Menu\Tools::ResetHomepage() ){
			\gp\admin\Tools::SaveConfig();
		}
		$label = \gp\tool::GetLabelIndex($config['homepath_key']);
		echo ' ';
		echo $langmessage['Homepage'] . ': ';
		echo \gp\tool::Link(
				'Admin/Menu/Ajax',
				$label,
				'cmd=HomepageSelect',
				'data-cmd="gpabox"'
			);
		if( empty($config['homepath_auto']) ){
			echo '  ';
			echo \gp\tool::Link(
				'Admin/Menu/Ajax',
				'',
				'cmd=HomepageAuto',
				array(
					'class'		=> 'gpbutton',
					'title'		=> $langmessage['disable'],
					'data-cmd'	=> 'gpajax',
				)
			);
		}
	}
	public function CacheSettings(){
		global $gp_index, $gp_titles, $gp_menu;
		$this->settings_cache['gp_index'] = $gp_index;
		$this->settings_cache['gp_titles'] = $gp_titles;
		$this->settings_cache['gp_menu'] = $gp_menu;
		if( !$this->is_main_menu ){
			$this->settings_cache['curr_menu_array'] = $this->curr_menu_array;
		}
	}
	public function RestoreSettings(){
		global $gp_index, $gp_titles, $gp_menu;
		if( isset($this->settings_cache['gp_titles']) ){
			$gp_titles = $this->settings_cache['gp_titles'];
		}
		if( isset($this->settings_cache['gp_menu']) ){
			$gp_menu = $this->settings_cache['gp_menu'];
		}
		if( isset($this->settings_cache['gp_index']) ){
			$gp_index = $this->settings_cache['gp_index'];
		}
		if( isset($this->settings_cache['curr_menu_array']) ){
			$this->curr_menu_array = $this->settings_cache['curr_menu_array'];
		}
	}
}