<?php
/*
 *  $Id$
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the LGPL. For more information, see
 * <http://www.phpdoctrine.com>.
 */
/**
 * Doctrine_Node_Interface
 *
 * @package     Doctrine
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @category    Object Relational Mapping
 * @link        www.phpdoctrine.com
 * @since       1.0
 * @version     $Revision$
 * @author      Joe Simms <joe.simms@websites4.com>
 */
interface Doctrine_Node_Interface {

	/**
	 * test if node has previous sibling
	 *
	 * @return bool			
	 */
  public function hasPrevSibling();

	/**
	 * test if node has next sibling
	 *
	 * @return bool			
	 */  
  public function hasNextSibling();

	/**
	 * test if node has children
	 *
	 * @return bool			
	 */ 
  public function hasChildren();

	/**
	 * test if node has parent
	 *
	 * @return bool			
	 */ 
  public function hasParent();

	/**
	 * gets record of prev sibling or empty record
	 *
	 * @return object   Doctrine_Record			
	 */
  public function getPrevSibling();
  
	/**
	 * gets record of next sibling or empty record
	 *
	 * @return object   Doctrine_Record			
	 */
  public function getNextSibling();
  
	/**
	 * gets siblings for node
	 *
	 * @return array   array of sibling Doctrine_Record objects			
	 */
  public function getSiblings($includeNode = false);

	/**
	 * gets record of first child or empty record
	 *
	 * @return object   Doctrine_Record			
	 */
  public function getFirstChild();

	/**
	 * gets record of last child or empty record
	 *
	 * @return object   Doctrine_Record			
	 */
  public function getLastChild();

	/**
	 * gets children for node (direct descendants only)
	 *
	 * @return array   array of sibling Doctrine_Record objects				
	 */
  public function getChildren();

	/**
	 * gets descendants for node (direct descendants only)
	 *
	 * @return iterator   iterator to traverse descendants from node				
	 */
  public function getDescendants();

	/**
	 * gets record of parent or empty record
	 *
	 * @return object   Doctrine_Record			
	 */
  public function getParent();

	/**
	 * gets ancestors for node
	 *
	 * @return object   Doctrine_Collection				
	 */
  public function getAncestors();

	/**
	 * gets path to node from root, uses record::toString() method to get node names
	 *
	 * @param string   $seperator   path seperator
	 * @param bool   $includeNode   whether or not to include node at end of path
	 * @return string   string representation of path				
	 */  
  public function getPath($seperator = ' > ', $includeNode = false);

	/**
	 * gets level (depth) of node in the tree
	 *
	 * @return int			
	 */ 
  public function getLevel();

	/**
	 * gets number of children (direct descendants)
	 *
	 * @return int			
	 */   
  public function getNumberChildren();

	/**
	 * gets number of descendants (children and their children)
	 *
	 * @return int			
	 */
  public function getNumberDescendants();

	/**
	 * inserts node as parent of dest record
	 *
	 * @return bool			
	 */
  public function insertAsParentOf(Doctrine_Record $dest);

	/**
	 * inserts node as previous sibling of dest record
	 *
	 * @return bool			
	 */
  public function insertAsPrevSiblingOf(Doctrine_Record $dest);

	/**
	 * inserts node as next sibling of dest record
	 *
	 * @return bool			
	 */
  public function insertAsNextSiblingOf(Doctrine_Record $dest);

	/**
	 * inserts node as first child of dest record
	 *
	 * @return bool			
	 */
  public function insertAsFirstChildOf(Doctrine_Record $dest);

	/**
	 * inserts node as first child of dest record
	 *
	 * @return bool			
	 */
  public function insertAsLastChildOf(Doctrine_Record $dest);

	/**
	 * moves node as prev sibling of dest record
	 *		
	 */  
  public function moveAsPrevSiblingOf(Doctrine_Record $dest);

	/**
	 * moves node as next sibling of dest record
	 *		
	 */
  public function moveAsNextSiblingOf(Doctrine_Record $dest);

	/**
	 * moves node as first child of dest record
	 *			
	 */
  public function moveAsFirstChildOf(Doctrine_Record $dest);

	/**
	 * moves node as last child of dest record
	 *		
	 */
  public function moveAsLastChildOf(Doctrine_Record $dest);

	/**
	 * adds node as last child of record
	 *		
	 */
  public function addChild(Doctrine_Record $record);

	/**
	 * determines if node is leaf
	 *
	 * @return bool			
	 */
  public function isLeaf();

	/**
	 * determines if node is root
	 *
	 * @return bool			
	 */
  public function isRoot();

	/**
	 * determines if node is equal to subject node
	 *
	 * @return bool			
	 */
  public function isEqualTo(Doctrine_Record $subj);

	/**
	 * determines if node is child of subject node
	 *
	 * @return bool			
	 */
  public function isDescendantOf(Doctrine_Record $subj);

	/**
	 * determines if node is child of or sibling to subject node
	 *
	 * @return bool			
	 */
  public function isDescendantOfOrEqualTo(Doctrine_Record $subj);

	/**
	 * determines if node is valid
	 *
	 * @return bool			
	 */
  public function isValidNode();

	/**
	 * deletes node and it's descendants
	 *			
	 */
  public function delete();
}