<?php
/**
 * File containing the ezcTreeMemory 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
 */

/**
 * ezcTreeMemory is an implementation of a tree backend that operates on
 * an in-memory tree structure. Meta-information is kept in objects of the
 * ezcTreeMemoryNode class.
 *
 * Example:
 * <code>
 * <?php
 *     // Create a new tree
 *     $tree = ezcTreeMemory::create( new ezcTreeMemoryDataStore() );
 *     // or
 *     $tree = new ezcTreeMemory( new ezcTreeMemoryDataStore() );
 * ?>
 * </code>
 *
 * See {@link ezcTree} for examples on how to operate on the tree.
 *
 * @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.
 *
 * @package Tree
 * @version //autogentag//
 * @mainclass
 */
class ezcTreeMemory extends ezcTree
{
    /**
     * Contains a list of all nodes, indexed by node ID that link directly to the create node so that they can be looked up quickly.
     *
     * @var array(string=>ezcTreeMemoryNode)
     */
    private $nodeList = array();

    /**
     * Contains the root node.
     *
     * @var ezcTreeMemoryNode
     */
    private $rootNode;

    /**
     * Stores the last auto generated ID that was used.
     *
     * @var integer $autoNodeId
     */
    private $autoNodeId = 0;

    /**
     * Constructs a new ezcTreeMemory object.
     *
     * The store that is used for data storage should be passed as the
     * $store argument.
     *
     * @param ezcTreeMemoryDataStore $store
     */
    protected function __construct( ezcTreeMemoryDataStore $store )
    {
        $this->properties['store'] = $store;
        $this->properties['autoId'] = false;
    }

    /**
     * This method generates the next node ID.
     *
     * @return integer
     */
    protected function generateNodeID()
    {
        $this->autoNodeId++;
        return $this->autoNodeId;
    }

    /**
     * A factory method that creates a new empty tree using the data store $store.
     *
     * @param ezcTreeMemoryDataStore $store
     * @return ezcTreeMemory
     */
    public static function create( ezcTreeMemoryDataStore $store )
    {
        $newTree = new ezcTreeMemory( $store );
        $newTree->nodeList = null;
        $newTree->rootNode = null;
        return $newTree;
    }

    /**
     * Returns whether the node with ID $nodeId exists.
     *
     * @param string $nodeId
     * @return bool
     */
    public function nodeExists( $nodeId )
    {
        return isset( $this->nodeList[$nodeId] );
    }

    /**
     * Returns the node identified by the ID $nodeId.
     *
     * @param string $nodeId
     * @throws ezcTreeInvalidIdException if there is no node with ID $nodeId
     * @return ezcTreeNode
     */
    public function fetchNodeById( $nodeId )
    {
        return $this->getNodeById( $nodeId )->node;
    }

    /**
     * Returns the node container for node $nodeId.
     *
     * @param string $nodeId
     * @throws ezcTreeInvalidIdException if there is no node with ID $nodeId
     * @return ezcTreeMemoryNode
     */
    private function getNodeById( $nodeId )
    {
        if ( !$this->nodeExists( $nodeId ) )
        {
            throw new ezcTreeUnknownIdException( $nodeId );
        }
        return $this->nodeList[$nodeId];
    }

    /**
     * Returns all the children of the node with ID $nodeId.
     *
     * @param string $nodeId
     * @return ezcTreeNodeList
     */
    public function fetchChildren( $nodeId )
    {
        $treeNode = $this->getNodeById( $nodeId );
        $list = new ezcTreeNodeList;
        foreach ( $treeNode->children as $nodeId => $child )
        {
            $list->addNode( $child->node );
        }
        return $list;
    }

    /**
     * Returns the parent node of the node with ID $nodeId.
     *
     * This method returns null if there is no parent node.
     *
     * @param string $nodeId
     * @return ezcTreeNode
     */
    public function fetchParent( $nodeId )
    {
        $treeNode = $this->getNodeById( $nodeId );
        $parentNode = $treeNode->parent;
        return $parentNode !== null ? $parentNode->node : null;
    }

    /**
     * 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
     */
    public function fetchPath( $nodeId )
    {
        $list = new ezcTreeNodeList;
        $memoryNode = $this->getNodeById( $nodeId );

        $nodes = array();
        $nodes[] = $memoryNode->node;

        $memoryNode = $memoryNode->parent;

        while ( $memoryNode !== null )
        {
            $nodes[] =  $memoryNode->node;
            $memoryNode = $memoryNode->parent;
        }

        $list = new ezcTreeNodeList;
        foreach ( array_reverse( $nodes ) as $node )
        {
            $list->addNode( $node );
        }
        return $list;
    }

