void GLIDebugVariableGrid::SetUniformData(const UniformDataArray &newData)
{
  //Clear existing array
  uniformDataArray.clear();

  //Loop for all values
  for(uint i=0; i<newData.size(); i++)
  {
    UniformRowData newUniformRowData;

    //Assign the uniform data
    newUniformRowData.name = newData[i].name;
    newUniformRowData.type = newData[i].type;
    newUniformRowData.numTypeElements  = newData[i].numTypeElements;
    newUniformRowData.isFloatType      = newData[i].isFloatType;

    newUniformRowData.intUniformData   = newData[i].intUniformData;
    newUniformRowData.floatUniformData = newData[i].floatUniformData;

    //Calculate the array size
    if(newUniformRowData.isFloatType)
    {
      //Ensure the array values are correct
      if(newUniformRowData.floatUniformData.size() % newUniformRowData.numTypeElements != 0)
      {
        newUniformRowData.arrayCount = 0;
      }
      else
      {
        newUniformRowData.arrayCount = newUniformRowData.floatUniformData.size() / newUniformRowData.numTypeElements; 
      }
    }
    else
    {
      //Ensure the array values are correct
      if(newUniformRowData.intUniformData.size() % newUniformRowData.numTypeElements != 0)
      {
        newUniformRowData.arrayCount = 0;
      }
      else
      {
        newUniformRowData.arrayCount = newUniformRowData.intUniformData.size() / newUniformRowData.numTypeElements; 
      }
    }

    //Add to the array
    uniformDataArray.push_back(newUniformRowData);
  }

}
void SubstituteShaderGLSL::GenerateUniformRemapArray(string &initLog)
{
  uint i;
  string bufferStr;

  //Get the uniforms of the old program
  UniformDataArray oldUniformData;
  if(!shaderUtils.GetUniformData(oldProgramID, oldUniformData))
  {
    initLog += "Unble to get old program unform data\n";
    return;
  }

  //Get the uniforms of the new program
  UniformDataArray newUniformData;
  if(!shaderUtils.GetUniformData(programID, newUniformData))
  {
    initLog += "Unble to get new program unform data\n";
    return;
  }

  //Clear the mapping array
  remapUniformArray.clear();

  //Loop for all values in the old array
  for(i=0; i<oldUniformData.size(); i++)
  {
    bool foundFlag = false;
    const UniformData & oldData = oldUniformData[i];

    //Loop for all new values
    for(uint i2=0; i2<newUniformData.size(); i2++)
    {
      const UniformData & newData = newUniformData[i2];

      //Check for a name match
      if(oldData.name == newData.name)
      {
        foundFlag = true;

        //Check the types and abort if not equal 
        if(oldData.type != newData.type)
        {
          StringPrintF(bufferStr," %s - Uniforms types are different\n",oldData.name.c_str());
          initLog += bufferStr;
          break;
        }

        //Check the sizes 
        uint addDataTypeSize = oldData.size;
        if(oldData.size != newData.size)
        {
          StringPrintF(bufferStr," %s - Uniform sizes are different (%u != %u)\n",
                                    oldData.name.c_str(),oldData.size,newData.size);
          initLog += bufferStr;

          //Take the minimum of the two sizes
          if(newData.size < addDataTypeSize)
          {
            addDataTypeSize = newData.size;
          }
        }
        
        //Check the type size
        if(addDataTypeSize == 0)
        {
          StringPrintF(bufferStr," %s - Uniform size is zero?\n", oldData.name.c_str());
          initLog += bufferStr;
          break;
        }

        //Create a new entry in the mapping array
        UniformData addData;
        
        addData.indexData  = oldData.indexData;
        addData.remapIndex = newData.indexData[0];

        addData.name = newData.name;
        addData.size = addDataTypeSize;
        addData.type = newData.type;

        //Get the data about the type 
        if(!shaderUtils.GetTypeData(addData.type, addData.numTypeElements, addData.baseFormat))
        {
          StringPrintF(bufferStr," %s - Uniform is not a known type: 0x%x\n", addData.name.c_str(),addData.type);
          initLog += bufferStr;
          break;
        }

        //Test if the data can be copied without OpenGL errors (ATI bug)
        if(TestUniformDataCopy(addData, initLog))
        {
          //Add the data to the array
          remapUniformArray.push_back(addData);
        }

#ifdef  GLI_ATI_UNIFORM_GLSL_BUG

        //If it is just a single variable (hopefully a sampler), use the ATI override
        else if(addData.baseFormat == GL_INT && addData.numTypeElements == 1)
        {
          initLog += string("Using ATI uniform override on ") + addData.name + string("\n");
          addData.isATIUniformOverride = true; 
          remapUniformArray.push_back(addData);
        }

#endif  //GLI_ATI_UNIFORM_GLSL_BUG


        break;
      }
    }

    //If not found
    if(!foundFlag)
    {
      StringPrintF(bufferStr," %s - Uniform not found in new program\n",
                                oldData.name.c_str());
      initLog += bufferStr;
    }
  }

  //Log all the new uniforms not in the old program
  for(i=0; i<newUniformData.size(); i++)
  {
    bool foundFlag = false;
    const UniformData & newData = newUniformData[i];

    //Loop for all old values
    for(uint i2=0; i2<oldUniformData.size(); i2++)
    {
      const UniformData & oldData = oldUniformData[i2];

      //Check for a name match
      if(oldData.name == newData.name)
      {
        foundFlag = true;
        break;
      }
    }

    //If not found
    if(!foundFlag)
    {
      StringPrintF(bufferStr," %s - Uniform in new program -not in old program\n",
                               newData.name.c_str());
      initLog += bufferStr;
    }
  }

}