/***************************************************************************
 *   Copyright (C) 2005 by Robot Group Leipzig                             *
 *    martius@informatik.uni-leipzig.de                                    *
 *    fhesse@informatik.uni-leipzig.de                                     *
 *    der@informatik.uni-leipzig.de                                        *
 *    guettler@informatik.uni-leipzig.de                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 *                                                                         *
 *   $Log: measureadapter.h,v $
 *   Revision 1.2  2008/04/17 14:54:45  martius
 *   randomGen added, which is a random generator with long period and an
 *    internal state. Each Agent has an instance and passed it to the controller
 *    and the wiring. This is good for
 *   a) repeatability on agent basis,
 *   b) parallel execution as done in ode_robots
 *
 *   Revision 1.1  2008/01/17 10:04:04  der
 *   first version
 *
 *
 *                                                                         *
 ***************************************************************************/
#ifndef __MEASUREADAPTER_H
#define __MEASUREADAPTER_H

#include "abstractcontrolleradapter.h"
#include "statistictools.h"
#include "complexmeasure.h"

// begin forward declaration
// end forward declaration

/**
 * This is a passive controller adapter who is passive and can handle AbstractMeasures.
 * Normally the sensor and/or motor values are measured.
 * @see AbstractControllerAdapter
 */
class MeasureAdapter : public AbstractControllerAdapter
{

public:

  /**
   * Constructs the MeasureAdapter.
   *
   */
  MeasureAdapter(AbstractController* controller);

  virtual ~MeasureAdapter();

  /**
   * Adds a ComplexMeasure for measuring sensor values. For each
   * sensor a ComplexMeasure is created.
   */
  virtual std::list<ComplexMeasure*> addSensorComplexMeasure(char* measureName, ComplexMeasureMode mode,int numberBins, int stepSize);

  /****************************************************************************/
  /*	BEGIN methods of AbstractController                                 */
  /****************************************************************************/

  /** initialisation of the controller with the given sensor/ motornumber
  * Must NORMALLY be called before use. For all ControllerAdapters
  * call first AbstractControllerAdapter::init(sensornumber,motornumber)
  * if you overwrite this method
  */
  virtual void init(int sensornumber, int motornumber, RandGen* randGen = 0);

  /** performs one step (includes learning).
      Calculates motor commands from sensor inputs.
  @param sensors sensors inputs scaled to [-1,1]
  @param sensornumber length of the sensor array
  @param motors motors outputs. MUST have enough space for motor values!
  @param motornumber length of the provided motor array
  */
  virtual void step(const sensor* sensors, int sensornumber,
                    motor* motors, int motornumber);

  /** performs one step without learning.
  @see step
  */
  virtual void stepNoLearning(const sensor* sensors , int sensornumber,
                              motor* motors, int motornumber);

  /****************************************************************************/
  /*	END methods of AbstractController                                 	    */
  /****************************************************************************/

  /****************************************************************************/
  /*	BEGIN methods of Storeable                                           	*/
  /****************************************************************************/
  
  /** stores the object to the given file stream (binary).
  */
  virtual bool store(FILE* f) const;
  
  /** loads the object from the given file stream (binary).
  */
  virtual bool restore(FILE* f);
  
  /****************************************************************************/
  /*	END methods of Storeable                                          	    */
  /****************************************************************************/

  /****************************************************************************/
  /*	BEGIN methods of Inspectable                                          	*/
  /****************************************************************************/

  /** The list of the names of all internal parameters given by getInternalParams().
      The naming convention is "v[i]" for vectors
       and "A[i][j]" for matrices, where i, j start at 0.
  @return: list of keys
   */
  virtual iparamkeylist getInternalParamNames() const;

  /** @return: list of values
  */
  virtual iparamvallist getInternalParams() const;

  /****************************************************************************/
  /*	END methods of Inspectable                                       	    */
  /****************************************************************************/



protected:
  StatisticTools* st;
  bool initialized;
  motor* motorValues;
  sensor* sensorValues;

};

#endif
