#ifndef __JLANG__JABSTRACTOBJECTREADER__
#define __JLANG__JABSTRACTOBJECTREADER__

#include "JLang/JObjectIterator.hh"


/**
 * \author mdejong
 */

namespace JLANG {}
namespace JPP { using namespace JLANG; }

namespace JLANG {

  /**
   * Abstract interface for object reading.
   *
   * This class implements the JObjectIterator interface by transferring
   * the interface methods to a helper object via a single interface method getHelper().
   */
  template<class T>
  struct JAbstractObjectReader :
    public virtual JObjectIterator<T>
  {

    typedef typename JObjectIterator<T>::pointer_type  pointer_type;

    
    /**
     * Get helper.
     *
     * \return            pointer to helper
     */
    virtual JObjectIterator<T>* getHelper() const = 0;
    

    /**
     * Check availability of next element.
     *
     * \return            true if the iteration has more elements; else false
     */
    virtual bool hasNext() override 
    {
      return (this->getHelper() != NULL && this->getHelper()->hasNext());
    }


    /**
     * Get next element.
     *
     * \return            pointer to element
     */
    virtual const pointer_type& next() override 
    {
      if (this->getHelper() != NULL)
	return this->getHelper()->next();
      else
	return ps;
    }


    /**
     * Skip items.
     *
     * \param  ns         number of items to skip
     * \return            number of items skipped
     */
    virtual skip_type skip(const skip_type ns) override 
    {
      if (this->getHelper() != NULL)
	return this->getHelper()->skip(ns);
      else
	return 0;
    } 

  private:
    pointer_type ps;
  };


  /**
   * Abstract interface for object reading with rewinding.
   *
   * This class implements the JRewindableObjectIterator interface by transferring
   * the interface methods to a helper object via a single interface method getHelper().
   */
  template<class T>
  struct JAbstractRewindableObjectReader :
    public virtual JRewindableObjectIterator<T>,
    public JAbstractObjectReader            <T>
  {
    /**
     * Get helper.
     *
     * \return            pointer to helper
     */
    virtual JRewindableObjectIterator<T>* getHelper() const = 0;


    /**
     * Rewind.
     */
    virtual void rewind() override 
    {
      if (this->getHelper() != NULL) {
	this->getHelper()->rewind();
      }
    }
  };


  /**
   * Abstract interface for object reading with named access.
   *
   * This class implements the JAccessibleObjectIterator interface by transferring
   * the interface methods to a helper object via a single interface method getHelper().
   */
  template<class T>
  struct JAbstractAccessibleObjectReader :
    public virtual JAccessibleObjectIterator<T>,
    public JAbstractObjectReader            <T>
  {
    /**
     * Get helper.
     *
     * \return            pointer to helper
     */
    virtual JAccessibleObjectIterator<T>* getHelper() const = 0;


    /**
     * Check is device is open.
     *
     * \return            true if open; else false
     */
    virtual bool is_open() const override 
    {
      if (this->getHelper() != NULL)
	return this->getHelper()->is_open();
      else
	return false;
    }


    /**
     * Open device.
     *
     * \param  file_name  file name
     */
    virtual void open(const char* file_name) override 
    {
      if (this->getHelper() != NULL) {
	this->getHelper()->open(file_name);
      }
    }


    /**
     * Close device.
     */
    virtual void close() override 
    {
      if (this->getHelper() != NULL) {
	this->getHelper()->close();
      }
    }
  };
}

#endif