// SwiftShader Software Renderer
//
// Copyright(c) 2005-2013 TransGaming Inc.
//
// All rights reserved. No part of this software may be copied, distributed, transmitted,
// transcribed, stored in a retrieval system, translated into any human or computer
// language by any means, or disclosed to third parties without the explicit written
// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
// or implied, including but not limited to any patent rights, are granted to you.
//

// Program.cpp: Implements the Program class. Implements GL program objects
// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.

#include "Program.h"

#include "main.h"
#include "Shader.h"
#include "utilities.h"
#include "common/debug.h"
#include "Shader/PixelShader.hpp"
#include "Shader/VertexShader.hpp"

#include <string>
#include <stdlib.h>

namespace es2
{
	unsigned int Program::currentSerial = 1;

	std::string str(int i)
	{
		char buffer[20];
		sprintf(buffer, "%d", i);
		return buffer;
	}

	Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize) : type(type), precision(precision), name(name), arraySize(arraySize)
	{
		int bytes = UniformTypeSize(type) * size();
		data = new unsigned char[bytes];
		memset(data, 0, bytes);
		dirty = true;

		psRegisterIndex = -1;
		vsRegisterIndex = -1;
	}

	Uniform::~Uniform()
	{
		delete[] data;
	}

	bool Uniform::isArray() const
	{
		return arraySize >= 1;
	}

	int Uniform::size() const
	{
		return arraySize > 0 ? arraySize : 1;
	}

	int Uniform::registerCount() const
	{
		return size() * VariableRowCount(type);
	}

	UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) : name(name), element(element), index(index)
	{
	}

	Program::Program(ResourceManager *manager, GLuint handle) : resourceManager(manager), handle(handle), serial(issueSerial())
	{
		device = getDevice();

		fragmentShader = 0;
		vertexShader = 0;
		pixelBinary = 0;
		vertexBinary = 0;

		infoLog = 0;
		validated = false;

		unlink();

		orphaned = false;
		referenceCount = 0;
	}

	Program::~Program()
	{
		unlink();

		if(vertexShader)
		{
			vertexShader->release();
		}

		if(fragmentShader)
		{
			fragmentShader->release();
		}
	}

	bool Program::attachShader(Shader *shader)
	{
		if(shader->getType() == GL_VERTEX_SHADER)
		{
			if(vertexShader)
			{
				return false;
			}

			vertexShader = (VertexShader*)shader;
			vertexShader->addRef();
		}
		else if(shader->getType() == GL_FRAGMENT_SHADER)
		{
			if(fragmentShader)
			{
				return false;
			}

			fragmentShader = (FragmentShader*)shader;
			fragmentShader->addRef();
		}
		else UNREACHABLE();

		return true;
	}

	bool Program::detachShader(Shader *shader)
	{
		if(shader->getType() == GL_VERTEX_SHADER)
		{
			if(vertexShader != shader)
			{
				return false;
			}

			vertexShader->release();
			vertexShader = 0;
		}
		else if(shader->getType() == GL_FRAGMENT_SHADER)
		{
			if(fragmentShader != shader)
			{
				return false;
			}

			fragmentShader->release();
			fragmentShader = 0;
		}
		else UNREACHABLE();

		return true;
	}

	int Program::getAttachedShadersCount() const
	{
		return (vertexShader ? 1 : 0) + (fragmentShader ? 1 : 0);
	}

	sw::PixelShader *Program::getPixelShader()
	{
		return pixelBinary;
	}

	sw::VertexShader *Program::getVertexShader()
	{
		return vertexBinary;
	}

	void Program::bindAttributeLocation(GLuint index, const char *name)
	{
		if(index < MAX_VERTEX_ATTRIBS)
		{
			for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
			{
				attributeBinding[i].erase(name);
			}

			attributeBinding[index].insert(name);
		}
	}

	GLuint Program::getAttributeLocation(const char *name)
	{
		if(name)
		{
			for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
			{
				if(linkedAttribute[index].name == std::string(name))
				{
					return index;
				}
			}
		}

		return -1;
	}

	int Program::getAttributeStream(int attributeIndex)
	{
		ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
    
		return attributeStream[attributeIndex];
	}

	// Returns the index of the texture image unit (0-19) corresponding to a sampler index (0-15 for the pixel shader and 0-3 for the vertex shader)
	GLint Program::getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex)
	{
		GLuint logicalTextureUnit = -1;

		switch(type)
		{
		case sw::SAMPLER_PIXEL:
			ASSERT(samplerIndex < sizeof(samplersPS) / sizeof(samplersPS[0]));

			if(samplersPS[samplerIndex].active)
			{
				logicalTextureUnit = samplersPS[samplerIndex].logicalTextureUnit;
			}
			break;
		case sw::SAMPLER_VERTEX:
			ASSERT(samplerIndex < sizeof(samplersVS) / sizeof(samplersVS[0]));

			if(samplersVS[samplerIndex].active)
			{
				logicalTextureUnit = samplersVS[samplerIndex].logicalTextureUnit;
			}
			break;
		default: UNREACHABLE();
		}

		if(logicalTextureUnit >= 0 && logicalTextureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS)
		{
			return logicalTextureUnit;
		}

		return -1;
	}

	// Returns the texture type for a given sampler type and index (0-15 for the pixel shader and 0-3 for the vertex shader)
	TextureType Program::getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex)
	{
		switch(type)
		{
		case sw::SAMPLER_PIXEL:
			ASSERT(samplerIndex < sizeof(samplersPS)/sizeof(samplersPS[0]));
			ASSERT(samplersPS[samplerIndex].active);
			return samplersPS[samplerIndex].textureType;
		case sw::SAMPLER_VERTEX:
			ASSERT(samplerIndex < sizeof(samplersVS)/sizeof(samplersVS[0]));
			ASSERT(samplersVS[samplerIndex].active);
			return samplersVS[samplerIndex].textureType;
		default: UNREACHABLE();
		}

		return TEXTURE_2D;
	}

	GLint Program::getUniformLocation(std::string name)
	{
		int subscript = 0;

		// Strip any trailing array operator and retrieve the subscript
		size_t open = name.find_last_of('[');
		size_t close = name.find_last_of(']');
		if(open != std::string::npos && close == name.length() - 1)
		{
			subscript = atoi(name.substr(open + 1).c_str());
			name.erase(open);
		}

		unsigned int numUniforms = uniformIndex.size();
		for(unsigned int location = 0; location < numUniforms; location++)
		{
			if(uniformIndex[location].name == name &&
			   uniformIndex[location].element == subscript)
			{
				return location;
			}
		}

		return -1;
	}

	bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
	{
		if(location < 0 || location >= (int)uniformIndex.size())
		{
			return false;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];
		targetUniform->dirty = true;

		int size = targetUniform->size();

		if(size == 1 && count > 1)
		{
			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
		}
	
		count = std::min(size - (int)uniformIndex[location].element, count);

		if(targetUniform->type == GL_FLOAT)
		{
			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat),
				   v, sizeof(GLfloat) * count);
		}
		else if(targetUniform->type == GL_BOOL)
		{
			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element;

			for(int i = 0; i < count; i++)
			{
				if(v[i] == 0.0f)
				{
					boolParams[i] = GL_FALSE;
				}
				else
				{
					boolParams[i] = GL_TRUE;
				}
			}
		}
		else
		{
			return false;
		}

		return true;
	}

	bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
	{
		if(location < 0 || location >= (int)uniformIndex.size())
		{
			return false;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];
		targetUniform->dirty = true;

		int size = targetUniform->size();

		if(size == 1 && count > 1)
		{
			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
		}
	
		count = std::min(size - (int)uniformIndex[location].element, count);

		if(targetUniform->type == GL_FLOAT_VEC2)
		{
			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 2,
				   v, 2 * sizeof(GLfloat) * count);
		}
		else if(targetUniform->type == GL_BOOL_VEC2)
		{
			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * 2;

			for(int i = 0; i < count * 2; i++)
			{
				if(v[i] == 0.0f)
				{
					boolParams[i] = GL_FALSE;
				}
				else
				{
					boolParams[i] = GL_TRUE;
				}
			}
		}
		else 
		{
			return false;
		}

		return true;
	}

	bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
	{
		if(location < 0 || location >= (int)uniformIndex.size())
		{
			return false;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];
		targetUniform->dirty = true;

		int size = targetUniform->size();

		if(size == 1 && count > 1)
		{
			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
		}
	
		count = std::min(size - (int)uniformIndex[location].element, count);

		if(targetUniform->type == GL_FLOAT_VEC3)
		{
			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 3,
				   v, 3 * sizeof(GLfloat) * count);
		}
		else if(targetUniform->type == GL_BOOL_VEC3)
		{
			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * 3;

			for(int i = 0; i < count * 3; i++)
			{
				if(v[i] == 0.0f)
				{
					boolParams[i] = GL_FALSE;
				}
				else
				{
					boolParams[i] = GL_TRUE;
				}
			}
		}
		else 
		{
			return false;
		}

		return true;
	}

	bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
	{
		if(location < 0 || location >= (int)uniformIndex.size())
		{
			return false;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];
		targetUniform->dirty = true;

		int size = targetUniform->size();

		if(size == 1 && count > 1)
		{
			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
		}
	
		count = std::min(size - (int)uniformIndex[location].element, count);

		if(targetUniform->type == GL_FLOAT_VEC4)
		{
			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 4,
				   v, 4 * sizeof(GLfloat) * count);
		}
		else if(targetUniform->type == GL_BOOL_VEC4)
		{
			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * 4;

			for(int i = 0; i < count * 4; i++)
			{
				if(v[i] == 0.0f)
				{
					boolParams[i] = GL_FALSE;
				}
				else
				{
					boolParams[i] = GL_TRUE;
				}
			}
		}
		else 
		{
			return false;
		}

		return true;
	}

	bool Program::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)
	{
		if(location < 0 || location >= (int)uniformIndex.size())
		{
			return false;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];
		targetUniform->dirty = true;

		if(targetUniform->type != GL_FLOAT_MAT2)
		{
			return false;
		}

		int size = targetUniform->size();

		if(size == 1 && count > 1)
		{
			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
		}

		count = std::min(size - (int)uniformIndex[location].element, count);

		memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 4,
			   value, 4 * sizeof(GLfloat) * count);

		return true;
	}

	bool Program::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)
	{
		if(location < 0 || location >= (int)uniformIndex.size())
		{
			return false;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];
		targetUniform->dirty = true;

		if(targetUniform->type != GL_FLOAT_MAT3)
		{
			return false;
		}

		int size = targetUniform->size();

		if(size == 1 && count > 1)
		{
			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
		}

		count = std::min(size - (int)uniformIndex[location].element, count);

		memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 9,
			   value, 9 * sizeof(GLfloat) * count);

		return true;
	}

	bool Program::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)
	{
		if(location < 0 || location >= (int)uniformIndex.size())
		{
			return false;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];
		targetUniform->dirty = true;

		if(targetUniform->type != GL_FLOAT_MAT4)
		{
			return false;
		}

		int size = targetUniform->size();

		if(size == 1 && count > 1)
		{
			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
		}

		count = std::min(size - (int)uniformIndex[location].element, count);

		memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 16,
			   value, 16 * sizeof(GLfloat) * count);

		return true;
	}

	bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
	{
		if(location < 0 || location >= (int)uniformIndex.size())
		{
			return false;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];
		targetUniform->dirty = true;

		int size = targetUniform->size();

		if(size == 1 && count > 1)
		{
			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
		}
	
		count = std::min(size - (int)uniformIndex[location].element, count);

		if(targetUniform->type == GL_INT ||
		   targetUniform->type == GL_SAMPLER_2D ||
		   targetUniform->type == GL_SAMPLER_CUBE ||
           targetUniform->type == GL_SAMPLER_EXTERNAL_OES)
		{
			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint),
				   v, sizeof(GLint) * count);
		}
		else if(targetUniform->type == GL_BOOL)
		{
			GLboolean *boolParams = new GLboolean[count];

			for(int i = 0; i < count; i++)
			{
				if(v[i] == 0)
				{
					boolParams[i] = GL_FALSE;
				}
				else
				{
					boolParams[i] = GL_TRUE;
				}
			}

			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),
				   boolParams, sizeof(GLboolean) * count);

			delete[] boolParams;
		}
		else
		{
			return false;
		}

		return true;
	}

	bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
	{
		if(location < 0 || location >= (int)uniformIndex.size())
		{
			return false;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];
		targetUniform->dirty = true;

		int size = targetUniform->size();

		if(size == 1 && count > 1)
		{
			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
		}
	
		count = std::min(size - (int)uniformIndex[location].element, count);

		if(targetUniform->type == GL_INT_VEC2)
		{
			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint) * 2,
				   v, 2 * sizeof(GLint) * count);
		}
		else if(targetUniform->type == GL_BOOL_VEC2)
		{
			GLboolean *boolParams = new GLboolean[count * 2];

			for(int i = 0; i < count * 2; i++)
			{
				if(v[i] == 0)
				{
					boolParams[i] = GL_FALSE;
				}
				else
				{
					boolParams[i] = GL_TRUE;
				}
			}

			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean) * 2,
				   boolParams, 2 * sizeof(GLboolean) * count);

			delete[] boolParams;
		}
		else
		{
			return false;
		}

		return true;
	}

	bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
	{
		if(location < 0 || location >= (int)uniformIndex.size())
		{
			return false;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];
		targetUniform->dirty = true;

		int size = targetUniform->size();

		if(size == 1 && count > 1)
		{
			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
		}
	
		count = std::min(size - (int)uniformIndex[location].element, count);

		if(targetUniform->type == GL_INT_VEC3)
		{
			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint) * 3,
				   v, 3 * sizeof(GLint) * count);
		}
		else if(targetUniform->type == GL_BOOL_VEC3)
		{
			GLboolean *boolParams = new GLboolean[count * 3];

			for(int i = 0; i < count * 3; i++)
			{
				if(v[i] == 0)
				{
					boolParams[i] = GL_FALSE;
				}
				else
				{
					boolParams[i] = GL_TRUE;
				}
			}

			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean) * 3,
				   boolParams, 3 * sizeof(GLboolean) * count);

			delete[] boolParams;
		}
		else
		{
			return false;
		}

		return true;
	}

	bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
	{
		if(location < 0 || location >= (int)uniformIndex.size())
		{
			return false;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];
		targetUniform->dirty = true;

		int size = targetUniform->size();

		if(size == 1 && count > 1)
		{
			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
		}
	
		count = std::min(size - (int)uniformIndex[location].element, count);

		if(targetUniform->type == GL_INT_VEC4)
		{
			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint) * 4,
				   v, 4 * sizeof(GLint) * count);
		}
		else if(targetUniform->type == GL_BOOL_VEC4)
		{
			GLboolean *boolParams = new GLboolean[count * 4];

			for(int i = 0; i < count * 4; i++)
			{
				if(v[i] == 0)
				{
					boolParams[i] = GL_FALSE;
				}
				else
				{
					boolParams[i] = GL_TRUE;
				}
			}

			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean) * 4,
				   boolParams, 4 * sizeof(GLboolean) * count);

			delete[] boolParams;
		}
		else
		{
			return false;
		}

		return true;
	}

	bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
	{
		if(location < 0 || location >= (int)uniformIndex.size())
		{
			return false;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];
		unsigned int count = UniformComponentCount(targetUniform->type);

		// Sized query - ensure the provided buffer is large enough
		if(bufSize && *bufSize < count * sizeof(GLfloat))
		{
			return false;
		}

		switch (UniformComponentType(targetUniform->type))
		{
		  case GL_BOOL:
			{
				GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * count;

				for(unsigned int i = 0; i < count; i++)
				{
					params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f;
				}
			}
			break;
		  case GL_FLOAT:
			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLfloat),
				   count * sizeof(GLfloat));
			break;
		  case GL_INT:
			{
				GLint *intParams = (GLint*)targetUniform->data + uniformIndex[location].element * count;

				for(unsigned int i = 0; i < count; i++)
				{
					params[i] = (float)intParams[i];
				}
			}
			break;
		  default: UNREACHABLE();
		}

		return true;
	}

	bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
	{
		if(location < 0 || location >= (int)uniformIndex.size())
		{
			return false;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];
		unsigned int count = UniformComponentCount(targetUniform->type);

		// Sized query - ensure the provided buffer is large enough
		if(bufSize && *bufSize < count * sizeof(GLint))
		{
			return false;
		}

		switch (UniformComponentType(targetUniform->type))
		{
		  case GL_BOOL:
			{
				GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;

				for(unsigned int i = 0; i < count; i++)
				{
					params[i] = (GLint)boolParams[i];
				}
			}
			break;
		  case GL_FLOAT:
			{
				GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;

				for(unsigned int i = 0; i < count; i++)
				{
					params[i] = (GLint)floatParams[i];
				}
			}
			break;
		  case GL_INT:
			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLint),
				   count * sizeof(GLint));
			break;
		  default: UNREACHABLE();
		}

		return true;
	}

	void Program::dirtyAllUniforms()
	{
		unsigned int numUniforms = uniforms.size();
		for(unsigned int index = 0; index < numUniforms; index++)
		{
			uniforms[index]->dirty = true;
		}
	}

	// Applies all the uniforms set for this program object to the device
	void Program::applyUniforms()
	{
		unsigned int numUniforms = uniformIndex.size();
		for(unsigned int location = 0; location < numUniforms; location++)
		{
			if(uniformIndex[location].element != 0)
			{
				continue;
			}

			Uniform *targetUniform = uniforms[uniformIndex[location].index];

			if(targetUniform->dirty)
			{
				int size = targetUniform->size();
				GLfloat *f = (GLfloat*)targetUniform->data;
				GLint *i = (GLint*)targetUniform->data;
				GLboolean *b = (GLboolean*)targetUniform->data;

				switch(targetUniform->type)
				{
				  case GL_BOOL:       applyUniform1bv(location, size, b);       break;
				  case GL_BOOL_VEC2:  applyUniform2bv(location, size, b);       break;
				  case GL_BOOL_VEC3:  applyUniform3bv(location, size, b);       break;
				  case GL_BOOL_VEC4:  applyUniform4bv(location, size, b);       break;
				  case GL_FLOAT:      applyUniform1fv(location, size, f);       break;
				  case GL_FLOAT_VEC2: applyUniform2fv(location, size, f);       break;
				  case GL_FLOAT_VEC3: applyUniform3fv(location, size, f);       break;
				  case GL_FLOAT_VEC4: applyUniform4fv(location, size, f);       break;
				  case GL_FLOAT_MAT2: applyUniformMatrix2fv(location, size, f); break;
				  case GL_FLOAT_MAT3: applyUniformMatrix3fv(location, size, f); break;
				  case GL_FLOAT_MAT4: applyUniformMatrix4fv(location, size, f); break;
				  case GL_SAMPLER_2D:
				  case GL_SAMPLER_CUBE:
                  case GL_SAMPLER_EXTERNAL_OES:
				  case GL_INT:        applyUniform1iv(location, size, i);       break;
				  case GL_INT_VEC2:   applyUniform2iv(location, size, i);       break;
				  case GL_INT_VEC3:   applyUniform3iv(location, size, i);       break;
				  case GL_INT_VEC4:   applyUniform4iv(location, size, i);       break;
				  default:
					UNREACHABLE();
				}

				targetUniform->dirty = false;
			}
		}
	}

	// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
	// Returns the number of used varying registers, or -1 if unsuccesful
	int Program::packVaryings(const sh::Varying *packing[][4])
	{
		for(sh::VaryingList::iterator varying = fragmentShader->varyings.begin(); varying != fragmentShader->varyings.end(); varying++)
		{
			int n = VariableRowCount(varying->type) * varying->size();
			int m = VariableColumnCount(varying->type);
			bool success = false;

			if(m == 2 || m == 3 || m == 4)
			{
				for(int r = 0; r <= MAX_VARYING_VECTORS - n && !success; r++)
				{
					bool available = true;

					for(int y = 0; y < n && available; y++)
					{
						for(int x = 0; x < m && available; x++)
						{
							if(packing[r + y][x])
							{
								available = false;
							}
						}
					}

					if(available)
					{
						varying->reg = r;
						varying->col = 0;

						for(int y = 0; y < n; y++)
						{
							for(int x = 0; x < m; x++)
							{
								packing[r + y][x] = &*varying;
							}
						}

						success = true;
					}
				}

				if(!success && m == 2)
				{
					for(int r = MAX_VARYING_VECTORS - n; r >= 0 && !success; r--)
					{
						bool available = true;

						for(int y = 0; y < n && available; y++)
						{
							for(int x = 2; x < 4 && available; x++)
							{
								if(packing[r + y][x])
								{
									available = false;
								}
							}
						}

						if(available)
						{
							varying->reg = r;
							varying->col = 2;

							for(int y = 0; y < n; y++)
							{
								for(int x = 2; x < 4; x++)
								{
									packing[r + y][x] = &*varying;
								}
							}

							success = true;
						}
					}
				}
			}
			else if(m == 1)
			{
				int space[4] = {0};

				for(int y = 0; y < MAX_VARYING_VECTORS; y++)
				{
					for(int x = 0; x < 4; x++)
					{
						space[x] += packing[y][x] ? 0 : 1;
					}
				}

				int column = 0;

				for(int x = 0; x < 4; x++)
				{
					if(space[x] >= n && space[x] < space[column])
					{
						column = x;
					}
				}

				if(space[column] >= n)
				{
					for(int r = 0; r < MAX_VARYING_VECTORS; r++)
					{
						if(!packing[r][column])
						{
							varying->reg = r;

							for(int y = r; y < r + n; y++)
							{
								packing[y][column] = &*varying;
							}

							break;
						}
					}

					varying->col = column;

					success = true;
				}
			}
			else UNREACHABLE();

			if(!success)
			{
				appendToInfoLog("Could not pack varying %s", varying->name.c_str());

				return -1;
			}
		}

		// Return the number of used registers
		int registers = 0;

		for(int r = 0; r < MAX_VARYING_VECTORS; r++)
		{
			if(packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3])
			{
				registers++;
			}
		}

		return registers;
	}

	bool Program::linkVaryings()
	{
		for(sh::VaryingList::iterator input = fragmentShader->varyings.begin(); input != fragmentShader->varyings.end(); input++)
		{
			bool matched = false;

			for(sh::VaryingList::iterator output = vertexShader->varyings.begin(); output != vertexShader->varyings.end(); output++)
			{
				if(output->name == input->name)
				{
					if(output->type != input->type || output->size() != input->size())
					{
						appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str());

						return false;
					}

					matched = true;
					break;
				}
			}

			if(!matched)
			{
				appendToInfoLog("Fragment varying %s does not match any vertex varying", input->name.c_str());

				return false;
			}
		}

		sh::VaryingList &psVaryings = fragmentShader->varyings;
		sh::VaryingList &vsVaryings = vertexShader->varyings;

		for(sh::VaryingList::iterator output = vsVaryings.begin(); output != vsVaryings.end(); output++)
		{
			for(sh::VaryingList::iterator input = psVaryings.begin(); input != psVaryings.end(); input++)
			{
				if(output->name == input->name)
				{
					int in = input->reg;
					int out = output->reg;
					int components = VariableColumnCount(output->type);
					int registers = VariableRowCount(output->type) * output->size();

					ASSERT(in >= 0);

					if(in + registers > MAX_VARYING_VECTORS)
					{
						appendToInfoLog("Too many varyings");
						return false;
					}

					if(out >= 0)
					{
						if(out + registers > MAX_VARYING_VECTORS)
						{
							appendToInfoLog("Too many varyings");
							return false;
						}

						for(int i = 0; i < registers; i++)
						{
							if(components >= 1) vertexBinary->output[out + i][0] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
							if(components >= 2) vertexBinary->output[out + i][1] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
							if(components >= 3) vertexBinary->output[out + i][2] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
							if(components >= 4) vertexBinary->output[out + i][3] = sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i);
						}
					}
					else   // Vertex varying is declared but not written to
					{
						for(int i = 0; i < registers; i++)
						{
							if(components >= 1) pixelBinary->semantic[in + i][0] = sw::Shader::Semantic();
							if(components >= 2) pixelBinary->semantic[in + i][1] = sw::Shader::Semantic();
							if(components >= 3) pixelBinary->semantic[in + i][2] = sw::Shader::Semantic();
							if(components >= 4) pixelBinary->semantic[in + i][3] = sw::Shader::Semantic();					
						}
					}

					break;
				}
			}
		}

		return true;
	}

	// Links the code of the vertex and pixel shader by matching up their varyings,
	// compiling them into binaries, determining the attribute mappings, and collecting
	// a list of uniforms
	void Program::link()
	{
		unlink();

		if(!fragmentShader || !fragmentShader->isCompiled())
		{
			return;
		}

		if(!vertexShader || !vertexShader->isCompiled())
		{
			return;
		}

		vertexBinary = new sw::VertexShader(vertexShader->getVertexShader());
		pixelBinary = new sw::PixelShader(fragmentShader->getPixelShader());
			
		if(!linkVaryings())
		{
			return;
		}

		if(!linkAttributes())
		{
			return;
		}

		if(!linkUniforms(fragmentShader))
		{
			return;
		}

		if(!linkUniforms(vertexShader))
		{
			return;
		}

		linked = true;   // Success
	}

	// Determines the mapping between GL attributes and vertex stream usage indices
	bool Program::linkAttributes()
	{
		unsigned int usedLocations = 0;

		// Link attributes that have a binding location
		for(sh::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); attribute++)
		{
			int location = getAttributeBinding(attribute->name);

			if(location != -1)   // Set by glBindAttribLocation
			{
				if(!linkedAttribute[location].name.empty())
				{
					// Multiple active attributes bound to the same location; not an error
				}

				linkedAttribute[location] = *attribute;

				int rows = VariableRowCount(attribute->type);

				if(rows + location > MAX_VERTEX_ATTRIBS)
				{
					appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);
					return false;
				}

				for(int i = 0; i < rows; i++)
				{
					usedLocations |= 1 << (location + i);
				}
			}
		}

		// Link attributes that don't have a binding location
		for(sh::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); attribute++)
		{
			int location = getAttributeBinding(attribute->name);

			if(location == -1)   // Not set by glBindAttribLocation
			{
				int rows = VariableRowCount(attribute->type);
				int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);

				if(availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
				{
					appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str());
					return false;   // Fail to link
				}

				linkedAttribute[availableIndex] = *attribute;
			}
		}

		for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
		{
			int index = vertexShader->getSemanticIndex(linkedAttribute[attributeIndex].name);
			int rows = std::max(VariableRowCount(linkedAttribute[attributeIndex].type), 1);

			for(int r = 0; r < rows; r++)
			{
				attributeStream[attributeIndex++] = index++;
			}
		}

		return true;
	}

	int Program::getAttributeBinding(const std::string &name)
	{
		for(int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
		{
			if(attributeBinding[location].find(name) != attributeBinding[location].end())
			{
				return location;
			}
		}

		return -1;
	}

	bool Program::linkUniforms(Shader *shader)
	{
		const sh::ActiveUniforms &activeUniforms = shader->activeUniforms;

		for(unsigned int uniformIndex = 0; uniformIndex < activeUniforms.size(); uniformIndex++)
		{
			const sh::Uniform &uniform = activeUniforms[uniformIndex];

			if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex))
			{
				return false;
			}
		}

		return true;
	}

	bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex)
	{
		if(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES)
	    {
			int index = registerIndex;
			
			do
			{
				if(shader == GL_VERTEX_SHADER)
				{
					if(index < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
					{
						samplersVS[index].active = true;
						samplersVS[index].textureType = (type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;
						samplersVS[index].logicalTextureUnit = 0;
					}
					else
					{
					   appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", MAX_VERTEX_TEXTURE_IMAGE_UNITS);
					   return false;
					}
				}
				else if(shader == GL_FRAGMENT_SHADER)
				{
					if(index < MAX_TEXTURE_IMAGE_UNITS)
					{
						samplersPS[index].active = true;
						samplersPS[index].textureType = (type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;
						samplersPS[index].logicalTextureUnit = 0;
					}
					else
					{
						appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);
						return false;
					}
				}
				else UNREACHABLE();

				index++;
			}
			while(index < registerIndex + arraySize);
	    }

		Uniform *uniform = 0;
		GLint location = getUniformLocation(name);

		if(location >= 0)   // Previously defined, types must match
		{
			uniform = uniforms[uniformIndex[location].index];

			if(uniform->type != type)
			{
				appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
				return false;
			}

			if(uniform->precision != precision)
			{
				appendToInfoLog("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
				return false;
			}
		}
		else
		{
			uniform = new Uniform(type, precision, name, arraySize);
		}

		if(!uniform)
		{
			return false;
		}

		if(shader == GL_VERTEX_SHADER)
		{
			uniform->vsRegisterIndex = registerIndex;
		}
		else if(shader == GL_FRAGMENT_SHADER)
		{
			uniform->psRegisterIndex = registerIndex;
		}
		else UNREACHABLE();

		if(location == -1)   // Not previously defined
		{
			uniforms.push_back(uniform);
			unsigned int index = uniforms.size() - 1;

			for(unsigned int i = 0; i < uniform->size(); i++)
			{
				uniformIndex.push_back(UniformLocation(name, i, index));
			}
		}

		if(shader == GL_VERTEX_SHADER)
		{
			if(registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS)
			{
				appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS);
				return false;
			}
		}
		else if(shader == GL_FRAGMENT_SHADER)
		{
			if(registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS)
			{
				appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS);
				return false;
			}
		}
		else UNREACHABLE();

		return true;
	}

	bool Program::applyUniform1bv(GLint location, GLsizei count, const GLboolean *v)
	{
		int vector[MAX_UNIFORM_VECTORS][4];

		for(int i = 0; i < count; i++)
		{
			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
			vector[i][1] = 0;
			vector[i][2] = 0;
			vector[i][3] = 0;

			v += 1;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];

		if(targetUniform->psRegisterIndex != -1)
		{
			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		if(targetUniform->vsRegisterIndex != -1)
		{
			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		return true;
	}

	bool Program::applyUniform2bv(GLint location, GLsizei count, const GLboolean *v)
	{
		int vector[MAX_UNIFORM_VECTORS][4];

		for(int i = 0; i < count; i++)
		{
			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
			vector[i][2] = 0;
			vector[i][3] = 0;

			v += 2;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];

		if(targetUniform->psRegisterIndex != -1)
		{
			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		if(targetUniform->vsRegisterIndex != -1)
		{
			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		return true;
	}

	bool Program::applyUniform3bv(GLint location, GLsizei count, const GLboolean *v)
	{
		int vector[MAX_UNIFORM_VECTORS][4];

		for(int i = 0; i < count; i++)
		{
			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
			vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
			vector[i][3] = 0;

			v += 3;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];

		if(targetUniform->psRegisterIndex != -1)
		{
			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		if(targetUniform->vsRegisterIndex != -1)
		{
			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		return true;
	}

	bool Program::applyUniform4bv(GLint location, GLsizei count, const GLboolean *v)
	{
		int vector[MAX_UNIFORM_VECTORS][4];

		for(int i = 0; i < count; i++)
		{
			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
			vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
			vector[i][3] = (v[3] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);

			v += 4;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];

		if(targetUniform->psRegisterIndex != -1)
		{
			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		if(targetUniform->vsRegisterIndex != -1)
		{
			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		return true;
	}

	bool Program::applyUniform1fv(GLint location, GLsizei count, const GLfloat *v)
	{
		float vector[MAX_UNIFORM_VECTORS][4];

		for(int i = 0; i < count; i++)
		{
			vector[i][0] = v[0];
			vector[i][1] = 0;
			vector[i][2] = 0;
			vector[i][3] = 0;

			v += 1;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];

		if(targetUniform->psRegisterIndex != -1)
		{
			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		if(targetUniform->vsRegisterIndex != -1)
		{
			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		return true;
	}

	bool Program::applyUniform2fv(GLint location, GLsizei count, const GLfloat *v)
	{
		float vector[MAX_UNIFORM_VECTORS][4];

		for(int i = 0; i < count; i++)
		{
			vector[i][0] = v[0];
			vector[i][1] = v[1];
			vector[i][2] = 0;
			vector[i][3] = 0;

			v += 2;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];

		if(targetUniform->psRegisterIndex != -1)
		{
			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		if(targetUniform->vsRegisterIndex != -1)
		{
			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		return true;
	}

	bool Program::applyUniform3fv(GLint location, GLsizei count, const GLfloat *v)
	{
		float vector[MAX_UNIFORM_VECTORS][4];

		for(int i = 0; i < count; i++)
		{
			vector[i][0] = v[0];
			vector[i][1] = v[1];
			vector[i][2] = v[2];
			vector[i][3] = 0;

			v += 3;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];

		if(targetUniform->psRegisterIndex != -1)
		{
			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		if(targetUniform->vsRegisterIndex != -1)
		{
			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		return true;
	}

	bool Program::applyUniform4fv(GLint location, GLsizei count, const GLfloat *v)
	{
		Uniform *targetUniform = uniforms[uniformIndex[location].index];

		if(targetUniform->psRegisterIndex != -1)
		{
			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)v, targetUniform->registerCount());
		}

		if(targetUniform->vsRegisterIndex != -1)
		{
			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)v, targetUniform->registerCount());
		}

		return true;
	}

	bool Program::applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)
	{
		float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];

		for(int i = 0; i < count; i++)
		{
			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = 0; matrix[i][0][3] = 0;
			matrix[i][1][0] = value[2];	matrix[i][1][1] = value[3];	matrix[i][1][2] = 0; matrix[i][1][3] = 0;

			value += 4;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];

		if(targetUniform->psRegisterIndex != -1)
		{
			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)matrix, targetUniform->registerCount());
		}

		if(targetUniform->vsRegisterIndex != -1)
		{
			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)matrix, targetUniform->registerCount());
		}

		return true;
	}

	bool Program::applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)
	{
		float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];

		for(int i = 0; i < count; i++)
		{
			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2];	matrix[i][0][3] = 0;
			matrix[i][1][0] = value[3];	matrix[i][1][1] = value[4];	matrix[i][1][2] = value[5];	matrix[i][1][3] = 0;
			matrix[i][2][0] = value[6];	matrix[i][2][1] = value[7];	matrix[i][2][2] = value[8];	matrix[i][2][3] = 0;

			value += 9;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];

		if(targetUniform->psRegisterIndex != -1)
		{
			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)matrix, targetUniform->registerCount());
		}

		if(targetUniform->vsRegisterIndex != -1)
		{	
			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)matrix, targetUniform->registerCount());
		}

		return true;
	}

	bool Program::applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)
	{
		Uniform *targetUniform = uniforms[uniformIndex[location].index];
	
		if(targetUniform->psRegisterIndex != -1)
		{
			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)value, targetUniform->registerCount());
		}

		if(targetUniform->vsRegisterIndex != -1)
		{
			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)value, targetUniform->registerCount());
		}

		return true;
	}

	bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)
	{
		float vector[MAX_UNIFORM_VECTORS][4];

		for(int i = 0; i < count; i++)
		{
			vector[i][0] = (float)v[i];
			vector[i][1] = 0;
			vector[i][2] = 0;
			vector[i][3] = 0;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];

		if(targetUniform->psRegisterIndex != -1)
		{
            if(targetUniform->type == GL_SAMPLER_2D ||
               targetUniform->type == GL_SAMPLER_CUBE ||
               targetUniform->type == GL_SAMPLER_EXTERNAL_OES)
			{
				for(int i = 0; i < count; i++)
				{
					unsigned int samplerIndex = targetUniform->psRegisterIndex + i;

					if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
					{
						ASSERT(samplersPS[samplerIndex].active);
						samplersPS[samplerIndex].logicalTextureUnit = v[i];
					}
				}
			}
			else
			{
				device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
			}
		}

		if(targetUniform->vsRegisterIndex != -1)
		{
			if(targetUniform->type == GL_SAMPLER_2D ||
               targetUniform->type == GL_SAMPLER_CUBE ||
               targetUniform->type == GL_SAMPLER_EXTERNAL_OES)
			{
				for(int i = 0; i < count; i++)
				{
					unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;

					if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
					{
						ASSERT(samplersVS[samplerIndex].active);
						samplersVS[samplerIndex].logicalTextureUnit = v[i];
					}
				}
			}
			else
			{
				device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
			}
		}

		return true;
	}

	bool Program::applyUniform2iv(GLint location, GLsizei count, const GLint *v)
	{
		float vector[MAX_UNIFORM_VECTORS][4];

		for(int i = 0; i < count; i++)
		{
			vector[i][0] = (float)v[0];
			vector[i][1] = (float)v[1];
			vector[i][2] = 0;
			vector[i][3] = 0;

			v += 2;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];

		if(targetUniform->psRegisterIndex != -1)
		{
			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		if(targetUniform->vsRegisterIndex != -1)
		{
			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		return true;
	}

	bool Program::applyUniform3iv(GLint location, GLsizei count, const GLint *v)
	{
		float vector[MAX_UNIFORM_VECTORS][4];

		for(int i = 0; i < count; i++)
		{
			vector[i][0] = (float)v[0];
			vector[i][1] = (float)v[1];
			vector[i][2] = (float)v[2];
			vector[i][3] = 0;

			v += 3;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];

		if(targetUniform->psRegisterIndex != -1)
		{
			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		if(targetUniform->vsRegisterIndex != -1)
		{
			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		return true;
	}

	bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v)
	{
		float vector[MAX_UNIFORM_VECTORS][4];

		for(int i = 0; i < count; i++)
		{
			vector[i][0] = (float)v[0];
			vector[i][1] = (float)v[1];
			vector[i][2] = (float)v[2];
			vector[i][3] = (float)v[3];

			v += 4;
		}

		Uniform *targetUniform = uniforms[uniformIndex[location].index];

		if(targetUniform->psRegisterIndex != -1)
		{
			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		if(targetUniform->vsRegisterIndex != -1)
		{
			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
		}

		return true;
	}

	void Program::appendToInfoLog(const char *format, ...)
	{
		if(!format)
		{
			return;
		}

		char info[1024];

		va_list vararg;
		va_start(vararg, format);
		vsnprintf(info, sizeof(info), format, vararg);
		va_end(vararg);

		size_t infoLength = strlen(info);

		if(!infoLog)
		{
			infoLog = new char[infoLength + 2];
			strcpy(infoLog, info);
			strcpy(infoLog + infoLength, "\n");
		}
		else
		{
			size_t logLength = strlen(infoLog);
			char *newLog = new char[logLength + infoLength + 2];
			strcpy(newLog, infoLog);
			strcpy(newLog + logLength, info);
			strcpy(newLog + logLength + infoLength, "\n");

			delete[] infoLog;
			infoLog = newLog;
		}
	}

	void Program::resetInfoLog()
	{
		if(infoLog)
		{
			delete[] infoLog;
			infoLog = 0;
		}
	}

	// Returns the program object to an unlinked state, before re-linking, or at destruction
	void Program::unlink()
	{
		delete vertexBinary;
		vertexBinary = 0;
		delete pixelBinary;
		pixelBinary = 0;

		for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
		{
			linkedAttribute[index].name.clear();
			attributeStream[index] = -1;
		}

		for(int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
		{
			samplersPS[index].active = false;
		}

		for(int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
		{
			samplersVS[index].active = false;
		}

		while(!uniforms.empty())
		{
			delete uniforms.back();
			uniforms.pop_back();
		}

		uniformIndex.clear();

		delete[] infoLog;
		infoLog = 0;

		linked = false;
	}

	bool Program::isLinked()
	{
		return linked;
	}

	bool Program::isValidated() const 
	{
		return validated;
	}

	void Program::release()
	{
		referenceCount--;

		if(referenceCount == 0 && orphaned)
		{
			resourceManager->deleteProgram(handle);
		}
	}

	void Program::addRef()
	{
		referenceCount++;
	}

	unsigned int Program::getRefCount() const
	{
		return referenceCount;
	}

	unsigned int Program::getSerial() const
	{
		return serial;
	}

	unsigned int Program::issueSerial()
	{
		return currentSerial++;
	}

	int Program::getInfoLogLength() const
	{
		if(!infoLog)
		{
			return 0;
		}
		else
		{
		   return strlen(infoLog) + 1;
		}
	}

	void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *buffer)
	{
		int index = 0;

		if(bufSize > 0)
		{
			if(infoLog)
			{
				index = std::min(bufSize - 1, (int)strlen(infoLog));
				memcpy(buffer, infoLog, index);
			}

			buffer[index] = '\0';
		}

		if(length)
		{
			*length = index;
		}
	}

	void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)
	{
		int total = 0;

		if(vertexShader)
		{
			if(total < maxCount)
			{
				shaders[total] = vertexShader->getHandle();
			}

			total++;
		}

		if(fragmentShader)
		{
			if(total < maxCount)
			{
				shaders[total] = fragmentShader->getHandle();
			}

			total++;
		}

		if(count)
		{
			*count = total;
		}
	}

	void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
	{
		// Skip over inactive attributes
		unsigned int activeAttribute = 0;
		unsigned int attribute;
		for(attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
		{
			if(linkedAttribute[attribute].name.empty())
			{
				continue;
			}

			if(activeAttribute == index)
			{
				break;
			}

			activeAttribute++;
		}

		if(bufsize > 0)
		{
			const char *string = linkedAttribute[attribute].name.c_str();

			strncpy(name, string, bufsize);
			name[bufsize - 1] = '\0';

			if(length)
			{
				*length = strlen(name);
			}
		}

		*size = 1;   // Always a single 'type' instance

		*type = linkedAttribute[attribute].type;
	}

	GLint Program::getActiveAttributeCount() const
	{
		int count = 0;

		for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
		{
			if(!linkedAttribute[attributeIndex].name.empty())
			{
				count++;
			}
		}

		return count;
	}

	GLint Program::getActiveAttributeMaxLength() const
	{
		int maxLength = 0;

		for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
		{
			if(!linkedAttribute[attributeIndex].name.empty())
			{
				maxLength = std::max((int)(linkedAttribute[attributeIndex].name.length() + 1), maxLength);
			}
		}

		return maxLength;
	}

	void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
	{
		if(bufsize > 0)
		{
			std::string string = uniforms[index]->name;

			if(uniforms[index]->isArray())
			{
				string += "[0]";
			}

			strncpy(name, string.c_str(), bufsize);
			name[bufsize - 1] = '\0';

			if(length)
			{
				*length = strlen(name);
			}
		}

		*size = uniforms[index]->size();

		*type = uniforms[index]->type;
	}

	GLint Program::getActiveUniformCount() const
	{
		return uniforms.size();
	}

	GLint Program::getActiveUniformMaxLength() const
	{
		int maxLength = 0;

		unsigned int numUniforms = uniforms.size();
		for(unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
		{
			if(!uniforms[uniformIndex]->name.empty())
			{
				int length = (int)(uniforms[uniformIndex]->name.length() + 1);
				if(uniforms[uniformIndex]->isArray())
				{
					length += 3;  // Counting in "[0]".
				}
				maxLength = std::max(length, maxLength);
			}
		}

		return maxLength;
	}

	void Program::flagForDeletion()
	{
		orphaned = true;
	}

	bool Program::isFlaggedForDeletion() const
	{
		return orphaned;
	}

	void Program::validate()
	{
		resetInfoLog();

		if(!isLinked()) 
		{
			appendToInfoLog("Program has not been successfully linked.");
			validated = false;
		}
		else
		{
			applyUniforms();
			if(!validateSamplers(true))
			{
				validated = false;
			}
			else
			{
				validated = true;
			}
		}
	}

	bool Program::validateSamplers(bool logErrors)
	{
		// if any two active samplers in a program are of different types, but refer to the same
		// texture image unit, and this is the current program, then ValidateProgram will fail, and
		// DrawArrays and DrawElements will issue the INVALID_OPERATION error.

		TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS];

		for(unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; i++)
		{
			textureUnitType[i] = TEXTURE_UNKNOWN;
		}

		for(unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
		{
			if(samplersPS[i].active)
			{
				unsigned int unit = samplersPS[i].logicalTextureUnit;
            
				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
				{
					if(logErrors)
					{
						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
					}

					return false;
				}

				if(textureUnitType[unit] != TEXTURE_UNKNOWN)
				{
					if(samplersPS[i].textureType != textureUnitType[unit])
					{
						if(logErrors)
						{
							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
						}

						return false;
					}
				}
				else
				{
					textureUnitType[unit] = samplersPS[i].textureType;
				}
			}
		}

		for(unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
		{
			if(samplersVS[i].active)
			{
				unsigned int unit = samplersVS[i].logicalTextureUnit;
            
				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
				{
					if(logErrors)
					{
						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
					}

					return false;
				}

				if(textureUnitType[unit] != TEXTURE_UNKNOWN)
				{
					if(samplersVS[i].textureType != textureUnitType[unit])
					{
						if(logErrors)
						{
							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
						}

						return false;
					}
				}
				else
				{
					textureUnitType[unit] = samplersVS[i].textureType;
				}
			}
		}

		return true;
	}
}
