#include "customTextureShaderOverride.h"
#include "customTextureShader.h"
#include <maya/MString.h>
#include <maya/MDrawContext.h>
#include <maya/MGlobal.h>
customTextureShaderOverride::customTextureShaderOverride(
const MObject& obj)
{
    m_beautyShaderInstance = NULL;
    m_multiDrawBeautyShaderInstance = NULL;
    m_shaderBound = false;
    m_inBeautyPass = false;
    
    m_customTextureData = NULL;
    if (!renderer)
        return;
    if (!shaderMgr)
        return;
    
        shaderLocation = 
MString(getenv(
"MAYA_LOCATION")) + 
MString(
"/devkit");
    }
    shaderLocation += 
MString(
"/plug-ins/customTextureShader/CustomTextureBlock");
    
    shaderLocation += 
MString(
"MultiDraw");
}
{
    return new customTextureShaderOverride(obj);
}
customTextureShaderOverride::~customTextureShaderOverride()
{
    if (m_beautyShaderInstance || m_multiDrawBeautyShaderInstance)
    {
        if (renderer)
        {
            if (shaderMgr)
            {
                if (m_beautyShaderInstance)
                {
                    m_beautyShaderInstance = NULL;
                }
                if (m_multiDrawBeautyShaderInstance)
                {
                    m_multiDrawBeautyShaderInstance = NULL;
                }
            }
        }
    }
    
    delete m_customTextureData;
    m_customTextureData = NULL;
}
MString customTextureShaderOverride::initialize(
const MInitContext& initContext, MInitFeedback& initFeedback)
 
{
    
        empty,
        3);
        empty,
        2);
    addGeometryRequirement(positionDesc);
    addGeometryRequirement(uvDesc);
    if (m_beautyShaderInstance)
    {
        addShaderSignature(*m_beautyShaderInstance);
    }
    if (m_multiDrawBeautyShaderInstance)
    {
        addShaderSignature(*m_multiDrawBeautyShaderInstance);
    }
    return MString(
"customTextureShaderOverride");
 
}
{
    if (m_inBeautyPass)
    {
        {
            return m_multiDrawBeautyShaderInstance;
        }
        else
        {
            return m_beautyShaderInstance;
        }
    }
    return NULL;
}
void customTextureShaderOverride::updateDG(
MObject object)
 
{
}
void customTextureShaderOverride::updateDevice()
{
    
    updateShaderInstance();
    
    buildAndUpdateCustomDataTextureViaMaya();
}
void customTextureShaderOverride::endUpdate()
{
}
{
    m_inBeautyPass = false;
    
    
    
    bool handlePass = false;
    for (
unsigned int i=0; i<passSem.
length(); i++)
 
    {
        {
            if (!hasOverrideShader)
                handlePass = true;
            m_inBeautyPass = true;
        }
        
        
        {
            handlePass = false;
        }
    }
    return handlePass;
}
{
    m_inMultiDrawMode = false;
    if (m_inBeautyPass)
    {
        if (m_inMultiDrawMode && m_multiDrawBeautyShaderInstance)
        {
            m_multiDrawBeautyShaderInstance->bind(context); 
        }
        else if (!m_inMultiDrawMode && m_beautyShaderInstance)
        {
            m_beautyShaderInstance->bind(context);  
        }
        m_shaderBound = true;
    }
}
{
    if (!m_shaderBound)
        return false;
    
    if (m_inBeautyPass)
    {
        if (m_inMultiDrawMode)
        {
            shaderInstance = m_multiDrawBeautyShaderInstance;
        }
        else
        {
            shaderInstance = m_beautyShaderInstance;
        }
        if (shaderInstance)
        {
            unsigned int passCount = shaderInstance->
getPassCount(context);
 
            if (passCount)
            {
                for (unsigned int i=0; i<passCount; i++)
                {
                }
            }
        }
        return true;
    }
    return false;
}
{
    if (m_shaderBound && m_inBeautyPass)
    {
        if (m_inMultiDrawMode && m_multiDrawBeautyShaderInstance)
        {
            m_multiDrawBeautyShaderInstance->unbind(context);
        }
        else if (!m_inMultiDrawMode && m_beautyShaderInstance)
        {
            m_beautyShaderInstance->unbind(context);
        }
    }
    m_inMultiDrawMode = false;
    m_shaderBound = false;
}
{
}
bool customTextureShaderOverride::isTransparent()
{
    return false;
}
bool customTextureShaderOverride::overridesDrawState()
{
    return false;
}
bool customTextureShaderOverride::supportsMultiDraw() const
{
    return m_multiDrawBeautyShaderInstance != NULL;
}
void customTextureShaderOverride::updateShaderInstance()
{
    if (!renderer)
        return;
    
    
    if (m_beautyShaderInstance)
    {
        m_beautyShaderInstance->setParameter("colVal", 1.0f);
    }
    if (m_multiDrawBeautyShaderInstance)
    {
        m_multiDrawBeautyShaderInstance->setParameter("colVal", 1.0f);
    }
}
void customTextureShaderOverride::buildAndUpdateCustomDataTextureViaMaya()
{
    if (!renderer)
        return;
    generateCustomTexture();
    if (myTex)
    {
        texResource.
texture = myTex;
        if (m_beautyShaderInstance)
        {
            m_beautyShaderInstance->setParameter("MyTexture", texResource);
        }
        
        if (m_multiDrawBeautyShaderInstance)
        {
            m_multiDrawBeautyShaderInstance->setParameter("MyTexture", texResource);
        }
    }
}
void customTextureShaderOverride::generateCustomTexture()
{
    int textureSize = 256;
    int numSlice = 1; 
    
    if (!m_customTextureData)
    {
        m_customTextureData = new unsigned char[4*textureSize*textureSize*numSlice];
        
        
        int index = 0;
        for (int face=0 ; face<numSlice ; face++)
        {
            for (int j=0 ; j<textureSize ; j++)
            {
                for (int i=0 ; i<textureSize ; i++)
                {
                    m_customTextureData[index++] = (unsigned char)(i);
                    m_customTextureData[index++] = (unsigned char)(j);
                    m_customTextureData[index++] = (unsigned char)(255*face/numSlice);
                    m_customTextureData[index++] = 255;
                }
            }
        }
        
        m_desc.setToDefault2DTexture();
        m_desc.fWidth = textureSize;
        m_desc.fHeight = textureSize;
        m_desc.fDepth = 1;
        m_desc.fBytesPerRow = 4*textureSize;
        m_desc.fBytesPerSlice = 4*textureSize*textureSize;
        m_desc.fMipmaps = 1;
        m_desc.fArraySlices = numSlice;
    }
}