#include <maya/MDrawContext.h>
#include <maya/MGlobal.h>
#include "cgfxPassStateSetter.h"
#include "cgfxShaderNode.h"
#include <string>
#include <map>
#include <set>
#ifndef GL_INCR_WRAP
#define GL_INCR_WRAP                      0x8507
#endif
#ifndef GL_DECR_WRAP
#define GL_DECR_WRAP                      0x8508
#endif
namespace
{
    std::string lowerCaseString(const char* str) {
        std::string lower;
        lower.reserve(strlen(str));
        for (const char* p=str; *p != 0; ++p) {
            lower += char(tolower(*p));
        }
        return lower;
    }
    
    
    
    class StateAssignment
    {
    public:
        typedef void (*HandlerFn)(
            const CGstateassignment&    sa,
        
        
        
        typedef bool (*UnsupportedCheckFn)(const CGstateassignment& sa);
        static void registerHandler(const char* stateName, HandlerFn handler) {
            CGstate cgState = cgGetNamedState(cgfxShaderNode::sCgContext, stateName);
            if (cgState) {
                std::string lstateName = lowerCaseString(stateName);
                const bool inserted =
                    map.insert(
                        std::make_pair(lstateName,StateAssignment(cgState, handler))
                    ).second;
                if (!inserted) {
                    s += "cgfxPassStateSetter is trying to register multiple "
                        "handlers for the same CgFX state \"";
                    s += stateName;
                    s += "\".";
                }
            }
            else {
                s += "The CgFX state assignment \"";
                s += stateName;
                s += "\" is unknown to the Cg library.";
            }
        }
        static void registerUnsupportedCheck(const char* stateName, UnsupportedCheckFn check) {
            CGstate cgState = cgGetNamedState(cgfxShaderNode::sCgContext, stateName);
            if (cgState) {
                std::string lstateName = lowerCaseString(stateName);
                const bool inserted =
                    unsupportedChecks.insert(
                        std::make_pair(lstateName,check)
                    ).second;
                if (!inserted) {
                    s += "cgfxPassStateSetter is trying to register multiple "
                        "unsupported checks for the same CgFX state \"";
                    s += stateName;
                    s += "\".";
                }
            }
            else {
                s += "The CgFX state assignment \"";
                s += stateName;
                s += "\" is unknown to the Cg library.";
            }
        }
        static void registerIgnoredState(const char* stateName) {
            CGstate cgState = cgGetNamedState(cgfxShaderNode::sCgContext, stateName);
            if (cgState) {
                const bool inserted =
                    ignoredSet.insert(lowerCaseString(stateName)).second;
                if (!inserted) {
                    s += "cgfxPassStateSetter is trying to register multiple "
                        "ignore handlers for the same CgFX state \"";
                    s += stateName;
                    s += "\".";
                }
            }
            else {
                s += "The CgFX state assignment \"";
                s += stateName;
                s += "\" is unknown to the Cg library.";
            }
        }
        static void registerDefaultCallBacks()
        {
            
            cgSetParameterSettingMode(cgfxShaderNode::sCgContext,
                                      CG_IMMEDIATE_PARAMETER_SETTING);
            const Map::const_iterator itEnd = map.end();
            for ( Map::const_iterator it    = map.begin();
                  it != itEnd; ++it) {
                it->second.setDefaultCallbacks();
            }
        }
        static void registerVP20CallBacks()
        {
            
            cgSetParameterSettingMode(cgfxShaderNode::sCgContext,
                                      CG_DEFERRED_PARAMETER_SETTING);
            const Map::const_iterator itEnd = map.end();
            for ( Map::const_iterator it    = map.begin();
                  it != itEnd; ++it) {
                it->second.setVP20Callbacks();
            }
        }
        
        
        
        
        
        
        static bool callHandler(
            const CGstateassignment&            sa,
        {
            
            CGstate state = cgGetStateAssignmentState(sa);
            const char *stateName = cgGetStateName(state);
            std::string lstateName = lowerCaseString(stateName);
            {
                const Map::const_iterator handler = map.find(lstateName);
                if (handler != map.end()) {
                    handler->second.fHandler(sa,
                                             blendStateDesc,
                                             rasterizerStateDesc,
                                             depthStencilStateDesc);
                    return false;
                }
            }
            {
                const UnsupportedChecks::const_iterator unsupportedCheck =
                    unsupportedChecks.find(lstateName);
                if (unsupportedCheck != unsupportedChecks.end()) {
                    return unsupportedCheck->second(sa);
                }
            }
            if (ignoredSet.find(lstateName) != ignoredSet.end()) {
                
                
                
                
                return false;
            }
#ifdef DEBUG
            
            
            
            s += "cgfxShader: The CgFX state assignment \"";
            s += stateName;
            s += "\" contained in the shader file is not accelarated by the "
                "cgfxShader plugin in a VP2.0 viewport and will results in lower "
                "performance.";
#endif
            return true;
        }
    private:
        typedef std::map<std::string, StateAssignment> Map;
        typedef std::map<std::string, UnsupportedCheckFn> UnsupportedChecks;
        typedef std::set<std::string> IgnoredSet;
        friend class std::map<std::string, StateAssignment>;
        static CGbool noopStateAssignment(CGstateassignment sa) {
            return CG_TRUE;
        }
        StateAssignment(CGstate cgState, HandlerFn handler) {
            fCgState           = cgState;
            fDefaultSetCB      = cgGetStateSetCallback(cgState);
            fDefaultResetCB    = cgGetStateResetCallback(cgState);
            fDefaultValidateCB = cgGetStateValidateCallback(cgState);
            fHandler           = handler;
        }
        
        StateAssignment()
            : fCgState(NULL),
              fDefaultSetCB(NULL),
              fDefaultResetCB(NULL),
              fDefaultValidateCB(NULL),
              fHandler(NULL)
        {};
        void setDefaultCallbacks() const
        {
            cgSetStateCallbacks(fCgState,
                                fDefaultSetCB,
                                fDefaultResetCB,
                                fDefaultValidateCB);
        }
        void setVP20Callbacks() const
        {
            cgSetStateCallbacks(fCgState,
                                noopStateAssignment,
                                noopStateAssignment,
                                NULL);
        }
        static Map                  map;
        static UnsupportedChecks    unsupportedChecks;
        static IgnoredSet           ignoredSet;
        CGstate         fCgState;
        CGstatecallback fDefaultSetCB;
        CGstatecallback fDefaultResetCB;
        CGstatecallback fDefaultValidateCB;
        HandlerFn       fHandler;
    };
    StateAssignment::Map                StateAssignment::map;
    StateAssignment::UnsupportedChecks  StateAssignment::unsupportedChecks;
    StateAssignment::IgnoredSet         StateAssignment::ignoredSet;
    
    
    
    {
        switch(blendOption) {
            
            
            
            
        }
    }
    {
        switch(blendOperation) {
            
        }
    }
    {
        switch(compareMode)
        {
            
        }
    }
    {
        switch(stencilOp)
        {
            
        }
    }
    
    
    
    
    
    
    
    
    
    
        "cgfxPassStateSetter : Incoherent number of state assignment values");
    
    
    
