// SwiftShader Software Renderer
//
// Copyright(c) 2005-2012 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.
//

#include "TextureStage.hpp"

#include "Sampler.hpp"
#include "Debug.hpp"

#include <string.h>

namespace sw
{
	TextureStage::State::State()
	{
		memset(this, 0, sizeof(State));
	}

	TextureStage::TextureStage() : sampler(0), previousStage(0)
	{
	}

	TextureStage::~TextureStage()
	{
	}

	void TextureStage::init(int stage, const Sampler *sampler, const TextureStage *previousStage)
	{
		this->stage = stage;

		stageOperation = (stage == 0 ? STAGE_MODULATE : STAGE_DISABLE);
		firstArgument = SOURCE_TEXTURE;
		secondArgument = SOURCE_CURRENT;
		thirdArgument = SOURCE_CURRENT;
		stageOperationAlpha = (stage == 0 ? STAGE_SELECTARG1 : STAGE_DISABLE);
		firstArgumentAlpha = SOURCE_DIFFUSE;
		secondArgumentAlpha = SOURCE_CURRENT;
		thirdArgumentAlpha = SOURCE_CURRENT;
		firstModifier = MODIFIER_COLOR;
		secondModifier = MODIFIER_COLOR;
		thirdModifier = MODIFIER_COLOR;
	    firstModifierAlpha = MODIFIER_COLOR;
		secondModifierAlpha = MODIFIER_COLOR;
		thirdModifierAlpha = MODIFIER_COLOR;
		destinationArgument = DESTINATION_CURRENT;

		texCoordIndex = stage;
		this->sampler = sampler;
		this->previousStage = previousStage;
	}

	TextureStage::State TextureStage::textureStageState() const
	{
		State state;

		if(!isStageDisabled())
		{
			state.stageOperation = stageOperation;
			state.firstArgument = firstArgument;
			state.secondArgument = secondArgument;
			state.thirdArgument = thirdArgument;
			state.stageOperationAlpha = stageOperationAlpha;
			state.firstArgumentAlpha = firstArgumentAlpha;
			state.secondArgumentAlpha = secondArgumentAlpha;
			state.thirdArgumentAlpha = thirdArgumentAlpha;
			state.firstModifier = firstModifier;
			state.secondModifier = secondModifier;
			state.thirdModifier = thirdModifier;
			state.firstModifierAlpha = firstModifierAlpha;
			state.secondModifierAlpha = secondModifierAlpha;
			state.thirdModifierAlpha = thirdModifierAlpha;
			state.destinationArgument = destinationArgument;
			state.texCoordIndex = texCoordIndex;

			state.cantUnderflow = sampler->hasUnsignedTexture() || !usesTexture();
			state.usesTexture = usesTexture();
		}

		return state;
	}

	void TextureStage::setConstantColor(const Color<float> &constantColor)
	{
		// FIXME: Compact into generic function   // FIXME: Clamp
		short r = iround(4095 * constantColor.r);
		short g = iround(4095 * constantColor.g);
		short b = iround(4095 * constantColor.b);
		short a = iround(4095 * constantColor.a);

		uniforms.constantColor4[0][0] = uniforms.constantColor4[0][1] = uniforms.constantColor4[0][2] = uniforms.constantColor4[0][3] = r;
		uniforms.constantColor4[1][0] = uniforms.constantColor4[1][1] = uniforms.constantColor4[1][2] = uniforms.constantColor4[1][3] = g;
		uniforms.constantColor4[2][0] = uniforms.constantColor4[2][1] = uniforms.constantColor4[2][2] = uniforms.constantColor4[2][3] = b;
		uniforms.constantColor4[3][0] = uniforms.constantColor4[3][1] = uniforms.constantColor4[3][2] = uniforms.constantColor4[3][3] = a;
	}

	void TextureStage::setBumpmapMatrix(int element, float value)
	{
		uniforms.bumpmapMatrix4F[element / 2][element % 2][0] = value;
		uniforms.bumpmapMatrix4F[element / 2][element % 2][1] = value;
		uniforms.bumpmapMatrix4F[element / 2][element % 2][2] = value;
		uniforms.bumpmapMatrix4F[element / 2][element % 2][3] = value;

		uniforms.bumpmapMatrix4W[element / 2][element % 2][0] = iround(4095 * value);
		uniforms.bumpmapMatrix4W[element / 2][element % 2][1] = iround(4095 * value);
		uniforms.bumpmapMatrix4W[element / 2][element % 2][2] = iround(4095 * value);
		uniforms.bumpmapMatrix4W[element / 2][element % 2][3] = iround(4095 * value);
	}

