#ifndef _MOTORFACTORY_H_
#define _MOTORFACTORY_H_
class CMotorBase;
class CMtrProfile;
class CMotionControllerBase;
#ifdef  BUILD_IODLL
#define     IODLLCLASS  __declspec(dllexport)
#else
#define     IODLLCLASS  __declspec(dllimport)
#endif

class IODLLCLASS CAbstractMotorFactory
{
private:
    int m_cardType;
public:
    CAbstractMotorFactory(int index);
    virtual ~CAbstractMotorFactory();
    virtual CMotorBase *CreateMotor(const CMtrProfile &MtrProfile, double *dpPos, CMotionControllerBase *pBaseController) = 0;
};

/**
 * @class   CMotorFactory
 *
 * @brief   The CMotorFactory is used to create all motors.
 *
 */

class IODLLCLASS CMotorFactory
{
private:
    CMotorFactory(void);
public:
    virtual ~CMotorFactory(void);
    static CMotorFactory &Instance();
    void                  AddFactory(int index, CAbstractMotorFactory *pFactory);
    void                  RemoveFactory(int cardType);
    CMotorBase           *CreateMotor(const CMtrProfile &MtrProfile, double *dpPos, CMotionControllerBase *pBaseController);
};

/**
 * @def REGISTER_MOTOR_FACTORY(id, motor_class)
 *
 * @brief   A macro that defines motor factory.
 *
 * The factories are registered to the CMotorFactory which uses them to create motors.
 * To define a new type of motor it needs to derive from CMotorBase and be registered.
 *
 * Example usage:
 *
 * \code{.cpp}
 * REGISTER_MOTOR_FACTORY(PCI_8164_ADLINK, CMotor_8164)
 * \endcode
 *
 * @param   mType       The motor type.
 * @param   motor_class The class of the motor that the factory creates.
 */

#define REGISTER_MOTOR_FACTORY(mType, motor_class) \
    class Factory ## motor_class : public CAbstractMotorFactory \
    { \
    public: \
        Factory ## motor_class() : CAbstractMotorFactory(mType){} \
        CMotorBase *CreateMotor(const CMtrProfile &MtrProfile, double *dpPos, CMotionControllerBase * pBaseController) \
        { return new motor_class(MtrProfile, dpPos, pBaseController); } \
    }; \
    static Factory ## motor_class StaticFactory ## motor_class;
#endif // _MOTORFACTORY_H_
