#include<math.h>
#include<iostream.h>
#include <maya/MPxNode.h>
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MArrayDataHandle.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnLightDataAttribute.h>
#include <maya/MFloatVector.h>
#include <maya/MFnPlugin.h>
#include <maya/MGlobal.h>

class outlineshade : public MPxNode
{
public:
	 outlineshade();
	 virtual ~outlineshade();

         virtual MStatus compute( const MPlug&, MDataBlock& );
         static  void    *creator();
         static  MStatus initialize();
         static  MTypeId id;
protected:
	 static MObject color1R,color1G,color1B,color1;
	 static MObject color2R,color2G,color2B,color2;
	 static MObject color3R,color3G,color3B,color3;
         static MObject aNormalCameraX, aNormalCameraY, aNormalCameraZ, 
aNormalCamera;
         static MObject aPointCameraX, aPointCameraY, aPointCameraZ, 
aPointCamera;
         static MObject aOutColorR, aOutColorG, aOutColorB, aOutColor;
         static MObject aOutColorR2, aOutColorG2, aOutColorB2, aOutColor=
2;
         static MObject aOutline;
         static MObject aTest1,aTest2;
};

MObject outlineshade::color1R;
MObject outlineshade::color1G;
MObject outlineshade::color1B;
MObject outlineshade::color1;
MObject outlineshade::color2R;
MObject outlineshade::color2G;
MObject outlineshade::color2B;
MObject outlineshade::color2;
MObject outlineshade::color3R;
MObject outlineshade::color3G;
MObject outlineshade::color3B;
MObject outlineshade::color3;

MObject outlineshade::aNormalCameraX;
MObject outlineshade::aNormalCameraY;
MObject outlineshade::aNormalCameraZ;
MObject outlineshade::aNormalCamera;
MObject outlineshade::aPointCameraX;
MObject outlineshade::aPointCameraY;
MObject outlineshade::aPointCameraZ;
MObject outlineshade::aPointCamera;
MObject outlineshade::aOutColorR;
MObject outlineshade::aOutColorG;
MObject outlineshade::aOutColorB;
MObject outlineshade::aOutColor;
MObject outlineshade::aOutColorR2;
MObject outlineshade::aOutColorG2;
MObject outlineshade::aOutColorB2;
MObject outlineshade::aOutColor2;
MObject outlineshade::aOutline;
MObject outlineshade::aTest1;
MObject outlineshade::aTest2;

outlineshade::outlineshade()
{
}

outlineshade::~outlineshade()
{
}

void* outlineshade::creator()
{
    return new outlineshade();
}

