<?php
/**
 * Menu Item
 *
 * @author Elze Kool <info@visualmedia.nl>
 */

namespace VisualM\ManagementBundle\Menu;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

/**
 * Menu Item
 *
 * @author Elze Kool <info@visualmedia.nl>
 */
class MenuItem implements MenuItemInterface
{
    /**
     * Title
     * @var string
     */
    private $title;

    /**
     * Icon class (is put in an <i> element)
     * @var string
     */
    private $iconClass;

    /**
     * Link
     * @var string
     */
    private $link;

    /**
     * Open
     * @var boolean
     */
    private $open = false;

    /**
     * Regular expression that is used on the active route to check if the
     * item is active
     * @var string
     */
    private $activeRouteRegex;

    /**
     * Required permission, if empty no permission is needed
     * @var string
     */
    private $requiredPermission;

    /**
     * Children elements
     * @var array
     */
    private $children = [];

    /**
     * Priorty
     * @var string
     */
    private $priority = 0;

    /**
     * Children need sorting
     * @var bool
     */
    private $childrenNeedSort = false;

    /**
     * JS
     * @var string
     */
    private $js = null;

    /**
     * {@inheritdoc}
     **/
    public function getTitle()
    {
        return $this->title;
    }

    /**
     * {@inheritdoc}
     **/
    public function getIconClass()
    {
        return $this->iconClass;
    }

    /**
     * {@inheritdoc}
     **/
    public function getLink()
    {
        return $this->link;
    }

    /**
     * {@inheritdoc}
     **/
    public function getChildren()
    {
        if ($this->childrenNeedSort) {
            usort($this->children, function($a, $b) {
                $prioA = $a->getPriority();
                $prioB = $b->getPriority();
                if ($prioA == $prioB) {
                    $prioA = 0 - array_search($a, $this->children);
                    $prioB = 0 - array_search($b, $this->children);
                }
                return $prioB - $prioA;
            });
            $this->childrenNeedSort = false;
        }


        return $this->children;
    }

    /**
     * {@inheritdoc}
     **/
    public function isActive(Request $request = null)
    {
        if (empty($this->activeRouteRegex)) {
            foreach($this->getChildren() as $child) {
                if ($child->isActive($request)) {
                    return true;
                }
            }
            return false;
        }

        if ($request === null) {
            return false;
        }

        $route = $request->attributes->get('_route');
        if (preg_match($this->activeRouteRegex, $route) == 0) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * {@inheritdoc}
     **/
    public function isAllowedToDisplay(Request $request, AuthorizationCheckerInterface $authChecker = null)
    {
        if (empty($this->requiredPermission)) {
            return true;
        } else if ($authChecker === null) {
            return false;
        } else {
            return $authChecker->isGranted($this->requiredPermission);
        }
    }

    /**
     * Set Title
     *
     * @param string $title Title
     **/
    public function setTitle($title)
    {
        $this->title = $title;
    }

    /**
     * Set IconClass
     *
     * @param string $iconClass IconClass
     **/
    public function setIconClass($iconClass)
    {
        $this->iconClass = $iconClass;
    }

    /**
     * Set Link
     *
     * @param string $link Link
     **/
    public function setLink($link)
    {
        $this->link = $link;
    }

    /**
     * Get Active Route Regex
     *
     * @return string Active Route Regex
     **/
    public function getActiveRouteRegex()
    {
        return $this->activeRouteRegex;
    }

    /**
     * Set Active Route Regex
     *
     * @param string $activeRouteRegex Active Route Regex
     **/
    public function setActiveRouteRegex($activeRouteRegex)
    {
        $this->activeRouteRegex = $activeRouteRegex;
    }

    /**
     * Get Required Permission
     *
     * @return string Required Permission
     **/
    public function getRequiredPermission()
    {
        return $this->requiredPermission;
    }

    /**
     * Set Required Permission
     *
     * @param string $requiredPermission Required Permission
     **/
    public function setRequiredPermission($requiredPermission)
    {
        $this->requiredPermission = $requiredPermission;
    }

    /**
     * Add Child Item
     *
     * @param MenuItemInterface $menuItem Item
     */
    public function addChild(MenuItemInterface $menuItem)
    {
        $this->children[] = $menuItem;
        $this->childrenNeedSort = true;
    }

    /**
     * Get Priority
     *
     * @return int Priority
     **/
    public function getPriority()
    {
        return $this->priority;
    }

    /**
     * Set Priority
     *
     * @param int $priority Priority
     **/
    public function setPriority($priority)
    {
        $this->priority = $priority;
    }

    /**
     * {@inheritdoc}
     **/
    public function getOpen()
    {
        return $this->open;
    }

    /**
     * Set Open
     *
     * @param string $open Open
     **/
    public function setOpen($open)
    {
        $this->open = $open;
    }

    /**
     * Get Js
     **/
    public function getJs()
    {
        return $this->js;
    }

    /**
     * Set Js
     *
     * @param string $js js
     **/
    public function setJs($js)
    {
        $this->js = $js;
    }

}
