#include <maya/MFnPlugin.h>
#include <maya/MPxNode.h>
#include <maya/MIOStream.h>
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnStringData.h>
#include <maya/MRenderUtil.h>
#include <maya/MImage.h>
#include <maya/MFloatVector.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MDrawRegistry.h>
#include <maya/MPxShadingNodeOverride.h>
#include <maya/MViewport2Renderer.h>
#include <maya/MFragmentManager.h>
#include <maya/MShaderManager.h>
#include <maya/MTextureManager.h>
#include <maya/MStateManager.h>
{
public:
    static void* creator();
    FileNode();
    virtual ~FileNode();
    
private:
    size_t fWidth;
    size_t fHeight;
    
};
{
public:
    virtual ~FileNodeOverride();
private:
    FileNodeOverride(
const MObject& obj);
    mutable MString fResolvedSamplerName;
 
};
const MTypeId FileNode::id(0x00081057);
 
void* FileNode::creator()
{
    return new FileNode();
}
FileNode::FileNode()
: fWidth(0)
, fHeight(0)
{
}
FileNode::~FileNode()
{
}
void FileNode::postConstructor()
{
    setMPSafe(true);
}
MStatus FileNode::setDependentsDirty(
 
{
    if (plug == aFileName)
    {
        fImage.release();
        fWidth = fHeight = 0;
    }
}
{
    
    if ((plug != aOutColor) &&
        (plug.
parent() != aOutColor) &&
        (plug != aOutAlpha))
    {
    }
    float resultAlpha = 1.0f;
    
    if (!fImage.pixels())
    {
        
        
        
        {
            unsigned int width = 0;
            unsigned int height = 0;
            if (fImage.readFromFile(exactName) &&
                fImage.getSize(width, height))
            {
                fWidth = width;
                fHeight = height;
            }
        }
    }
    
    unsigned char* data = fImage.pixels();
    if (data && fWidth > 0 && fHeight > 0)
    {
        float u = uv[0]; if (u<0.0f) u=0.0f; if (u>1.0f) u=1.0f;
        float v = uv[1]; if (v<0.0f) v=0.0f; if (v>1.0f) v=1.0f;
        static const size_t pixelSize = 4;
        size_t rowOffset = (size_t)(v*(fHeight-1)) * fWidth;
        size_t colOffset = (size_t)(u*(fWidth-1));
        const unsigned char* pixel = data +
            ((rowOffset + colOffset) * pixelSize);
        resultColor[0] = ((float)pixel[0])/255.0f;
        resultColor[1] = ((float)pixel[1])/255.0f;
        resultColor[2] = ((float)pixel[2])/255.0f;
        resultAlpha = ((float)pixel[3])/255.0f;
    }
    
    outColor = resultColor;
    
    float& outAlpha = outAlphaHandle.
asFloat();
 
    outAlpha = resultAlpha;
}
#define MAKE_INPUT(attr) \
    CHECK_MSTATUS(attr.setKeyable(true)); \
    CHECK_MSTATUS(attr.setStorable(true)); \
    CHECK_MSTATUS(attr.setReadable(true)); \
    CHECK_MSTATUS(attr.setWritable(true));
#define MAKE_OUTPUT(attr) \
    CHECK_MSTATUS(attr.setKeyable(false)); \
    CHECK_MSTATUS(attr.setStorable(false)); \
    CHECK_MSTATUS(attr.setReadable(true)); \
    CHECK_MSTATUS(attr.setWritable(false));
{
    
    MAKE_INPUT(tAttr);
    aUVCoord = nAttr.
create(
"uvCoord",
"uv", child1, child2);
    MAKE_INPUT(nAttr);
    
    MAKE_OUTPUT(nAttr);
    MAKE_OUTPUT(nAttr);
    
    
}
{
    return new FileNodeOverride(obj);
}
FileNodeOverride::FileNodeOverride(
const MObject& obj)
: MPxShadingNodeOverride(obj)
, fObject(obj)
, fFragmentName("")
, fFileName("")
, fSamplerState(NULL)
, fResolvedMapName("")
, fResolvedSamplerName("")
{
    
    
    
    static const MString sFragmentOutputName(
"fileTexturePluginFragmentOutput");
 
    static const char* sFragmentOutputBody =
        "<fragment uiName=\"fileTexturePluginFragmentOutput\" name=\"fileTexturePluginFragmentOutput\" type=\"structure\" class=\"ShadeFragment\" version=\"1.0\">"
        "   <description><![CDATA[Struct output for simple file texture fragment]]></description>"
        "   <properties>"
        "       <struct name=\"fileTexturePluginFragmentOutput\" struct_name=\"fileTexturePluginFragmentOutput\" />"
        "   </properties>"
        "   <values>"
        "   </values>"
        "   <outputs>"
        "       <alias name=\"fileTexturePluginFragmentOutput\" struct_name=\"fileTexturePluginFragmentOutput\" />"
        "       <float3 name=\"outColor\" />"
        "       <float name=\"outAlpha\" />"
        "   </outputs>"
        "   <implementation>"
        "   <implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.1\">"
        "       <function_name val=\"\" />"
        "       <declaration name=\"fileTexturePluginFragmentOutput\"><![CDATA["
        "struct fileTexturePluginFragmentOutput \n"
        "{ \n"
        "   float3 outColor; \n"
        "   float outAlpha; \n"
        "}; \n]]>"
        "       </declaration>"
        "   </implementation>"
        "   <implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.0\">"
        "       <function_name val=\"\" />"
        "       <declaration name=\"fileTexturePluginFragmentOutput\"><![CDATA["
        "struct fileTexturePluginFragmentOutput \n"
        "{ \n"
        "   float3 outColor; \n"
        "   float outAlpha; \n"
        "}; \n]]>"
        "       </declaration>"
        "   </implementation>"
        "   <implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\">"
        "       <function_name val=\"\" />"
        "       <declaration name=\"fileTexturePluginFragmentOutput\"><![CDATA["
        "struct fileTexturePluginFragmentOutput \n"
        "{ \n"
        "   vec3 outColor; \n"
        "   float outAlpha; \n"
        "}; \n]]>"
        "       </declaration>"
        "   </implementation>"
        "   </implementation>"
        "</fragment>";
    static const MString sFragmentName(
"fileTexturePluginFragment");
 
    static const char* sFragmentBody =
        "<fragment uiName=\"fileTexturePluginFragment\" name=\"fileTexturePluginFragment\" type=\"plumbing\" class=\"ShadeFragment\" version=\"1.0\">"
        "   <description><![CDATA[Simple file texture fragment]]></description>"
        "   <properties>"
        "       <float2 name=\"uvCoord\" semantic=\"mayaUvCoordSemantic\" flags=\"varyingInputParam\" />"
        "       <texture2 name=\"map\" />"
        "       <sampler name=\"textureSampler\" />"
        "   </properties>"
        "   <values>"
        "   </values>"
        "   <outputs>"
        "       <struct name=\"output\" struct_name=\"fileTexturePluginFragmentOutput\" />"
        "   </outputs>"
        "   <implementation>"
        "   <implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.100000\">"
        "       <function_name val=\"fileTexturePluginFragment\" />"
        "       <source><![CDATA["
        "fileTexturePluginFragmentOutput fileTexturePluginFragment(float2 uv, texture2D map, sampler2D mapSampler) \n"
        "{ \n"
        "   fileTexturePluginFragmentOutput result; \n"
        "   uv -= floor(uv); \n"
        "   uv.y = 1.0f - uv.y; \n"
        "   float4 color = tex2D(mapSampler, uv); \n"
        "   result.outColor = color.rgb; \n"
        "   result.outAlpha = color.a; \n"
        "   return result; \n"
        "} \n]]>"
        "       </source>"
        "   </implementation>"
        "   <implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.000000\">"
        "       <function_name val=\"fileTexturePluginFragment\" />"
        "       <source><![CDATA["
        "fileTexturePluginFragmentOutput fileTexturePluginFragment(float2 uv, Texture2D map, sampler mapSampler) \n"
        "{ \n"
        "   fileTexturePluginFragmentOutput result; \n"
        "   uv -= floor(uv); \n"
        "   uv.y = 1.0f - uv.y; \n"
        "   float4 color = map.Sample(mapSampler, uv); \n"
        "   result.outColor = color.rgb; \n"
        "   result.outAlpha = color.a; \n"
        "   return result; \n"
        "} \n]]>"
        "       </source>"
        "   </implementation>"
        "   <implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\">"
        "       <function_name val=\"fileTexturePluginFragment\" />"
        "       <source><![CDATA["
        "fileTexturePluginFragmentOutput fileTexturePluginFragment(vec2 uv, sampler2D mapSampler) \n"
        "{ \n"
        "   fileTexturePluginFragmentOutput result; \n"
        "   uv -= floor(uv); \n"
        "   uv.y = 1.0f - uv.y; \n"
        "   vec4 color = texture(mapSampler, uv); \n"
        "   result.outColor = color.rgb; \n"
        "   result.outAlpha = color.a; \n"
        "   return result; \n"
        "} \n]]>"
        "       </source>"
        "   </implementation>"
        "   </implementation>"
        "</fragment>";
    static const MString sFragmentGraphName(
"fileTexturePluginGraph");
 
    static const char* sFragmentGraphBody =
        "<fragment_graph name=\"fileTexturePluginGraph\" ref=\"fileTexturePluginGraph\" class=\"FragmentGraph\" version=\"1.0\">"
        "   <fragments>"
        "           <fragment_ref name=\"fileTexturePluginFragment\" ref=\"fileTexturePluginFragment\" />"
        "           <fragment_ref name=\"fileTexturePluginFragmentOutput\" ref=\"fileTexturePluginFragmentOutput\" />"
        "   </fragments>"
        "   <connections>"
        "       <connect from=\"fileTexturePluginFragment.output\" to=\"fileTexturePluginFragmentOutput.fileTexturePluginFragmentOutput\" />"
        "   </connections>"
        "   <properties>"
        "       <float2 name=\"uvCoord\" ref=\"fileTexturePluginFragment.uvCoord\" semantic=\"mayaUvCoordSemantic\" flags=\"varyingInputParam\" />"
        "       <texture2 name=\"map\" ref=\"fileTexturePluginFragment.map\" />"
        "       <sampler name=\"textureSampler\" ref=\"fileTexturePluginFragment.textureSampler\" />"
        "   </properties>"
        "   <values>"
        "   </values>"
        "   <outputs>"
        "       <struct name=\"output\" ref=\"fileTexturePluginFragmentOutput.fileTexturePluginFragmentOutput\" />"
        "   </outputs>"
        "</fragment_graph>";
    
    
    if (theRenderer)
    {
        if (fragmentMgr)
        {
            
            bool fragAdded = fragmentMgr->
hasFragment(sFragmentName);
 
            bool structAdded = fragmentMgr->
hasFragment(sFragmentOutputName);
 
            bool graphAdded = fragmentMgr->
hasFragment(sFragmentGraphName);
 
            if (!fragAdded)
            {
            }
            if (!structAdded)
            {
            }
            if (!graphAdded)
            {
            }
            
            if (fragAdded && structAdded && graphAdded)
            {
                fFragmentName = sFragmentGraphName;
            }
        }
    }
}
FileNodeOverride::~FileNodeOverride()
{
    fSamplerState = NULL;
}
{
}
MString FileNodeOverride::fragmentName()
 const 
{
    
    fResolvedMapName = "";
    fResolvedSamplerName = "";
    return fFragmentName;
}
void FileNodeOverride::getCustomMappings(
{
    
    
    
        "map", "", false, true);
        "textureSampler", "", false, true);
    mappings.
append(textureSamplerMapping);
}
void FileNodeOverride::updateDG()
{
    
    if (status)
    {
        node.findPlug("fileName").getValue(name);
    }
}
void FileNodeOverride::updateShader(
{
    
    if (fResolvedMapName.length() == 0)
    {
        if (mapping)
        {
        }
    }
    if (fResolvedSamplerName.length() == 0)
    {
        if (mapping)
        {
        }
    }
    
    if (fResolvedMapName.length() > 0 && fResolvedSamplerName.length() > 0)
    {
        
        if (!fSamplerState)
        {
        }
        if (fSamplerState)
        {
        }
        
        if (renderer)
        {
            if (textureManager)
            {
                if (texture)
                {
                    textureAssignment.
texture = texture;
                    
                }
            }
        }
    }
}
static const MString sRegistrantId(
"fileTexturePlugin");
 
{
    const MString UserClassify(
"texture/2d:drawdb/shader/texture/2d/fileTexture");
 
    MFnPlugin plugin(obj, PLUGIN_COMPANY, 
"1.0", 
"Any");
 
        "fileTexture",
        FileNode::id,
        FileNode::creator,
        FileNode::initialize,
        &UserClassify));
            "drawdb/shader/texture/2d/fileTexture",
            sRegistrantId,
            FileNodeOverride::creator));
}
{
            "drawdb/shader/texture/2d/fileTexture",
            sRegistrantId));
}