    /**
     * Adds the children nodes of the node $memoryNode to the
     * ezcTreeNodeList $list.
     *
     * @param ezcTreeNodeList $list
     * @param ezcTreeMemoryNode $memoryNode
     */
    private function addChildNodesDepthFirst( ezcTreeNodeList $list, ezcTreeMemoryNode $memoryNode )
    {
        foreach ( $memoryNode->children as $nodeId => $childMemoryNode )
        {
            $list->addNode( $childMemoryNode->node );
            $this->addChildNodesDepthFirst( $list, $childMemoryNode );
        }
    }

    /**
     * Returns the node with ID $nodeId and all its children, sorted accoring to
     * the {@link http://en.wikipedia.org/wiki/Depth-first_search Depthth-first sorting}
     * algorithm.
     *
     * @param string $nodeId
     * @return ezcTreeNodeList
     */
    public function fetchSubtreeDepthFirst( $nodeId )
    {
        $list = new ezcTreeNodeList;
        $memoryNode = $this->getNodeById( $nodeId );
        $list->addNode( $memoryNode->node );
        $this->addChildNodesDepthFirst( $list, $memoryNode );
        return $list;
    }

    /**
     * Alias for fetchSubtreeDepthFirst().
     *
     * @param string $nodeId
     * @return ezcTreeNodeList
     */
    public function fetchSubtree( $nodeId )
    {
        return $this->fetchSubtreeDepthFirst( $nodeId );
    }

    /**
     * Adds the children nodes of the node $memoryNode to the
     * ezcTreeNodeList $list.
     *
     * @param ezcTreeNodeList $list
     * @param ezcTreeMemoryNode $memoryNode
     */
    private function addChildNodesBreadthFirst( ezcTreeNodeList $list, ezcTreeMemoryNode $memoryNode )
    {
        foreach ( $memoryNode->children as $nodeId => $childMemoryNode )
        {
            $list->addNode( $childMemoryNode->node );
        }
        foreach ( $memoryNode->children as $nodeId => $childMemoryNode )
        {
            $this->addChildNodesBreadthFirst( $list, $childMemoryNode );
        }
    }

    /**
     * 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
     */
    public function fetchSubtreeBreadthFirst( $nodeId )
    {
        $list = new ezcTreeNodeList;
        $memoryNode = $this->getNodeById( $nodeId );
        $list->addNode( $memoryNode->node );
        $this->addChildNodesBreadthFirst( $list, $memoryNode );
        return $list;
    }

    /**
     * Returns the number of direct children of the node with ID $nodeId.
     *
     * @param string $nodeId
     * @return int
     */
    public function getChildCount( $nodeId )
    {
        return count( $this->getNodeById( $nodeId )->children );
    }

    /**
     * Helper method that iterates recursively over the children of $node to
     * count the number of children.
     *
     * @param integer $count
     * @param ezcTreeMemoryNode $node
     */
    private function countChildNodes( &$count, ezcTreeMemoryNode $node )
    {
        foreach ( $node->children as $nodeId => $node )
        {
            $count++;
            $this->countChildNodes( $count, $node );
        }
    }

    /**
     * Returns the number of children of the node with ID $nodeId, recursively
     *
     * @param string $nodeId
     * @return int
     */
    public function getChildCountRecursive( $nodeId )
    {
        $count = 0;
        $node = $this->getNodeById( $nodeId );
        $this->countChildNodes( $count, $node );
        return $count;
    }

    /**
     * Returns the distance from the root node to the node with ID $nodeId
     *
     * @param string $nodeId
     * @return int
     */
    public function getPathLength( $nodeId )
    {
        $childNode = $this->getNodeById( $nodeId );
        $length = -1;

        while ( $childNode !== null )
        {
            $childNode = $childNode->parent;
            $length++;
        }
        return $length;
    }

    /**
     * Returns whether the node with ID $nodeId has children
     *
     * @param string $nodeId
     * @return bool
     */
    public function hasChildNodes( $nodeId )
    {
        return count( $this->getNodeById( $nodeId )->children ) > 0;
    }

    /**
     * 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
     */
    public function isChildOf( $childId, $parentId )
    {
        $childNode = $this->getNodeById( $childId );
        $parentNode = $this->getNodeById( $parentId );

        if ( $childNode->parent->node === $parentNode->node )
        {
            return true;
        }
        return false;
    }

