#include <stdio.h>
#include <maya/MString.h>
#include <maya/MViewport2Renderer.h>
#include <maya/MRenderTargetManager.h>
#include "viewRenderOverride.h"
viewRenderOverride::viewRenderOverride( 
const MString & name )
    : MRenderOverride( name )
    
    
    
    , mUIName("Sample VP2 Renderer Override")
    , mRendererChangeCB(0)
    , mRenderOverrideChangeCB(0)
{
    for (unsigned int i=0; i<kNumberOfOps; i++)
        mRenderOperations[i] = NULL;
    mCurrentOperation = -1;
    
    unsigned int sampleCount = 1; 
    
    
    
    
    
    mTargetOverrideNames[kMyColorTarget] = 
MString(
"__viewRenderOverrideCustomColorTarget__");
    mTargets            [kMyColorTarget] = NULL;
    mTargetSupportsSRGBWrite[kMyColorTarget] = false;
    mTargetOverrideNames[kMyDepthTarget] = 
MString(
"__viewRenderOverrideCustomDepthTarget__");
    mTargets            [kMyDepthTarget] = NULL;
    mTargetSupportsSRGBWrite[kMyDepthTarget] = false;
    mTargetOverrideNames[kMyBlurTarget] = 
MString(
"__viewRenderOverrideBlurTarget__");
    mTargets            [kMyBlurTarget] = NULL;
    mTargetSupportsSRGBWrite[kMyBlurTarget] = false;
    
    mSplitUIDraw = false;
    
    mDebugOverride = false;
    
    mSimpleRendering = false;
    mPanelName.clear();
}
viewRenderOverride::~viewRenderOverride()
{
    
    for(unsigned int targetId = 0; targetId < kTargetCount; ++targetId)
    {
        if (mTargetDescriptions[targetId])
        {
            delete mTargetDescriptions[targetId];
            mTargetDescriptions[targetId] = NULL;
        }
        if (mTargets[targetId])
        {
            if (targetManager)
            {
            }
            mTargets[targetId] = NULL;
        }
    }
    cleanup();
    
    
    
    for (unsigned int i=0; i<kNumberOfOps; i++)
    {
        if (mRenderOperations[i])
        {
            delete mRenderOperations[i];
            mRenderOperations[i] = NULL;
        }
    }
    
    
    if (mRendererChangeCB)
    {
    }
    if (mRenderOverrideChangeCB)
    {
    }
}
viewRenderOverride::supportedDrawAPIs() const
{
}
bool
viewRenderOverride::startOperationIterator()
{
    mCurrentOperation = 0;
    return true;
}
viewRenderOverride::renderOperation()
{
    if (mCurrentOperation >= 0 && mCurrentOperation < kNumberOfOps)
    {
        while(!mRenderOperations[mCurrentOperation])
        {
            mCurrentOperation++;
            if (mCurrentOperation >= kNumberOfOps)
            {
                return NULL;
            }
        }
        if (mRenderOperations[mCurrentOperation])
        {
            if (mDebugOverride)
            {
                printf("\t%s : Queue render operation[%d] = (%s)\n",
                    mName.asChar(),
                    mCurrentOperation,
                    mRenderOperations[mCurrentOperation]->name().asChar());
            }
            return mRenderOperations[mCurrentOperation];
        }
    }
    return NULL;
}
bool
viewRenderOverride::nextRenderOperation()
{
    mCurrentOperation++;
    if (mCurrentOperation < kNumberOfOps)
    {
        return true;
    }
    return false;
}
bool viewRenderOverride::updateRenderTargets()
{
    if (mDebugOverride)
    {
        printf("\t%s : Set output render target overrides: color=%s, depth=%s\n",
            mName.asChar(),
            mTargetDescriptions[0]->name().asChar(), mTargetDescriptions[1]->name().asChar());
    }
    
    
    
    unsigned int targetWidth = 0;
    unsigned int targetHeight = 0;
    if( theRenderer )
    {
    }
    if (mTargetDescriptions[0]->width() != targetWidth ||
        mTargetDescriptions[1]->height() != targetHeight)
    {
        
    }
    
    
    
    
    for(unsigned int targetId = 0; targetId < kTargetCount; ++targetId)
    {
        mTargetDescriptions[targetId]->setWidth( targetWidth );
        mTargetDescriptions[targetId]->setHeight( targetHeight );
    }
    
    bool colorTargetSupportsSGRBWrite = false;
    
    static const bool sDebugSRGBWrite = false;
    
    static const bool testUnorderedWriteAccess = false;
    
    
    if (targetManager)
    {
        if (sDebugSRGBWrite)
        {
            {
                
                {
                        printf("Format %d supports SRGBwrite\n", i);
                }
            }
        }
        for(unsigned int targetId = 0; targetId < kTargetCount; ++targetId)
        {
            
            
            bool supportsSRGBWrite = false;
            {
                mTargetSupportsSRGBWrite[targetId] = supportsSRGBWrite =
            }
            mTargetDescriptions[targetId]->setAllowsUnorderedAccess( testUnorderedWriteAccess );
            
            if (targetId == kMyColorTarget)
                colorTargetSupportsSGRBWrite = supportsSRGBWrite;
            if (sDebugSRGBWrite)
            {
                if (targetId == kMyColorTarget || targetId == kMyBlurTarget)
                {
                    printf("Color target %d supports sRGB write = %d\n", targetId, supportsSRGBWrite );
                }
                
                if (targetId == kMyDepthTarget)
                {
                    printf("Depth target supports sRGB write = %d\n", supportsSRGBWrite );
                }
            }
            
            if (!mTargets[targetId])
            {
            }
            
            else
            {
            }
            if (testUnorderedWriteAccess && mTargets[targetId])
            {
                (mTargets[targetId])->targetDescription(returnDesc);
                printf("Acquire target[%s] with unordered access = %d. Should fail if attempting with depth target = %d\n",
                    targetId == kMyDepthTarget);
            }
        }
    }
    
    
    
    
    
    
    viewRenderQuadRender *quadOp = (viewRenderQuadRender *)mRenderOperations[kBackgroundBlit];
    if (quadOp)
        quadOp->setRenderTargets(mTargets);
    viewRenderSceneRender *sceneOp = (viewRenderSceneRender *)mRenderOperations[kMaya3dSceneRender];
    if (sceneOp)
    {
        sceneOp->setRenderTargets(mTargets);
        sceneOp->setEnableSRGBWriteFlag( colorTargetSupportsSGRBWrite );
    }
    viewRenderSceneRender *opaqueSceneOp = (viewRenderSceneRender *)mRenderOperations[kMaya3dSceneRenderOpaque];
    if (opaqueSceneOp)
    {
        opaqueSceneOp->setRenderTargets(mTargets);
        opaqueSceneOp->setEnableSRGBWriteFlag( colorTargetSupportsSGRBWrite );
    }
    viewRenderSceneRender *transparentSceneOp = (viewRenderSceneRender *)mRenderOperations[kMaya3dSceneRenderTransparent];
    if (transparentSceneOp)
    {
        transparentSceneOp->setRenderTargets(mTargets);
        transparentSceneOp->setEnableSRGBWriteFlag( colorTargetSupportsSGRBWrite );
    }
    viewRenderSceneRender *uiSceneOp = (viewRenderSceneRender *)mRenderOperations[kMaya3dSceneRenderUI];
    if (uiSceneOp)
    {
        uiSceneOp->setRenderTargets(mTargets);
        uiSceneOp->setEnableSRGBWriteFlag( false ); 
    }
    viewRenderQuadRender *quadOp2 = (viewRenderQuadRender *)mRenderOperations[kPostOperation1];
    if (quadOp2)
        quadOp2->setRenderTargets(mTargets);
    viewRenderQuadRender *quadOp3 = (viewRenderQuadRender *)mRenderOperations[kPostOperation2];
    if (quadOp3)
        quadOp3->setRenderTargets(mTargets);
    viewRenderUserOperation *userOp = (viewRenderUserOperation *) mRenderOperations[kUserOpNumber];
    if (userOp)
    {
        userOp->setRenderTargets(mTargets);
        userOp->setEnableSRGBWriteFlag( colorTargetSupportsSGRBWrite ); 
    }
    viewRenderPresentTarget *presentOp = (viewRenderPresentTarget *) mRenderOperations[kPresentOp];
    if (presentOp)
        presentOp->setRenderTargets(mTargets);
    viewRenderQuadRender *thresholdOp = (viewRenderQuadRender *)mRenderOperations[kThresholdOp];
    if (thresholdOp)
        thresholdOp->setRenderTargets(mTargets);
    viewRenderQuadRender *horizBlur = (viewRenderQuadRender *)mRenderOperations[kHorizBlurOp];
    if (horizBlur)
        horizBlur->setRenderTargets(mTargets);
    viewRenderQuadRender *vertBlur = (viewRenderQuadRender *)mRenderOperations[kVertBlurOp];
    if (vertBlur)
        vertBlur->setRenderTargets(mTargets);
    viewRenderQuadRender *blendOp = (viewRenderQuadRender *)mRenderOperations[kBlendOp];
    if (blendOp)
        blendOp->setRenderTargets(mTargets);
    viewRenderHUDOperation *hudOp = (viewRenderHUDOperation *)mRenderOperations[kHUDBlit];
    if (hudOp)
        hudOp->setRenderTargets(mTargets);
    return (mTargets[kMyColorTarget] && mTargets[kMyDepthTarget] && mTargets[kMyBlurTarget]);
}
viewRenderOverride::setup( 
const MString & destination )
{
    if (mDebugOverride)
    {
        printf("%s : Perform setup with panel [%s]\n",
            mName.asChar(), destination.
asChar() );
    }
    
    
    
    
    
    if (!mRendererChangeCB)
    {
    }
    if (!mRenderOverrideChangeCB)
    {
    }
    if (mRenderOperations[kPresentOp] == NULL)
    {
        
        
        if (mSimpleRendering)
        {
            mSplitUIDraw = false;
            mRenderOperations[kBackgroundBlit] = NULL;
            mRenderOperationNames[kMaya3dSceneRender] = "__MySimpleSceneRender";
            simpleViewRenderSceneRender *sceneOp = new simpleViewRenderSceneRender( mRenderOperationNames[kMaya3dSceneRender] );
            mRenderOperations[kMaya3dSceneRender] = sceneOp;
            
            mRenderOperations[kMaya3dSceneRenderOpaque] = NULL;
            mRenderOperations[kMaya3dSceneRenderTransparent] = NULL;
            mRenderOperations[kThresholdOp] = NULL;
            mRenderOperations[kHorizBlurOp] = NULL;
            mRenderOperations[kVertBlurOp] = NULL;
            mRenderOperations[kPostOperation1] = NULL;
            mRenderOperations[kPostOperation2] = NULL;
            mRenderOperations[kMaya3dSceneRenderUI] = NULL;
            mRenderOperations[kUserOpNumber] = NULL;
            mRenderOperations[kHUDBlit] = new viewRenderHUDOperation();
            mRenderOperationNames[kHUDBlit] = (mRenderOperations[kHUDBlit])->name();
            mRenderOperationNames[kPresentOp] = "__MyPresentTarget";
            mRenderOperations[kPresentOp] = new viewRenderPresentTarget( mRenderOperationNames[kPresentOp] );
            mRenderOperationNames[kPresentOp] = (mRenderOperations[kPresentOp])->name();
        }
        
        
        else
        {
            rect[0] = 0.0f;
            rect[1] = 0.0f;
            rect[2] = 1.0f;
            rect[3] = 1.0f;
            
            
            mRenderOperationNames[kBackgroundBlit] = "__MyPreQuadRender";
            viewRenderQuadRender *quadOp = new viewRenderQuadRender( mRenderOperationNames[kBackgroundBlit] );
            quadOp->setShader( viewRenderQuadRender::kPre_MandelBrot ); 
            quadOp->setViewRectangle(rect);
            mRenderOperations[kBackgroundBlit] = quadOp;
            
            
            
            
            
            
            
            
            
            
            mSplitUIDraw = true;
            mRenderOperations[kMaya3dSceneRender] = NULL;
            mRenderOperations[kMaya3dSceneRenderOpaque] = NULL;
            mRenderOperations[kMaya3dSceneRenderTransparent] = NULL;
            mRenderOperations[kMaya3dSceneRenderUI] = NULL;
            if (mSplitUIDraw)
            {
                
                viewRenderSceneRender* sceneOp = NULL;
                static const bool sDrawOpaque = true; 
                if (sDrawOpaque)
                {
                    mRenderOperationNames[kMaya3dSceneRenderOpaque] = "__MyStdSceneRenderOpaque";
                    sceneOp = new viewRenderSceneRender(
                        mRenderOperationNames[kMaya3dSceneRenderOpaque],
                    sceneOp->setViewRectangle(rect);
                    mRenderOperations[kMaya3dSceneRenderOpaque] = sceneOp;
                }
                
                static const bool sDrawTransparent = true; 
                if (sDrawTransparent)
                {
                    mRenderOperationNames[kMaya3dSceneRenderTransparent] = "__MyStdSceneRenderTransparent";
                    sceneOp = new viewRenderSceneRender(
                        mRenderOperationNames[kMaya3dSceneRenderTransparent],
                        sDrawOpaque
                    sceneOp->setViewRectangle(rect);
                    mRenderOperations[kMaya3dSceneRenderTransparent] = sceneOp;
                }
                
                mRenderOperationNames[kMaya3dSceneRenderUI] = "__MyStdSceneRenderUI";
                sceneOp = new viewRenderSceneRender(
                    mRenderOperationNames[kMaya3dSceneRenderUI],
                    MHWRender::MSceneRender::kRenderUIItems,
                    sDrawOpaque || sDrawTransparent
                sceneOp->setViewRectangle(rect);
                mRenderOperations[kMaya3dSceneRenderUI] = sceneOp;
            }
            else
            {
                
                mRenderOperationNames[kMaya3dSceneRender] = "__MyStdSceneRender";
                viewRenderSceneRender* sceneOp = new viewRenderSceneRender(
                    mRenderOperationNames[kMaya3dSceneRender],
                    MHWRender::MSceneRender::kNoSceneFilterOverride,
                sceneOp->setViewRectangle(rect);
                mRenderOperations[kMaya3dSceneRender] = sceneOp;
            }
            
            
            
            
            mRenderOperationNames[kThresholdOp] = "__ThresholdColor";
            viewRenderQuadRender *quadThreshold  = new viewRenderQuadRender( mRenderOperationNames[kThresholdOp] );
            quadThreshold->setShader( viewRenderQuadRender::kScene_Threshold ); 
            quadThreshold->setViewRectangle(rect);
            mRenderOperations[kThresholdOp] = quadThreshold;
            mRenderOperationNames[kHorizBlurOp] = "__HorizontalBlur";
            viewRenderQuadRender *quadHBlur  = new viewRenderQuadRender( mRenderOperationNames[kHorizBlurOp] );
            quadHBlur->setShader( viewRenderQuadRender::kScene_BlurHoriz ); 
            quadHBlur->setViewRectangle(rect);
            mRenderOperations[kHorizBlurOp] = quadHBlur;
            mRenderOperationNames[kVertBlurOp] = "__VerticalBlur";
            viewRenderQuadRender *quadVBlur  = new viewRenderQuadRender( mRenderOperationNames[kVertBlurOp] );
            quadVBlur->setShader( viewRenderQuadRender::kScene_BlurVert ); 
            quadVBlur->setViewRectangle(rect);
            mRenderOperations[kVertBlurOp] = quadVBlur;
            mRenderOperationNames[kBlendOp] = "__SceneBlurBlend";
            viewRenderQuadRender *quadBlend  = new viewRenderQuadRender( mRenderOperationNames[kBlendOp] );
            quadBlend->setShader( viewRenderQuadRender::kSceneBlur_Blend ); 
            quadBlend->setViewRectangle(rect);
            mRenderOperations[kBlendOp] = quadBlend;
            
            
            mRenderOperationNames[kUserOpNumber] = "__MyCustomSceneRender";
            viewRenderUserOperation *userOp = new viewRenderUserOperation( mRenderOperationNames[kUserOpNumber] );
            userOp->setViewRectangle(rect);
            mRenderOperations[kUserOpNumber] = userOp;
            bool wantPostQuadOps = false;
            
            
            mRenderOperationNames[kPostOperation1] = "__PostOperation1";
            viewRenderQuadRender *quadOp2  = new viewRenderQuadRender( mRenderOperationNames[kPostOperation1] );
            quadOp2->setShader( viewRenderQuadRender::kPost_EffectMonochrome );
            quadOp2->setViewRectangle(rect);
            if (wantPostQuadOps)
                mRenderOperations[kPostOperation1] = quadOp2;
            else
                mRenderOperations[kPostOperation1] = NULL;
            
            mRenderOperationNames[kPostOperation2] = "__PostOperation2";
            viewRenderQuadRender *quadOp3  = new viewRenderQuadRender( mRenderOperationNames[kPostOperation2] );
            quadOp3->setShader( viewRenderQuadRender::kPost_EffectInvert );
            quadOp3->setViewRectangle(rect);
            if (wantPostQuadOps)
                mRenderOperations[kPostOperation2] = quadOp3;
            else
                mRenderOperations[kPostOperation2] = NULL;
            
            
            
            mRenderOperationNames[kPresentOp] = "__MyPresentTarget";
            mRenderOperations[kPresentOp] = new viewRenderPresentTarget( mRenderOperationNames[kPresentOp] );
            mRenderOperationNames[kPresentOp] = (mRenderOperations[kPresentOp])->name();
            
            mRenderOperations[kHUDBlit] = new viewRenderHUDOperation();
            mRenderOperationNames[kHUDBlit] = (mRenderOperations[kHUDBlit])->name();
        }
    }
    bool gotTargets = true;
    if (!mSimpleRendering)
    {
        
        gotTargets = updateRenderTargets();
        
        
        if (mRenderOperations[kMaya3dSceneRender])
            ((viewRenderSceneRender * )mRenderOperations[kMaya3dSceneRender])->setPanelName( mPanelName );
        if (mRenderOperations[kMaya3dSceneRenderOpaque])
            ((viewRenderSceneRender * )mRenderOperations[kMaya3dSceneRenderOpaque])->setPanelName( mPanelName );
        if (mRenderOperations[kMaya3dSceneRenderTransparent])
            ((viewRenderSceneRender * )mRenderOperations[kMaya3dSceneRenderTransparent])->setPanelName( mPanelName );
        if (mRenderOperations[kMaya3dSceneRenderUI])
            ((viewRenderSceneRender * )mRenderOperations[kMaya3dSceneRenderUI])->setPanelName( mPanelName );
        if (mRenderOperations[kUserOpNumber])
            ((viewRenderUserOperation *)mRenderOperations[kUserOpNumber])->setPanelName( mPanelName );
    }
    mCurrentOperation = -1;
}
viewRenderOverride::cleanup()
{
    if (mDebugOverride)
    {
        printf("%s : Perform cleanup. panelname=%s\n", mName.asChar(), mPanelName.asChar());
    }
    viewRenderQuadRender *quadOp = (viewRenderQuadRender *) mRenderOperations[kPostOperation1];
    if (quadOp)
    {
        quadOp->setRenderTargets(NULL);
    }
    quadOp = (viewRenderQuadRender *) mRenderOperations[kPostOperation2];
    if (quadOp)
    {
        quadOp->setRenderTargets(NULL);
    }
    
    
    mCurrentOperation = -1;
}
void viewRenderOverride::sRendererChangeFunc(
    void* clientData)
{
    if (clientData)
    {
        printf("Renderer changed for panel '%s'. New renderer is '%s', old was '%s'.\n",
    }
}
void viewRenderOverride::sRenderOverrideChangeFunc(
    void* clientData)
{
    if (clientData)
    {
        printf("Render override changed for panel '%s'. New override is '%s', old was '%s'.\n",
    }
}