    void assignHdlr_BlendColor(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const float* values = cgGetFloatStateAssignmentValues(sa, &numValues);
        if(numValues == 4) {
        }
        else {
        }
    }
    void assignHdlr_BlendEnable(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const CGbool *values = cgGetBoolStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
            const bool value = (values[0] == CG_TRUE) ? true : false;
            
            
        }
        else {
        }
    }
    void assignHdlr_SrcBlend(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
            
            
                mapBlendOption(values[0]);
                mapBlendOption(values[0]);
        }
        else {
        }
    }
    void assignHdlr_DestBlend(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
            
            
                mapBlendOption(values[0]);
                mapBlendOption(values[0]);
        }
        else {
        }
    }
    void assignHdlr_BlendFunc(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 2) {
            
            
                mapBlendOption(values[0]);
                mapBlendOption(values[1]);
                mapBlendOption(values[0]);
                mapBlendOption(values[1]);
        }
        else {
        }
    }
    void assignHdlr_BlendOp(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
            
            
                mapBlendOperation(values[0]);
        }
        else {
        }
    }
    void assignHdlr_BlendFuncSeparate(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 4) {
            
            
                mapBlendOption(values[0]);
                mapBlendOption(values[1]);
                mapBlendOption(values[2]);
                mapBlendOption(values[3]);
        }
        else {
        }
    }
    void assignHdlr_BlendEquationSeparate(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 2) {
            
            
                mapBlendOperation(values[0]);
                mapBlendOperation(values[1]);
        }
        else {
        }
    }
    void assignHdlr_ColorWriteEnable(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const CGbool* values = cgGetBoolStateAssignmentValues(sa, &numValues);
        if (numValues == 4) {
            
            
        }
        else {
        }
    }
    
    
    
    void assignHdlr_FillMode(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues >= 1) {
            switch(values[0])
            {
                case GL_POINT: 
                default:; 
            }
        }
        else {
        }
    }
    void assignHdlr_CullFace(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
            switch(values[0])
            {
                case GL_FRONT_AND_BACK:   
                default:; 
            }
        }
        else {
        }
    }
    void assignHdlr_CullFaceEnable(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const CGbool *values = cgGetBoolStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
            if(values[0] == CG_TRUE) {
                
            }
            else {
            }
        }
        else {
        }
    }
    void assignHdlr_FrontFace(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
            switch(values[0])
            {
                default:; 
            }
        }
        else {
        }
    }
    void assignHdlr_PolygonMode(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 2) {
            switch(values[0])
            {
                case GL_FRONT_AND_BACK:   
                default:; 
            }
            switch(values[1])
            {
                case GL_POINT: 
                default:; 
            }
        }
        else {
        }
    }
    void assignHdlr_PolygonOffset(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const float *values = cgGetFloatStateAssignmentValues(sa, &numValues);
        if (numValues == 2) {
        }
        else {
        }
    }
    void assignHdlr_DepthBias(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const float *values = cgGetFloatStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
        }
        else {
        }
    }
    void assignHdlr_SlopScaleDepthBias(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const float *values = cgGetFloatStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
        }
        else {
        }
    }
    void assignHdlr_PolygonOffsetFillEnable(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const CGbool *values = cgGetBoolStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
            rasterizerStateDesc->
depthClipEnable = (values[0] == CG_TRUE) ? 
true : 
false;
        }
        else {
        }
    }
    void assignHdlr_ScissorTestEnable(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const CGbool *values = cgGetBoolStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
            rasterizerStateDesc->
scissorEnable = (values[0] == CG_TRUE) ? 
true : 
false;
        }
        else {
        }
    }
    void assignHdlr_MultisampleEnable(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const CGbool *values = cgGetBoolStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
        }
        else {
        }
    }
    void assignHdlr_LineSmoothEnable(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const CGbool *values = cgGetBoolStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
        }
        else {
        }
    }
    
    
    
    void assignHdlr_DepthTestEnable(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const CGbool *values = cgGetBoolStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
            const bool value = (values[0] == CG_TRUE) ? true : false;
        }
        else {
        }
    }
    void assignHdlr_DepthMask(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const CGbool *values = cgGetBoolStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
            const bool value = (values[0] == CG_TRUE) ? true : false;
        }
        else {
        }
    }
    void assignHdlr_DepthFunc(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if(numValues == 1) {
            depthStencilStateDesc->
depthFunc = mapCompareMode(values[0]);
        }
        else {
        }
    }
    void assignHdlr_StencilEnable(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const CGbool *values = cgGetBoolStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
            const bool value = (values[0] == CG_TRUE) ? true : false;
        }
        else {
        }
    }
    void assignHdlr_StencilWriteMask(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 1)
        {
        }
        else {
        }
    }
    void assignHdlr_StencilFunc(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
                mapCompareMode(values[0]);
                mapCompareMode(values[0]);
        }
        else if (numValues == 3)
        {
                mapCompareMode(values[0]);
                mapCompareMode(values[0]);
        }
        else {
        }
    }
    void assignHdlr_StencilFuncSeparate(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 4) {
            switch (values[0]) {
                case GL_FRONT:
                        mapCompareMode(values[1]);
                    break;
                case GL_BACK:
                        mapCompareMode(values[1]);
                    break;
                case GL_FRONT_AND_BACK:
                default:
                        mapCompareMode(values[1]);
                        mapCompareMode(values[1]);
                    break;
            }
            
            
        }
        else {
        }
    }
    void assignHdlr_StencilOp(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 3) {
                mapStencilOperation(values[0]);
                mapStencilOperation(values[1]);
                mapStencilOperation(values[2]);
                mapStencilOperation(values[0]);
                mapStencilOperation(values[1]);
                mapStencilOperation(values[2]);
        }
        else {
        }
    }
    void assignHdlr_StencilOpSeparate(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 4) {
            if (values[0] == GL_FRONT || values[0] == GL_FRONT_AND_BACK) {
                    mapStencilOperation(values[1]);
                    mapStencilOperation(values[2]);
                    mapStencilOperation(values[3]);
            }
            if (values[0] == GL_BACK || values[0] == GL_FRONT_AND_BACK) {
                    mapStencilOperation(values[1]);
                    mapStencilOperation(values[2]);
                    mapStencilOperation(values[3]);
            }
        }
        else {
        }
    }
    void assignHdlr_StencilRef(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
        }
        else {
        }
    }
    void assignHdlr_StencilFail(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
                mapStencilOperation(values[0]);
                mapStencilOperation(values[0]);
        }
        else {
        }
    }
    void assignHdlr_StencilZFail(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
                mapStencilOperation(values[0]);
                mapStencilOperation(values[0]);
        }
        else {
        }
    }
    void assignHdlr_StencilPass(
        const CGstateassignment& sa,
    {
        int numValues = 0;
        const int *values = cgGetIntStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
                mapStencilOperation(values[0]);
                mapStencilOperation(values[0]);
        }
        else {
        }
    }
    
    
    
    bool unsupportedIfTrue(const CGstateassignment& sa)
    {
        int numValues = 0;
        const CGbool *values = cgGetBoolStateAssignmentValues(sa, &numValues);
        if (numValues == 1) {
            const bool value = (values[0] == CG_TRUE) ? true : false;
            if (value) {
#ifdef DEBUG
                CGstate state = cgGetStateAssignmentState(sa);
                const char *stateName = cgGetStateName(state);
                
                
                
                s += "cgfxShader: The CgFX state assignment \"";
                s += stateName;
                s += " = true;\" contained in the shader file is not accelarated by the "
                    "cgfxShader plugin in a VP2.0 viewport and will results in lower "
                    "performance.";
#endif
                return true;
            }
            else {
                
                
                
                
                return false;
            }
        }
        else {
            return true;
        }
    }
}
cgfxPassStateSetter::ViewportMode cgfxPassStateSetter::sActiveViewportMode =
    cgfxPassStateSetter::kUnknown;