    /**
     * 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
     */
    public function isDescendantOf( $childId, $parentId )
    {
        $childNode = $this->getNodeById( $childId );
        $parentNode = $this->getNodeById( $parentId );

        if ( $childNode === $parentNode )
        {
            return false;
        }

        while ( $childNode !== null )
        {
            if ( $childNode->node === $parentNode->node )
            {
                    return true;
            }
            $childNode = $childNode->parent;
        }
        return false;
    }

    /**
     * Returns whether the nodes with IDs $child1Id and $child2Id are siblings
     * (ie, the share the same parent)
     *
     * @param string $child1Id
     * @param string $child2Id
     * @return bool
     */
    public function isSiblingOf( $child1Id, $child2Id )
    {
        $elem1 = $this->getNodeById( $child1Id );
        $elem2 = $this->getNodeById( $child2Id );
        return (
            ( $child1Id !== $child2Id ) && 
            ( $elem1->parent === $elem2->parent )
        );
    }

    /**
     * Sets a new node as root node, this wipes also out the whole tree
     *
     * @param ezcTreeNode $node
     */
    public function setRootNode( ezcTreeNode $node )
    {
        // wipe nodelist and data
        $this->nodeList = array();
        $this->store->deleteDataForAllNodes();

        // replace root node
        $newObj = new ezcTreeMemoryNode( $node, array() );
        $this->rootNode = $newObj;

        // Add to node list
        $this->nodeList[$node->id] = $newObj;
    }

    /**
     * Returns the root node
     *
     * This methods returns null if there is no root node.
     *
     * @return ezcTreeNode
     */
    public function getRootNode()
    {
        if ( $this->rootNode )
        {
            return $this->rootNode->node;
        }
        return null;
    }

    /**
     * Adds the node $childNode as child of the node with ID $parentId
     *
     * @param string $parentId
     * @param ezcTreeNode $childNode
     */
    public function addChild( $parentId, ezcTreeNode $childNode )
    {
        if ( $this->inTransaction )
        {
            $this->addTransactionItem( new ezcTreeTransactionItem( ezcTreeTransactionItem::ADD, $childNode, null, $parentId ) );
            return;
        }

        // Locate parent node
        $parentMemoryNode = $this->getNodeById( $parentId );

        // Create new node
        $newObj = new ezcTreeMemoryNode( $childNode, array(), $parentMemoryNode );

        // Append to parent node
        $parentMemoryNode->children[$childNode->id] = $newObj;

        // Add to node list
        $this->nodeList[$childNode->id] = $newObj;
    }

    /**
     * Deletes the node with ID $nodeId from the tree, including all its children
     *
     * @param string $nodeId
     */
    public function delete( $nodeId )
    {
        if ( $this->inTransaction )
        {
            $this->addTransactionItem( new ezcTreeTransactionItem( ezcTreeTransactionItem::DELETE, null, $nodeId ) );
            return;
        }

        // locate node to move
        $nodeToDelete = $this->getNodeById( $nodeId );

        // fetch the whole subtree and delete all the associated data
        $children = $nodeToDelete->node->fetchSubtree();
        $this->store->deleteDataForNodes( $children );

        // Use the parent to remove the child
        unset( $nodeToDelete->parent->children[$nodeId] );

        // Remove the node and all its children
        foreach ( new ezcTreeNodeListIterator( $this, $children ) as $nodeId => $data )
        {
            unset( $this->nodeList[$nodeId] );
        }
    }

    /**
     * Moves the node with ID $nodeId as child to the node with ID $targetParentId
     *
     * @param string $nodeId
     * @param string $targetParentId
     */
    public function move( $nodeId, $targetParentId )
    {
        if ( $this->inTransaction )
        {
            $this->addTransactionItem( new ezcTreeTransactionItem( ezcTreeTransactionItem::MOVE, null, $nodeId, $targetParentId ) );
            return;
        }

        // locate node to move
        $nodeToMove = $this->getNodeById( $nodeId );

        // locate new parent
        $newParent = $this->getNodeById( $targetParentId );

        // new placement for node
        $newParent->children[$nodeId] = $nodeToMove;

        // remove old location from previous parent
        unset( $nodeToMove->parent->children[$nodeId] );

        // update parent attribute of the node
        $nodeToMove->parent = $newParent;
    }

    /**
     * Fixates the transaction.
     */
    public function fixateTransaction()
    {
    }
}
?>
