<?php

class ContentTreeNode {
    protected $urlIdentifier;
    protected $title;
    protected $menu_title;
    protected $subTitle;
    protected $visible;
    protected $id;
    protected $nodeClass;
    protected $credentials;
    protected $permsType;
    protected $seo_keywords_type;
    protected $seo_keywords_content;
    protected $seo_description_type;
    protected $seo_description_content;
    protected $current_layout_type;
    protected $current_layout_content;
    protected $browser_title_type;
    protected $browser_title_content;
    protected $url_provider;
    protected $locale;
    protected $open_target_provider;
    protected $pending_delete = false;
    public $children = array();
    /**
     *
     * @var ContentTreeNode
     */
    public $parent;
    public $previousSibling;
    public $active = false;
    public $nextSibling;
    protected $owner_tree = null;
    protected $mockTranslation = false;

    function setOwnerTree($value)
    {
        $this->owner_tree = $value;
    }
    /**
     * @return ContentTree
     */

    function getOwnerTree()
    {
        return $this->owner_tree;
    }

    function setMockTranslation($value)
    {
        $this->mockTranslation = $value;
    }

    function __construct($node, $parentTreeNode, $locale = null)
    {
        if (null == $locale) {
            $locale = sfConfig::get('app_translations_default_language');
        }
        $this->setCulture($locale);
        $this->refreshProperties($node);
        $this->parent = $parentTreeNode;
    }

    function setCulture($value)
    {
        $this->locale = $value;
    }

    function getCulture()
    {
        return $this->locale;
    }

    public function refreshProperties(Node $node)
    {
        $this->urlIdentifier = $node->getUrlIdentifier($this->locale);
        $this->url_provider = $node->getUrlProvider();
        $this->open_target_provider = $node->getOpenTargetProvider();
        $this->title = $node->getTitle();
        $this->subTitle = $node->getSubTitle();
        $this->visible = $node->getIsVisibleInMenu();
        $this->nodeClass = $node->getNodeClass();
        $this->id = $node->getId();
        $this->credentials = $node->getCredentials();
        $this->menu_title = $node->getMenuTitle();
        $this->permsType = $node->getPermsType();
        $this->seo_keywords_type = $node->getSeoKeywordsType();
        $this->seo_keywords_content = $node->getSeoKeywordsContent($this->locale);
        $this->seo_description_type = $node->getSeoDescriptionType();
        $this->seo_description_content = $node->getSeoDescriptionContent($this->locale);
        $this->current_layout_content = $node->getCurrentLayout();
        $this->current_layout_type = $node->getCurrentLayoutType();
        $this->browser_title_type = $node->getBrowserTitleType();
        $this->browser_title_content = $node->getBrowserTitleContent($this->locale);
    }
    function setUrlIdentifier($value)
    {
        $this->urlIdentifier = $value;
    }

	function setBrowserTitleType($value)
	{
		$this->browser_title_type = $value;
	}

	function getBrowserTitleType()
	{
		return $this->browser_title_type;
	}

	function getBrowserTitleContent()
    {
        return $this->browser_title_content;
    }
    function setBrowserTitleContent($value)
    {
        $this->browser_title_content = $value;
    }

    function isVisibleInMenu()
    {
        return $this->visible;
    }
    function getUrl($locale = null, $force_script_name = true)
    {
        if (null == $locale) {
            $locale = $this->locale;
        }
        if ($this->mockTranslation || $locale != $this->locale) {
            // $this->mockTranslation &&
            $localizedContentTree = ContentTree::instance($locale);
            $localizedContentTree->build();
            $localizedNode = $localizedContentTree->getContentTreeNodeById($this->getId());
            // var_dump($localizedNode);exit;
            return $localizedNode->getUrl(null, $force_script_name);
        }
        $default = '';
        if (null == $this->parent && count(sfConfig::get('app_translations_available_languages')) > 1) {
            $default = '/' . $locale;
        } else {
            $node = $this;
            if (!$node->parent) {
                $default = '/';
            } else {
                while ($node->parent) {
                    $default = '/' . $node->getUrlIdentifier() . $default;
                    $node = $node->parent;
                }
                if ($default != '/' && count(sfConfig::get('app_translations_available_languages')) > 1) {
                    $default = '/' . $locale . $default;
                }
            }
        }
        if ($this->url_provider) {
            $className = $this->getNodeClass();
            return eval("return Node$className::getUrl(\$this, '$default');");
        }
        if ($force_script_name && !empty($_SERVER['SCRIPT_NAME']) && !sfConfig::get('sf_no_script_name')) {
            $default = $_SERVER['SCRIPT_NAME'] . $default;
        }
        return $default;
    }
    function getOpenTarget()
    {
        if ($this->open_target_provider) {
            $className = $this->getNodeClass();
            return eval("return Node$className::getOpenTarget(\$this);");
        }
        return '_self';
    }
    function getUrlIdentifier()
    {
        return $this->urlIdentifier;
    }

