#include <math.h>
#include <maya/MIOStream.h>
#include <maya/MSimple.h>
#include <maya/MFnNurbsCurve.h>
#include <maya/MPointArray.h>
#include <maya/MDoubleArray.h>
#include <maya/MPoint.h>
#include <maya/MRampAttribute.h>
#include <maya/MFnVolumeLight.h>
#include <maya/MFloatArray.h>
#include <maya/MIntArray.h>
#include <maya/MColorArray.h>
#include <maya/MColor.h>
DeclareSimpleCommand( volumeLight, PLUGIN_COMPANY, "5.0");
#define EQUAL(a,b) ( (((a-b) > -0.00001) && ((a-b) < 0.00001)) ? 1 : 0 )
MStatus volumeLight::doIt( const MArgList& args )
{
        MStatus stat;
        double arc = 180.0f;
        double coneEndRadius = 0.0f;
        MFnVolumeLight::MLightDirection volumeLightDirection = MFnVolumeLight::kOutward;
        MFnVolumeLight::MLightShape lightShape = MFnVolumeLight::kConeVolume;
        bool emitAmbient = true;
        unsigned        i;
        
        for ( i = 0; i < args.length(); i++ )
        {
                if ( MString( "-a" ) == args.asString( i, &stat )
                                && MS::kSuccess == stat)
                {
                        double tmp = args.asDouble( ++i, &stat );
                        if ( MS::kSuccess == stat )
                                arc = tmp;
                }
                else if ( MString( "-c" ) == args.asString( i, &stat )
                                && MS::kSuccess == stat)
                {
                        double tmp = args.asDouble( ++i, &stat );
                        if ( MS::kSuccess == stat )
                                coneEndRadius = tmp;
                }
                else if ( MString( "-e" ) == args.asString( i, &stat )
                                && MS::kSuccess == stat)
                {
                        bool tmp = args.asBool( ++i, &stat );
                        if ( MS::kSuccess == stat )
                                emitAmbient = tmp;
                }
        }
        MFnVolumeLight light;
        light.create( true, &stat);
        cout<<"What's up?";
        if ( MS::kSuccess != stat )
        {
                cout<<"Error creating light."<<endl;
                return stat;
        }
        
        stat = light.setArc ((float)arc);
        if ( MS::kSuccess != stat )
        {
                cout<<"Error setting \"arc\" attribute."<<endl;
                return stat;
        }
        stat = light.setVolumeLightDirection (volumeLightDirection);
        if ( MS::kSuccess != stat )
        {
                cout<<"Error setting \"volumeLightDirection\" attribute."<<endl;
                return stat;
        }
        stat = light.setConeEndRadius ((float)coneEndRadius);
        if ( MS::kSuccess != stat )
        {
                cout<<"Error setting \"coneEndRadius\" attribute."<<endl;
                return stat;
        }
        stat = light.setEmitAmbient (emitAmbient);
        if ( MS::kSuccess != stat )
        {
                cout<<"Error setting \"emitAmbient\" attribute."<<endl;
                return stat;
        }
        stat = light.setLightShape (lightShape);
        if ( MS::kSuccess != stat )
        {
                cout<<"Error setting \"lightShape\" attribute."<<endl;
                return stat;
        }
        double arcGet = light.arc (&stat);
        if ( MS::kSuccess != stat || arcGet != arc)
        {
                cout<<"Error getting \"arc\" attribute."<<endl;
                return stat;
        }
        MFnVolumeLight::MLightDirection volumeLightDirectionGet = light.volumeLightDirection (&stat);
        if ( MS::kSuccess != stat || volumeLightDirectionGet != volumeLightDirection)
        {
                cout<<"Error getting \"volumeLightDirection\" attribute."<<endl;
                return stat;
        }
        double coneEndRadiusGet = light.coneEndRadius (&stat);
        if ( MS::kSuccess != stat || coneEndRadiusGet != coneEndRadius)
        {
                cout<<"Error getting \"coneEndRadius\" attribute."<<endl;
                return stat;
        }
        bool emitAmbientGet = light.emitAmbient (&stat);
        if ( MS::kSuccess != stat || emitAmbientGet != emitAmbient)
        {
                cout<<"Error getting \"emitAmbient\" attribute."<<endl;
                return stat;
        }
        MFnVolumeLight::MLightShape lightShapeGet = light.lightShape (&stat);
        if ( MS::kSuccess != stat || lightShapeGet != lightShape)
        {
                cout<<"Error getting \"lightShape\" attribute."<<endl;
                return stat;
        }
        
        MRampAttribute ramp = light.penumbraRamp (&stat);
        if ( MS::kSuccess != stat )
        {
                cout<<"Error getting \"penumbraRamp\" attribute."<<endl;
                return stat;
        }
        MFloatArray a, b;
        MIntArray c,d;
        
        ramp.getEntries (d, a, b, c, &stat);
        if ( MS::kSuccess != stat )
        {
                cout<<"Error getting entries from \"penumbraRamp\" attribute."<<endl;
                return stat;
        }
        
        if (d.length() != 2)
        {
                cout<<"Invalid number of entries in \"penumbraRamp\" attribute."<<endl;
                return stat;
        }
        MFloatArray a1, b1;
        MIntArray c1;
        
        
        
        a1.append (0.5f);
        b1.append (0.25f);
        c1.append (MRampAttribute::kLinear);
        
        ramp.addEntries (a1, b1, c1, &stat);
        if ( MS::kSuccess != stat)
        {
                cout<<"Error adding entries to \"penumbraRamp\" attribute."<<endl;
                return stat;
        }
        
        MFloatArray a2, b2;
        MIntArray c2,d2;
        ramp.getEntries (d2, a2, b2, c2, &stat);
        if ( MS::kSuccess != stat )
        {
                cout<<"Error getting entries from \"penumbraRamp\" attribute."<<endl;
                return stat;
        }
        if ( a.length() + a1.length() != a2.length())
        {
                cout<<"Invalid number of entries in \"penumbraRamp\" attribute."<<endl;
                return stat;
        }
        
        float newVal = -1;
        ramp.getValueAtPosition(.3f, newVal, &stat);
        if ( MS::kSuccess != stat )
        {
                cout<<"Error interpolating value from \"penumbraRamp\" attribute."<<endl;
                return stat;
        }
        if ( !EQUAL(newVal, .15f))
        {
                cout<<"Invalid interpolation in  \"penumbraRamp\" expected .15 got "<<newVal
                        <<" ."<<endl;
        }
        
        
        
        
        
        MIntArray entriesToDelete;
        entriesToDelete.append (0);
        ramp.deleteEntries (entriesToDelete, &stat);
        if ( MS::kSuccess != stat )
        {
                cout<<"Error deleting entries from \"penumbraRamp\" attribute."<<endl;
                return stat;
        }
        
        
        
        
        ramp.getEntries (d2, a2, b2, c2, &stat);
        if ( a2.length() != 2)
        {
                cout<<"Invalid number of entries in \"penumbraRamp\" attribute."<<endl;
                return stat;
        }
        
        entriesToDelete.clear();
        entriesToDelete.append (0);
        ramp.deleteEntries (entriesToDelete, &stat);
        
        if ( MS::kSuccess == stat)
        {
                cout<<"Error deleting entries from \"penumbraRamp\" attribute."<<endl;
                return stat;
        }
        if ( a2.length() != 2)
        {
                cout<<"Invalid number of entries in \"penumbraRamp\" attribute."<<endl;
                return stat;
        }
        
        ramp.getEntries (d2, a2, b2, c2, &stat);
        entriesToDelete.clear();
        entriesToDelete.append (d2[0]);
        
        ramp.deleteEntries (entriesToDelete, &stat);
        if ( MS::kSuccess != stat)
        {
                cout<<"Error deleting entries from \"penumbraRamp\" attribute."<<endl;
                return stat;
        }
        
        ramp.getEntries (d2, a2, b2, c2, &stat);
        if ( MS::kSuccess != stat)
        {
                cout<<"Error getting entries from \"penumbraRamp\" attribute."<<endl;
                return stat;
        }
        entriesToDelete.clear();
        entriesToDelete.append (d2[0]);
        
        ramp.deleteEntries (entriesToDelete, &stat);
        if ( MS::kSuccess == stat)
        {
                cout<<"Error deleting entries from \"penumbraRamp\" attribute."<<endl;
                return stat;
        }
        ramp.setPositionAtIndex (0.0f, d2[0], &stat);
        if ( MS::kSuccess != stat)
        {
                printf("Error setting position at index: %d, of \"penumbraRamp\" attribute.\n", d2[0]);
                return stat;
        }
        ramp.setValueAtIndex (1.0f, d2[0], &stat);
        if ( MS::kSuccess != stat)
        {
                printf("Error setting value at index: %d, of \"penumbraRamp\" attribute.\n", d2[0]);
                return stat;
        }
        ramp.setInterpolationAtIndex (MRampAttribute::kNone, d2[0], &stat);
        if ( MS::kSuccess != stat)
        {
                printf("Error setting interpolation at index: %d, of \"penumbraRamp\" attribute.\n", d2[0]);
                return stat;
        }
        MRampAttribute ramp2 = light.colorRamp (&stat);
        if ( MS::kSuccess != stat)
        {
                cout<<"Error getting  \"colorRamp\" attribute."<<endl;
                return stat;
        }       
        MFloatArray a3;
        MColorArray b3;
        MIntArray c3,d3;
        
        ramp2.getEntries (d3, a3, b3, c3, &stat);
        if ( MS::kSuccess != stat)
        {
                cout<<"Error getting entries from \"colorRamp\" attribute."<<endl;
                return stat;
        }
        
        if ( d3.length() != 2)
        {
                cout<<"Invalid number of entries in \"colorRamp\" attribute."<<endl;
                return stat;
        }
        MFloatArray a4;
        MColorArray b4;
        MIntArray c4;
        
        
        
        a4.append (0.5f);
        b4.append (MColor (0.0f, 0.0f, 0.75f));
        c4.append (MRampAttribute::kLinear);
        
        ramp2.addEntries (a4, b4, c4, &stat);
        if ( MS::kSuccess != stat)
        {
                cout<<"Error adding entries to \"colorRamp\" attribute."<<endl;
                return stat;
        }
        
        MFloatArray a5;
        MColorArray b5;
        MIntArray c5,d5;
        ramp2.getEntries (d5, a5, b5, c5, &stat);
        if ( MS::kSuccess != stat)
        {
                cout<<"Error getting entries from \"colorRamp\" attribute."<<endl;
                return stat;
        }
        if (  a3.length() + a4.length() != a5.length())
        {
                cout<<"Invalid number of entries in \"colorRamp\" attribute."<<endl;
                return stat;
        }
        
        MColor newCol(0.0, 0.0, 0.0);
        ramp2.getColorAtPosition(.3f, newCol, &stat);
        if ( MS::kSuccess != stat )
        {
                cout<<"Error interpolating color from \"penumbraRamp\" attribute."<<endl;
                return stat;
        }
        if ( !EQUAL(newCol[2], .45))
        {
                cout<<"Invalid color interpolation in  \"colorRamp\" expected .45 got "<<newCol[2]<<endl;
        }
        MColor clr (0.5, 0.5, 0.0);
        ramp2.setColorAtIndex (clr, d5[0], &stat);
        if ( MS::kSuccess != stat)
        {
                cout<<"Error setting color at index: "<<d5[0]
                        <<", of \"colorRamp\" attribute."<<endl;
                return stat;
        }
        ramp2.setInterpolationAtIndex (MRampAttribute::kSpline, d5[1], &stat);
        if ( MS::kSuccess != stat)
        {
                cout<<"Error setting interpolation at index: "<<d5[1]
                        <<", of \"colorRamp\" attribute."<<endl;
                return stat;
        }
        return stat;
}