#ifndef _RSGVARIABLEMANAGER_HPP
#define _RSGVARIABLEMANAGER_HPP
/*-------------------------------------------------------------------------
 * 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 Variable manager.
 *
 * Memory management:
 *  Variable manager owns variable objects until they are either explictly
 *  removed or moved to currently active scope. After that the ownership
 *  is transferred to Scope or the object that called removeEntry().
 *//*--------------------------------------------------------------------*/

#include "rsgDefs.hpp"
#include "rsgVariable.hpp"
#include "rsgVariableValue.hpp"
#include "rsgNameAllocator.hpp"

#include <iterator>
#include <vector>
#include <set>

namespace rsg
{

class ValueEntry
{
public:
							ValueEntry				(const Variable* variable);
							~ValueEntry				(void) {}

	const Variable*			getVariable				(void) const	{ return m_variable;	}

	ConstValueRangeAccess	getValueRange			(void) const	{ return m_valueRange.asAccess();	}
	ValueRangeAccess		getValueRange			(void)			{ return m_valueRange.asAccess();	}

private:
	const Variable*			m_variable;
	ValueRange				m_valueRange;
};

// Variable scope manages variable allocation.
class VariableScope
{
public:
										VariableScope			(void);
										~VariableScope			(void);

	Variable*							allocate				(const VariableType& type, Variable::Storage storage, const char* name);
	void								declare					(Variable* variable);		//!< Move from live set to declared set
	void								removeLive				(const Variable* variable);	//!< Just remove from live set (when migrating to parent).

	const std::vector<Variable*>&		getDeclaredVariables	(void) const	{ return m_declaredVariables;	}

	std::vector<Variable*>&				getLiveVariables		(void)			{ return m_liveVariables;		}
	const std::vector<Variable*>&		getLiveVariables		(void) const	{ return m_liveVariables;		}

private:
										VariableScope			(const VariableScope& other);
	VariableScope&						operator=				(const VariableScope& other);

	std::vector<Variable*>				m_declaredVariables;	//!< Variables declared in this scope. Not available for expressions.
	std::vector<Variable*>				m_liveVariables;		//!< Live variables (available for expression) that can be declared in this scope.
};

class ValueScope
{
public:
										ValueScope				(void);
										~ValueScope				(void);

	ValueEntry*							allocate				(const Variable* variable);
	ValueEntry*							findEntry				(const Variable* variable) const;
	void								setValue				(const Variable* variable, ConstValueRangeAccess value);
	void								removeValue				(const Variable* variable);

	std::vector<ValueEntry*>&			getValues				(void)			{ return m_entries;	}
	const std::vector<ValueEntry*>&		getValues				(void) const	{ return m_entries; }

	void								clear					(void);

private:
										ValueScope				(const ValueScope& other);
	ValueScope&							operator=				(const ValueScope& other);

	std::vector<ValueEntry*>			m_entries;
};

class ReservedScalars
{
public:
	int numScalars;

	ReservedScalars (void)
		: numScalars(0)
	{
	}
};

// \todo [2011-05-26 pyry] Clean up this a bit, separate const variant.
template <typename Item, typename Iterator, class Filter>
class FilteredIterator : public std::iterator<std::input_iterator_tag, Item>
{
public:
	FilteredIterator (Iterator iter, Iterator end, Filter filter)
		: m_iter	(iter)
		, m_end		(end)
		, m_filter	(filter)
	{
	}

	FilteredIterator operator+ (ptrdiff_t offset) const
	{
		Iterator nextEntry = m_iter;
		while (offset--)
			nextEntry = findNext(m_filter, nextEntry, m_end);
		return FilteredIterator(nextEntry, m_end, m_filter);
	}

	FilteredIterator& operator++ ()
	{
		// Pre-increment
		m_iter = findNext(m_filter, m_iter, m_end);
		return *this;
	}

	FilteredIterator operator++ (int)
	{
		// Post-increment
		FilteredIterator copy = *this;
		m_iter = findNext(m_filter, m_iter, m_end);
		return copy;
	}

	bool operator== (const FilteredIterator& other) const
	{
		return m_iter == other.m_iter;
	}

	bool operator!= (const FilteredIterator& other) const
	{
		return m_iter != other.m_iter;
	}

	const Item& operator* (void)
	{
		DE_ASSERT(m_iter != m_end);
		DE_ASSERT(m_filter(*m_iter));
		return *m_iter;
	}

private:
	static Iterator findNext (Filter filter, Iterator iter, Iterator end)
	{
		do
			iter++;
		while (iter != end && !filter(*iter));
		return iter;
	}

	Iterator		m_iter;
	Iterator		m_end;
	Filter			m_filter;
};

template <class Filter>
class ValueEntryIterator : public FilteredIterator<const ValueEntry*, std::vector<const ValueEntry*>::const_iterator, Filter>
{
public:
	ValueEntryIterator (std::vector<const ValueEntry*>::const_iterator begin, std::vector<const ValueEntry*>::const_iterator end, Filter filter)
		: FilteredIterator<const ValueEntry*, std::vector<const ValueEntry*>::const_iterator, Filter>(begin, end, filter)
	{
	}
};

class VariableManager
{
public:
									VariableManager					(NameAllocator& nameAllocator);
									~VariableManager				(void);

