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

/**
 * @category  Core
 * @package   Core_Form
 * @copyright Copyright (c) 2011. Burza d.o.o. (http://web.burza.hr/en/)
 * @license   proprietary
 */
class Core_Form_Group_Display extends Core_Form_Group_Abstract
{
    /**
     * @var boolean
     */
    protected $_ignored = true;
    
    /**
     * @var boolean
     */
    protected $_escalateErrors = true;
    
    /**
     * @var string
     */
    protected $_macro = 'display_group';
    
    /**
     * @var array
     */
    protected $_managedGroups = array();
    
    /**
     * @var array
     */
    protected $_managedElements = array();
    
    /**
     * @param Zend_Config|array $options
     *
     * @return void
     */
    public function __construct($options = null)
    {
        if (is_array($options)) {
            $this->setOptions($options);
        } elseif ($options instanceof Zend_Config) {
            $this->setConfig($options);
        }
    }
    
    /**
     * @return Core_Form_Group_Interface
     */
    public function getParent()
    {
        $parent = parent::getParent();
        if (null === $parent) {
            throw new RuntimeException('Failed fetching display group parent, none set');
        }
        return $parent;
    }
    
    /**
     * @param Core_Plugin_Manager $pluginManager
     * 
     * @return Core_Form_Group_Display
     */
    public function setPluginManager(Core_Plugin_Manager $pluginManager)
    {
        $this->getParent()->setPluginManager($pluginManager);
        return $this;
    }
    
    /**
     * @return Core_Plugin_Manager
     */
    public function getPluginManager()
    {
        return $this->getParent()->getPluginManager();
    }
    
    /**
     * @param array $groups
     * 
     * @return \Core_Form_Group_Display
     * @throws InvalidArgumentException
     */
    public function addGroups(array $groups)
    {
        foreach($groups as $name => $group) {
            if ($group instanceof Core_Form_Group_Interface) {
                $this->addGroup($group);
            } else if (is_array($group)) {
                $type = $group['type'];
                unset($group['type']);
                
                $options = array('owner' => $this->getParent());
                if (array_key_exists('options', $group)) {
                    $options += $group['options'];
                }
                $this->createGroup($type, $name, $options);
            } else {
                $message = sprintf('Failed adding group %s, not an instance of Core_Form_Group_Interface or array', $name);
                throw new InvalidArgumentException($message);
            }
        }
        return $this;
    }
    
    /**
     * @param string $type    Group type
     * @param string $name    Group name
     * @param array  $options Group options
     * 
     * @return Core_Form_Group_Interface
     */
    public function createGroup($type, $name, array $options = null)
    {
        $options = (array) $options + array('__autoAdd' => false);
        $group   = $this->getPluginManager()
            ->createPlugin('Core_Form_Group_Interface', $type, $name, $options);
        
        $this->addGroup($group);
        return $group;
    }

    /**
     * @param Core_Form_Group_Interface $group
     * 
     * @return \Core_Form_Group_Display
     */
    public function addGroup(Core_Form_Group_Interface $group)
    {
        $this->getPluginManager()->addPlugin('Core_Form_Group_Interface', $group, false);
        $normalizedName                        = strtolower($group->getName());
        $this->_managedGroups[$normalizedName] = true;
        return $this;
    }
    
    /**
     * @return array(Core_Form_Group_Interface)
     */
    public function getGroups()
    {
        return $this->getPluginManager()
                ->getPlugins('Core_Form_Group_Interface', array_keys($this->_managedGroups));
    }
    
    /**
     * @param string $name
     * 
     * @return \Core_Form_Group_Display
     */
    public function removeGroup($name)
    {
        $this->getPluginManager()->removePlugin('Core_Form_Group_Interface', $name);
        $normalizedName = strtolower($name);
        if (isset($this->_managedGroups[$normalizedName])) {
            unset($this->_managedGroups[$normalizedName]);
        }
        return $this;
    }
    
    /**
     * @param array $elements
     * 
     * @return \Core_Form_Group_Display
     * @throws InvalidArgumentException
     */
    public function addElements(array $elements)
    {
        foreach($elements as $name => $element) {
            if ($element instanceof Core_Form_Element_Interface) {
                $this->addElement($element);
            } else if (is_array($element)) {
                $type = $element['type'];
                unset($element['type']);
                
                $options = array('owner' => $this->getParent());
                if (array_key_exists('options', $element)) {
                    $options += $element['options'];
                }
                $this->createElement($type, $name, $options);
            } else {
                $message = sprintf('Failed adding element %s, not an instance of Core_Form_Element_Interface or array', $name);
                throw new InvalidArgumentException($message);
            }
        }
        return $this;
    }
    
    /**
     * @param string $type    Element type
     * @param string $name    Element name
     * @param array  $options Element options
     * 
     * @return Core_Form_Element_Interface
     */
    public function createElement($type, $name, array $options = null)
    {
        $options = (array) $options + array('__autoAdd' => false);
        $element = $this->getPluginManager()
            ->createPlugin('Core_Form_Element_Interface', $type, $name, $options);
        
        $this->addElement($element);
        return $element;
    }
    
    /**
     * @param Core_Form_Element_Interface $element
     * 
     * @return \Core_Form_Group_Display
     */
    public function addElement(Core_Form_Element_Interface $element)
    {
        $this->getPluginManager()->addPlugin('Core_Form_Element_Interface', $element, false);
        $normalizedName                           = strtolower($element->getName());
        $this->_managedElements[$normalizedName] = true;
        return $this;
    }
    
    /**
     * @param string $name
     * 
     * @return \Core_Form_Group_Display
     */
    public function removeElement($name)
    {
        $this->getPluginManager()->removePlugin('Core_Form_Element_Interface', $name);
        $normalizedName = strtolower($name);
        if (isset($this->_managedElements[$normalizedName])) {
            unset($this->_managedElements[$normalizedName]);
        }
        return $this;
    }
    
    /**
     * @return string
     */
    public function getElements()
    {        
        return $this->getPluginManager()
            ->getPlugins('Core_Form_Element_Interface', array_keys($this->_managedElements));
    }
    
    /**
     * @return void
     */
    public function __clone()
    {
        $this->setPrototype(false);
    }
}
