#include <stdio.h>
#define OPENMAYA_EXPORT
#include <maya/MIOStream.h>
#include <maya/MGlobal.h>
#include <maya/MString.h>
#include <maya/MStringArray.h>
#include <maya/MEventMessage.h>
#include <maya/MUiMessage.h>
#include <maya/MFnPlugin.h>
#include <maya/MPxCommand.h>
#include <maya/MSyntax.h>
#include <maya/MArgDatabase.h>
#include <maya/MArgList.h>
#include <maya/M3dView.h>
#include <maya/MPoint.h>
#include <maya/MImage.h>
#include <stdio.h>
class refreshCompute;
static refreshCompute* currentRefreshCompute[4] = { 0, 0, 0, 0 };
enum MbufferOperation {
    kInvertColorBuffer,
    kDrawDepthBuffer
};
{
public:
    viewCallbackTest();
    virtual                 ~viewCallbackTest(); 
    static void*            creator();
private:
    
    MbufferOperation        mBufferOperation;
};
class refreshCompute
{
public:
    refreshCompute(
const MString &panelName, MbufferOperation bufferOperation);
    ~refreshCompute();
    const MString &panelName()
 const { 
return mPanelName; }
 
    void setPanelName(
const MString &panelName) { mPanelName = panelName; }
 
    MbufferOperation bufferOperation() const { return mBufferOperation; }
    void setBufferOperation(const MbufferOperation operation) { mBufferOperation = operation; }
    void clearCallbacks();
protected:
    static void             deleteCB(
const MString& panelName, 
void * data);
 
    static void             preRenderCB(
const MString& panelName, 
void * data);
 
    static void             postRenderCB(
const MString& panelName, 
void * data);
 
    MCallbackId             mDeleteId;
    MCallbackId             mPreRenderId;
    MCallbackId             mPostRenderId;
    MbufferOperation        mBufferOperation;
};
viewCallbackTest::viewCallbackTest()
{
    mBufferOperation = kInvertColorBuffer;
}
viewCallbackTest::~viewCallbackTest()
{
    
}
void* viewCallbackTest::creator()
{
    return (void *) (new viewCallbackTest);
}
const char *bufferOperationShortName = "-bo";
const char *bufferOperationLongName = "-bufferOperation";
#define _NUMBER_BUFFER_OPERATIONS_ 2
const MString bufferOperationStrings[_NUMBER_BUFFER_OPERATIONS_ ] = 
 
const MbufferOperation bufferOperations[_NUMBER_BUFFER_OPERATIONS_] = 
        { kInvertColorBuffer, kDrawDepthBuffer };
MSyntax viewCallbackTest::newSyntax()
 
{
    
    
    return syntax;
}
{
    
    mBufferOperation = kInvertColorBuffer;
    for ( 
unsigned int i = 0; i < args.
length(); i++ ) 
 
    {
        if (!status)              
            continue;
        if ( arg == 
MString(bufferOperationShortName) || arg == 
MString(bufferOperationLongName) ) 
 
        {
                arg += ": must specify a buffer operation.";
                displayError(arg);
            }
            i++;
            args.
get(i, operationString );
            bool validOperation = false;
            for (unsigned int k=0; k<_NUMBER_BUFFER_OPERATIONS_; k++)
            {
                if (bufferOperationStrings[i] == operationString)
                {
                    mBufferOperation = bufferOperations[k];
                    validOperation = true;
                }
            }
            if (!validOperation)
                status.
perror(
"Invalid operation specified. Using invert by default.");
        }
    }
    
    status = argData.getCommandArgument(0, mPanelName);
    if (!status)
    {
        status.
perror(
"No panel name specified as command argument");
        return status;
    }
}
{
    status = parseArgs(args);
    if (!status)
    {
        return status;
    }
    try
    {
        
        refreshCompute *foundComputePtr = 0;
        unsigned int i;
        for (i=0; i<4; i++)
        {
            if (currentRefreshCompute[i] && 
                (currentRefreshCompute[i])->panelName() == mPanelName)
            {
                foundComputePtr = currentRefreshCompute[i];
            }
        }
        
        if (foundComputePtr)
        {
            foundComputePtr->setBufferOperation( mBufferOperation);
        }
        else
        {
            for (i=0; i<4; i++)
            {
                if (!currentRefreshCompute[i])
                {
                    currentRefreshCompute[i] = new refreshCompute(mPanelName, mBufferOperation);
                    break;
                }
            }
        }
    }
    {
        return status;
    }
    catch(...)
    {
        throw;
    }
    return status;
}
refreshCompute::refreshCompute(
const MString &panelName, 
                               MbufferOperation postBufferOperation)
{
    
    mPanelName = panelName;
    mBufferOperation = postBufferOperation;
    
    
    mDeleteId
                                           &refreshCompute::deleteCB,
                                           (void *) this, &status);
    if (mDeleteId == 0)
        status.
perror(
MString(
"Could not attach view deletion callback to panel ") +
                      panelName);
    mPreRenderId
                                          &refreshCompute::preRenderCB,
                                          (void *) this, &status);
    if (mPreRenderId == 0)
        status.
