#ifndef __INVERTCONTROLLER_H
#define __INVERTCONTROLLER_H

#include "abstractcontroller.h"
#include <stdlib.h>
#include <string.h>

/**
 * Abstract class (interface) for robot controller that use direct matrix inversion and
 * simple one layer networks.
 * 
 * Implements standart parameters: eps, rho, mu, stepnumber4avg, stepnumber4delay
 */
class InvertController : public AbstractController {
public:
  InvertController(){
     eps=0.3;
     rho=0.0; 
     s4delay=1;
     s4avg=1;
     delta=0.01;
     factor_a=1.0;
     desens=0.0; // name form desensitization
     number_it=0;
     epsilon_it= 0; 
     damping_c=0.0;
  }

  virtual paramval getParam(const paramkey& key) const{
    if(key == "eps") return eps; 
    else if(key == "rho") return rho; 
    else if(key == "desens") return desens;  	
    else if(key == "s4delay") return s4delay; 
    else if(key == "s4avg") return s4avg; 
    else if(key == "factor_a") return factor_a;     
    else if(key == "number_it") return number_it; 
    else if(key == "epsilon_it") return epsilon_it; 
    else if(key == "delta") return delta;             
    else if(key == "damping_c") return damping_c;             
    else  return AbstractController::getParam(key) ;
  }

  virtual bool setParam(const paramkey& key, paramval val){
    if(key == "eps") eps=val;
    else if(key == "rho") rho=val; 
    else if(key == "desens") desens=val;
    else if(key == "s4delay") s4delay=val; 
    else if(key == "s4avg") s4avg=val;
    else if(key == "factor_a") factor_a=val;
    else if(key == "number_it") number_it=val;
    else if(key == "epsilon_it") epsilon_it=val;
    else if(key == "delta") delta=val;                
    else if(key == "damping_c") damping_c=val;                
    else return AbstractController::setParam(key, val);
    //    else fprintf(stderr, "parameter %s unknown\n", key);
    return true;
  }

  virtual paramlist getParamList() const{
    paramlist list;
    list.push_back(pair<paramkey, paramval> ("eps", eps));
    list.push_back(pair<paramkey, paramval> ("rho", rho));
    list.push_back(pair<paramkey, paramval> ("desens", desens));
    list.push_back(pair<paramkey, paramval> ("s4delay", s4delay));
    list.push_back(pair<paramkey, paramval> ("s4avg", s4avg));
    list.push_back(pair<paramkey, paramval> ("factor_a", factor_a));
    list.push_back(pair<paramkey, paramval> ("number_it", number_it));
    list.push_back(pair<paramkey, paramval> ("epsilon_it", epsilon_it));
    list.push_back(pair<paramkey, paramval> ("delta", delta));
    list.push_back(pair<paramkey, paramval> ("damping_c", damping_c));

    return list;
  }

protected:
  paramval eps;
  paramval rho;
  paramval desens;
  paramval s4delay;
  paramval s4avg;
  paramval factor_a;
  paramval number_it;
  paramval epsilon_it;
  paramval delta;
  paramval damping_c;
 
};

#endif
