void glslShader::Load(Loader &input)
{
	char token[MAX_INPUT_LENGTH];

	do
	{
		input.ReadToken(token);

		if (strcmp(token, "vertexshader") == 0)
		{
			char tmp[256];
			if (!input.ReadToken(tmp))
				input.Error("Couldn't find vertex shader name after vertexShader token in glslShader");
			else
				sprintf(vertexShaderName, "%s", tmp);
		}
		else if (strcmp(token, "fragmentshader") == 0)
		{
			char tmp[256];
			if (!input.ReadToken(tmp))
				input.Error("Couldn't find fragment shader name after vertexShader token in glslShader");
			else
				sprintf(fragmentShaderName, "%s", tmp);
		}
		else if (strcmp(token, "uniform") == 0)
		{
			input.ReadToken(uniformParamNames[nUniforms], true, false);  // This token should be upper & lower case
			nUniformComponents[nUniforms] = 0;
			for (int i = 0; i < 4; i++)
			{
				if (!input.ReadFloat(uniformParamValues[nUniforms][i]))
				{
					if (i == 0)	
						input.Error("Incomplete uniform parameter %s\n", uniformParamNames[nUniforms]);
					break;
				}
				else
					nUniformComponents[nUniforms]++;
			}
			nUniforms++;
		}
		else if (strncmp(token, "end", 3) != 0)
			input.Error(token, "Unrecognized glslShader shader command: %s", token);
	} while (strncmp(token, "end", 3) != 0);
}
void sphere::Read(Loader &input)
{
	char token[MAX_INPUT_LENGTH];

	bool moreTokens;
	do 
	{
		// We need to "peek" because if the token isn't giving us one
		// of the sphere properties, then it is a shape attribute like
		// color and if we've already read it out of the file, the shape
		// class would not be able to read the attribute afterwords.
		// So we "peek" at the token which does not remove it from the 
		// file stream.  For more information, see the "PeekTokens" 
		// method defined in the Loader class
		input.PeekTokens(token, 1);
		
		moreTokens = true;
		if (strcmp(token, "center") == 0)
		{
			input.ReadToken(token);
			for (int i = 0; i < 3; i++)
				if (!input.ReadFloat(center[i]))
					input.Error("Not enough parameters for sphere's center in sphere '%s'", objectName);
		}
		else if (strcmp(token, "radius") == 0)
		{
			input.ReadToken(token);
			if (!input.ReadFloat(radius))
				input.Error("Error reading radius in sphere '%s'", objectName);
		}
		else if (strcmp(token, "resolution") == 0)
		{
			input.ReadToken(token);
			if (!input.ReadInt(resolution))
				input.Error("Error reading resolution in sphere '%s'", objectName);
		}
		else 
			moreTokens = false; // If we don't recognize it jump out ... it is an attribute
	} while (moreTokens);

	SetupShape();
}
void cone::Read(Loader &input)
{
	char token[MAX_INPUT_LENGTH];

	bool moreTokens;
	do 
	{
		input.PeekTokens(token, 1);
		
		moreTokens = true;
		if (strcmp(token, "base") == 0)
		{
			input.ReadToken(token);
			for (int i = 0; i < 3; i++)
				if (!input.ReadFloat(base[i]))
					input.Error("Not enough parameters for cone's base in cone '%s'", objectName);
		}
		else if (strcmp(token, "radius") == 0)
		{
			input.ReadToken(token);
			if (!input.ReadFloat(radius))
				input.Error("Error reading radius in cone '%s'", objectName);
		}
		else if (strcmp(token, "height") == 0)
		{
			input.ReadToken(token);
			if (!input.ReadFloat(height))
				input.Error("Error reading height in cone '%s'", objectName);
		}
		else if (strcmp(token, "axis") == 0)
		{
			input.ReadToken(token);
			if (!input.ReadInt(axis))
				input.Error("Error reading axis number in cone '%s'", objectName);
		}
		else if (strcmp(token, "capped") == 0)
		{
			input.ReadToken(token);
			if (!input.ReadBool(capped))
				input.Error("Error reading height in cone '%s'", objectName);
		}
		else if (strcmp(token, "resolution") == 0)
		{
			input.ReadToken(token);
			if (!input.ReadInt(resolution))
				input.Error("Error reading resolution in cone '%s'", objectName);
		}
		else 
			moreTokens = false; // If we don't recognize it jump out ... it is an attribute
	} while (moreTokens);

	SetupShape();
}
void simpleTextureShader::Load(Loader &input)
{
	char token[MAX_INPUT_LENGTH];
	char tmp[MAX_INPUT_LENGTH];

	uvTransform = matrix::Identity(4);  // 4x4 identity matrix

	do
	{
		input.ReadToken(token);

		if (strncmp(token, "texture", 3) == 0)
		{
			tex = texture::LoadTexture(input);
			if (tex == NULL)
				input.Error("Unrecognized texture type in simpleTextureShader");
		}
		else if (strcmp(token, "transform") == 0)
		{
			matrix m(4, 4, 1.0);

			input.ReadToken(tmp);
			if (!strcmp(tmp, "translate"))
			{
				float x[3];
				for (int i = 0; i < 3; i++)
					if (!input.ReadFloat(x[i]))
						input.Error("Incomplete translation information for texture");	
				
				m.MakeTranslation(x[0], x[1], x[2]);
				uvTransform = m * uvTransform;
			}
			else if (!strcmp(tmp, "scale"))
			{
				float x[3];
				for (int i = 0; i < 3; i++)
					if (!input.ReadFloat(x[i]))
						input.Error("Incomplete scale information for texture");	

				m.MakeScale(x[0], x[1], x[2]);
				uvTransform = m * uvTransform;
			}
			else if (!strcmp(tmp, "rotate"))
			{
				float x[3];
				for (int i = 0; i < 3; i++)
					if (!input.ReadFloat(x[i]))
						input.Error("Incomplete rotation information for texture");	

				m.MakeRotationX(x[0]);
				uvTransform = m * uvTransform;
				m.MakeRotationY(x[1]);
				uvTransform = m * uvTransform;
				m.MakeRotationZ(x[2]);
				uvTransform = m * uvTransform;
			}
			else if (!strcmp(tmp, "matrix")) // matrix
			{
				for (int i = 0; i < 3; i++)
					for (int j = 0; j < 3; j++)
						if (!input.ReadFloat(m(i, j)))
							input.Error("Incomplete matrix information for texture");
				uvTransform = m * uvTransform;
			}
			else if (!strcmp(tmp, "homogeneous")) // homogeneous matrix
			{
				for (int i = 0; i < 3; i++)
					for (int j = 0; j < 3; j++)
						if (!input.ReadFloat(m(i, j)))
							input.Error("Incomplete homogeneous matrix information for texture");
				uvTransform = m * uvTransform;
			}
			else
				input.Error(tmp, "Unrecognized texture transform command: %s", tmp);
		}
		else if (strncmp(token, "end", 3) != 0)
			input.Error(token, "Unrecognized texture shader command: %s", token);
	} while (strncmp(token, "end", 3) != 0);
}
void multiTextureShader::Load(Loader &input)
{
	char token[MAX_INPUT_LENGTH];
	char tmp[MAX_INPUT_LENGTH];

	uvTransform = matrix::Identity(4);  // 4x4 identity matrix

	do
	{
		input.ReadToken(token);

		if (strncmp(token, "texture", 3) == 0)
		{
			texture *tex = texture::LoadTexture(input);
			if (tex == NULL)
				input.Error("Unrecognized texture type in multiTextureShader");
			else
				textures.Append(tex);
		}
		else if (strcmp(token, "vertexshader") == 0)
		{
			char tmp[256];
			if (!input.ReadToken(tmp))
				input.Error("Couldn't find vertex shader name after vertexShader token in multiTextureShader");
			else
				sprintf(vertexShaderName, "%s%s", exePath, tmp);
		}
		else if (strcmp(token, "fragmentshader") == 0)
		{
			char tmp[256];
			if (!input.ReadToken(tmp))
				input.Error("Couldn't find fragment shader name after vertexShader token in multiTextureShader");
			else
				sprintf(fragmentShaderName, "%s%s", exePath, tmp);
		}
		else if (strcmp(token, "transform") == 0)
		{
			matrix m(4, 4, 1.0);

			input.ReadToken(tmp);
			if (!strcmp(tmp, "translate"))
			{
				float x[3];
				int nComp;
				for (nComp = 0; nComp < 3; nComp++)
					if (!input.ReadFloat(x[nComp]))
						break;
			
				if (nComp < 2)
					input.Error("Incomplete translate information for texture");	
				else if (nComp == 2)
					x[2] = 0.0;

				m.MakeTranslation(x[0], x[1], x[2]);
				uvTransform = m * uvTransform;
			}
			else if (!strcmp(tmp, "scale"))
			{
				float x[3];
				int nComp;
				for (nComp = 0; nComp < 3; nComp++)
					if (!input.ReadFloat(x[nComp]))
						break;
			
				if (nComp < 2)
					input.Error("Incomplete scale information for texture");	
				else if (nComp == 2)
					x[2] = 0.0;

				m.MakeScale(x[0], x[1], x[2]);
				uvTransform = m * uvTransform;
			}
			else if (!strcmp(tmp, "rotate"))
			{
				float x[3];
				int nComp;
				for (nComp = 0; nComp < 3; nComp++)
					if (!input.ReadFloat(x[nComp]))
						break;

				if (nComp == 0)
					input.Error("Incomplete rotation information for texture");
				else if (nComp == 1)  // Assume a rotation about the z-axis
				{
					x[2] = x[0];
					x[0] = x[1] = 0.0;
				}
				else if (nComp == 2)
					x[2] = 0.0;
				

				m.MakeRotationX(x[0]);
				uvTransform = m * uvTransform;
				m.MakeRotationY(x[1]);
				uvTransform = m * uvTransform;
				m.MakeRotationZ(x[2]);
				uvTransform = m * uvTransform;
			}
			else if (!strcmp(tmp, "matrix")) // matrix
			{
				for (int i = 0; i < 3; i++)
					for (int j = 0; j < 3; j++)
						if (!input.ReadFloat(m(i, j)))
							input.Error("Incomplete matrix information for texture");
				uvTransform = m * uvTransform;
			}
			else if (!strcmp(tmp, "homogeneous")) // homogeneous matrix
			{
				for (int i = 0; i < 3; i++)
					for (int j = 0; j < 3; j++)
						if (!input.ReadFloat(m(i, j)))
							input.Error("Incomplete homogeneous matrix information for texture");
				uvTransform = m * uvTransform;
			}
			else
				input.Error(tmp, "Unrecognized multiTexture transform command: %s", tmp);
		}
		else if (strcmp(token, "uniform") == 0)
		{
			input.ReadToken(uniformParamNames[nUniforms], true, false);  // This token should be upper & lower case
			nUniformComponents[nUniforms] = 0;
			for (int i = 0; i < 4; i++)
			{
				if (!input.ReadFloat(uniformParamValues[nUniforms][i]))
				{
					if (i == 0)	
						input.Error("Incomplete uniform parameter %s\n", uniformParamNames[nUniforms]);
					break;
				}
				else
					nUniformComponents[nUniforms]++;
			}
			nUniforms++;
		}
		else if (strncmp(token, "end", 3) != 0)
			input.Error(token, "Unrecognized multiTexture shader command: %s", token);
	} while (strncmp(token, "end", 3) != 0);
}