<?php
/**
 * core.framework
 *
 * @category  Core
 * @package   Core_Controller
 * @copyright Copyright (c) 2011. Burza d.o.o. (http://web.burza.hr/en/)
 * @license   proprietary
 */

/**
 * @category  Core
 * @package   Core_Controller
 * @copyright Copyright (c) 2011. Burza d.o.o. (http://web.burza.hr/en/)
 * @license   proprietary
 * @property  Core_Application $app
 * @property  Core_Config      $config
 * @property  Core_Request     $request
 * @property  Core_Response    $response
 * @property  Core_Router      $router
 * @property  Core_Session     $session
 * @property  Core_User        $user
 */
abstract class Core_Controller_Abstract implements Core_Controller_Interface, Core_Security_Resource_Interface
{
    /**
     * @var Core_Dispatcher_Location_Interface
     */
    protected $_location;

    /**
     * @var Core_Module_ResourceFinder
     */
    protected $_resourceFinder;

    /**
     * @var string
     */
    protected $_securityResource;

    /**
     * @param Core_Module_ResourceFinder $resourceFinder
     *
     * @return Core_Controller_Abstract
     */
    public function setResourceFinder(Core_Module_ResourceFinder $resourceFinder)
    {
        $this->_resourceFinder = $resourceFinder;
        return $this;
    }

    /**
     * @return Core_Module_ResourceFinder
     */
    public function getResourceFinder()
    {
        if (null === $this->_resourceFinder) {
            $this->setResourceFinder(Core_Application::get('ResourceFinder'));
        }
        return $this->_resourceFinder;
    }

    /**
     * @param Core_Dispatcher_Location_Interface $location
     *
     * @throws InvalidArgumentException
     * @return mixed
     */
    public function invoke(Core_Dispatcher_Location_Interface $location)
    {
        $finder   = $this->getResourceFinder();
        $action   = $finder->findControllerAction($location);
        $callable = array($this, $action);
        if (!is_callable($callable)) {
            throw new InvalidArgumentException(sprintf('Unable to invoke controller action %s::%s(), not found', get_class($this), $action));
        }
        $this->_location = $location;
        return call_user_func($callable);
    }
    
    /**
     * @return Core_Security_Resource_Interface
     */
    public function getSecurityResource()
    {
        return $this->_securityResource;
    }

    /**
     * @return Core_Dispatcher_Location_Interface
     */
    public function getLocation()
    {
        return $this->_location;
    }

    /**
     * Proxy to Core_Application::get()
     *
     * @param string $name
     *
     * @return mixed
     */
    public function __get($name)
    {
        return Core_Application::get($name);
    }
}