	void TextureStage::setLuminanceScale(float value)
	{
		short scale = iround(4095 * value);

		uniforms.luminanceScale4[0] = uniforms.luminanceScale4[1] = uniforms.luminanceScale4[2] = uniforms.luminanceScale4[3] = scale;
	}

	void TextureStage::setLuminanceOffset(float value)
	{
		short offset = iround(4095 * value);

		uniforms.luminanceOffset4[0] = uniforms.luminanceOffset4[1] = uniforms.luminanceOffset4[2] = uniforms.luminanceOffset4[3] = offset;
	}

	void TextureStage::setTexCoordIndex(unsigned int texCoordIndex)
	{
		ASSERT(texCoordIndex < 8);

		this->texCoordIndex = texCoordIndex;
	}

	void TextureStage::setStageOperation(StageOperation stageOperation)
	{
		this->stageOperation = stageOperation;
	}

	void TextureStage::setFirstArgument(SourceArgument firstArgument)
	{
		this->firstArgument = firstArgument;
	}

	void TextureStage::setSecondArgument(SourceArgument secondArgument)
	{
		this->secondArgument = secondArgument;
	}

	void TextureStage::setThirdArgument(SourceArgument thirdArgument)
	{
		this->thirdArgument = thirdArgument;
	}

	void TextureStage::setStageOperationAlpha(StageOperation stageOperationAlpha)
	{
		this->stageOperationAlpha = stageOperationAlpha;
	}

	void TextureStage::setFirstArgumentAlpha(SourceArgument firstArgumentAlpha)
	{
		this->firstArgumentAlpha = firstArgumentAlpha;
	}

	void TextureStage::setSecondArgumentAlpha(SourceArgument secondArgumentAlpha)
	{
		this->secondArgumentAlpha = secondArgumentAlpha;
	}

	void TextureStage::setThirdArgumentAlpha(SourceArgument thirdArgumentAlpha)
	{
		this->thirdArgumentAlpha= thirdArgumentAlpha;
	}

	void TextureStage::setFirstModifier(ArgumentModifier firstModifier)
	{
		this->firstModifier = firstModifier;
	}

	void TextureStage::setSecondModifier(ArgumentModifier secondModifier)
	{
		this->secondModifier = secondModifier;
	}

	void TextureStage::setThirdModifier(ArgumentModifier thirdModifier)
	{
		this->thirdModifier = thirdModifier;
	}

	void TextureStage::setFirstModifierAlpha(ArgumentModifier firstModifierAlpha)
	{
		this->firstModifierAlpha = firstModifierAlpha;
	}

	void TextureStage::setSecondModifierAlpha(ArgumentModifier secondModifierAlpha)
	{
		this->secondModifierAlpha = secondModifierAlpha;
	}

	void TextureStage::setThirdModifierAlpha(ArgumentModifier thirdModifierAlpha)
	{
		this->thirdModifierAlpha = thirdModifierAlpha;
	}

	void TextureStage::setDestinationArgument(DestinationArgument destinationArgument)
	{
		this->destinationArgument = destinationArgument;
	}

	bool TextureStage::usesColor(SourceArgument source) const
	{
		// One argument
		if(stageOperation == STAGE_SELECTARG1 || stageOperation == STAGE_PREMODULATE)
		{
			return firstArgument == source;
		}
		else if(stageOperation == STAGE_SELECTARG2)
		{
			return secondArgument == source;
		}
		else if(stageOperation == STAGE_SELECTARG3)
		{
			return thirdArgument == source;
		}
		else
		{
			// Two arguments or more
			if(firstArgument == source || secondArgument == source)
			{
				return true;
			}

			// Three arguments
			if(stageOperation == STAGE_MULTIPLYADD || stageOperation == STAGE_LERP)
			{
				return thirdArgument == source;
			}
		}
		
		return false;
	}

