<?php

  /**
   * Search item implementation
   * 
   * @package angie.frameworks.search
   * @subpackage subpackage
   */
  abstract class ISearchItemImplementation {
  
    /**
     * Parent object
     *
     * @var ISearchItem
     */
    protected $object;
    
    /**
     * Construct search item implementation
     * 
     * @param ISearchItem $object
     */
    function __construct(ISearchItem $object) {
      if($object instanceof ISearchItem) {
        $this->object = $object;
      } else {
        throw new InvalidInstanceError('object', $object, 'ISearchItem');
      } // if
    } // __construct
    
    /**
     * Return list of indices that index parent object
     * 
     * Result is an array where key is the index name, while value is list of 
     * fields that's watched for changes
     * 
     * @return array
     */
    abstract function getIndices();
    
    /**
     * Return item context for given index
     * 
     * @param SearchIndex $index
     * @return string
     */
    function getContext(SearchIndex $index) {
      if($this->object instanceof IObjectContext) {
        return $this->object->getObjectContextDomain() . ':' . $this->object->getObjectContextPath();
      } else {
        throw new InvalidInstanceError('$this->object', $this->object, 'IObjectContext');
      } // if
    } // getContext
    
    /**
     * Return additional properties for a given index
     * 
     * @param SearchIndex $index
     * @return mixed
     */
    function getAdditional(SearchIndex $index) {
      return null;
    } // getAdditional
    
    // ---------------------------------------------------
    //  Management
    // ---------------------------------------------------
    
    /**
     * Create records in search indices
     */
    function create() {
      foreach($this->getIndices() as $index => $fields) {
        Search::set($index, $this->object);
      } // foreach
    } // create
    
    /**
     * Update indices on parent update
     * 
     * @param array $modifications
     * @param boolean $force
     */
    function update($modifications = null, $force = false) {
      if($modifications && count($modifications)) {
        foreach($this->getIndices() as $index => $fields) {
          foreach($modifications as $k => $v) {
            if(in_array($k, $fields)) {
              Search::set($index, $this->object);
              break;
            } // if
          } // foreach
        } // foreach
      } // if
    } // update
    
    /**
     * Remove related records from indices
     */
    function clear() {
      foreach($this->getIndices() as $index => $fields) {
        Search::remove($index, $this->object);
      } // foreach
    } // clear
    
  }