/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES Utilities
 * ------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * 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.
 *
 *//*!
 * \file
 * \brief Shader variable type.
 *//*--------------------------------------------------------------------*/

#include "gluVarType.hpp"
#include "deStringUtil.hpp"
#include "deArrayUtil.hpp"

namespace glu
{

VarType::VarType (void)
	: m_type(VARTYPE_LAST)
{
}

VarType::VarType (const VarType& other)
	: m_type(VARTYPE_LAST)
{
	*this = other;
}

VarType::VarType (DataType basicType, Precision precision)
	: m_type(VARTYPE_BASIC)
{
	m_data.basic.type		= basicType;
	m_data.basic.precision	= precision;
}

VarType::VarType (const VarType& elementType, int arraySize)
	: m_type(VARTYPE_ARRAY)
{
	DE_ASSERT(arraySize >= 0 || arraySize == UNSIZED_ARRAY);
	m_data.array.size			= arraySize;
	m_data.array.elementType	= new VarType(elementType);
}

VarType::VarType (const StructType* structPtr)
	: m_type(VARTYPE_STRUCT)
{
	m_data.structPtr = structPtr;
}

VarType::~VarType (void)
{
	if (m_type == VARTYPE_ARRAY)
		delete m_data.array.elementType;
}

VarType& VarType::operator= (const VarType& other)
{
	if (this == &other)
		return *this; // Self-assignment.

	VarType *oldElementType = m_type == VARTYPE_ARRAY ? m_data.array.elementType : DE_NULL;

	m_type	= other.m_type;
	m_data	= Data();

	if (m_type == VARTYPE_ARRAY)
	{
		m_data.array.elementType	= new VarType(*other.m_data.array.elementType);
		m_data.array.size			= other.m_data.array.size;
	}
	else
		m_data = other.m_data;

	delete oldElementType;

	return *this;
}

int VarType::getScalarSize (void) const
{
	switch (m_type)
	{
		case VARTYPE_BASIC:	return glu::getDataTypeScalarSize(m_data.basic.type);
		case VARTYPE_ARRAY:	return m_data.array.elementType->getScalarSize()*m_data.array.size;

		case VARTYPE_STRUCT:
		{
			int size = 0;
			for (StructType::ConstIterator iter = m_data.structPtr->begin(); iter != m_data.structPtr->end(); iter++)
				size += iter->getType().getScalarSize();
			return size;
		}

		default:
			DE_ASSERT(false);
			return 0;
	}
}

bool VarType::operator== (const VarType& other) const
{
	if (m_type != other.m_type)
		return false;

	switch (m_type)
	{
		case VARTYPE_BASIC:
			return	m_data.basic.type == other.m_data.basic.type &&
					m_data.basic.precision == other.m_data.basic.precision;

		case VARTYPE_ARRAY:
			return	*m_data.array.elementType == *other.m_data.array.elementType &&
					m_data.array.size == other.m_data.array.size;

		case VARTYPE_STRUCT:
			return m_data.structPtr == other.m_data.structPtr;

		default:
			DE_ASSERT(false);
			return 0;
	}
}

bool VarType::operator!= (const VarType& other) const
{
	return !(*this == other);
}

// StructMember implementation

bool StructMember::operator== (const StructMember& other) const
{
	return (m_name == other.m_name) && (m_type == other.m_type);
}

bool StructMember::operator!= (const StructMember& other) const
{
	return !(*this == other);
}

// StructType implementation.

void StructType::addMember (const char* name, const VarType& type)
{
	m_members.push_back(StructMember(name, type));
}

bool StructType::operator== (const StructType& other) const
{
	return (m_typeName == other.m_typeName) && (m_members == other.m_members);
}

bool StructType::operator!= (const StructType& other) const
{
	return !(*this == other);
}

const char* getStorageName (Storage storage)
{
	static const char* const s_names[] = { "in", "out", "const", "uniform", "buffer", "patch in", "patch out" };

	return de::getSizedArrayElement<STORAGE_LAST>(s_names, storage);
}

const char* getInterpolationName (Interpolation interpolation)
{
	static const char* const s_names[] = { "smooth", "flat", "centroid" };

	return de::getSizedArrayElement<INTERPOLATION_LAST>(s_names, interpolation);
}

const char* getFormatLayoutName (FormatLayout layout)
{
	static const char* s_names[] =
	{
		"rgba32f",			// FORMATLAYOUT_RGBA32F
		"rgba16f",			// FORMATLAYOUT_RGBA16F
		"r32f",				// FORMATLAYOUT_R32F
		"rgba8",			// FORMATLAYOUT_RGBA8
		"rgba8_snorm",		// FORMATLAYOUT_RGBA8_SNORM
		"rgba32i",			// FORMATLAYOUT_RGBA32I
		"rgba16i",			// FORMATLAYOUT_RGBA16I
		"rgba8i",			// FORMATLAYOUT_RGBA8I
		"r32i",				// FORMATLAYOUT_R32I
		"rgba32ui",			// FORMATLAYOUT_RGBA32UI
		"rgba16ui",			// FORMATLAYOUT_RGBA16UI
		"rgba8ui",			// FORMATLAYOUT_RGBA8UI
		"r32ui",			// FORMATLAYOUT_R32UI
	};

	return de::getSizedArrayElement<FORMATLAYOUT_LAST>(s_names, layout);
}

const char* getMemoryAccessQualifierName (MemoryAccessQualifier qualifier)
{
	switch (qualifier)
	{
		case MEMORYACCESSQUALIFIER_COHERENT_BIT:	return "coherent";
		case MEMORYACCESSQUALIFIER_VOLATILE_BIT:	return "volatile";
		case MEMORYACCESSQUALIFIER_RESTRICT_BIT:	return "restrict";
		case MEMORYACCESSQUALIFIER_READONLY_BIT:	return "readonly";
		case MEMORYACCESSQUALIFIER_WRITEONLY_BIT:	return "writeonly";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

const char* getMatrixOrderName (MatrixOrder qualifier)
{
	static const char* s_names[] =
	{
		"column_major",	// MATRIXORDER_COLUMN_MAJOR
		"row_major",	// MATRIXORDER_ROW_MAJOR
	};

	return de::getSizedArrayElement<MATRIXORDER_LAST>(s_names, qualifier);
}

// Layout Implementation

Layout::Layout (int location_, int binding_, int offset_, FormatLayout format_, MatrixOrder matrixOrder_)
	: location			(location_)
	, binding			(binding_)
	, offset			(offset_)
	, format			(format_)
	, matrixOrder		(matrixOrder_)
{
}

bool Layout::operator== (const Layout& other) const
{
	return	location == other.location &&
			binding == other.binding &&
			offset == other.offset &&
			format == other.format &&
			matrixOrder == other.matrixOrder;
}

bool Layout::operator!= (const Layout& other) const
{
	return !(*this == other);
}

// VariableDeclaration Implementation

VariableDeclaration::VariableDeclaration (const VarType& varType_, const std::string& name_, Storage storage_, Interpolation interpolation_, const Layout& layout_, deUint32 memoryAccessQualifierBits_)
	: layout						(layout_)
	, interpolation					(interpolation_)
	, storage						(storage_)
	, varType						(varType_)
	, memoryAccessQualifierBits		(memoryAccessQualifierBits_)
	, name							(name_)
{
}

bool VariableDeclaration::operator== (const VariableDeclaration& other) const
{
	return	layout == other.layout &&
			interpolation == other.interpolation &&
			storage == other.storage &&
			varType == other.varType &&
			memoryAccessQualifierBits == other.memoryAccessQualifierBits &&
			name == other.name;
}

bool VariableDeclaration::operator!= (const VariableDeclaration& other) const
{
	return !(*this == other);
}

// InterfaceBlock Implementation

InterfaceBlock::InterfaceBlock (void)
	: layout						(Layout())
	, storage						(glu::STORAGE_LAST)
	, memoryAccessQualifierFlags	(0)
{
}

// Declaration utilties.

std::ostream& operator<< (std::ostream& str, const Layout& layout)
{
	std::vector<std::string> layoutDeclarationList;

	if (layout.location != -1)
		layoutDeclarationList.push_back("location=" + de::toString(layout.location));

	if (layout.binding != -1)
		layoutDeclarationList.push_back("binding=" + de::toString(layout.binding));

	if (layout.offset != -1)
		layoutDeclarationList.push_back("offset=" + de::toString(layout.offset));

	if (layout.format != FORMATLAYOUT_LAST)
		layoutDeclarationList.push_back(getFormatLayoutName(layout.format));

	if (layout.matrixOrder != MATRIXORDER_LAST)
		layoutDeclarationList.push_back(getMatrixOrderName(layout.matrixOrder));

	if (!layoutDeclarationList.empty())
	{
		str << "layout(" << layoutDeclarationList[0];

		for (int layoutNdx = 1; layoutNdx < (int)layoutDeclarationList.size(); ++layoutNdx)
			str << ", " << layoutDeclarationList[layoutNdx];

		str << ")";
	}

	return str;
}

std::ostream& operator<< (std::ostream& str, const VariableDeclaration& decl)
{
	if (decl.layout != Layout())
		str << decl.layout << " ";

	for (int bitNdx = 0; (1 << bitNdx) & MEMORYACCESSQUALIFIER_MASK; ++bitNdx)
		if (decl.memoryAccessQualifierBits & (1 << bitNdx))
			str << getMemoryAccessQualifierName((glu::MemoryAccessQualifier)(1 << bitNdx)) << " ";

	if (decl.interpolation != INTERPOLATION_LAST)
		str << getInterpolationName(decl.interpolation) << " ";

	if (decl.storage != STORAGE_LAST)
		str << getStorageName(decl.storage) << " ";

	str << declare(decl.varType, decl.name);

	return str;
}

namespace decl
{

std::ostream& operator<< (std::ostream& str, const Indent& indent)
{
	for (int i = 0; i < indent.level; i++)
		str << "\t";
	return str;
}

std::ostream& operator<< (std::ostream& str, const DeclareVariable& decl)
{
	const VarType&		type	= decl.varType;
	const VarType*		curType	= &type;
	std::vector<int>	arraySizes;

	// Handle arrays.
	while (curType->isArrayType())
	{
		arraySizes.push_back(curType->getArraySize());
		curType = &curType->getElementType();
	}

	if (curType->isBasicType())
	{
		if (curType->getPrecision() != PRECISION_LAST && !glu::isDataTypeFloat16OrVec(curType->getBasicType()))
				str << glu::getPrecisionName(curType->getPrecision()) << " ";
		str << glu::getDataTypeName(curType->getBasicType());
	}
	else if (curType->isStructType())
	{
		const StructType* structPtr = curType->getStructPtr();

		if (structPtr->hasTypeName())
			str << structPtr->getTypeName();
		else
			str << declare(structPtr, decl.indentLevel); // Generate inline declaration.
	}
	else
		DE_ASSERT(false);

	str << " " << decl.name;

	// Print array sizes.
	for (std::vector<int>::const_iterator sizeIter = arraySizes.begin(); sizeIter != arraySizes.end(); sizeIter++)
	{
		const int arrSize = *sizeIter;
		if (arrSize == VarType::UNSIZED_ARRAY)
			str << "[]";
		else
			str << "[" << arrSize << "]";
	}

	return str;
}

std::ostream& operator<< (std::ostream& str, const DeclareStructTypePtr& decl)
{
	str << "struct";

	// Type name is optional.
	if (decl.structPtr->hasTypeName())
		str << " " << decl.structPtr->getTypeName();

	str << "\n" << indent(decl.indentLevel) << "{\n";

	for (StructType::ConstIterator memberIter = decl.structPtr->begin(); memberIter != decl.structPtr->end(); memberIter++)
	{
		str << indent(decl.indentLevel+1);
		str << declare(memberIter->getType(), memberIter->getName(), decl.indentLevel+1) << ";\n";
	}

	str << indent(decl.indentLevel) << "}";

	return str;
}

std::ostream& operator<< (std::ostream& str, const DeclareStructType& decl)
{
	return str << declare(&decl.structType, decl.indentLevel);
}

} // decl
} // glu
