<?php
class container{
  var $name;
  var $ancestor;
  var $children=array();
  function __construct($name,$ancestor=null) {
    $this->name=$name;
    $this->ancestor=$ancestor;
  }
  function addChild($child){
    $this->children[]=$child;
  }
  function display($padding=""){
    $paddingAdd="";
    $responseText="";
    if ($this->ancestor!=null){
      $responseText.= $padding . ($this->name) . "{\n";
      $paddingAdd="  ";
    }
    foreach($this->children as $child){
      $responseText.=$child->display($padding.$paddingAdd);
    }
    if ($this->ancestor!=null){
      $responseText.=$padding."}\n";
    }
    return $responseText;
  }
  function find($searchTerm){
    $returnList=array();
    if (substr($searchTerm,0,1)=="*"){
      foreach($this->children as $child){
        $returnList=array_merge($returnList,$child->find($searchTerm));
      }
      $searchTerm=substr($searchTerm,1);
    }
    $nextSlash=strpos($searchTerm,"/");
    $childSearchTerm="";
    $name=$searchTerm;
    if ($nextSlash!=false){
      $name=substr($searchTerm,0,$nextSlash);
      $childSearchTerm=substr($searchTerm,$nextSlash+1);
    }
    foreach($this->children as $child){
      if ($child->name==$name){
        if($nextSlash==false){
          $returnList[]=$child;
        } else {
          $returnList=array_merge($returnList, $child->find($childSearchTerm));
        }
      }
    }
    return $returnList;
  }
}

class association{
  var $name;
  var $data;
  var $ancestor;
  function __construct($name,$data,$ancestor) {
    $this->name=$name;
    $this->data=$data;
    $this->ancestor=$ancestor;
  }
  function display($padding=""){
    return $padding . ($this->name) . " : " . ($this->data) . ";\n";
  }
  function find($searchTerm){
    return array();
  }
}

function findNext($text){
  $result=false;
  $temp=strpos($text,"{");
  if ($temp!=false && (($result==false) || ($temp<$result))) $result=$temp;
  $temp=strpos($text,"}");
  if ($temp!=false && (($result==false) || ($temp<$result))) $result=$temp;
  $temp=strpos($text,":");
  if ($temp!=false && (($result==false) || ($temp<$result))) $result=$temp;
  return $result;
}

function parse($text){
  $root=new container("root");
  $current=$root;
  while(strlen($text)>0){
    $nextOperator=findNext($text);
    $data=trim(substr($text,0,$nextOperator));
    $operator=substr($text,$nextOperator,1);
    $text=substr($text,$nextOperator+1);
    switch($operator){
      case "{":
        $temp=new container($data,$current);
  			$current->addChild($temp);
  			$current=$temp;
        break;
      case "}":
        $current=$current->ancestor;
        break;
      case ":":
        $nextSemiColon=strpos($text,";");
  			$value=substr($text,0,$nextSemiColon);
  			if (substr($value,0,1)==" " || substr($value,0,1)=="\n"){
  				$value=substr($value,1);
        }
  			$text=substr($text,$nextSemiColon+1);
  			$current->addChild(new association($data,$value,$current));
        break;
    }
  }
  return $root;
}

?>