<?php
/**
 * File containing the ezcTree class.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 * @version //autogentag//
 * @filesource
 * @package Tree
 */

/**
 * ezcTree is an abstract class from which all the tree implementations
 * inherit.
 *
 * Example:
 * <code>
 * <?php
 *     // Instantiating an existing tree, and creating a new tree is done through
 *     // the inherited classes
 *     
 *     // Creating a new in-memory tree
 *     $tree = ezcTreeMemory::create( new ezcTreeMemoryDataStore() );
 * 
 *     // Opening an existing tree in an XML file
 *     $tree = new ezcTreeXml( 'test.xml', new ezcTreeXmlInternalDataStore() );
 * 
 *     // Opening an existing tree from a database, using a nested set backend
 *     // - This retrieves data from the ezcTreeDbExternalTableDataStore store
 *     //   using $this->dbh as database handle, $dataTable as table where to fetch
 *     //   data from using 'id' as ID field.
 *     $store = new ezcTreeDbExternalTableDataStore( $this->dbh, $dataTable, 'id' );
 *     // - It uses the 'nested_set' table for keeping the tree structure
 *     $tree = new ezcTreeDbNestedSet( $this->dbh, 'nested_set', $store );
 * 
 *     // Fetching nodes and subtrees
 *     $node = $tree->fetchNodeById( 'He' );
 *     $nodeList = $tree->fetchSubtree( 'Pantherinae' );
 * 
 *     // Checking for relations between nodes
 *     $tree->isDescendantOf( 'Tiger', 'Panthera' );
 *     $tree->isSiblingOf( 'Lion', 'Leopard' );
 * ?>
 * </code>
 *
 * @property-read ezcTreeXmlDataStore $store
 *                The data store that is used for retrieving/storing data.
 * @property      string              $nodeClassName
 *                Which class is used as tree node - this class *must* inherit
 *                the ezcTreeNode class.
 * @property      boolean             $autoId
 *                When set to true, you can add nodes to the database without
 *                setting the ID. This only works with numeric keys however.
 * 
 * @package Tree
 * @version //autogentag//
 */
abstract class ezcTree implements ezcTreeVisitable
{
    /**
     * Holds the properties of this class.
     *
     * @var array(string=>mixed)
     */
    protected $properties = array( 'nodeClassName' => 'ezcTreeNode' );

    /**
     * Contains whether a transaction has been started.
     *
     * @var bool
     */
    protected $inTransaction = false;

    /**
     * Contains whether we are in a transaction commit stage.
     *
     * @var bool
     */
    protected $inTransactionCommit = false;

    /**
     * Contains a list of transaction items.
     *
     * @var array(ezcTreeTransactionItem)
     */
    private $transactionList = array();

    /**
     * Returns the value of the property $name.
     *
     * @throws ezcBasePropertyNotFoundException if the property does not exist.
     * @param string $name
     * @ignore
     */
    public function __get( $name )
    {
        switch ( $name )
        {
            case 'autoId':
            case 'store':
            case 'nodeClassName':
                return $this->properties[$name];
        }
        throw new ezcBasePropertyNotFoundException( $name );
    }

    /**
     * Sets the property $name to $value.
     *
     * @throws ezcBasePropertyNotFoundException if the property does not exist.
     * @throws ezcBasePropertyPermissionException if a read-only property is
     *         tried to be modified.
     * @throws ezcBaseValueException if trying to assign a wrong value to the
     *         property
     * @throws ezcBaseInvalidParentClassException
     *         if the class name passed as replacement for the ezcTreeNode
     *         classs does not inherit from the ezcTreeNode class.
     * @param string $name
     * @param mixed $value
     * @ignore
     */
    public function __set( $name, $value )
    {
        switch ( $name )
        {
            case 'store':
                throw new ezcBasePropertyPermissionException( $name, ezcBasePropertyPermissionException::READ );

            case 'autoId':
                if ( !is_bool( $value ) )
                {
                    throw new ezcBaseValueException( $name, $value, 'boolean' );
                }
                $this->properties[$name] = $value;
                break;

            case 'nodeClassName':
                if ( !is_string( $value ) )
                {
                    throw new ezcBaseValueException( $name, $value, 'string that contains a class name' );
                }

                // Check if the passed classname actually implements the
                // correct parent class.
                if ( 'ezcTreeNode' !== $value &&
                    !in_array( 'ezcTreeNode', class_parents( $value ) ) )
                {
                    throw new ezcBaseInvalidParentClassException( 'ezcTreeNode', $value );
                }
                $this->properties[$name] = $value;
                break;

            default:
                throw new ezcBasePropertyNotFoundException( $name );
        }
    }

    /**
     * Returns true if the property $name is set, otherwise false.
     *
     * @param string $name     
     * @return bool
     * @ignore
     */
    public function __isset( $name )
    {
        switch ( $name )
        {
            case 'autoId':
            case 'store':
            case 'nodeClassName':
                return isset( $this->properties[$name] );

            default:
                return false;
        }
    }

