#ifndef carcontrolImpl_h
#define carcontrolImpl_h

#ifndef __cplusplus
#error This is a C++ include file and cannot be used from plain C
#endif

#include <baciCharacteristicComponentImpl.h>
#include <baciROdouble.h>
#include <baciRWdouble.h>

#include <baciSmartPropertyPointer.h>

#include <carcontrolS.h>
// #include "hptPadC.h"

using namespace baci;


class CarControlImpl;

class SpeedControlThread :public ACS::Thread
{
  public:
    SpeedControlThread(const ACE_CString& name, 
		  CarControlImpl *car_p, 
		  bool suspended=false,
		  const ACS::TimeInterval& responseTime=ThreadBase::defaultResponseTime, 
			  const ACS::TimeInterval& sleepTime=ThreadBase::defaultSleepTime);
    ~SpeedControlThread();

    virtual void runLoop();

  protected:
    CarControlImpl *m_car_p;
};

class OnCBvoid: public virtual POA_ACS::CBvoid
{   
  public:

    OnCBvoid(ACE_CString _ref) :
	ref(_ref),
	cb(_this())
	{ };

    ~OnCBvoid() {};

    void OnCBvoid::working (const ACSErr::Completion &c, const ACS::CBDescOut &desc) 
	throw (CORBA::SystemException)
        { 
	    ACS_SHORT_LOG ((LM_INFO, "%s::CBvoid::working", ref.c_str())); 
	};
    void OnCBvoid::done (const ACSErr::Completion &c, const ACS::CBDescOut &desc)
	throw (CORBA::SystemException)
	{
	    ACS_SHORT_LOG ((LM_INFO, "%s::CBvoid::done", ref.c_str()));
	};

    CORBA::Boolean 
    negotiate (ACS::TimeInterval time_to_transmit, const ACS::CBDescOut &desc) 
	throw (CORBA::SystemException)
	{
	    return true;
	};

    ACS::CBvoid_ptr getCb()
	{
	    return cb._retn();
	};

  protected:

    ACE_CString     ref;
    ACS::CBvoid_var cb;
};

class CarControlImpl: public virtual CharacteristicComponentImpl,
		      public virtual POA_TESTIDL_CAR::CarControl
{
  public:
    CarControlImpl(const ACE_CString &name, maci::ContainerServices *containerServices);
    
    virtual ~CarControlImpl();
    
    virtual void accelerate (CORBA::Double pressure)
	throw (CORBA::SystemException);
    virtual void brake (CORBA::Boolean on)
	throw (CORBA::SystemException);

    virtual void execute()
	throw (acsErrTypeLifeCycle::LifeCycleExImpl);
    virtual void cleanUp()
	throw (acsErrTypeLifeCycle::LifeCycleExImpl);

    virtual ACS::RWdouble_ptr 
    setSpeed ()
	throw (CORBA::SystemException);

    virtual ACS::ROdouble_ptr 
    actSpeed ()
	throw (CORBA::SystemException);

    virtual ACS::RWdouble_ptr 
    pressure ()
	throw (CORBA::SystemException);

  private:
    void operator=(const CarControlImpl&);

    SmartPropertyPointer<RWdouble> m_setSpeed_sp;
    SmartPropertyPointer<ROdouble> m_actSpeed_sp;
    SmartPropertyPointer<RWdouble> m_pressure_sp;

    friend class SpeedControlThread;

    /**
     *  The Joystick used to operate the car.
     */
//    hptPad::Pad_var m_pad_p;
    OnCBvoid        onCallback;
};

#endif /*!carcontrolImpl_H*/