<?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 );
  }
}