#ifndef _MotionControllerFACTORY_H_
#define _MotionControllerFACTORY_H_

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

class IODLLCLASS CAbstractMotionControllerFactory
{
private:
    int   m_cardType;
    char *m_cardName;
public:
    CAbstractMotionControllerFactory(int cardType, char* m_cardName);
    virtual ~CAbstractMotionControllerFactory();
    virtual CMotionControllerBase *CreateMotionController(int index) = 0;
    int                            GetCardType();
    char                         * GetCardName();
};

/**
 * @class   CMotionControllerFactory
 *
 * @brief   The CMotionControllerFactory is used to create all MotionControllers.
 *
 */

class IODLLCLASS CMotionControllerFactory
{
private:
    CMotionControllerFactory(void);
public:
    virtual ~CMotionControllerFactory(void);
    static CMotionControllerFactory &Instance();
    void                             AddFactory(CAbstractMotionControllerFactory *pFactory);
    void                             RemoveFactory(CAbstractMotionControllerFactory *pFactory);
    CMotionControllerBase           *CreateMotionController(int index, const char* cardName);
    CMotionControllerBase           *CreateMotionController(int index, int cardType);
    int                              GetCardType(const char* cardName);
};

/**
 * @def REGISTER_MOTIONCONTROLLER_FACTORY(mType, name, MotionController_class)
 *
 * @brief   A macro that defines MotionController factory.
 *
 * The factories are registered to the CMotionControllerFactory which uses them to create MotionControllers.
 * To define a new type of MotionController it needs to derive from CMotionControllerBase and be registered.
 *
 * Example usage:
 *
 * \code{.cpp}
 * REGISTER_MOTIONCONTROLLER_FACTORY(PCI_8164_ADLINK, "8164", CMotionController_8164)
 * \endcode
 *
 * @param   mType       The MotionController type.
 * @param   MotionController_class  The class of the MotionController that the factory creates.
 */

#define REGISTER_MOTIONCONTROLLER_FACTORY(mType, name, MotionController_class) \
    class Factory ## MotionController_class : public CAbstractMotionControllerFactory \
    { \
    public: \
        Factory ## MotionController_class() : CAbstractMotionControllerFactory(mType, name){} \
        CMotionControllerBase *CreateMotionController(int index) \
        { \
            CMotionControllerBase *ptr = new MotionController_class(index); \
            ptr->SetCardInfo(mType, name); \
            return ptr; \
        } \
    }; \
    static                            Factory ## MotionController_class StaticFactory ## MotionController_class; \
    CAbstractMotionControllerFactory* GetFactory ## MotionController_class() { return &StaticFactory ## MotionController_class; }

#endif // _MotionControllerFACTORY_H_