MStatus outlineshade::initialize()
{
   MFnNumericAttribute nAttr;

   color1R = nAttr.create( "color1R", "c1r", MFnNumericData::kFloat);
   color1G = nAttr.create( "color1G", "c1g", MFnNumericData::kFloat);
   color1B = nAttr.create( "color1B", "c1b", MFnNumericData::kFloat);
   color1 = nAttr.create( "Color", "c1", color1R, color1G, color1B);
   nAttr.setStorable(true);
   nAttr.setUsedAsColor(true);
   nAttr.setDefault(1.0f, 1.0f, 1.0f);

   color2R = nAttr.create( "color2R", "c2r", MFnNumericData::kFloat);
   color2G = nAttr.create( "color2G", "c2g", MFnNumericData::kFloat);
   color2B = nAttr.create( "color2B", "c2b", MFnNumericData::kFloat);
   color2 = nAttr.create( "Color2", "c2", color2R, color2G, color2B);
   nAttr.setStorable(true);
   nAttr.setUsedAsColor(true);
   nAttr.setDefault(1.0f, 1.0f, 1.0f);

   color3R = nAttr.create( "color3R", "c3r", MFnNumericData::kFloat);
   color3G = nAttr.create( "color3G", "c3g", MFnNumericData::kFloat);
   color3B = nAttr.create( "color3B", "c3b", MFnNumericData::kFloat);
   color3 = nAttr.create( "Color3", "c3", color3R, color3G, color3B);
   nAttr.setStorable(true);
   nAttr.setUsedAsColor(true);
   nAttr.setDefault(1.0f, 1.0f, 1.0f);

   aNormalCameraX = nAttr.create( "normalCameraX", "nx", 
MFnNumericData::kFloat);
   nAttr.setStorable(false);
   nAttr.setDefault(1.0f);

   aNormalCameraY = nAttr.create( "normalCameraY", "ny", 
MFnNumericData::kFloat);
   nAttr.setStorable(false);
   nAttr.setDefault(1.0f);

   aNormalCameraZ = nAttr.create( "normalCameraZ", "nz", 
MFnNumericData::kFloat);
   nAttr.setStorable(false);
   nAttr.setDefault(1.0f);

   aNormalCamera = nAttr.create( "normalCamera","n", aNormalCameraX,
                          aNormalCameraY, aNormalCameraZ);
   nAttr.setStorable(false);
   nAttr.setDefault(1.0f,1.0f,1.0f);
   nAttr.setHidden(true);

   aPointCameraX = nAttr.create( "pointCameraX", "px", 
MFnNumericData::kFloat);
   nAttr.setStorable(false);
   nAttr.setDefault(1.0f);

   aPointCameraY = nAttr.create( "pointCameraY", "py", 
MFnNumericData::kFloat);
   nAttr.setStorable(false);
   nAttr.setDefault(1.0f);

   aPointCameraZ = nAttr.create( "pointCameraZ", "pz", 
MFnNumericData::kFloat);
   nAttr.setStorable(false);
   nAttr.setDefault(1.0f);

   aPointCamera = nAttr.create( "pointCamera","p", aPointCameraX,
                          aPointCameraY, aPointCameraZ);
   nAttr.setStorable(false);
   nAttr.setDefault(1.0f,1.0f,1.0f);
   nAttr.setHidden(true);

   aOutColorR = nAttr.create( "outColorR", "ocr", MFnNumericData::kFlo=
at);
   aOutColorG = nAttr.create( "outColorG", "ocg", MFnNumericData::kFlo=
at);
   aOutColorB = nAttr.create( "outColorB", "ocb", MFnNumericData::kFlo=
at);
   aOutColor  = nAttr.create( "outColor",   "oc", aOutColorR, aOutColo=
rG, 
aOutColorB);
   nAttr.setStorable(false);
   nAttr.setHidden(false);
   nAttr.setReadable(true);
   nAttr.setWritable(false);


aOutline =nAttr.create("outline","oline",MFnNumericData::kFloat);
nAttr.setStorable(true);
nAttr.setMin(-0.2f);
nAttr.setMax(5.0f);
nAttr.setDefault(0.463f);

aTest1 =nAttr.create("test1","ts1",MFnNumericData::kFloat);
nAttr.setStorable(true);
nAttr.setMin(-0.2f);
nAttr.setMax(1.0f);
nAttr.setDefault(0.012f);

aTest2 =nAttr.create("test2","ts2",MFnNumericData::kFloat);
nAttr.setStorable(true);
nAttr.setMin(-0.2f);
nAttr.setMax(9.0f);
nAttr.setDefault(0.612f);

   addAttribute(color1R);
   addAttribute(color1G);
   addAttribute(color1B);
   addAttribute(color1);
   addAttribute(color2R);
   addAttribute(color2G);
   addAttribute(color2B);
   addAttribute(color2);
   addAttribute(color3R);
   addAttribute(color3G);
   addAttribute(color3B);
   addAttribute(color3);
   addAttribute(aNormalCameraX);
   addAttribute(aNormalCameraY);
   addAttribute(aNormalCameraZ);
   addAttribute(aNormalCamera);
   addAttribute(aPointCameraX);
   addAttribute(aPointCameraY);
   addAttribute(aPointCameraZ);
   addAttribute(aPointCamera);
   addAttribute(aOutColorR);
   addAttribute(aOutColorG);
   addAttribute(aOutColorB);
   addAttribute(aOutColor);
   addAttribute(aOutline);
   addAttribute(aTest1);
   addAttribute(aTest2);

   attributeAffects(color1R, color1);
   attributeAffects(color1G, color1);
   attributeAffects(color1B, color1);
   attributeAffects(color1,  aOutColor);
   attributeAffects(color2R, color2);
   attributeAffects(color2G, color2);
   attributeAffects(color2B, color2);
   attributeAffects(color2,  aOutColor);
   attributeAffects(color3R, color3);
   attributeAffects(color3G, color3);
   attributeAffects(color3B, color3);
   attributeAffects(color3,  aOutColor);
   attributeAffects(aNormalCameraX, aOutColor);
   attributeAffects(aNormalCameraY, aOutColor);
   attributeAffects(aNormalCameraZ, aOutColor);
   attributeAffects(aNormalCamera,  aOutColor);
   attributeAffects(aPointCameraX, aOutColor);
   attributeAffects(aPointCameraY, aOutColor);
   attributeAffects(aPointCameraZ, aOutColor);
   attributeAffects(aPointCamera,  aOutColor);
   attributeAffects(aOutline,  aOutColor);
   attributeAffects(aTest1,  aOutColor);
   attributeAffects(aTest2,  aOutColor);

   return MS::kSuccess;
   }

   MTypeId outlineshade::id( 0x70001 );

   MStatus outlineshade::compute( const MPlug& plug, MDataBlock& block )
  {
   int k = 0;
   float gamma, scalar;

   k |= (plug == aOutColor);
   k |= (plug == aOutColorR);
   k |= (plug == aOutColorG);
   k |= (plug == aOutColorB);
  if(!k)
{
    return MS::kUnknownParameter;
  }

   MFloatVector resultColor(0.0, 0.0, 0.0);

   MFloatVector& col = block.inputValue( color1 ).asFloatVector();
   MFloatVector& col2 = block.inputValue( color2 ).asFloatVector();
   MFloatVector& col3 = block.inputValue( color3 ).asFloatVector();
   MFloatVector& surfaceNormal = block.inputValue( aNormalCamera 
).asFloatVector();
   MFloatVector& viewVector = block.inputValue( 
aPointCamera).asFloatVector();

   double& line = block.inputValue ( aOutline ).asFloat () ;
   double& test1 = block.inputValue ( aTest1 ).asFloat () ;
   double& test2 = block.inputValue ( aTest2 ).asFloat () ;

   double d =sqrt((viewVector[0] * viewVector[0]) +

                  (viewVector[1] * viewVector[1]) +
                   (viewVector[2] * viewVector[2]));

      if (d!=(double)0.0) {
	  viewVector[0] /= d;
          viewVector[1] /= d;
          viewVector[2] /= d;
    }

        viewVector[0] *= -1 ;
        viewVector[1] *= -1 ;
        viewVector[2] *= -1 ;


   float sign = surfaceNormal*viewVector;

     if(sign>0.0&&sign<line )
    {
      resultColor = col;

    }
     else if(sign>test1&&sign<test2)
     {
      resultColor = col2;
     }
     else if(surfaceNormal=0.3){
      resultColor = col3;
     }





      MDataHandle outColorHandle = block.outputValue( aOutColor );
      MFloatVector& outColor = outColorHandle.asFloatVector();
      outColor = resultColor;
      outColorHandle.setClean();

      return MS::kSuccess;
}

  MStatus initializePlugin( MObject obj )
{
const MString UserClassify( "shader/surface" );
MString command( "if( `window -exists createRenderNodeWindow` )  
{refreshCreateRenderNodeWindow(\"" );

MFnPlugin plugin( obj, "Alias|Wavefront", "1.0", "Ary");
plugin.registerNode( "outlineshade", outlineshade::id,
               outlineshade::creator, outlineshade::initialize,
              MPxNode::kDependNode, &UserClassify );
command += UserClassify;
command += "\");}\n";

MGlobal::executeCommand(command);


return MS::kSuccess;


}

MStatus uninitializePlugin( MObject obj)
{
  const MString UserClassify( "shader/surface" );
  MString command( "if( `window -exists createRenderNodeWindow` )  
{refreshCreateRenderNodeWindow(\"" );

  MFnPlugin plugin( obj );
  plugin.deregisterNode( outlineshade::id );

  command += UserClassify;
  command += "\");}\n";

  MGlobal::executeCommand(command);

  return MS::kSuccess;
}

