// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#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;
	}
}