perror(
MString(
"Could not attach view prerender callback to panel ") +
                panelName);
    mPostRenderId
                                           &refreshCompute::postRenderCB,
                                           (void *) this, &status);
    if (mPostRenderId == 0)
        status.
perror(
MString(
"Could not attach view postrender callback to panel ") +
                      panelName);
}
void refreshCompute::clearCallbacks()
{   
    if (mDeleteId)
    if (mPreRenderId)
    if (mPostRenderId)
}
refreshCompute::~refreshCompute()
{
    clearCallbacks();
    
    for (unsigned int i=0; i<4; i++)
    {
        if (currentRefreshCompute[i] && 
            (currentRefreshCompute[i])->panelName() == mPanelName)
        {
            currentRefreshCompute[i] = 0;
        }
    }
}
void refreshCompute::deleteCB(
const MString& panelName, 
void * data)
 
{
    refreshCompute *pf = (refreshCompute *) data;
    cout<<
"In delete view callback for view "<<panelName.
asChar()
        <<". Remove all callbacks."<<endl;
    
    delete pf;
}
void refreshCompute::preRenderCB(
const MString& panelName, 
void * data)
 
{
    refreshCompute *thisCompute = (refreshCompute *) data;
    if (!thisCompute)
        return;
        return;
    int width = 0, height = 0;
        return;
        return;
    unsigned int vx,vy,vwidth,vheight;
    vx = 0;
    vy = 0;
    vwidth = width / 2;
    vheight = height / 2;
    if (thisCompute->mBufferOperation != kDrawDepthBuffer)
    {
        status = view.
drawText( 
MString(
"Pre render callback: ") + panelName, origin );
    }
}
void refreshCompute::postRenderCB(
const MString& panelName, 
void * data)
 
{   
    refreshCompute *thisCompute = (refreshCompute *) data;
    if (!thisCompute)
        return;
    
        return;
    if (thisCompute->mBufferOperation == kDrawDepthBuffer)
    {
        int width = 0, height = 0;
            return;
            return;
        unsigned int numPixels = width * height;
        float *depthPixels = new float[numPixels];
        if (!depthPixels)
            return;
        unsigned char *colorPixels = new unsigned char[numPixels * 4];
        if (!colorPixels)
        {
            delete [] depthPixels;
            delete [] colorPixels;
            return;
        }
        
        {
            delete [] depthPixels;
            delete [] colorPixels;
            return;
        }
        
        
        float *dPtr = depthPixels;
        unsigned int i = 0;
        float zmin = 100.0f; 
        float zmax = -100.0f; 
        for(i=0; i<numPixels; i++)
        {
            float val = *dPtr; 
            if(val < zmin) {
                zmin = *dPtr;
            }
            if(val > zmax) {
                zmax = *dPtr;
            }
            dPtr++;
        }
        float zrange = zmax - zmin;
        
        unsigned char *cPtr = colorPixels;
        dPtr = depthPixels;
        for(i=0; i < numPixels; i++)
        {
            float val = *dPtr; 
            
            unsigned char depth = (unsigned char)(255.0f * (( (val)-zmin) / zrange) );
            
            *cPtr = depth; cPtr++;
            *cPtr = depth; cPtr++;
            *cPtr = depth; cPtr++;
            *cPtr = 0xff;   
            cPtr++;
            dPtr++;
        }
        image.
setPixels( colorPixels, width, height );
        
        
        
        
        if (depthPixels)
            delete [] depthPixels;
        if (colorPixels)
            delete [] colorPixels;
    }
    
    
    else if (thisCompute->mBufferOperation == kInvertColorBuffer)
    {
        
        
        
        bool readAsRGBA = true;
        
            return;
        unsigned char *pixelPtr = (
unsigned char*)image.
pixels();
 
        if (pixelPtr)
        {
            unsigned int width, height;
            image2.
create( width, height );
            unsigned char *pixelPtr2 = (
unsigned char*)image2.
pixels();
 
            unsigned int numPixels = width * height;
            for (unsigned int i=0; i < numPixels; i++)
            {
                *pixelPtr2 = (255 - *pixelPtr); 
                pixelPtr2++; pixelPtr++;
                *pixelPtr2 = (255 - *pixelPtr); 
                pixelPtr2++; pixelPtr++;
                *pixelPtr2 = (255 - *pixelPtr); 
                pixelPtr2++; pixelPtr++;
                *pixelPtr2 = 255;   
                pixelPtr2++; pixelPtr++;
            }
            
            
        }
    }
}
{ 
    MFnPlugin plugin( obj, PLUGIN_COMPANY, 
"6.5", 
"Any");
 
    
    
    status = plugin.registerCommand("viewCallbackTest",
                                    viewCallbackTest::creator,
                                    viewCallbackTest::newSyntax);
    if (!status)
    {
        status.
perror(
"registerCommand");
    }
    return status;
}
{
    
    for (unsigned int i=0; i<4; i++)
    {
        delete currentRefreshCompute[i];
        currentRefreshCompute[i] = 0;
    }
    
    
    status = plugin.deregisterCommand("viewCallbackTest");
    if (!status)
    {
        status.
perror(
"deregisterCommand");
    }
    return status;
}