<?php
/*
 * This file is part of the easy-CMS project.
 * easy-CMS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * easy-CMS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with easy-CMS; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

/**
 * @package    Core
 * @subpackage menuNodes
 */

include_once('classes/core/CoreObject.class.php');
include_once('classes/core/DBManipulator.class.php');
include_once('classes/core/ACL/ACL.class.php');
include_once('classes/core/pages/Page.class.php');
include_once('classes/core/users/User.class.php');
include_once('classes/core/menuNodes/MenuNodesManager.class.php');

include_once('interface/egManager.class.php');
include_once('interface/egContainer.class.php');
include_once('interface/egContextMenu.class.php');

/**
 * menuNode Class
 *
 * A menuNode holds infos about template, sort order, number to be shown and
 * exhaustive list of contents that are to be displayed in this container.
 *
 * @access     public
 * @author	   Cedric Francoys <cedric.francoys@easy-cms.org>
 * @version	   MenuNode.class, Sat Nov 13 11:37:29 CET 2004
 * @package    Core
 * @subpackage MenuNodes
 */
class MenuNode extends CoreObject {
	/**
	 * @var integer
	 */
  var $id;

	/**
	 * @var integer
	 */
	var $menuId;

	/**
	 * @var integer
	 */
	var $parentNodeId;

	/**
	 * @var integer
	 */
	var $pageId;

	/**
	 * @var object
	 */
	var $page;

	/**
	 * @var string
	 */
	var $sortField;

	/**
	 * @var integer
	 */
	var $sortOrder;

	/**
	 * @var integer
	 */
	var $sortingType;

	/**
	 * @var integer
	 */
	var $aclId;

	/**
	 * @var object
	 */
	var $acl;

	/**
	 * @var array
	 */
	var $nodesTable;

	/**
	 * @var array
	 */
	var $sortedList;
	
	var $index;
	
	var $deleted;

	/**
	 * Constructor
	 *
	 * @param integer $id MenuNode Id
	 * @param integer $aclId MenuNode ACL Id
	 */
	function MenuNode($id=0, $pageId=0, $sortingType=0, $sortField='', $sortOrder=0, $aclId=0) {
    parent::setClassName('MenuNode');
		$this->setMenuNodeId($id);
		$this->setMenuNodePageId($pageId);
		$this->setMenuNodeAclId($aclId);
    $this->setMenuNodeSortingType($sortingType);
    $this->setMenuNodeSortField($sortField);
    $this->setMenuNodeSortOrder($sortOrder);
		$this->nodesTable = array();
	}

	function isPublished() {
		if(isset($this->page) && is_object($this->page)) {
			return $this->page->isPublished();
		}
		return false;
	}

	/**
	 * Gets MenuNode Id
	 *
	 * @return integer
	 */
	function getMenuNodeId(){
		return $this->id;
	}

	/**
	 * Sets MenuNode Id
	 *
	 * @param integer $id MenuNode Id
	 */
	function setMenuNodeId($id){
		$this->id = $id;
	}

	/**
	 * Gets MenuNode Page Id
	 *
	 * @return integer
	 */
	function getMenuNodePageId(){
		return $this->pageId;
	}

	/**
	 * Sets MenuNode Page Id
	 *
	 * @param integer $pageId
	 */
	function setMenuNodePageId($pageId){
		$this->pageId = $pageId;
	}

	/**
	 * Sets MenuNode Menu Id
	 *
	 * @param integer $menuId
	 */
	function setMenuNodeMenuId($menuId){
		$this->menuId = $menuId;
	}

	/**
	 * Gets MenuNode Menu Id
	 *
	 * @return integer
	 */
	function getMenuNodeMenuId(){
		return $this->menuId;
	}

  function setMenuNodeIndex($index) {
    $this->index = $index;
  }

  function getMenuNodeIndex() {
    return $this->index;
  }

  function setMenuNodeDeleted($deleted) {
    $this->deleted = $deleted;
  }

  function getMenuNodeDeleted() {
    return $this->deleted;
  }
  
	/**
	 * Gets MenuNode Page
	 *
	 * @return object
	 */
	function &getMenuNodePage(){
		return $this->page;
	}

	/**
	 * Sets MenuNode Page
	 *
	 * @param object $page
	 */
	function setMenuNodePage(&$page){
		$this->page = &$page;
	}

