#include <maya/MCommonSystemUtils.h>
#include <maya/MGlobal.h>
#include <maya/MStringArray.h>
#include "cgfxProfile.h"
#include <Cg/cgGL.h>
static const char* CgGLProfileList[][4] = {
{"gp5",  "gp5vp",  "gp5gp", "gp5fp"},
{"gp4",  "gp4vp",  "gp4gp", "gp4fp"},
{"glsl", "glslv",  "glslg", "glslf"},
{"NV4X", "vp40",   "",      "fp40"},
{"arb1", "arbvp1", "",      "arbfp1"},
{"NV3X", "vp30",   "",      "fp30"},
{"NV2X", "vp20",   "",      "fp20"}
};
cgfxProfile::TexCoordOrientation cgfxProfile::sTexCoordOrientation =
    cgfxProfile::TEXCOORD_OPENGL;
cgfxProfile*       cgfxProfile::sProfileList = NULL;
const cgfxProfile* cgfxProfile::sBestProfile = NULL;
void cgfxProfile::initialize()
{
    
    {
        if (status) 
        {
            if (str == "OPENGL" || str == "")
                sTexCoordOrientation = TEXCOORD_OPENGL;
            else if (str == "DIRECTX")
                sTexCoordOrientation = TEXCOORD_DIRECTX;
            else {
                MString es = 
"cgfxShader : The value ";
 
                es += str;
                es += " of the MAYA_TEXCOORD_ORIENTATION environment variable is unsupported. ";
                es += "Supported values are OPENGL and DIRECTX";
            }
        }
    }
    
    
    {
        const int nbKnownProfiles = sizeof(CgGLProfileList)/sizeof(const char*[4]);
        cgfxProfile** currentEntry = &sProfileList;
        
        for (int i=0; i<nbKnownProfiles; ++i) {
            const char* shortName       = CgGLProfileList[i][0];
            const char* vtxProfileName  = CgGLProfileList[i][1];
            const char* geomProfileName = CgGLProfileList[i][2];
            const char* fragProfileName = CgGLProfileList[i][3];
            CGprofile vtxProfile  = cgGetProfile(vtxProfileName);
            CGprofile geomProfile = cgGetProfile(geomProfileName);
            CGprofile fragProfile = cgGetProfile(fragProfileName);
            
            if (
                cgGLIsProfileSupported(vtxProfile) &&
                (geomProfileName[0] == '\0' || cgGLIsProfileSupported(geomProfile)) &&
                cgGLIsProfileSupported(fragProfile)
            ) {
                *currentEntry = new cgfxProfile(
                    shortName, vtxProfile, geomProfile, fragProfile);
                currentEntry = &(*currentEntry)->fNext;
            }
        }
    }
    
    if (sProfileList == NULL) {
        sBestProfile = NULL;
    }
    else if (sProfileList->fNext == NULL) {
        
        sBestProfile = sProfileList;
    }
    else {
        if (sProfileList->fName == "glsl") {
            
            
            
            sBestProfile = sProfileList->fNext;
        }
        else {
            sBestProfile = sProfileList;
        }
    }
}
void cgfxProfile::uninitialize()
{
    cgfxProfile* profile = sProfileList;
    while (profile) {
      cgfxProfile* nextProfile = profile->fNext;
      delete profile;
      profile = nextProfile;
    }
    sProfileList = 0;
    sBestProfile = 0;    
}
{
    cgfxProfile* profile = sProfileList;
    while (profile) {
        result.
append(profile->fName);
        profile = profile->fNext;
    }
    return result;
}
const cgfxProfile* cgfxProfile::getProfile(
MString profileName)
 
{
    if (profileName == "") {
        
        return NULL;
    }
    else {
        
        const cgfxProfile* profile = sProfileList;
        while (profile) {
            if (profile->fName == profileName) {
                return profile;
            }
            profile = profile->fNext;
        }
    }
    return NULL;
}
cgfxProfile::cgfxProfile(
  MString name, CGprofile vtx, CGprofile geom, CGprofile frag
 
) 
  : fName(name),
    fVtx(vtx),
    fGeom(geom),
    fFrag(frag),
    fNext(NULL)
{}
cgfxProfile::cgfxProfile(
MString name, CGpass pass)
  : fName(name),
    fVtx(CG_PROFILE_UNKNOWN),
    fGeom(CG_PROFILE_UNKNOWN),
    fFrag(CG_PROFILE_UNKNOWN),
    fNext(NULL)
{
    CGprogram vp = cgGetPassProgram(pass, CG_VERTEX_DOMAIN);
    if (vp != NULL) {
        fVtx = cgGetProgramProfile(vp);
    }
    CGprogram gp = cgGetPassProgram(pass, CG_GEOMETRY_DOMAIN);
    if (gp != NULL) {
        fGeom = cgGetProgramProfile(gp);
    }
    CGprogram fp = cgGetPassProgram(pass, CG_FRAGMENT_DOMAIN);
    if (fp != NULL) {
        fFrag = cgGetProgramProfile(fp);
    }
}
cgfxProfile::~cgfxProfile()
{}
bool cgfxProfile::isSupported() const
{
    return
        (fVtx == CG_PROFILE_UNKNOWN  || cgGLIsProfileSupported(fVtx)) &&
        (fGeom == CG_PROFILE_UNKNOWN || cgGLIsProfileSupported(fGeom)) &&
        (fFrag == CG_PROFILE_UNKNOWN || cgGLIsProfileSupported(fFrag));
}