    function getId()
    {
        return $this->id;
    }
    function getNodeClass()
    {
        return $this->nodeClass;
    }
    function getPage()
    {
        // printf('Id: %s, Class: %s', $this->getId(), $this->getNodeClass());
        return Catalyz::getPageByNodeIdAndClass($this->getId(), $this->getNodeClass(), $this->getCulture());
    }
    protected $node = null;

    /**
     *
     * @return Node
     */
    function getNode()
    {
        // var_dump($this->getId());
        if (empty($this->node)) {
            $criteria = new Criteria();
            $criteria->add(NodePeer::ID, $this->getId());
            $nodes = NodePeer::doSelectWithI18n($criteria, $this->getOwnerTree()->getCulture());
            if (count($nodes) > 0) {
                $this->node = array_shift($nodes);
            } else {
            	$criteria = new Criteria();
            	$criteria->add(NodePeer::ID, $this->getId());
            	$nodes = NodePeer::doSelectWithI18n($criteria, sfConfig::get('app_translations_default_language'));
            	if (count($nodes) > 0) {
            		$this->node = array_shift($nodes);
            	} else {
            		$this->node = null;
            	}
            }
        }
        return $this->node;
    }
    function getTitle()
    {
        return $this->title;
    }

    function setTitle($value)
    {
        $this->title = $value;
    }
    function getMenuTitle()
    {
        return $this->menu_title;
    }
    function getSubTitle()
    {
        return $this->subTitle;
    }
    function setSubTitle($value)
    {
        $this->subTitle = $value;
    }
    function addChild($treeNode)
    {
        $this->children[] = $treeNode;
        $treeNode->parent = $this;
        if (count($this->children) > 1) {
            $prevSibling = $this->children[count($this->children) - 2];
            $prevSibling->nextSibling = $treeNode;
            $treeNode->previousSibling = $prevSibling;
        }
        // printf('%s is now a child of %s<br />', $treeNode->getCaption(), $this->getCaption());
    }
    function getChildByUrlIdentifier($urlIdentifier)
    {
        foreach($this->children as $child) {
            if ($child->getUrlIdentifier() == $urlIdentifier) {
                return $child;
            }
        }
        return null;
    }

    function getVisibleChildren()
    {
        $result = array();
        foreach($this->children as $child) {
            if ($child->isVisibleInMenu()) {
                $result[] = $child;
            }
        }
        return $result;
    }
    function getChildren()
    {
        return $this->children;
    }
    function isActive()
    {
        return $this->active;
    }
    function getActiveChildren()
    {
        foreach($this->children as $child) {
            if ($child->isActive()) {
                return $child;
            }
        }
        return null;
    }
    function getContentTreeNodeById($id)
    {
        if ($this->getId() == $id) {
            return $this;
        }
        foreach($this->children as $child) {
            $result = $child->getContentTreeNodeById($id);
            if (null != $result) {
                return $result;
            }
        }
        return null;
    }

    public function getPermsData()
    {
        if ($this->permsType == Node::PERMS_INHERIT) {
            if (is_null($this->parent)) {
                return array(Node::PERMS_ALLOWED_TO_ANYBODY, '');
            }
            return $this->parent->getPermsData();
        }
        if ($this->permsType == Node::PERMS_ALLOWED_TO_ANYBODY) {
            return array(Node::PERMS_ALLOWED_TO_ANYBODY, '');
        }
        if ($this->permsType == Node::PERMS_RESTRICTED) {
            return array(Node::PERMS_RESTRICTED, $this->credentials);
        }
        throw new Exception('Unknown permission type: ' . $this->permsType);
    }

    public function getSeoKeywords()
    {
        switch ($this->getSeoKeywordsType()) {
            case Node::SEO_KEYWORDS_CUSTOM:
                return $this->getSeoKeywordsContent();
            case Node::SEO_KEYWORDS_INHERIT:
                if ($this->parent) {
                    return $this->parent->getSeoKeywords();
                } else {
                    return '';
                }
        } // switch
        return '';
    }
	public function getSeoKeywordsType(){
		return $this->seo_keywords_type;
	}
    public function setSeoKeywordsType($value)
    {
        $this->seo_keywords_type = $value;
    }
    public function getSeoKeywordsContent()
    {
        return $this->seo_keywords_content;
    }
    public function setSeoKeywordsContent($value)
    {
        $this->seo_keywords_content = $value;
    }
    public function getSeoDescription()
    {
        switch ($this->getSeoDescriptionType()) {
            case Node::SEO_DESCRIPTION_CUSTOM:
                return $this->getSeoDescriptionContent();
            case Node::SEO_DESCRIPTION_INHERIT:
                if ($this->parent) {
                    return $this->parent->getSeoDescription();
                } else {
                    return '';
                }
        } // switch
        return '';
    }
	public function getSeoDescriptionType(){
		return $this->seo_description_type;
	}
    public function setSeoDescriptionType($value)
    {
        $this->seo_description_type = $value;
    }
    public function getSeoDescriptionContent()
    {
        return $this->seo_description_content;
    }
    public function setSeoDescriptionContent($value)
    {
        $this->seo_description_content = $value;
    }
    public function getCurrentLayoutForAction()
    {
        switch ($this->current_layout_type) {
            case Node::LAYOUT_INHERIT:
                if (!$this->parent) {
                    return $this->current_layout_content;
                } else {
                    return $this->parent->getCurrentLayoutForAction();
                }
            case Node::LAYOUT_CUSTOM:
                return $this->current_layout_content;
            default:
                throw new Exception('Unknown CurrentLayoutType value: ' . $this->current_layout_type);
        }
    }
    // function getCurrentLayoutForAction()
    // {
    // switch ($this->getCurrentLayoutType()) {
    // case self::LAYOUT_INHERIT:
    // // printf('%s -&gt; isRoot: %d<br />', $this->getTitle(), $this->isRoot());
    // if ($this->isRoot()) {
    // return $this->getCurrentLayout();
    // } else {
    // return $this->getParent()->getCurrentLayoutForAction();
    // }
    // case self::LAYOUT_CUSTOM:
    // return $this->getCurrentLayout();
    // // case self::LAYOUT_USE_CURRENT:
    // // return $this->getCurrentLayout();
    // default:
    // throw new Exception('Unknown CurrentLayoutType value: ' . $this->getCurrentLayoutType());
    // }
    // }
    protected function formatLayoutName($layoutIdentifier)
    {
        return explode('/', $layoutIdentifier);
    }