bool cgfxPassStateSetter::registerCgStateCallBacks(
    cgfxPassStateSetter::ViewportMode mode
) {
    static bool initialized = false;
    if(!initialized)
    {
        
        StateAssignment::registerIgnoredState("VertexProgram");
        StateAssignment::registerIgnoredState("VertexShader");
        StateAssignment::registerIgnoredState("GeometryProgram");
        StateAssignment::registerIgnoredState("GeometryShader");
        StateAssignment::registerIgnoredState("FragmentProgram");
        StateAssignment::registerIgnoredState("PixelShader");
        
        StateAssignment::registerHandler("BlendColor",        assignHdlr_BlendColor      );
        StateAssignment::registerHandler("BlendEnable",       assignHdlr_BlendEnable     );
        StateAssignment::registerHandler("AlphaBlendEnable",  assignHdlr_BlendEnable     );
        StateAssignment::registerHandler("SrcBlend",          assignHdlr_SrcBlend        );
        StateAssignment::registerHandler("DestBlend",         assignHdlr_DestBlend       );
        StateAssignment::registerHandler("BlendFunc",         assignHdlr_BlendFunc       );
        StateAssignment::registerHandler("BlendOp",           assignHdlr_BlendOp         );
        StateAssignment::registerHandler("BlendEquation",     assignHdlr_BlendOp         );
        StateAssignment::registerHandler("BlendFuncSeparate", assignHdlr_BlendFuncSeparate );
        StateAssignment::registerHandler("BlendEquationSeparate", assignHdlr_BlendEquationSeparate );
        StateAssignment::registerHandler("ColorWriteEnable",  assignHdlr_ColorWriteEnable);
        
        
        
        
        
        
        
        
        
        
        
        StateAssignment::registerHandler("FillMode",                assignHdlr_FillMode                );
        StateAssignment::registerHandler("CullMode",                assignHdlr_CullFace                );
        StateAssignment::registerHandler("CullFace",                assignHdlr_CullFace                );
        StateAssignment::registerHandler("CullFaceEnable",          assignHdlr_CullFaceEnable          );
        StateAssignment::registerHandler("FrontFace",               assignHdlr_FrontFace               );
        StateAssignment::registerHandler("PolygonMode",             assignHdlr_PolygonMode             );
        StateAssignment::registerHandler("PolygonOffset",           assignHdlr_PolygonOffset           );
        StateAssignment::registerHandler("DepthBias",               assignHdlr_DepthBias               );
        StateAssignment::registerHandler("SlopScaleDepthBias",      assignHdlr_SlopScaleDepthBias      );
        StateAssignment::registerHandler("PolygonOffsetFillEnable", assignHdlr_PolygonOffsetFillEnable );
        StateAssignment::registerHandler("ScissorTestEnable",       assignHdlr_ScissorTestEnable       );
        StateAssignment::registerHandler("MultisampleEnable",       assignHdlr_MultisampleEnable       );
        StateAssignment::registerHandler("MultiSampleAntialias",    assignHdlr_MultisampleEnable       );
        
        
        
        StateAssignment::registerHandler("LineSmoothEnable",        assignHdlr_LineSmoothEnable       );
        StateAssignment::registerHandler("PointSmoothEnable",       assignHdlr_LineSmoothEnable       );
        
        StateAssignment::registerHandler("DepthTestEnable",         assignHdlr_DepthTestEnable         );
        StateAssignment::registerHandler("ZEnable",                 assignHdlr_DepthTestEnable         );
        StateAssignment::registerHandler("DepthMask",               assignHdlr_DepthMask               );
        StateAssignment::registerHandler("ZWriteEnable",            assignHdlr_DepthMask               );
        StateAssignment::registerHandler("DepthFunc",               assignHdlr_DepthFunc               );
        StateAssignment::registerHandler("StencilEnable",           assignHdlr_StencilEnable           );
        StateAssignment::registerHandler("StencilTestEnable",       assignHdlr_StencilEnable           );
        StateAssignment::registerHandler("StencilMask",             assignHdlr_StencilWriteMask        );
        StateAssignment::registerHandler("StencilWriteMask",        assignHdlr_StencilWriteMask        );
        StateAssignment::registerHandler("StencilFunc",             assignHdlr_StencilFunc             );
        StateAssignment::registerHandler("StencilFuncSeparate",     assignHdlr_StencilFuncSeparate     );
        StateAssignment::registerHandler("StencilOp",               assignHdlr_StencilOp               );
        StateAssignment::registerHandler("StencilOpSeparate",       assignHdlr_StencilOpSeparate       );
        StateAssignment::registerHandler("StencilRef",              assignHdlr_StencilRef              );
        StateAssignment::registerHandler("StencilFail",             assignHdlr_StencilFail             );
        StateAssignment::registerHandler("StencilZFail",            assignHdlr_StencilZFail            );
        StateAssignment::registerHandler("StencilPass",             assignHdlr_StencilPass             );
        
        StateAssignment::registerUnsupportedCheck("AutoNormalEnable",               unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("AlphaTestEnable",                unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("ClipPlaneEnable",                unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("ColorLogicOpEnable",             unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("ColorVertex",                    unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("DepthBoundsEnable",              unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("DepthClampEnable",               unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("DitherEnable",                   unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("FogEnable",                      unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("LightEnable",                    unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("LightModelLocalViewerEnable",    unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("LightModelTwoSideEnable",        unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("LightingEnable",                 unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("LineStippleEnable",              unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("LocalViewer",                    unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("LogicOpEnable",                  unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("NormalizeEnable",                unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("PointScaleEnable",               unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("PointSmoothEnable",              unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("PointSpriteCoordReplace",        unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("PointSpriteEnable",              unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("PolygonOffsetLineEnable",        unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("PolygonOffsetPointEnable",       unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("PolygonStippleEnable",           unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("RescaleNormalEnable",            unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("SampleAlphaToCoverageEnable",    unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("SampleAlphaToOneEnable",         unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("SampleCoverageEnable",           unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("ScissorTestEnable",              unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("StencilTestTwoSideEnable",       unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("TexGenQEnable",                  unsupportedIfTrue);
        StateAssignment::registerUnsupportedCheck("TexGenREnable",                  unsupportedIfTrue );
        StateAssignment::registerUnsupportedCheck("TexGenSEnable",                  unsupportedIfTrue );
        StateAssignment::registerUnsupportedCheck("TexGenTEnable",                  unsupportedIfTrue );
        StateAssignment::registerUnsupportedCheck("Texture1DEnable",                unsupportedIfTrue );
        StateAssignment::registerUnsupportedCheck("Texture2DEnable",                unsupportedIfTrue );
        StateAssignment::registerUnsupportedCheck("Texture3DEnable",                unsupportedIfTrue );
        StateAssignment::registerUnsupportedCheck("TextureCubeMapEnable",           unsupportedIfTrue );
        StateAssignment::registerUnsupportedCheck("TextureRectangleEnable",         unsupportedIfTrue );
        StateAssignment::registerUnsupportedCheck("VertexProgramPointSizeEnable",   unsupportedIfTrue );
        StateAssignment::registerUnsupportedCheck("VertexProgramTwoSideEnable",     unsupportedIfTrue );
        initialized = true;
    }
    if(mode == cgfxPassStateSetter::kUnknown)
        return false;
    if(mode == cgfxPassStateSetter::sActiveViewportMode)
        return true;
    if(mode == cgfxPassStateSetter::kDefaultViewport)
    {
        StateAssignment::registerDefaultCallBacks();
        sActiveViewportMode = cgfxPassStateSetter::kDefaultViewport;
    }
    else
    {
        StateAssignment::registerVP20CallBacks();
        sActiveViewportMode = cgfxPassStateSetter::kVP20Viewport;
    }
    return true;
}
cgfxPassStateSetter::cgfxPassStateSetter()
    : fBlendState(NULL),
      fRasterizerState(NULL),
      fDepthStencilState(NULL),
      fIsPushPopAttribsRequired(false)
{}
void cgfxPassStateSetter::init(
    CGpass pass
)
{
    
    CGstateassignment sa = cgGetFirstStateAssignment(pass);
    while (sa) {
        fIsPushPopAttribsRequired |=
            StateAssignment::callHandler(sa,
                                         &blendStateDesc,
                                         &rasterizerStateDesc,
                                         &depthStencilStateDesc);
        sa = cgGetNextStateAssignment(sa);
    }
}
cgfxPassStateSetter::~cgfxPassStateSetter()
{
    MStateManager::releaseBlendState(fBlendState);
    fBlendState = NULL;
    MStateManager::releaseDepthStencilState(fDepthStencilState);
    fDepthStencilState = NULL;
    MStateManager::releaseRasterizerState(fRasterizerState);
    fRasterizerState = NULL;
}
void cgfxPassStateSetter::setPassState(
MStateManager* stateMgr)
 const 
{
}