	/**
	 * Gets MenuNode Acl Id
	 *
	 * @return integer
	 */
	function getMenuNodeAclId(){
		return $this->aclId;
	}

	function setMenuNodeParentNodeId($parentNodeId) {
		$this->parentNodeId = $parentNodeId;
	}

	function getMenuNodeParentNodeId() {
		return $this->parentNodeId;
	}

	/**
	 * Sets MenuNode Acl Id
	 *
	 * @param integer $aclId
	 */
	function setMenuNodeAclId($aclId){
		$this->aclId = $aclId;
	}

	/**
	 * Gets MenuNode ACL
	 *
	 * @return object
	 */
	function &getMenuNodeAcl(){
		if (!isset($this->acl)) {
			return null;
    }
		return $this->acl;
	}

	/**
	 * Sets MenuNode ACL
	 *
	 * @param object $acl
	 */
	function setMenuNodeAcl(&$acl){
		$this->acl = &$acl;
	}

	/**
	 * Gets MenuNode "SortingType" Property
	 *
	 * Indicates if we must operate a field or index based sort
	 *
	 * @return integer
	 */
	function getMenuNodeSortingType(){
		return $this->sortingType;
	}

	/**
	 * Sets MenuNode "SortingType" Property
	 *
	 * Indicates if we must operate a field or index based sort
	 *
	 * @param integer $sortingType
	 */
	function setMenuNodeSortingType($sortingType){
		$this->sortingType = $sortingType;
	}

	/**
	 * Gets MenuNode "SortField" Property
	 *
	 * Indicates on which Node field applies the sort
	 *
	 * @return string
	 */
	function getMenuNodeSortField(){
		return $this->sortField;
	}

	/**
	 * Sets MenuNode "SortField" Property
	 *
	 * Indicates on which Content field applies the sort
	 *
	 * @param string $sortField
	 */
	function setMenuNodeSortField($sortField){
		$this->sortField = $sortField;
	}

	/**
	 * Gets MenuNode "SortOrder" Property
	 *
	 * Sort order is ascending or descending
	 *
	 * @return integer
	 */
	function getMenuNodeSortOrder(){
		return $this->sortOrder;
	}

	/**
	 * Sets MenuNode "SortOrder" Property
	 *
	 * Sort order is ascending or descending
	 *
	 * @param integer $sortOrder
	 */
	function setMenuNodeSortOrder($sortOrder){
		$this->sortOrder = $sortOrder;
	}

	/**
	 * Gets Nodes Table
	 *
	 * @return array
	 */
	function &getNodesTable(){
    $table = null;
		if (!isset($this->nodesTable)) {
			// error
		}
		else {
      $table = &$this->nodesTable;
		}
		return $table;
	}

	/**
	 * Sets Nodes Table
	 *
	 * @param array $table Array of MenuNode objects
	 */
	function setNodesTable(&$table){
		$this->nodesTable = &$table;
	}

	/**
	 * Gets Nodes Count
	 *
	 * Number of MenuNode objects holded by MenuNode
	 *
	 * @return integer
	 */
	function getNodesCount(){
    $count = 0;
		if (!isset($this->nodesTable)) {
			// error
		}
		else {
      $count = count($this->nodesTable);
		}
		return $count;
	}

	/**
	 * Adds a content object to the contentsTable
	 *
	 * @param object $content
	 */
	function addNode(&$menuNode){
		if(!is_object($menuNode)) {
			$this->debug('MenuNode::addNode, error : trying to add a non-object to the nodesTable.', 4);
		}
		else {
		  $this->nodesTable[] = &$menuNode;
    }
	}

	/**
	 * Gets Node
	 *
	 * @param  integer $nodeId MenuNode Id
	 * @return object
	 */
	function &getNode($nodeId){
    $node = null;
		if (!isset($this->nodesTable[$nodeId])) {
			$this->debug('MenuNode::getNode, error : node ('.$nodeId.') not found.', 4);
		}
		else {
		  $node = &$this->nodesTable[$nodeId];
		}
		return $node;
	}


	/**
	 * Checks if a page-id is referenced by a subNode
	 *
	 * @param  integer $pageId Page ID for Comparison
	 * @return integer
	 */
	function isSubNodePageId($pageId){
    $result = false;
		if($this->pageId == $pageId) {
			$result = true;
		}
		else {
			foreach($this->nodesTable as $node) {
				if($node->isSubNodePageId($pageId)) {
          $result = true;
          break;
        }
			}
		}
		return $result;
	}