    function getCurrentLayoutNameForAction()
    {
        return $this->formatLayoutName($this->getCurrentLayoutForAction());
    }

	public function canViewContent()
	{
		list($perms_type, $credentials) = $this->getPermsData();
		switch ($perms_type) {
			case Node::PERMS_ALLOWED_TO_ANYBODY:
				return true;
			case Node::PERMS_RESTRICTED:
				$credentials = explode('|', $credentials);
				$sfUser = sfContext::getInstance()->getUser();
				// var_dump($credentials);exit;
				return $sfUser->hasCredential(CREDENTIAL_WEBMASTER) || $sfUser->hasCredential($credentials, false);
			default:
				return false;
		} // switch
	}
	public function canContentBeSeenByAnonymous()
	{
		list($perms_type, $credentials) = $this->getPermsData();
		return $perms_type == Node::PERMS_ALLOWED_TO_ANYBODY;
	}

    public function hasPendingDelete()
    {
        return $this->pending_delete;
    }

    public function setPendingDelete($value)
    {
        $this->pending_delete = $value;
    }

    public function getFirstChildByClass($class, $recursive = false)
    {
        if (count($this->children) == 0) {
            return null;
        }
        $node = $this->children[0];
        do {
			if ($node->getNodeClass() == $class) {
                return $node;
            }
			if($recursive && count($node->children)>0){
				$result = $node->getFirstChildByClass($class, $recursive);
				if(null != $result){
					return $result;
				}
			}
            $node = $node->nextSibling;
        } while ($node);
        return null;
    }

    function cacheChildrenPages()
    {
        $children_pages = array();
        foreach ($this->getChildren() as $child) {
            $children_pages[$child->getNodeClass()][] = $child->getId();
        }

        foreach ($children_pages as $node_class => $node_ids) {
            Catalyz::cachePageByNodeIdsAndClass($node_ids, $node_class);
        }
    }

    function getNumberOfDescendants()
    {
        $result = 0;
        foreach($this->children as $child) {
            $result += $child->getNumberOfDescendants() + 1 ;
        }
        return $result;
    }

    function getAvailableTranslations($force_locale_culture = false)
    {
        if (null == $this->getId()) {
            return array();
        }
        return $this->getNode()->getAvailableTranslations($force_locale_culture);
    }

    function getAll()
    {
        $result = $this->children;
        foreach($this->children as $child) {
            $result = array_merge($result, $child->getAll());
        }
        return $result;
    }

    function getBreadcrum($separator = ' > ', $truncate = false)
    {
        sfLoader::loadHelpers(array('Text'));
        $title = $this->getTitle();
        if ($truncate && 0 < $truncate) {
            $title = truncate_text($title, $truncate);
        }
        $result = $title;
        $parent = $this->parent;
        while ($parent && $parent->parent) {
            $title = $parent->getTitle();
            if ($truncate && 0 < $truncate) {
                $title = truncate_text($title, $truncate);
            }
            $result = $title . $separator . $result;
            $parent = $parent->parent;
        }
        return $result;
    }

    /**
     * ContentTreeNode::getPathToCacheFile()
     *
     * @param string $culture
     * @return string
     */
    public function getPathToCacheFile($culture = '')
    {
        return sprintf('%s/cache%s.html', sfConfig::get('sf_web_dir'), $this->getUrl($culture, false));
    }

    public function isTranslationAvailable($culture)
    {
        $translations = $this->getAvailableTranslations();
        return !empty($translations[$culture]);
    }

    /**
     * ContentTreeNode::setMenuTitle()
     *
     * @param mixed $node
     * @return
     */
    public function setMenuTitle($value)
    {
        $this->menu_title = $value;
    }

    function isChildOfNodeId($nodeId)
    {
        $result = false;
        $parent = $this->parent;
        while (!$result && $parent) {
            $result = $parent->getId() == $nodeId;
        	$parent = $parent->parent;
        }
        return $result;
    }
}

?>