	bool TextureStage::usesAlpha(SourceArgument source) const
	{
		if(stageOperationAlpha == STAGE_DISABLE)
		{
			return false;
		}

		if(source == SOURCE_TEXTURE)
		{
			if(stageOperation == STAGE_BLENDTEXTUREALPHA ||	stageOperation == STAGE_BLENDTEXTUREALPHAPM)
			{
				return true;
			}
		}
		else if(source == SOURCE_CURRENT)
		{
			if(stageOperation == STAGE_BLENDCURRENTALPHA)
			{
				return true;
			}
		}
		else if(source == SOURCE_DIFFUSE)
		{
			if(stageOperation == STAGE_BLENDDIFFUSEALPHA)
			{
				return true;
			}
		}
		else if(source == SOURCE_TFACTOR)
		{
			if(stageOperation == STAGE_BLENDFACTORALPHA)
			{
				return true;
			}
		}

		// One argument
		if(stageOperation == STAGE_SELECTARG1 || stageOperation == STAGE_PREMODULATE)
		{
			if(firstArgument == source && (firstModifier == MODIFIER_ALPHA || firstModifier == MODIFIER_INVALPHA))
			{
				return true;
			}
		}
		else if(stageOperation == STAGE_SELECTARG2)
		{
			if(secondArgument == source && (secondModifier == MODIFIER_ALPHA || secondModifier == MODIFIER_INVALPHA))
			{
				return true;
			}
		}
		else if(stageOperation == STAGE_SELECTARG3)
		{
			if(thirdArgument == source && (thirdModifier == MODIFIER_ALPHA || thirdModifier == MODIFIER_INVALPHA))
			{
				return true;
			}
		}
		else
		{
			// Two arguments or more
			if(firstArgument == source || secondArgument == source)
			{
				if(firstArgument == source && (firstModifier == MODIFIER_ALPHA || firstModifier == MODIFIER_INVALPHA))
				{
					return true;
				}

				if(secondArgument == source && (secondModifier == MODIFIER_ALPHA || secondModifier == MODIFIER_INVALPHA))
				{
					return true;
				}
			}

			// Three arguments
			if(stageOperation == STAGE_MULTIPLYADD || stageOperation == STAGE_LERP)
			{
				if(thirdArgument == source && (thirdModifier == MODIFIER_ALPHA || thirdModifier == MODIFIER_INVALPHA))
				{
					return true;
				}
			}
		}

		// One argument
		if(stageOperationAlpha == STAGE_SELECTARG1 || stageOperationAlpha == STAGE_PREMODULATE)
		{
			return firstArgumentAlpha == source;
		}
		else if(stageOperationAlpha == STAGE_SELECTARG2)
		{
			return secondArgumentAlpha == source;
		}
		else if(stageOperationAlpha == STAGE_SELECTARG3)
		{
			return thirdArgumentAlpha == source;
		}
		else
		{
			// Two arguments or more
			if(firstArgumentAlpha == source || secondArgumentAlpha == source)
			{
				return true;
			}

			// Three arguments
			if(stageOperationAlpha == STAGE_MULTIPLYADD || stageOperationAlpha == STAGE_LERP)
			{
				return thirdArgumentAlpha == source;
			}
		}
		
		return false;
	}

	bool TextureStage::uses(SourceArgument source) const
	{
		return usesColor(source) || usesAlpha(source);
	}

	bool TextureStage::usesCurrent() const
	{
		return uses(SOURCE_CURRENT) || (stageOperation == STAGE_BLENDCURRENTALPHA || stageOperationAlpha == STAGE_BLENDCURRENTALPHA);
	}

	bool TextureStage::usesDiffuse() const
	{
		return uses(SOURCE_DIFFUSE) || (stageOperation == STAGE_BLENDDIFFUSEALPHA || stageOperationAlpha == STAGE_BLENDDIFFUSEALPHA);
	}

	bool TextureStage::usesSpecular() const
	{
		return uses(SOURCE_SPECULAR);
	}

	bool TextureStage::usesTexture() const
	{
		return uses(SOURCE_TEXTURE) ||
		       stageOperation == STAGE_BLENDTEXTUREALPHA ||
		       stageOperationAlpha == STAGE_BLENDTEXTUREALPHA ||
		       stageOperation == STAGE_BLENDTEXTUREALPHAPM ||
		       stageOperationAlpha == STAGE_BLENDTEXTUREALPHAPM ||
		       (previousStage && previousStage->stageOperation == STAGE_PREMODULATE) ||
		       (previousStage && previousStage->stageOperationAlpha == STAGE_PREMODULATE);
	}

	bool TextureStage::isStageDisabled() const
	{
		bool disabled = (stageOperation == STAGE_DISABLE) || (!sampler->hasTexture() && usesTexture());

		if(!previousStage || disabled)
		{
			return disabled;
		}
		else
		{
			return previousStage->isStageDisabled();
		}
	}

	bool TextureStage::writesCurrent() const
	{
		return !isStageDisabled() && destinationArgument == DESTINATION_CURRENT && stageOperation != STAGE_BUMPENVMAP && stageOperation != STAGE_BUMPENVMAPLUMINANCE;
	}
}