	/**
	 * Compares MenuNodes
	 *
	 * @param  object $container MenuNode Object
	 * @param  string $field Comparison Field
	 * @param  integer $langId Language of Comparison
	 * @return integer
	 */
	function compareTo(&$menuNode, $field, $langId=1){
    $page1 = &$this->getMenuNodePage();
    $page2 = &$menuNode->getMenuNodePage();

		if ($field == '' || !is_object($page1) || !is_object($page2)) {
			return 1;
		}

    $value1 = $page1->getPageValue($field, $langId);
		$value2 = $page2->getPageValue($field, $langId);

		if (is_numeric($value1) && is_numeric($value2)) {
			$value1 = sprintf("%05d", $value1);
			$value2 = sprintf("%05d", $value2);
		}
		return strcmp($value1, $value2);
	}

  function sortNodes($langId) {
    if (is_array($this->nodesTable)) {
			$count = $this->getNodesCount();
			$sortField = $this->getMenuNodeSortField();
			$sortOrder = $this->getMenuNodeSortOrder();
			$this->sortedList = array();
			for($i = 0; $i < $count; ++$i) {
				$node = &$this->nodesTable[$i];
				$page = &$node->getMenuNodePage();
        $field = $page->getPageValue($sortField, $langId);
				$this->sortedList[$i] = substr($field, 0, 20);
			}
			if($sortOrder == SORT_ASCENDING) {
				asort($this->sortedList);
			}
			else {
				arsort($this->sortedList);
			}
    }
  }

 	function toSubXML(&$user, $mode, $langId, $currentPageId, $countShown=0) {
		$count = $this->getNodesCount();
		$i = 0;
		$xml  = '';

		if ($this->acl->userHasViewRight($user) && ($mode == EDIT_MODE || $this->isPublished())) {
			// sorting by list
			if ($this->getMenuNodeSortingType() == SORTING_BY_LIST) {
				for (; $i < $count; ++$i) {
					if($countShown) {
						if($i >= $countShown) {
							break;
						}
					}
					if(!isset($this->nodesTable[$i]) || !is_object($this->nodesTable[$i])) {
						continue;
					}
					$node = &$this->nodesTable[$i];
					$xml .= $node->toXML($user, $mode, $langId, $currentPageId);
				}
			}
			// sorting by field
			else {
				$this->sortNodes($langId);
				$sortField = $this->getMenuNodeSortField();
				if (is_array($this->sortedList)) {
					reset($this->sortedList);
					for ($j = 0; $j < $i; ++$j) {
						next($this->sortedList);
					}
					for (; $i < $count; ++$i) {
						if($countShown) {
							if($i >= $countShown) {
								break;
							}
						}
						$index = key($this->sortedList);
						$node = &$this->nodesTable[$index];
						next($this->sortedList);
						$xml .= $node->toXML($user, $mode, $langId, $currentPageId);
					}
				}
			}
		}
		return $xml;
	}

