<?php
/**
* Web Application Component Toolkit
*
* @link http://www.phpwact.org/
*
* @author Wact Development Team
* @link http://www.phpwact.org/team
*
* @copyright Copyright 2006, Jeff Moore
* @license http://opensource.org/licenses/mit-license.php MIT
*/

/**
* A Wact_Request_Compound allows Parameters to be grouped and handled as a unit.
*/
class Wact_Request_Compound extends Wact_Request_Parameter implements ArrayAccess {

    /**
    * Child parameters.
    */
    protected $parameters = array();

    /**
    * Add a parameter to this Compound Parameter.
    */
    function addParameter($parameter) {
        $parameter->_setParent($this);
        $name = $parameter->getName();
        $this->parameters[$name] = $parameter;
    }

    /**
    */
    function getRawValue() {
        // SHould we return a structured representation of all the component parameters?
        die('UNIMPLEMENTED');
    }

    /**
    */
    function hasValue() {
        // What does it mean to say that a compound parameter has a value?
        die('UNIMPLEMENTED');
    }

    /**
    * Copy our child parameters into the model.
    */
    function copyToModel($model) {
        foreach ($this->parameters as $parameter) {
            $parameter->copyToModel($model);
        }
    }

    /**
    * Determine the value of a given property.  If the property is not declared, raise an
    * exception.
    */
    public function __get($name) {
        if (isset($this->parameters[$name])) {
            return $this->parameters[$name]->getValue();
        } else {
            throw new Wact_Property_Exception_PropertyNotFound($name);
        }
    }

    /**
    * Determine if a parameter has been defined and has a non-null value.
    */
    public function __isset($name) {
        if (isset($this->parameters[$name])) {
            $value = $this->parameters[$name]->getValue();
            // Emulate standard PHP behavior
            return isset($value);
        } else {
            // Parameters that do not exist cannot have a value.
            return FALSE;
        }
    }

    /**
    * This operation has no meaning for a parameter object
    */
    public function __set($name, $value) {
        throw new Wact_Request_Exception('Parameter value cannot be set for "{Parameter}"', $name);
    }

    /**
    * This operation has no meaning for a parameter object.
    */
    public function __unset($name) {
        throw new Wact_Request_Exception('Parameter value cannot be unset for "{Parameter}"', $name);
    }

    /**
    * implements ArrayAccess::offsetExists()
    */
    public function offsetExists($offset) {
        return isset($this->parameters[$offset]);
    }

    /**
    * implements ArrayAccess::offsetGet()
    */
    public function offsetGet($offset) {
        if (isset($this->parameters[$offset])) {
            return $this->parameters[$offset];
        } else {
            throw new Wact_Request_Exception('Parameter "{Parameter}" not found', $offset);
        }
    }

    /**
    * implements ArrayAccess::offsetSet()
    */
    public function offsetSet($offset, $value) {
        return $this->addParameter($value, $offset);
    }

    /**
    * implements ArrayAccess::offsetUnset()
    */
    public function offsetUnset($offset) {
        throw new Wact_Request_Exception('Parameters cannot be removed once defined');
    }

}

?>