<?PHP

  require_once ('twIf/i18n.php');
  require_once ('twIf/object.php');
  require_once ('twIf/generic/multi.php');
  
  /**
   * Generic Classed Multi
   * ---------------------
   * Generic Interface to handle subclasses including a item-loader
   * 
   * @class twIf_Generic_Multi_Classed
   * @extends twIf_Generic_Multi
   * @package twIf
   * @revision 01
   * @author Bernd Holzmueller <bernd@tiggerswelt.net>
   **/
  class twIf_Generic_Multi_Classed extends twIf_Generic_Multi {
    private $Handle = null;
    
    // {{{ __construct
    /**
     * Create a new Interface to handle subclasses with an object assigned
     * 
     * @param array $URL
     * @param string $Base
     * 
     * @access friendly
     * @return void
     */
    function __construct ($URL, $Base, $urlMode = self::MODE_URL) {
      // Set our URL-Mode first
      $this->urlMode = $urlMode;
      
      // Try to load item from URL
      if (!is_object ($this->getItem ())) {
        // Set our base first
        $this->setBase ($Base);
        
        // Try to assign a subitem
        $this->probeItem ($URL);
      }
      
      // Inherit to our parent
      parent::__construct ($URL, $this->getBase (), $urlMode);
    }
    // }}}
    
    // {{{ probeItem
    /**
     * Check if the given URL contains an item and assign it
     * 
     * @param array $URL
     * @param string $Base (optional) Use this as URL-Base
     * @param bool $Force (optional) Force the check even if an item was already loaded
     * 
     * @access protected
     * @return bool
     **/
    protected function probeItem (&$URL, $Base = null, $Force = false) {
      // Lazy check
      if (!$Force && is_object ($this->getItem ()))
        return true;
      
      // Check if we have all neccessary informations
      if ($this->urlMode == self::MODE_URL) {
        if (!isset ($URL [0]) || ($URL [0] == ''))
          return false;
        
        $Key = $URL [0];
      } elseif (isset ($_GET ['twIfMultiClass' . $this->getInstanceID ()]))
        $Key = $_GET ['twIfMultiClass' . $this->getInstanceID ()];
      else
        return false;
      
      // Retrive Name of the class we handle
      if (!($Class = $this->getClass ()))
        return false;
      
      // Try to load the object
      if (!is_object ($Item = call_user_func (array ($Class, 'getInstance'), $Key, twIf_Object::FLAG_ID_MD5)))
        return false;
      
      // Set our base if neccessary
      if ($Base != '')
        $this->setBase ($Base);
      
      // Set the item
      $this->setItem ($Item);
      
      if ($this->urlMode == self::MODE_URL)
        $this->setBase ($this->getBase () . array_shift ($URL) . '/');
      else
        $this->setBase ($this->insertURLParameter ('twIfMultiClass' . $this->getInstanceID (), null, $this->getBase ()));
      
      return true;
    }
    // }}}
    
    // {{{ setItem
    /**
     * Go into editor-mode
     * 
     * @param object $Item
     *  
     * @access protected
     * @return bool
     **/
    protected function setItem ($Item) {
      if (!is_object ($Item))
        return false;
      
      $this->Handle= $Item;
      
      self::inheritItem ();
      
      return true;
    }  
    // }}}
       
    // {{{ getItem
    /**
     * Retrive the selected item
     * 
     * @access public
     * @return object
     */   
    public function getItem () {
      return $this->Handle;
    }  
    // }}}
    
    // {{{ haveItem
    /**
     * Check wheter we have an assigned item
     * 
     * @access public
     * @return bool
     **/
    public function haveItem () {
      return is_object ($this->Handle);
    }
    // }}}
    
    // {{{ getBase
    /**
     * Retrive currently assigned URL-Base
     * 
     * @param bool $includeItem (optional)
     * 
     * @access public
     * @return string
     **/
    public function getBase ($Minimal = false) {
      $Base = parent::getBase ();
      
      if ($this->urlMode !== self::MODE_URL)
        return $Base;
      
      if (!$this->haveItem () || !$Minimal)
        return $Base;
      
      return dirname ($Base) . '/';
    }
    // }}}
    
    // {{{ inheritItem
    /**
     * Inherit our item to our subclass if possible
     * 
     * @access private
     * @return void
     **/
    private function inheritItem () {
      // Check if we have an subitem and an assigned class
      if (!is_object ($this->Subclass) || !is_object ($this->Handle))
        return;
      
      // Try to use new API
      if (is_callable (array ($this->Subclass, 'setMultiItem')))
        $this->Subclass->setMultiItem ($this->Handle);
      
      // Fallback to old API (and give a warning
      elseif (is_callable (array ($this->Subclass, 'setItem'))) {
        trigger_error (twIf_i18n::getText ('The class %s does not specify a setMultiItem() but the deprecated setItem() interface', get_class ($this->Subclass)), E_USER_DEPRECATED);
        
        $this->Subclass->setItem ($this->Handle);
      }
    }
    // }}}
    
    // {{{ assignURLClass
    /**
     * Assign an URL to a given class
     * 
     * @param string $URL URL of subclass
     * @param string $Class Which class to use
     * @param string $onNavigation (optional) Link this class with this caption on navigation
     * @param bool $First (optional) Put the class in first place on navigation
     * @param array $URL (optional) Just assign the class if there is an item in this URL
     * @param string $Base (optional) Use this base
     * 
     * @access protected
     * @return bool
     **/
    protected function assignURLClass ($URL, $Class, $onNavigation = null, $First = false, &$cURL = false, $Base = null) {
      if (($cURL !== false) && is_array ($cURL) && !$this->probeItem ($cURL, $Base))
        return false;
      
      return parent::assignURLClass ($URL, $Class, $onNavigation, $First);
    }
    // }}}
    
    // {{{ loadSubclass  
    /**
     * Load a given subclass
     * 
     * @param string $Class Name of subclass
     * @param array $URL
     * @param string $Base
     * @param bool $Strip (optional, default) Strip first chunk of URL and take it as base
     * 
     * @access private
     * @return object
     */
    protected function loadSubclass ($Class, $URL, $Base, $Strip = true) {
      // Inherit to our parent first
      $rc = parent::loadSubclass ($Class, $URL, $Base, $Strip);
      
      // Inherit handle to our subclass
      self::inheritItem ();
      
      return $rc;
    }
    // }}}
    
    // {{{ generateSubclassLink
    /** 
     * Generate the link to a given subclass
     * 
     * @access protected
     * @return string
     **/
    public function generateSubclassLink ($Subclass, $ignoreEncoding = false, $Handle = null) {
      if (is_object ($Handle))
        $hID = md5 ($Handle->getID ());
      elseif ($Handle !== null)
        $hID = $Handle;
      else
        $hID = '';
      
      if ($this->urlMode == self::MODE_URL)
        return $this->getBase (true) . (strlen ($hID) > 0 ? $hID . '/' : '') .  (strlen ($Subclass) > 0 ? $Subclass . '/' : '');
      
      $URL = $this->insertURLParameter ('twIfMulti' . $this->getInstanceID (), $Subclass, $this->getBase (), $ignoreEncoding);
      
      if (strlen ($hID) > 0)
        return $this->insertURLParameter ('twIfMultiClass' . $this->getInstanceID (), $hID, $URL, $ignoreEncoding);
      
      return $URL;
    }    
    // }}}
  }

?>