	/**
	 * Exports MenuNode Into XML
	 *
	 * @param  object $user User Object
	 * @param  integer $langId Language Id
	 * @param  string $mode
	 * @return string
	 */
 	function toXML(&$user, $mode, $langId, $currentPageId) {
		$menuNodeId = $this->getMenuNodeId();
		$page = $this->getMenuNodePage();

		$menuId 			= $this->getMenuNodeMenuId();
		$pageId     	= $page->getPageId();
		$parentNodeId = $this->getMenuNodeParentNodeId();



		$count = $this->getNodesCount();
		$i = 0;

		$xml = '';

		if ($this->acl->userHasViewRight($user) && ($mode == EDIT_MODE || $this->isPublished())) {
			$xml = "<page>\n";
			$xml .= "<id>".$this->getMenuNodePageId()."</id>\n";
			$xml .= "<name><![CDATA[".$page->getPageName($langId)."]]></name>\n";
			//$xml .= "<link><![CDATA[/index.php?pid=".$this->getMenuNodePageId()."]]></link>\n";
			$xml .= "<link><![CDATA[".$page->getPageLinkOrAlias($langId)."]]></link>\n";
			
			if ($mode == EDIT_MODE){
				$xml .= '<page_controls>'."\n";
				$xml .= '  <type>easy_cms_page</type>'."\n";
				$xml .= '  <id>'.$pageId.'</id>'."\n";
				$xml .= '  <menu-id>'.$menuId.'</menu-id>'."\n";
				$xml .= '  <node-id>'.$menuNodeId.'</node-id>'."\n";
				$xml .= '  <parent-node-id>'.$parentNodeId.'</parent-node-id>'."\n";
				$xml .= '</page_controls>'."\n";
			}

			if($this->isSubNodePageId($currentPageId)) {
				// sorting by list
				if ($this->getMenuNodeSortingType() == SORTING_BY_LIST) {
					for (; $i < $count; ++$i) {
						if(!isset($this->nodesTable[$i]) || !is_object($this->nodesTable[$i])) {
							continue;
						}
						$node = &$this->nodesTable[$i];
						$xml .= $node->toXML($user, $mode, $langId, $currentPageId);
					}
				}
				// sorting by field
				else {
					$this->sortNodes($langId);
					$sortField = $this->getMenuNodeSortField();
					if (is_array($this->sortedList)) {
						reset($this->sortedList);
						for ($j = 0; $j < $i; ++$j) {
							next($this->sortedList);
						}
						for (; $i < $count; ++$i) {
							$index = key($this->sortedList);
							$node = &$this->nodesTable[$index];
							next($this->sortedList);
							$xml .= $node->toXML($user, $mode, $langId, $currentPageId);
						}
					}
				}
			}
			$xml .= "</page>\n";
		}

		$this->getControls($user, $mode);
		return utf8_encode($xml);
	}

	/**
	 * Gets MenuNode Controls
	 *
	 * @param  object $user User Object
	 * @param  string $mode
	 * @return string
	 */
	function getControls(&$user, $mode=VIEW_MODE) {
		$menuId 			= $this->getMenuNodeMenuId();
		$menuNodeId 	= $this->getMenuNodeId();
		$page 				= &$this->getMenuNodePage();
		$pageId     	= $page->getPageId();
		$parentNodeId = $this->getMenuNodeParentNodeId();

		$html = '';

		if ($this->acl->userHasEditRight($user) && $mode == EDIT_MODE) {

			if(!isset($GLOBALS['contextMenuNode'])) {

	      $menu = &new egContextMenu("menu_page_node", 0, 0, 150, 350);

	      $menu->addListItem(new egMenuItem("mnu_mn_1", LANG_PAGE_MENU_ADD, "/interface/icons/add.png", "nodeMenuAddOption();"));

		    $menu->addSeparator();

				// move up
	      $menu->addListItem(new egMenuItem("mnu_mn_2", LANG_PAGE_MENU_MOVE_UP, "/interface/icons/move_up.png", "nodeMenuMoveUpOption();"));
				// move down
	      $menu->addListItem(new egMenuItem("mnu_mn_3", LANG_PAGE_MENU_MOVE_DOWN, "/interface/icons/move_down.png", "nodeMenuMoveDownOption();"));
				// move top
	      $menu->addListItem(new egMenuItem("mnu_mn_4", LANG_PAGE_MENU_MOVE_TOP, "/interface/icons/move_top.png", "nodeMenuMoveTopOption();"));
				// move bottom
	      $menu->addListItem(new egMenuItem("mnu_mn_5", LANG_PAGE_MENU_MOVE_BOTTOM, "/interface/icons/move_bottom.png", "nodeMenuMoveBottomOption();"));


		    $menu->addSeparator();

				// remove page
        $menu->addListItem(new egMenuItem("mnu_mn_6", LANG_PAGE_MENU_REMOVE, "/interface/icons/remove.png", "nodeMenuRemoveOption();"));

		    $menu->addSeparator();

				// page properties
		    $menu->addListItem(new egMenuItem("mnu_mn_7", LANG_PAGE_MENU_EDIT, "/interface/icons/edit.png", "nodeMenuEditOption();"));

	      $main = &new egContainer("eg_ctn_menu_node", 0, 0, 0, 0);

	      $main->addObject($menu);

	      $manager = &egManager::getInstance();
	    	$manager->addContainer($main);

				$GLOBALS['contextMenuNode'] = &$menu;
			}
			$html .= "<a class=\"easy-CMS_UI_Style_propertiesIcon\" href=\"javascript:selectNode('$menuId','$menuNodeId','$parentNodeId','$pageId');egShowContextMenu(contextMenu_menu_page_node);\"><img src=\"/interface/icons/properties.png\" /></a>";
    }
		return $html;
	}

}
?>