<?php
/**
 * An abstract class for general property objects.
 *
 * This class provides property objects smart getters and setters (like python).
 */
abstract class object
{
    ////////////////////////////////////////////////////////////////////////////
    // Construct and destruct functions.

    /**
     * @param array (optional) $property The properties.
     * @throws outofrangeexception If the property does not exist.
     */
    public function __construct(array $property = array())
    {
        foreach ($property as $k => $v)
        {
            if (!property_exists($this, $k))
            {
                throw new outofrangeexception('Property ' . $k . ' does not exist.');
            }
            
            $this->$k = $v;
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    // Overload functions.
    
    /**
     * Gets a property.
     * 
     * @param string $name The property name.
     * @throws outofrangeexception If the property does not exist.
     * @return mixed The value.
     */
    public function __get($name)
    {
        $function = 'get_' . $name;
        
        if (method_exists($this, $function))
        {
            return $this->$function();
        }
        
        if (!property_exists($this, $name))
        {
            throw new outofrangeexception('Property ' . $name . ' does not exist.');
        }
        
        return $this->$name;
    }
    
    /**
     * Sets a property.
     * 
     * @param string $name The property name.
     * @param mixed (optional) $value The value.
     * @throws outofrangeexception If the property does not exist.
     */
    public function __set($name, $value)
    {
        $function = 'set_' . $name;
        
        if (method_exists($this, $function))
        {
            $this->$function($value);
            return;
        }
        
        if (!property_exists($this, $name))
        {
            throw new outofrangeexception('Property ' . $name . ' does not exist.');
        }
        
        $this->$name = $value;
    }
    
    /**
     * Transforms the object into an associative array.
     *
     * @return array The array.
     */
    public function __toarray()
    {
        return get_object_vars($this);
    }
    
    ////////////////////////////////////////////////////////////////////////////
    // Interface functions.
    
    ////////////////////////////////////////////////////////////////////////////
    // Internal functions.
}
