/*-------------------------------------------------------------------------
 * drawElements Quality Program Random Shader Generator
 * ----------------------------------------------------
 *
 * 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 Source Formatter.
 *//*--------------------------------------------------------------------*/

#include "rsgPrettyPrinter.hpp"
#include "deStringUtil.hpp"

namespace rsg
{

static const char* s_tokenStr[] =
{
	DE_NULL,		// IDENTIFIER,
	"struct",		// STRUCT,
	"invariant",	// INVARIANT,
	"precision",	// PRECISION,
	"void",			// VOID,
	"break",		// BREAK,
	"continue",		// CONTINUE,
	"do ",			// DO,
	"while ",		// WHILE,
	"else ",		// ELSE,
	"for ",			// FOR,
	"if ",			// IF,
	"discard",		// DISCARD,
	"return ",		// RETURN,
	"++",			// INC_OP,
	"--",			// DEC_OP,
	"(",			// LEFT_PAREN,
	")",			// RIGHT_PAREN,
	"[",			// LEFT_BRACKET,
	"]",			// RIGHT_BRACKET,
	"{",			// LEFT_BRACE,
	"}",			// RIGHT_BRACE,
	".",			// DOT,
	", ",			// COMMA,
	" : ",			// COLON,
	";",			// SEMICOLON,
	" - ",			// MINUS,
	" + ",			// PLUS,
	" * ",			// MUL,
	" / ",			// DIV,
	" % ",			// MOD,
	" ? ",			// QUESTION,
	"bool",			// BOOL,
	"bvec2",		// BVEC2,
	"bvec3",		// BVEC3,
	"bvec4",		// BVEC4,
	"int",			// INT,
	"ivec2",		// IVEC2,
	"ivec3",		// IVEC3,
	"ivec4",		// IVEC4,
	"float",		// FLOAT,
	"vec2",			// VEC2,
	"vec3",			// VEC3,
	"vec4",			// VEC4,
	"mat2",			// MAT2,
	"mat3",			// MAT3,
	"mat4",			// MAT4,
	"sampler2D",	// SAMPLER2D,
	"samplerCube",	// SAMPLERCUBE,
	DE_NULL,		// FLOAT_LITERAL,
	DE_NULL,		// INT_LITERAL,
	DE_NULL,		// BOOL_LITERAL,
	" = ",			// EQUAL,
	" *= ",			// MUL_ASSIGN,
	" /= ",			// DIV_ASSIGN,
	" += ",			// ADD_ASSIGN,
	" -= ",			// SUB_ASSIGN,
	" < ",			// CMP_LT,
	" > ",			// CMP_GT,
	" <= ",			// CMP_LE,
	" >= ",			// CMP_GE,
	" == ",			// CMP_EQ,
	" != ",			// CMP_NE,
	" && ",			// LOGICAL_AND,
	" || ",			// LOGICAL_OR,
	"!",			// LOGICAL_NOT,
	" ^^ ",			// LOGICAL_XOR,
	"attribute",	// ATTRIBUTE,
	"uniform",		// UNIFORM,
	"varying",		// VARYING,
	"const",		// CONST,
	"flat",			// FLAT,
	"highp",		// HIGH_PRECISION,
	"mediump",		// MEDIUM_PRECISION,
	"lowp",			// LOW_PRECISION,
	"in",			// IN,
	"out",			// OUT,
	"inout",		// INOUT,
	"layout",		// LAYOUT,
	"location",		// LOCATION,
	DE_NULL,		// INDENT_INC,
	DE_NULL,		// INDENT_DEC,
	"\n"			// NEWLINE,
};

PrettyPrinter::PrettyPrinter (std::ostringstream& str)
	: m_str			(str)
	, m_indentDepth	(0)
{
}

inline const char* PrettyPrinter::getSimpleTokenStr (Token::Type token)
{
	DE_ASSERT(de::inBounds<int>(token, 0, (int)DE_LENGTH_OF_ARRAY(s_tokenStr)));
	return s_tokenStr[token];
}

void PrettyPrinter::append (const TokenStream& tokens)
{
	for (int ndx = 0; ndx < tokens.getSize(); ndx++)
		processToken(tokens[ndx]);
}

inline bool isIdentifierChar (char c)
{
	return de::inRange(c, 'a', 'z') || de::inRange(c, 'A', 'Z') || de::inRange(c, '0', '9') || c == '_';
}

void PrettyPrinter::processToken (const Token& token)
{
	bool prevIsIdentifierChar = m_line.length() > 0 && isIdentifierChar(m_line[m_line.length()-1]);

	switch (token.getType())
	{
		case Token::IDENTIFIER:
			if (prevIsIdentifierChar)
				m_line += " ";
			m_line += token.getIdentifier();
			break;

		case Token::FLOAT_LITERAL:
		{
			std::string f = de::toString(token.getFloat());
			if (f.find('.') == std::string::npos)
				f += ".0"; // Make sure value parses as float
			m_line += f;
			break;
		}

		case Token::INT_LITERAL:
			m_line += de::toString(token.getInt());
			break;

		case Token::BOOL_LITERAL:
			m_line += (token.getBool() ? "true" : "false");
			break;

		case Token::INDENT_INC:
			m_indentDepth += 1;
			break;

		case Token::INDENT_DEC:
			m_indentDepth -= 1;
			break;

		case Token::NEWLINE:
			// Indent
			for (int i = 0; i < m_indentDepth; i++)
				m_str << "\t";

			// Flush line to source
			m_str << m_line + "\n";
			m_line = "";
			break;

		default:
		{
			const char* tokenStr = getSimpleTokenStr(token.getType());
			if (prevIsIdentifierChar && isIdentifierChar(tokenStr[0]))
				m_line += " ";
			m_line += tokenStr;
			break;
		}
	}
}

} // rsg
