<?php
/**
 * ProxyComponent class file.
 *
 * @author Sergey Malyshev <malyshev.php@gmail.com>
 */

/**
 * ProxyComponent represents an ...
 *
 * Description of ProxyComponent
 *
 * @author Sergey Malyshev <malyshev.php@gmail.com>
 * @version $Id$
 * @package
 * @since 1.1.7
 */
class ProxyComponent extends CComponent
{

    private $_instance;

    private $_isProxy;

    protected $abstract = array();

    public function init()
    {
    }

    public function getIsProxy()
    {
        if (null === $this->_isProxy)
        {
            $this->_isProxy = (null !== $this->_instance && !($this->_instance instanceof $this));
        }
        return $this->_isProxy;
    }

    public function setInstance($value)
    {
        if (null === $this->_instance && false !== is_object($value))
        {
            $this->abstract = array_merge($this->abstract, get_object_vars($value));
            $this->_instance = $value;
        }
    }

    public function getInstance()
    {
        return $this->_instance;
    }

    public function  __call($name, $parameters)
    {
        if (false !== $this->getIsProxy() && false !== method_exists($this->_instance, $name))
        {
            return call_user_func_array(array($this->_instance, $name), $parameters);
        }

        return parent::__call($name, $parameters);
    }

    public function  __set($name, $value)
    {
        $setter='set'.$name;
        if (false !== method_exists($this, $setter))
        {
            return call_user_func_array(array($this, $setter), array($value));
        }
        else if (false !== property_exists($this, $name))
        {
            return $this->$name = $value;
        }
        else if (false !== $this->getIsProxy() && false !== method_exists($this->_instance, $setter))
        {
            return call_user_func_array(array($this->_instance, $setter), array($value));
        }
        else if (false !== $this->getIsProxy() && false !== property_exists($this->_instance, $name))
        {
            return $this->_instance->$name = $value;
        }
        else if (false === $this->getIsProxy() && false !== array_key_exists ($name, $this->abstract))
        {
            return $this->abstract[$name] = $value;
        }

        return parent::__set($name, $value);
    }

    public function  __get($name)
    {
        $getter='get'.$name;

        if (false !== method_exists($this, $getter))
        {
            return call_user_func(array($this, $getter));
        }
        else if (false !== property_exists($this, $name))
        {
            return $this->$name;
        }
        else if (false !== $this->getIsProxy() && false !== method_exists($this->_instance, $getter))
        {
            return call_user_func(array($this->_instance, $getter));
        }
        else if (false !== $this->getIsProxy() && false !== property_exists($this->_instance, $name))
        {
            return $this->_instance->$name;
        }
        else if (false === $this->getIsProxy() && false !== array_key_exists ($name, $this->abstract))
        {
            return $this->abstract[$name];
        }

        return parent::__get($name);
    }
}