#include <assert.h>
#include <maya/MGlobal.h>
#include <maya/MString.h>
#include <maya/MPoint.h>
#include <maya/MVector.h>
#include <maya/MVectorArray.h>
#include <maya/MFloatMatrix.h>
#include <maya/MArgList.h>
#include <maya/MPlug.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MDagPath.h>
#include <maya/MItDag.h>
#include <maya/MSelectionList.h>
#include <maya/MPlug.h>
#include <maya/MPlugArray.h>
#include <maya/MPxCommand.h>
#include <maya/MFnDagNode.h>
#include <maya/MFnFluid.h>
#include <maya/MFnPlugin.h>
#define mCommandName "fluidInfo"    // Command name
{
public:
                 fluidInfoCmd();
    virtual     ~fluidInfoCmd();
    static void* creator();
private:
    int     requestedVoxels;
};
fluidInfoCmd::fluidInfoCmd()
{
}
fluidInfoCmd::~fluidInfoCmd() 
{
}
{
    {
    }
}
{
    if(!methodStr) {
    } else {
        switch( method )
        {
            strcpy(methodStr, "Zero");
            break;
            strcpy(methodStr, "Static Grid");
            break;
            strcpy(methodStr, "Dynamic Grid");
            break;
            strcpy(methodStr, "Gradient");
            break;
        default:
            strcpy(methodStr, "Garbage");
            break;
        }
    }
    return stat;
}
{
    if(!methodStr) {
    } else {
        switch( method )
        {
            strcpy(methodStr, "No Falloff Grid");
            break;
            strcpy(methodStr, "Static Grid");
            break;
        default:
            strcpy(methodStr, "Garbage");
            break;
        }
    }
    return stat;
}
{
    if(!methodStr) {
    } else {
        switch( method )
        {
            strcpy(methodStr, "Shading Color");
            break;
            strcpy(methodStr, "Static Grid");
            break;
            strcpy(methodStr, "Dynamic Grid");
            break;
        default:
            strcpy(methodStr, "Garbage");
            break;
        }
    }
    return stat;
}
{
    if(!methodStr) {
    } else {
        switch( method )
        {
            strcpy(methodStr, "Fixed");
            break;
            strcpy(methodStr, "Grid");
            break;
        default:
            strcpy(methodStr, "Garbage");
            break;
        }
    }
    return stat;
}
{
    if(!gradientStr) {
    } else {
        switch( gradient )
        {
            strcpy(gradientStr, " Constant");
            break;
            strcpy(gradientStr, "X Gradient");
            break;
            strcpy(gradientStr, "Y Gradient");
            break;
            strcpy(gradientStr, "Z Gradient");
            break;
            strcpy(gradientStr, "Negative X Gradient");
            break;
            strcpy(gradientStr, "Negative Y Gradient");
            break;
            strcpy(gradientStr, "Negative Z Gradient");
            break;
            strcpy(gradientStr, "Center Gradient");
            break;
        default:
            strcpy(gradientStr, "Garbage");
            break;
        }
    }
    return stat;
}
{
    
    
    requestedVoxels = -1;
    {
    }
    {
    }
    {
    }
        
        
        requestedVoxels = -1;
    } else {
        requestedVoxels = args.
asInt( 1, &stat );
        {
        }
    }
    nodeFromName( fluidName, fluidNode );
    if( fluidNode.isNull() )
    {
    }
    {
    }
}
{
    {
        return stat;
    }
    unsigned Xres, Yres, Zres;
    fluffy.getResolution(Xres, Yres, Zres);
    double Xdim, Ydim, Zdim;
    fluffy.getDimensions(Xdim, Ydim, Zdim);
    char buffer[256];
    
    sprintf( buffer, "Fluid: %s", fluidName.asChar());
    sprintf( buffer, "resolution %u %u %u", Xres, Yres, Zres );
    sprintf( buffer, "dimensions %g %g %g\n", Xdim, Ydim, Zdim );
    
    
    int numPrintVoxels = requestedVoxels;
    if(requestedVoxels < 0 || requestedVoxels > (int)fluffy.gridSize()) {
        numPrintVoxels = fluffy.gridSize();     
    }
    
    fluffy.voxelCenterPosition(0, 0, 0, centerPt);
    sprintf( buffer, 
"first voxel pos %g %g %g", centerPt.
x, centerPt.
y, centerPt.
z );
    
    
    
    char methodName[32];
    char gradientName[32];
    fluffy.getDensityMode(method, gradient);
    fluidMethodName(method, methodName);
    fluidGradientName(gradient, gradientName);
        sprintf( buffer, "Density method: %s type: %s", methodName, gradientName);
    else 
        sprintf( buffer, "Density method: %s ", methodName);
        float *densityGrid = fluffy.density();
        if(densityGrid != NULL) {
            sprintf( buffer, "Density grid contents:");
            int xi, yi, zi;
            for(int i = 0; i < numPrintVoxels; i++) {
                fluffy.index(i, xi, yi, zi);
                sprintf(buffer, "index: %d voxel: [%d %d %d] density: %g", i, xi, yi, zi, densityGrid[i]);
            }
        }
    }
    
    
    
    fluffy.getTemperatureMode(method, gradient);
    fluidMethodName(method, methodName);
    fluidGradientName(gradient, gradientName);
        sprintf( buffer, "Temperature method: %s type: %s", methodName, gradientName);
    else 
        sprintf( buffer, "Temperature method: %s ", methodName);
        float *tempGrid = fluffy.temperature();
        if(tempGrid != NULL) {
            sprintf( buffer, "Tempereature grid contents:");
            int xi, yi, zi;
            for(int i = 0; i < numPrintVoxels; i++) {
                fluffy.index(i, xi, yi, zi);
                sprintf(buffer, "index: %d voxel: [%d %d %d] temperature: %g", i, xi, yi, zi, tempGrid[i]);
            }
        }
    }
    
    
    
    fluffy.getFuelMode(method, gradient);
    fluidMethodName(method, methodName);
    fluidGradientName(gradient, gradientName);
        sprintf( buffer, "Fuel method: %s type: %s", methodName, gradientName);
    else 
        sprintf( buffer, "Fuel method: %s ", methodName);
        float *fuelGrid = fluffy.fuel();
        if(fuelGrid != NULL) {
            sprintf( buffer, "Fuel grid contents:");
            int xi, yi, zi;
            for(int i = 0; i < numPrintVoxels; i++) {
                fluffy.index(i, xi, yi, zi);
                sprintf(buffer, "index: %d voxel: [%d %d %d] fuel: %g", i, xi, yi, zi, fuelGrid[i]);
            }
        }
    }
    
    
    
    
    fluffy.getVelocityMode(method, gradient);
    fluidMethodName(method, methodName);
    fluidGradientName(gradient, gradientName);
        sprintf( buffer, "Velocity method: %s type: %s", methodName, gradientName);
    else 
        sprintf( buffer, "Velocity method: %s ", methodName);
        float *xvelGrid;
        float *yvelGrid;
        float *zvelGrid;
        fluffy.getVelocity(xvelGrid, yvelGrid, zvelGrid);
        if(xvelGrid && yvelGrid && zvelGrid) {
            int i;
            int xi, yi, zi;
            float xvel, yvel, zvel;
                
            
            int xvSize, yvSize, zvSize;
            fluffy.velocityGridSizes(xvSize, yvSize, zvSize);
            int numXvelVoxels = requestedVoxels;
            if(requestedVoxels < 0 || requestedVoxels > xvSize) {
                numXvelVoxels = xvSize;     
            }
            sprintf( buffer, "X velocity grid contents:");
            for(i = 0; i < numXvelVoxels; i++) {
                fluffy.index(i, Xres+1, Yres, Zres, xi, yi, zi);
                sprintf(buffer, "index: %d voxel face: [%d %d %d] x velocity: %g", i, xi, yi, zi, xvelGrid[i]);
            }
            
            sprintf( buffer, "Voxel Center Velocity:");
            int viLow, viHigh;
            for(i = 0; i < numPrintVoxels; i++) {
                fluffy.index(i, xi, yi, zi);
                viLow = fluffy.index(xi, yi, zi, Xres+1, Yres, Zres);
                viHigh = fluffy.index(xi+1, yi, zi, Xres+1, Yres, Zres);
                xvel = (xvelGrid[viHigh] + xvelGrid[viLow])/2.0f;
                viLow = fluffy.index(xi, yi, zi, Xres, Yres+1, Zres);
                viHigh = fluffy.index(xi, yi+1, zi, Xres, Yres+1, Zres);
                yvel = (yvelGrid[viHigh] + yvelGrid[viLow])/2.0f;
                viLow = fluffy.index(xi, yi, zi, Xres, Yres, Zres+1);
                viHigh = fluffy.index(xi, yi, zi+1, Xres, Yres, Zres+1);
                zvel = (zvelGrid[viHigh] + zvelGrid[viLow])/2.0f;
                
                sprintf(buffer, "index: %d voxel: [%d %d %d] velocity: (%g, %g, %g)", i, xi, yi, zi, xvel, yvel, zvel);
            }
            
        }
        float *pressureGrid = fluffy.pressure();
        if(pressureGrid != NULL) {
            sprintf( buffer, "Pressure grid contents:");
            int xi, yi, zi;
            for(int i = 0; i < numPrintVoxels; i++) {
                fluffy.index(i, xi, yi, zi);
                sprintf(buffer, "index: %d voxel: [%d %d %d] pressure: %g", i, xi, yi, zi, pressureGrid[i]);
            }
        }
    }
    
    
    
    fluffy.getCoordinateMode(coordMethod);
    coordMethodName(coordMethod, methodName);
    sprintf( buffer, "Coordinate method: %s ", methodName);
        float *uGrid;
        float *vGrid;
        float *wGrid;
        fluffy.getCoordinates(uGrid, vGrid, wGrid);
        if(uGrid && vGrid && wGrid) {
            int xi, yi, zi;
                
            
            int i;
            sprintf( buffer, "Tex Coord grid contents:");
            for(i = 0; i < numPrintVoxels; i++) {
                fluffy.index(i, xi, yi, zi);
                sprintf(buffer, "index: %d voxel: [%d %d %d] uvw: (%g, %g, %g)", i, xi, yi, zi, uGrid[i], vGrid[i], wGrid[i]);
            }
            
        }
        else if(uGrid && vGrid && (Zres == 1)) {
            int xi, yi, zi;
                
            
            int i;
            sprintf( buffer, "Tex Coord grid contents:");
            for(i = 0; i < numPrintVoxels; i++) {
                fluffy.index(i, xi, yi, zi);
                sprintf(buffer, "index: %d voxel: [%d %d %d] uv: (%g, %g)", i, xi, yi, zi, uGrid[i], vGrid[i]);
            }
            
        }
    }
    
    
    
    fluffy.getColorMode(colorMethod);
    colorMethodName(colorMethod, methodName);
    sprintf( buffer, "Color method: %s ", methodName);
        float *rGrid;
        float *gGrid;
        float *bGrid;
        fluffy.getColors(rGrid, gGrid, bGrid);
        if(rGrid && gGrid && bGrid) {
            int xi, yi, zi;
                
            int i;
            sprintf( buffer, "Color grid contents:");
            for(i = 0; i < numPrintVoxels; i++) {
                fluffy.index(i, xi, yi, zi);
                sprintf(buffer, "index: %d voxel: [%d %d %d] color: (%g, %g, %g)", i, xi, yi, zi, rGrid[i], gGrid[i], bGrid[i]);
            }
            
        }
    }
    
    
    
    fluffy.getFalloffMode(falloffMethod);
    falloffMethodName(falloffMethod, methodName);
    sprintf( buffer, "Falloff method: %s ", methodName);
        float *falloffGrid = fluffy.falloff();
        if(falloffGrid != NULL) {
            sprintf( buffer, "Falloff grid contents:");
            int xi, yi, zi;
            for(int i = 0; i < numPrintVoxels; i++) {
                fluffy.index(i, xi, yi, zi);
                sprintf(buffer, "index: %d voxel: [%d %d %d] falloff: %g", i, xi, yi, zi, falloffGrid[i]);
            }
        }
    }
}
void * fluidInfoCmd::creator() { return new fluidInfoCmd(); }
{
    MFnPlugin plugin( obj, PLUGIN_COMPANY, 
"6.0", 
"Any");
 
    MStatus status = plugin.registerCommand(mCommandName,
 
                                            fluidInfoCmd::creator );
    if (!status) 
        status.
perror(
"registerCommand");
    return status;
}
{
    MStatus status = plugin.deregisterCommand(mCommandName);
 
    if (!status) 
        status.
perror(
"deregisterCommand");
    return status;
}