<?php

/**
 * Goweb Sitemanager 5 Framework
 * 
 * @version    5.0.0
 * @category   Goweb
 * @package    Goweb_Tree
 * @author     I&D <dev@goweb.pt>, Pedro Pinto <ppinto@goweb.pt>
 * @copyright  2009 (c) Goweb (http://www.goweb.pt)
 */

/**
 * Goweb_Tree_Node
 */
Goweb::loadClass('Goweb_Tree_Node');

/**
 * Classe Tree para representacaco de uma estrutura de dados em forma de ervore.
 *
 * @version    5.0.0
 * @category   Goweb
 * @package    Goweb_Tree
 * @author     I&D <dev@goweb.pt>, Pedro Pinto <ppinto@goweb.pt>
 * @copyright  2009 (c) Goweb (http://www.goweb.pt)
 */
class Goweb_Tree {

    /**
     * Nome do elemento identificador
     *
     * @var  string
     */
    protected $_idElement = '';

    /**
     * Nome do elemento identificador pai
     *
     * @var  string
     */
    protected $_parentIdElement = '';

    /**
     * Elementos por organizar
     *
     * @var  array
     */
    protected $_elements = array();
    
    /**
     * Estrutura da árvore
     *
     * @var  array
     */
    protected $_tree = array();

    /**
     * Indica se a estrutura se encontra carregada
     * 
     * @var  bool
     */
    protected $loaded = false;
    
    /**
     * Constructor
     */
    public function __construct($idElement, $parentIdElement) {
        $this->_idElement = $idElement;
        $this->_parentIdElement = $parentIdElement;
    }

    /**
     * Adiciona um elemento, o array tem de ser na forma $key => $value.
     *
     * @param  array  $array
     */
    public function addElement($array) {
        $this->_elements[] = $array;        
    }

    /**
     * Constroi a estrutura da ervore a partir de um array.
     *
     * @param  array  $array
     * @param  int    $parentId  Id do pai a partir do qual e para construir a estrutura
     */
    public function buildFromArray($array, $parentId = 0) {
        $this->_tree = $this->_buildTree($array, $parentId);
        $this->_loaded = true;
    }

    /**
     * Constroi a estrutura da ervore.
     *
     * @param  int $parentId  Id do pai a partir do qual e para construir a estrutura
     */
    public function build($parentId = 0) {
        $this->_tree = $this->_buildTree($this->_elements, $parentId);
        $this->_loaded = true;
    }

    /**
     * Retorna a estrutura da ervore.
     *
     * @return  array 
     */
    public function getTree() {
        return $this->_tree;
    }

    /**
     * Retorna se a estrutura je se encontra carregada
     * 
     * @return  TRUE se a estrutura je foi carregada
     */
    public function isLoaded() {
        return $this->_loaded;
    }
    
    /**
     * 
     * 
     * @param   array  $elements  O array do qual e para gerar a estrutura
     * @param   int    $parentId  Id do pai a partir do qual e para construir a estrutura
     * @param   int    $parentId  Nivel da ervore
     * @return  array             A estrutura em forma de ervore
     */
    protected function _buildTree($elements, $parentId = 0, $level = 0) {
        $level++;
        if (is_array($elements)) {
            $tree = array();
            foreach ($elements as $key => $element) {
                if ($element[$this->_parentIdElement] == $parentId) {
                    unset($elements[$key]);
                    $node = new Goweb_Tree_Node($element);
                    $node->level = $level;
                    $node->childs = $this->_buildTree($elements, $element[$this->_idElement], $level);
                    $tree[] = $node;                    
                }
                
            }            
            return $tree;            
        }
        return array();
    }
}