#include <maya/MFnPlugin.h>
#include <maya/MStatus.h>
#include <maya/MPxCommand.h>
#include <maya/MMessage.h>
#include <maya/MUserEventMessage.h>
#include <maya/MGlobal.h>
#include <maya/MArgList.h>
#include <maya/MArgDatabase.h>
#include <maya/MSyntax.h>
static const char *postFlag = "-p";
static const char *postLongFlag = "-post";
static const char *registerFlag = "-r";
static const char *registerLongFlag = "-register";
static const char *deregisterFlag = "-d";
static const char *deregisterLongFlag = "-deregister";
static const char *testFlag = "-t";
static const char *testLongFlag = "-test";
class userMessage : public MPxCommand
{
        public:
                virtual MStatus doIt( const MArgList& );
                void runTests();
                static void *creator();
                static MSyntax newSyntax();
                
                static void userCallback1(void* clientData);
                static void userCallback2(void* clientData);
        private:
                static MString stringClientData;
};
MString userMessage::stringClientData = "Sample Client Data (an MString object)";
MStatus userMessage::doIt( const MArgList& args )
{
        MStatus status = MS::kSuccess;
        MArgDatabase argData(syntax(), args);
        if (argData.isFlagSet(deregisterFlag))
        {
                MString event;
                argData.getFlagArgument(deregisterFlag, 0, event);
                status = MUserEventMessage::deregisterUserEvent(event);
        }
        else if (argData.isFlagSet(registerFlag))
        {
                
                MString event;
                argData.getFlagArgument(registerFlag, 0, event);
                if (!MUserEventMessage::isUserEvent(event)) {
                        status = MUserEventMessage::registerUserEvent(event);
                        if (status == MS::kSuccess)
                        {
                                MUserEventMessage::addUserEventCallback(event,userCallback1,(void*) &stringClientData,&status);
                                MUserEventMessage::addUserEventCallback(event,userCallback2,(void*) &stringClientData,&status);
                        }
                }
        }
        else if (argData.isFlagSet(postFlag))
        {
                MString event;
                argData.getFlagArgument(postFlag, 0, event);
                status = MUserEventMessage::postUserEvent(event);
        }
        else if (argData.isFlagSet(testFlag))
        {
                runTests();
        }
        return status;
}
void* userMessage::creator() 
{       
        return new userMessage;
}
MSyntax userMessage::newSyntax() {
        MSyntax syntax;
        syntax.addFlag( postFlag, postLongFlag, MSyntax::kString );
        syntax.addFlag( registerFlag, registerLongFlag, MSyntax::kString );
        syntax.addFlag( deregisterFlag, deregisterLongFlag, MSyntax::kString );
        syntax.addFlag( testFlag, testLongFlag );
        return syntax;
}
void userMessage::userCallback1(void* clientData) {
        MGlobal::displayInfo("Entered userMessage::userCallback1");
        if (clientData != 0)
        {
                MString receivedDataMsg(MString("Received data: ") + *((MString*) clientData));
                MGlobal::displayInfo(receivedDataMsg);
        }
}
void userMessage::userCallback2(void* clientData) {
        MGlobal::displayInfo("Entered userMessage::userCallback2");
        if (clientData != 0)
        {
                MString receivedDataMsg(MString("Received data: ") + *((MString*) clientData));
                MGlobal::displayInfo(receivedDataMsg);
        }
}
void userMessage::runTests() {
        MStatus status;
        
        MGlobal::displayInfo("Starting Test 1");
        MUserEventMessage::addUserEventCallback("TestEvent",userCallback1,0,&status);
        if (!status) {
                MGlobal::displayInfo("Test 1 passed");
        }
        else {
                MGlobal::displayInfo("Test 1 failed");
        }
        
        
        MGlobal::displayInfo("Starting Test 2");
        MUserEventMessage::registerUserEvent("TestEvent");
        MUserEventMessage::addUserEventCallback("TestEvent",userCallback1,0,&status);
        MUserEventMessage::postUserEvent("TestEvent");
        MUserEventMessage::deregisterUserEvent("TestEvent");
        
        MGlobal::displayInfo("Starting Test 3");
        MUserEventMessage::addUserEventCallback("TestEvent",userCallback1,0,&status);
        if (!status) {
                MGlobal::displayInfo("Test 3 passed");
        }
        else {
                MGlobal::displayInfo("Test 3 failed");
        }
        
        
        
        MGlobal::displayInfo("Starting Test 4");
        MUserEventMessage::registerUserEvent("TestEvent");
        MUserEventMessage::addUserEventCallback("TestEvent",userCallback1,0,&status);
        MUserEventMessage::addUserEventCallback("TestEvent",userCallback2,0,&status);
        MUserEventMessage::postUserEvent("TestEvent");
        MUserEventMessage::deregisterUserEvent("TestEvent");
   
        
        
        
        
        
        
        
        MGlobal::displayInfo("Starting Test 5");
        MUserEventMessage::registerUserEvent("TestEvent");
        MUserEventMessage::registerUserEvent("TestEvent2");
        MUserEventMessage::addUserEventCallback("TestEvent",userCallback1,0,&status);
        MUserEventMessage::addUserEventCallback("TestEvent",userCallback2,0,&status);
        MUserEventMessage::addUserEventCallback("TestEvent2",userCallback1,0,&status);
        MUserEventMessage::addUserEventCallback("TestEvent2",userCallback2,0,&status);
        MGlobal::displayInfo("Posting first event");
        MUserEventMessage::postUserEvent("TestEvent");
        MGlobal::displayInfo("Posting second event");
        MUserEventMessage::postUserEvent("TestEvent2");
        MUserEventMessage::deregisterUserEvent("TestEvent");
        MUserEventMessage::deregisterUserEvent("TestEvent2");
 
        MGlobal::displayInfo("Completed all tests");
}
MStatus initializePlugin(MObject obj)
{
        
        
        MFnPlugin pluginFn(obj, PLUGIN_COMPANY, "6.0");
        MStatus status;
        status = pluginFn.registerCommand("userMessage", userMessage::creator, userMessage::newSyntax);
        if( !status)
                status.perror("register Command failed");
        return status;
}
MStatus uninitializePlugin ( MObject obj )
{
        MFnPlugin pluginFn(obj);
        MStatus status = MS::kSuccess;
        
        
        MUserEventMessage::deregisterUserEvent("TestFoo1");
        MUserEventMessage::deregisterUserEvent("TestFoo2");
        status = pluginFn.deregisterCommand("userMessage");
        
        return status;
}