<?php
require_once("config.php");

abstract class 
MenuAbstract{
    protected 
$submenu;

    abstract protected function 
__construct();
    
//abstract public function toString();
    
abstract public function toString($indent$access$class);

    public function 
addItem($name$url$access){
        
$temp=new MenuItem($name$url$access);
        
array_push($this->submenu$temp);
        return 
$temp;
    }

    public function 
addItemArr($string){
        
$string=Menu::trimMiddle($string);
        
$arr=split("\t"$string3);
        if(
count($arr)!=3) die ("menu file is fucked up. ($string)");
        return 
$this->addItem($arr[0], $arr[2], intval(base_convert($arr[1], 1610)));
    }

    
//does not belong here
    
public static function permString($global$class$section){
        return (
$global<<$class)<<$section
    }

    
//does not belong here
    
public static function isAllowed($key$lock){
        
//echo "key:$key, lock:$lock\n";
        
if($lock==0) return true;
        
//echo "match: ".($key & $lock);
        
if(($key $lock)!=0)return true;
        return 
false;
    }

    
//does not belong here
    
public static function trimMiddle($string){
        return 
preg_replace("/\s\s+/""\t"$string);
    }

}


class 
MenuItem extends MenuAbstract{
    private 
$name;
    private 
$url;
    private 
$access;
    protected function 
__construct($name$url$access){
        
$this->name=$name;
        
$this->url=$url;
        
$this->access=$access;
        
$this->submenu=array();
    }

    public function 
toString($indent$access$class){
        if(!
MenuAbstract::isAllowed($access$this->access)) return "";
        global 
$MENU_PREFIX;
        
$out="<li class='$class'><a href='$MENU_PREFIX".$this->url."'>".$this->name."</a>";
        
$count=count($this->submenu);
        if(
$count>0){
            for(
$i=0$i<$count-1$i++){
                
$append=$this->submenu[$i]->toString("$indent\t"$access"menu");
                if(
$append!==""){
                    
$out="$out\n$indent\t$append";
                }
            }
            
$append=$this->submenu[$i]->toString("$indent\t"$access"menuLast");
            if(
$append!==""){
                
$out="$out\n$indent\t$append";
            }
        }
        return 
$out;
    }
}

/**
 * This is a tripple redundant class whet getMenu is called it tried to do the following
 *    If $menuInstance is set it is returned
 *    Else If file with instance of menu exists it is read back, stored to $menuInstance and returned
 *    Else If Menu is made, stored to file, stored to $menuInstance
 **/
class Menu extends MenuAbstract{
    private static 
$menuInstance;

    protected function 
__construct(){
        
$this->submenu=array();
    }

    public function 
toString($indent$access$class){
        if(!
MenuAbstract::isAllowed($access$this->access)) return "";
        
$out="";
        
$count=count($this->submenu);
        if(
$count>0){
            for(
$i=0$i<$count-1$i++){
                
$append=$this->submenu[$i]->toString("$indent"$access$class);
                if(
$append!==""){
                    
$out="$out\n$indent$append";
                }
            }
            
$append=$this->submenu[$i]->toString("$indent"$access$class."Last");
            if(
$append!==""){
                
$out="$out\n$indent$append";
            }
        }
        return 
$out."\n";
    }

    
//does not belong here
    
public static function countIndent($str){
        
$i=0;
        while(
substr($str$i1)=="\t"$i++;
        return 
$i;
    }

    private static function 
makeMenu($parent, &$contents, &$lines, &$line=0){    
        
$currLevel=Menu::countIndent($contents[$line]);
        while(
1){
            if(
$lines<=$line) return;
            
$child=$parent->addItemArr(trim($contents[$line]));
            
$line++;
            if(
$lines>$line){
                switch(
Menu::countIndent($contents[$line])-$currLevel){
                    case 
1//one deeper
                        
Menu::makeMenu($child$contents$lines$line);
                        if((
Menu::countIndent($contents[$line])-$currLevel)<0) return;
                        continue;
                    case 
0//save level
                        
continue;
                    case -
1//prev level
                        
return;
                    default:
                        if((
Menu::countIndent($contents[$line])-$currLevel)<0) return;
                        die(
"Menu file is fucked up, ".(countIndent($contents[$line])-$currLevel));
                }
            }else{
                break;
            }
        }
    }

    public static function 
getMenu(){
        if(isset(
self::$menuInstance)){
            echo 
"resuming from instance";
            return 
self::$menuInstance;
        }
        global 
$MENU_FILE$MENU_INSTANCE_FILE;
        if(!
file_exists($MENU_FILE)){
            die(
"Menu file ($MENU_FILE) does not exist.");
        }
        if(
file_exists($MENU_INSTANCE_FILE)){
            if(
filectime($MENU_FILE)>filectime($MENU_INSTANCE_FILE)){
                
$menu=Menu::makeStoreMenu();
                
self::$menuInstance=$menu;
                return 
$menu;
            }else{
                
$serialized=file_get_contents($MENU_INSTANCE_FILE);
                
$menu=unserialize($serialized);
                if(
get_class($menu)!="Menu"){
                    print 
"Shit, could not reopen menu instance\n";
                    
$menu=Menu::makeStoreMenu();
                    
self::$menuInstance=$menu;
                    return 
$menu;
                }
                
self::$menuInstance=$menu;
                return 
$menu;
            }
        }else{
            
$menu=Menu::makeStoreMenu();
            
self::$menuInstance=$menu;
            return 
$menu;
        }
    }

    private static function 
makeStoreMenu(){
        global 
$MENU_FILE$MENU_INSTANCE_FILE;
        
$contents=file($MENU_FILE);
        
$menu=new Menu();
        
$lines=count($contents);
        
$line=0;
        
Menu::makeMenu($menu$contents$lines$line);
        
$serialized=serialize($menu);
        
file_put_contents($MENU_INSTANCE_FILE$serialized);
        return 
$menu;
    }

}

//$menu=Menu::getMenu();
//echo $menu->toString("", intval(base_convert("ff0000", 16, 10)), "menu");

?>