<?php
/**
 * @version 0.9
 * @author Kees Schepers <kees.schepers@scooterbase.net> 
 * @package SB Framework
 * @copyright ScooterBase.net
 */   

/**
 * Exception which will be thrown when something happends with the menu building 
 */
class Site_Menu_Exception extends Exception {}

/**
 * Drawes and takes care for the whole menu, but not the contents
 * @version 0.9
 */
class Site_Menu {	
	/**
	 * Map with items first key is the parentid
	 *
	 * @var array
	 */
	private $items;
	/**
	 * HTML id of the first <ul> tag
	 *
	 * @var string
	 */
	private $elementId;
	/**
	 * Constructor, construct a menu
	 *
	 * @param string $elementId id of the root UL element
	 * @return void
	 */
	public function __construct($elementId) {
		$this->items = array();
		if(preg_match('/^[a-z]{1,}[a-z0-9]*/i',$elementId)) {
			$this->elementId = $elementId;
		} else {
			throw new Site_Menu_Exception('Element id ('.$elementId.') is not XHTML valid');
		}
	}
	/**
	 * Add an list item
	 *
	 * @param Site_Menu_Item $item
	 * @return void
	 */
	public function addItem(Site_Menu_Item $item) {		
		$this->items[$item->parent][] = $item;
	}
	/**
	 * Recursively loop all items
	 *
	 * @param string $parent
	 * @return string HTML contents
	 */
	private function getItems($parent) {
		$str = '';
		
		foreach ($this->items[$parent] as $item) {
			$str .= '<li><a '.(!is_null($item->class) ? 'class="'.$item->class.'"' : '').' href="'.$item->href.'" title="'.$item->title.'">'.$item->title.'</a>';
						
			if(array_key_exists($item->title,$this->items)) {				
				$str .= '<ul>';
				$str .= $this->getItems($item->title);
				$str .= '</ul>';
			}
			
			$str .= '</li>';
		}
		
		return $str;
	}
	public function getHTML() {
		return '<ul id="'.$this->elementId.'">'.$this->getItems('root').'</ul>';
	}
}

/**
 * Just an single menu item (link)
 *
 */
class Site_Menu_Item {
	/**
	 * An map with properties (href, class, title, etc)
	 *
	 * @var array
	 */
	private $properties;
	/**
	 * Create a new menu item
	 *
	 * @param string $title
	 * @param string $href
	 * @param string $parent
	 * @return void
	 */
	public function __construct($title,$href,$parent='root') {
		$this->properties = array();
		
		$this->__set('title',$title);
		$this->__set('href',$href);
		$this->__set('parent',$parent);
		$this->__set('class',null);
				
	}
	/**
	 * Get the properties of an menu element
	 *
	 * @param string $key
	 * @return mixed
	 */
	public function __get($key) {
		if(array_key_exists($key,$this->properties)) {
			return $this->properties[$key];
		} else {
			throw new Site_Menu_Exception('Cannot get property '.$key);
		}
	}
	/**
	 * Set the properties of an menu element
	 *
	 * @param string $key
	 * @param mixed $value
	 * @return boolean
	 */
	public function __set($key,$value) {
		switch ($key) {
			case 'href' :
			case 'title' :
			case 'parent' :
			case 'class' :
				$this->properties[$key] = $value;
				return true;
			default :
				throw new Site_Menu_Exception('Cannot set property '.$key);
				return false;
		}
	}
}
?>
CSS:
[code]
#nav {
	z-index:100;
	position:absolute;		
	margin-top:1px;
}

#nav, #nav ul, #nav ul li { 
	list-style:none;
	display:block;		
}

#nav li { 
  position: relative; 
  float:left;
	width:145px;  
  color:#fff; 
  font-size:14px;    
}
#nav li:hover { 
	background-color:#dbdbdb;
	color:#000;	
  background-image:url('/bmvv/images/layout/menu_background_right.jpg');
  background-repeat:no-repeat;
  background-position:top right;	
}
#nav ul li {
	background-color:#fff;
	color:#000;
	font-size:12px;
	border-left:1px solid #dbdbdb;
	border-right:1px solid #dbdbdb;
	width:140px;
	font-weight:bold;
	text-transform:capitalize;
	padding:5px 0px 5px 3px;		
}
#nav a {
  text-decoration:none; 
  display:block;    
  color:#000;  
  background-image:none;
}
#nav a.root { 
	color:#fff;
}
#nav a.root:hover {
	color:black;
}
#nav ul li:hover, #nav ul li a:hover{ 
	background-color:#dbdbdb;
	color:#000;
	background-image:none;
}

#nav ul{
  display:none;  
}
#nav ul ul, #nav ul ul ul{
	display:none; 
	border-top:1px solid #dbdbdb;
  position:absolute;
}
  
#nav li:hover ul ul, #nav li:hover ul ul ul, #nav li:hover ul ul ul ul, #nav li:hover ul ul ul ul ul{
  display:none; 
}

#nav li:hover ul, #nav ul li:hover ul, #nav ul ul li:hover ul, #nav ul ul ul li:hover ul, #nav ul ul ul ul li:hover ul{
  display:block;
}

li>ul { 
	top:0px;
	left:144px;
}
[/code]