    /**
     * This method checks whether a node ID is valid to be used in a backend.
     *
     * @throws ezcTreeInvalidNodeIDException if the node is not valid.
     *
     * @param string $nodeId
     */
    protected function checkNodeId( $nodeId )
    {
        /* The default implementation does not check anything */
    }

    /**
     * This method generates the next node ID.
     *
     * @return integer
     */
    abstract protected function generateNodeID();

    /**
     * Creates a new tree node with node ID $nodeId and $data.
     *
     * This method returns by default an object of the ezcTreeNode class, 
     * however if a replacement is configured through the nodeClassName property
     * an object of that class is returned instead. This object is guaranteed
     * to inherit from ezcTreeNode.
     *
     * @param string $nodeId
     * @param mixed  $data
     * @return ezcTreeNode
     */
    public function createNode( $nodeId, $data )
    {
        if ( $nodeId === null )
        {
            if ( $this->properties['autoId'] )
            {
                $nodeId = $this->generateNodeID();
            }
            else
            {
                throw new ezcTreeInvalidIdException( null, '' );
            }
        }
        $this->checkNodeID( $nodeId );
        $className = $this->properties['nodeClassName'];
        return new $className( $this, $nodeId, $data );
    }

    /**
     * Implements the accept method for visiting.
     *
     * @param ezcTreeVisitor $visitor
     */
    public function accept( ezcTreeVisitor $visitor )
    {
        $visitor->visit( $this );
        $root = $this->getRootNode();
        if ( $root instanceof ezcTreeNode )
        {
            $root->accept( $visitor );
        }
    }

    /**
     * Returns whether the node with ID $nodeId exists.
     *
     * @param string $nodeId
     * @return bool
     */
    abstract public function nodeExists( $nodeId );

    /**
     * Returns the node identified by the ID $nodeId.
     *
     * @param string $nodeId
     * @throws ezcTreeUnknownIdException if there is no node with ID $nodeId
     * @return ezcTreeNode
     */
    public function fetchNodeById( $nodeId )
    {
        if ( !$this->nodeExists( $nodeId ) )
        {
            throw new ezcTreeUnknownIdException( $nodeId );
        }
        $className = $this->properties['nodeClassName'];
        $node = new $className( $this, $nodeId );

        return $node;
    }

    /**
     * Returns all the children of the node with ID $nodeId.
     *
     * @param string $nodeId
     * @return ezcTreeNodeList
     */
    abstract public function fetchChildren( $nodeId );

    /**
     * Returns the parent node of the node with ID $nodeId.
     *
     * @param string $nodeId
     * @return ezcTreeNode
     */
    abstract public function fetchParent( $nodeId );

    /**
     * Returns all the nodes in the path from the root node to the node with ID
     * $nodeId, including those two nodes.
     *
     * @param string $nodeId
     * @return ezcTreeNodeList
     */
    abstract public function fetchPath( $nodeId );

    /**
     * Alias for fetchSubtreeDepthFirst().
     *
     * @param string $nodeId
     * @return ezcTreeNodeList
     */
    abstract public function fetchSubtree( $nodeId );

    /**
     * Returns the node with ID $nodeId and all its children, sorted according to
     * the {@link http://en.wikipedia.org/wiki/Breadth-first_search Breadth-first sorting}
     * algorithm.
     *
     * @param string $nodeId
     * @return ezcTreeNodeList
     */
    abstract public function fetchSubtreeBreadthFirst( $nodeId );

    /**
     * Returns the node with ID $nodeId and all its children, sorted according to
     * the {@link http://en.wikipedia.org/wiki/Depth-first_search Depth-first sorting}
     * algorithm.
     *
     * @param string $nodeId
     * @return ezcTreeNodeList
     */
    abstract public function fetchSubtreeDepthFirst( $nodeId );

    /**
     * Returns the number of direct children of the node with ID $nodeId.
     *
     * @param string $nodeId
     * @return int
     */
    abstract public function getChildCount( $nodeId );

    /**
     * Returns the number of children of the node with ID $nodeId, recursively.
     *
     * @param string $nodeId
     * @return int
     */
    abstract public function getChildCountRecursive( $nodeId );

    /**
     * Returns the distance from the root node to the node with ID $nodeId.
     *
     * @param string $nodeId
     * @return int
     */
    abstract public function getPathLength( $nodeId );

    /**
     * Returns whether the node with ID $nodeId has children.
     *
     * @param string $nodeId
     * @return bool
     */
    abstract public function hasChildNodes( $nodeId );

    /**
     * Returns whether the node with ID $childId is a direct child of the node
     * with ID $parentId.
     *
     * @param string $childId
     * @param string $parentId
     * @return bool
     */
    abstract public function isChildOf( $childId, $parentId );

    /**
     * Returns whether the node with ID $childId is a direct or indirect child
     * of the node with ID $parentId.
     *
     * @param string $childId
     * @param string $parentId
     * @return bool
     */
    abstract public function isDescendantOf( $childId, $parentId );

    /**
     * Returns whether the nodes with IDs $child1Id and $child2Id are siblings
     * (ie, they share the same parent).
     *
     * @param string $child1Id
     * @param string $child2Id
     * @return bool
     */
    abstract public function isSiblingOf( $child1Id, $child2Id );

