/*==================================================================================================

                    Copyright (c) 2007 UGS
                             Unpublished - All rights reserved
====================================================================================================
File description:

    Filename: OperationDispatcher.hxx
    Module  : extensionframework

    This operation dispatcher register for BO operation.

====================================================================================================
   Date      Name                    Description of Change
$HISTORY$
==================================================================================================*/
#ifndef OPERATIONDISPATCHERREGISTRY_HXX
#define OPERATIONDISPATCHERREGISTRY_HXX

#include <unidefs.h>
#include <string>
#include <map>
#include <metaframework/Object.hxx>
#include <extensionframework/OperationDispatcher.hxx>
#include <extensionframework/libextensionframework_exports.h>

namespace Teamcenter
{
    class OperationDispatcherRegistry;
}

typedef enum EXTENSIONFRAMEWORK_operation_int_type_e
{
    OPERATION_TYPE_UNDEFINED = 0,
    OPERATION_TYPE_SETBASED,                        /**< It determines that object based extensions needs to be merged to the set based dispatcher */
    OPERATION_TYPE_OBJECT_BASED_MESSAGE_BASED       /**< It determines that set based extensions needs to be merged to the object based or legacy message based dispatcher */
}EXTENSIONFRAMEWORK_operation_int_type_t;

/** To determine if a specific set-based operation is implemented for a given object. */
typedef enum EXTENSIONFRAMEWORK_bulk_operation_e
{
    OPER_SAVE,            /**< Bulk Save Operation   - Used in BulkInputImpl::isRefactoredAsSetBased to check if set-based save operation is implemented */
    OPER_DELETE,          /**< Bulk Delete Operation - Used in BulkInputImpl::isRefactoredAsSetBased to check if set-based delete operation is implemented */
    OPER_LOCK,            /**< Bulk Lock Operation   - Used in BulkInputImpl::isRefactoredAsSetBased to check if set-based lock operation is implemented */
    OPER_UNLOCK,          /**< Bulk Unlock Operation - Used in BulkInputImpl::isRefactoredAsSetBased to check if set-based unlock operation is implemented */
    OPER_REFRESH,         /**< Bulk Refresh Operation - Used in BulkInputImpl::isRefactoredAsSetBased to check if set-based refresh operation is implemented */
    OPER_UNDEFINED = 100  /**< None of the Above Bulk Operations */
}  EXTENSIONFRAMEWORK_bulk_operation_t;

class EXTENSIONFRAMEWORK_API Teamcenter::OperationDispatcherRegistry : public Teamcenter::Object
{
public:
    typedef OperationDispatcher* (*OperationDispatcherConstructor)();
    
    /**
     OperationDispatcherMap
     Key: operation id
     Value: OperationDispatcherMapValue, a vector of <OperationDispatcherConstructor, typeName> pairs.
     typeName can be an empty string -- default MatchAll case for Property operation and BMF operation
     If typeName is defined, it implies the operation is implemented at this type. The input
     type for looking up the OperationDispatcherConstructor must be a subtype.
    */

    typedef std::vector< std::pair< OperationDispatcherConstructor, std::string > > OperationDispatcherMapValue;
    typedef std::map< std::string, OperationDispatcherMapValue > OperationDispatcherMap;
    typedef std::map< int, std::vector<int> > SetBasedToObjectBasedOpIntMap;
    typedef std::map< int, std::vector<int> > ObjectBasedToSetBasedOpIntMap;
    static  OperationDispatcherRegistry& instance();
    void initializeRegister(const std::string& opId, OperationDispatcherConstructor ctr);
    void registerBusinessObjOperationDispatcherCtor( const std::string& opId, const std::string& typeName, OperationDispatcherConstructor ctr );
    int createOperationDispatcher( const std::string& opId, OperationDispatcher*& opDispatcher );
    int createBusinessObjOperationDispatcher( const std::string& opId, const std::string& typeName, OperationDispatcher*& opDispatcher );
    void registerTypeOperation(int opInt, tag_t typeTag);
    std::vector<tag_t>* getStopTraverseTypes( int opInt );

    /** @deprecated - tc11.2.4
    This method would be deprecated from tc11.2.4 */
    void getObjectBasedOpIntForSetBasedOpInt( int setBasedOpInt, std::vector<int>& objBasedOpInt );
    void getEquivalentObjectBasedOrSetBasedOpInt( int inputOpInt, std::vector<int>& equivalentOpInt, EXTENSIONFRAMEWORK_operation_int_type_t& opIntType );
    /** Dump function to display all member variables */
    void dumpFunction();

    /**
    Determines whether the fallback functionality is enabled for a given bulk operation
    */
    static void isFallbackEnabledOperation( const int                             inputOpInt,        /**< (I) Integer value of the operation. */
                                            bool&                                 isFallBackEnabled, /**< (O) Boolean value to determine if fallback mechanism is enabled. */
                                            EXTENSIONFRAMEWORK_bulk_operation_t&  bulkOperEnum       /**< (O) The bulk operation associated to @p operation. */
                                          );


protected:
    OperationDispatcherRegistry();
    ~OperationDispatcherRegistry();
private:
    OperationDispatcherMap m_operarionDispatchCtorMap;
    /** singleton */
    static OperationDispatcherRegistry* m_instance;
    std::map< int, std::vector< tag_t >* > m_typeOperations;
    static SetBasedToObjectBasedOpIntMap s_SetBasedToObjectBasedOpIntMap;
    static ObjectBasedToSetBasedOpIntMap s_ObjectBasedToSetBasedOpIntMap;
    void initializeSetBasedToObjectBaseOperationMap();
    void initializeObjectBasedToSetBaseOperationMap();

    /** Initializes and populates the s_fallbackEnabledOperationMap */
    static void initializeFallbackEnabledOperationMap();
};
#include <extensionframework/libextensionframework_undef.h>
#endif //OPERATIONDISPATCHERREGISTRY_HXX