	int								getNumAllocatedScalars			(void) const { return m_numAllocatedScalars; }
	int								getNumAllocatedShaderInScalars	(void) const { return m_numAllocatedShaderInScalars; }
	int								getNumAllocatedShaderInVariables(void) const { return m_numAllocatedShaderInVariables; }
	int								getNumAllocatedUniformScalars	(void) const { return m_numAllocatedUniformScalars; }

	void							reserve							(ReservedScalars& store, int numScalars);
	void							release							(ReservedScalars& store);

	Variable*						allocate						(const VariableType& type);
	Variable*						allocate						(const VariableType& type, Variable::Storage storage, const char* name);

	void							setStorage						(Variable* variable, Variable::Storage storage);

	void							setValue						(const Variable* variable, ConstValueRangeAccess value);
	const ValueEntry*				getValue						(const Variable* variable) const;
	const ValueEntry*				getParentValue					(const Variable* variable) const;

	void							removeValueFromCurrentScope		(const Variable* variable);

	void							declareVariable					(Variable* variable);
	bool							canDeclareInCurrentScope		(const Variable* variable) const;
	const std::vector<Variable*>&	getLiveVariables				(void) const;

	void							pushVariableScope				(VariableScope& scope);
	void							popVariableScope				(void);

	void							pushValueScope					(ValueScope& scope);
	void							popValueScope					(void);

	template <class Filter>
	ValueEntryIterator<Filter>		getBegin						(Filter filter = Filter()) const;

	template <class Filter>
	ValueEntryIterator<Filter>		getEnd							(Filter filter = Filter()) const;

	template <class Filter>
	bool							hasEntry						(Filter filter = Filter()) const;

private:
									VariableManager					(const VariableManager& other);
	VariableManager&				operator=						(const VariableManager& other);

	VariableScope&					getCurVariableScope				(void)			{ return *m_variableScopeStack.back();	}
	const VariableScope&			getCurVariableScope				(void) const	{ return *m_variableScopeStack.back();	}

	ValueScope&						getCurValueScope				(void)			{ return *m_valueScopeStack.back();	}
	const ValueScope&				getCurValueScope				(void) const	{ return *m_valueScopeStack.back();	}

	std::vector<VariableScope*>		m_variableScopeStack;
	std::vector<ValueScope*>		m_valueScopeStack;

	std::vector<const ValueEntry*>	m_entryCache;	//!< For faster value entry access.

	int								m_numAllocatedScalars;
	int								m_numAllocatedShaderInScalars;
	int								m_numAllocatedShaderInVariables;
	int								m_numAllocatedUniformScalars;
	NameAllocator&					m_nameAllocator;
};

template <class Filter>
ValueEntryIterator<Filter> VariableManager::getBegin (Filter filter) const
{
	std::vector<const ValueEntry*>::const_iterator first = m_entryCache.begin();
	while (first != m_entryCache.end() && !filter(*first))
		first++;
	return ValueEntryIterator<Filter>(first, m_entryCache.end(), filter);
}

template <class Filter>
ValueEntryIterator<Filter> VariableManager::getEnd (Filter filter) const
{
	return ValueEntryIterator<Filter>(m_entryCache.end(), m_entryCache.end(), filter);
}

template <class Filter>
bool VariableManager::hasEntry (Filter filter) const
{
	for (std::vector<const ValueEntry*>::const_iterator i = m_entryCache.begin(); i != m_entryCache.end(); i++)
	{
		if (filter(*i))
			return true;
	}
	return false;
}

// Common filters

class AnyEntry
{
public:
	typedef ValueEntryIterator<AnyEntry> Iterator;

	bool operator() (const ValueEntry* entry) const
	{
		DE_UNREF(entry);
		return true;
	}
};

class IsWritableEntry
{
public:
	bool operator() (const ValueEntry* entry) const
	{
		switch (entry->getVariable()->getStorage())
		{
			case Variable::STORAGE_LOCAL:
			case Variable::STORAGE_SHADER_OUT:
			case Variable::STORAGE_PARAMETER_IN:
			case Variable::STORAGE_PARAMETER_OUT:
			case Variable::STORAGE_PARAMETER_INOUT:
				return true;

			default:
				return false;
		}
	}
};

template <Variable::Storage Storage>
class EntryStorageFilter
{
public:
	typedef ValueEntryIterator<EntryStorageFilter<Storage> > Iterator;

	bool operator() (const ValueEntry* entry) const
	{
		return entry->getVariable()->getStorage() == Storage;
	}
};

typedef EntryStorageFilter<Variable::STORAGE_LOCAL>			LocalEntryFilter;
typedef EntryStorageFilter<Variable::STORAGE_SHADER_IN>		ShaderInEntryFilter;
typedef EntryStorageFilter<Variable::STORAGE_SHADER_OUT>	ShaderOutEntryFilter;

} // rsg

#endif // _RSGVARIABLEMANAGER_HPP