    /**
     * Sets a new node as root node, this also wipes out the whole tree.
     *
     * @param ezcTreeNode $node
     */
    abstract public function setRootNode( ezcTreeNode $node );

    /**
     * Returns the root node.
     *
     * @return ezcTreeNode
     */
    abstract public function getRootNode();

    /**
     * Adds the node $childNode as child of the node with ID $parentId.
     *
     * @param string $parentId
     * @param ezcTreeNode $childNode
     */
    abstract public function addChild( $parentId, ezcTreeNode $childNode );

    /**
     * Deletes the node with ID $nodeId from the tree, including all its children.
     *
     * @param string $nodeId
     */
    abstract public function delete( $nodeId );

    /**
     * Moves the node with ID $nodeId as child to the node with ID $targetParentId.
     *
     * @param string $nodeId
     * @param string $targetParentId
     */
    abstract public function move( $nodeId, $targetParentId );

    /**
     * Copies all the children of node $fromNode to node $toNode recursively.
     *
     * This method copies all children recursively from $fromNode to $toNode.
     * The $fromNode belongs to the $from tree and the $toNode to the $to tree.
     * Data associated with the nodes is copied as well from the store
     * associated with the $from tree to the $to tree.
     *
     * @param ezcTree $from
     * @param ezcTree $to
     * @param ezcTreeNode $fromNode
     * @param ezcTreeNode $toNode
     */
    private static function copyChildren( ezcTree $from, ezcTree $to, ezcTreeNode $fromNode, ezcTreeNode $toNode )
    {
        $children = $fromNode->fetchChildren();
        foreach ( new ezcTreeNodeListIterator( $from, $children, true ) as $childNodeKey => $childNodeData )
        {
            $fromChildNode = $from->fetchNodeById( $childNodeKey );
            $toChildNode = new ezcTreeNode( $to, $childNodeKey, $childNodeData );
            $toNode->addChild( $toChildNode );
            self::copyChildren( $from, $to, $fromChildNode, $toChildNode );
        }
    }

    /**
     * Copies the tree in $from to the empty tree in $to.
     *
     * This method copies all the nodes, including associated data from the
     * used data store, from the tree $from to the tree $to.  Because this
     * function uses internally setRootNode() the target tree will be cleared
     * out automatically. The method will not check whether the $from and $to
     * trees share the same database table or data store, so make sure they are
     * different to prevent unexpected behavior.
     *
     * @param ezcTree $from
     * @param ezcTree $to
     */
    public static function copy( ezcTree $from, ezcTree $to )
    {
        $fromRootNode = $from->getRootNode();
        $to->setRootNode( new ezcTreeNode( $to, $fromRootNode->id, $fromRootNode->data ) );
        $toRootNode = $to->getRootNode();
        self::copyChildren( $from, $to, $fromRootNode, $toRootNode );
    }

    /**
     * Returns whether we are currently in a transaction or not
     *
     * @return bool
     */
    public function inTransaction()
    {
        return $this->inTransaction;
    }

    /**
     * Returns whether we are currently in a transaction commit state or not
     *
     * @return bool
     */
    public function inTransactionCommit()
    {
        return $this->inTransactionCommit;
    }

    /**
     * Starts an transaction in which all tree modifications are queued until 
     * the transaction is committed with the commit() method.
     */
    public function beginTransaction()
    {
        if ( $this->inTransaction )
        {
            throw new ezcTreeTransactionAlreadyStartedException;
        }
        $this->inTransaction = true;
        $this->transactionList = array();
    }

    /**
     * Commits the transaction by running the stored instructions to modify
     * the tree structure.
     */
    public function commit()
    {
        if ( !$this->inTransaction )
        {
            throw new ezcTreeTransactionNotStartedException;
        }
        $this->inTransaction = false;
        $this->inTransactionCommit = true;
        foreach ( $this->transactionList as $transactionItem )
        {
            switch ( $transactionItem->type )
            {
                case ezcTreeTransactionItem::ADD:
                    $this->addChild( $transactionItem->parentId, $transactionItem->node );
                    break;

                case ezcTreeTransactionItem::DELETE:
                    $this->delete( $transactionItem->nodeId );
                    break;

                case ezcTreeTransactionItem::MOVE:
                    $this->move( $transactionItem->nodeId, $transactionItem->parentId );
                    break;
            }
        }
        $this->inTransactionCommit = false;
        $this->fixateTransaction();
    }

    /**
     * Adds a new transaction item to the list.
     *
     * @param ezcTreeTransactionItem $item
     */
    protected function addTransactionItem( ezcTreeTransactionItem $item )
    {
        $this->transactionList[] = $item;
    }

    /**
     * Rolls back the transaction by clearing all stored instructions.
     */
    public function rollback()
    {
        if ( !$this->inTransaction )
        {
            throw new ezcTreeTransactionNotStartedException;
        }
        $this->inTransaction = false;
        $this->transactionList = array();
    }
}
?>
