<?php
/*
 * Core_Doctrine_Record_Sitemap
 *
 * @package    ##PACKAGE##
 * @subpackage ##SUBPACKAGE##
 * @author     web.burza <developers@burza.hr>
 * @version    SVN: $Id: Builder.php 7490 2010-03-29 19:53:27Z jwage $
 */
class Core_Doctrine_Model_Sitemap extends Base_Sitemap
{
    /**
     * Additional properties to merge with (i.e. language_id)
     *
     * @var array
     */
    protected $_properties  = array();


    public function insertAsFirstChildOf($entity)
    {
        if ($entity->id === $this->id) {
            throw new Exception('Error while inserting as first child, can not insert node to itself');
        }

        $this->_mergeProperties($entity, $this->_properties);
        $this->parent_id    = $entity->id;
        $this->getNode()->insertAsFirstChildOf($entity);
        $this->recreatePath();
    }

    public function insertAsLastChildOf($entity)
    {
        if ($entity->id === $this->id) {
            throw new Exception('Error while inserting as last child, can not insert node to itself');
        }

        $this->_mergeProperties($entity, $this->_properties);
        $this->parent_id    = $entity->id;
        $this->getNode()->insertAsLastChildOf($entity);
        $this->recreatePath();
    }

    public function insertAsNextSiblingOf($entity)
    {
        if ($entity->id === $this->id) {
            throw new Exception('Error while inserting as next sibling, can not insert node as its own sibling');
        }

        $this->_mergeProperties($entity, $this->_properties);
        $this->parent_id    = $entity->parent_id;
        $this->getNode()->insertAsNextSiblingOf($entity);
        $this->recreatePath();
    }

    public function insertAsPrevSiblingOf($entity)
    {
        if ($entity->id === $this->id) {
            throw new Exception('Error while inserting as prev sibling, can not insert node as its own sibling');
        }

        $this->_mergeProperties($entity, $this->_properties);
        $this->parent_id    = $entity->parent_id;
        $this->getNode()->insertAsPrevSiblingOf($entity);
        $this->recreatePath();
    }

    public function moveAsFirstChildOf($entity)
    {
        if ($entity->id === $this->id) {
            throw new Exception('Error while moving as first child, can not move node to itself');
        }

        $this->_mergeProperties($entity, $this->_properties);
        $this->parent_id    = $entity->id;
        $this->getNode()->moveAsFirstChildOf($entity);
        $this->recreatePath();
    }

    public function moveAsLastChildOf($entity)
    {
        if ($entity->id === $this->id) {
            throw new Exception('Error while moving as last child, can not move node to itself');
        }

        $this->_mergeProperties($entity, $this->_properties);
        $this->parent_id    = $entity->id;
        $this->getNode()->moveAsLastChildOf($entity);
        $this->recreatePath();
    }

    public function moveAsNextSiblingOf($entity)
    {
        if ($entity->id === $this->id) {
            throw new Exception('Error while moving as next sibling, can not move node as its own sibling');
        }

        $this->_mergeProperties($entity, $this->_properties);
        $this->parent_id    = $entity->parent_id;
        $this->getNode()->moveAsNextSiblingOf($entity);
        $this->recreatePath();
    }

    public function moveAsPrevSiblingOf($entity)
    {
        if ($entity->id === $this->id) {
            throw new Exception('Error while moving as prev sibling, can not move node as its own sibling');
        }

        $this->_mergeProperties($entity, $this->_properties);
        $this->parent_id    = $entity->parent_id;
        $this->getNode()->moveAsPrevSiblingOf($entity);
        $this->recreatePath();
    }

    public function preSave($event)
    {
        $this->slug = Doctrine_Inflector::urlize($this->title);
        $this->path = $this->_createPath();

        if (is_array($this->layout_data)) {
            $this->layout_data = json_encode($this->layout_data);
        }
    }

    public function recreatePath()
    {
        $this->path = $this->_createPath();

        $children = $this->getNode()->getChildren();
        if ($children) {
            foreach ($children as $child) {
                // Force path update
                $child->path = null;
                $child->save();
            }
        }
    }

    protected function _createPath()
    {
        if ($this->parent_id > 0) {
            $parentCategory = $this->getTable()->find($this->parent_id);
        } else {
            return '';
        }

        // If parent category is root (level 0), don't take that path into
        // consideration
        if ($parentCategory && $parentCategory->level > 0) {
            $path = $parentCategory->path;
        } else {
            $path = '';
        }

        if (!strlen($this->slug)) {
            $this->slug = Doctrine_Inflector::urlize($this->title);
        }

        return trim($path .'/'. $this->slug, '/');
    }

    /**
     * Merge additional properties with entity
     * - i.e. language_id
     *
     * @param type $entity
     * @param array $properties
     */
    protected function _mergeProperties($entity, array $properties)
    {
        foreach ($properties as $property) {
            $this->{$property}  = $entity->{$property};
        }
    }
}
