//-----------------------------------------------------------------------------------------------
// ProceduralNames.hpp
//
#pragma once
#ifndef included_ProceduralNames
#define included_ProceduralNames

//-----------------------------------------------------------------------------------------------
#include "Engine/Core/EngineCommon.hpp"


/////////////////////////////////////////////////////////////////////////////////////////////////
struct StringWithQuantity
{
	int				m_quantity;
	std::string		m_string;
};


/////////////////////////////////////////////////////////////////////////////////////////////////
class ProceduralNameGenerator
{
protected:
	static const unsigned int SEED_NOT_PROVIDED;

public:
	static ProceduralNameGenerator& GetProceduralNameGeneratorForType( const char* nameTypeDefinitionName );
	ProceduralNameGenerator( const char* nameTypeDefinitionName );
	virtual void GenerateProceduralName( std::string& out_generatedName, unsigned int randomSeed = SEED_NOT_PROVIDED ) = 0;

protected:
	const ProceduralNameGenerator& operator = ( const ProceduralNameGenerator& copy ); // Not implemented
	bool IsAlwaysAVowel( char testChar );
	const std::string& GetRandomStringInList( const std::vector< StringWithQuantity >& listOfWeightedStrings, int totalOfWeights=-1 );

protected:
	static std::map< std::string, ProceduralNameGenerator* >	s_proceduralNameGeneratorRegistry;
};



/////////////////////////////////////////////////////////////////////////////////////////////////
class ProceduralNameGenerator_ClustersOnly : public ProceduralNameGenerator
{
protected:
	enum WordElementType
	{
		WORD_ELEMENT_STARTING_VOWEL,
		WORD_ELEMENT_STARTING_CONSONANT,
		WORD_ELEMENT_MIDDLE_VOWEL,
		WORD_ELEMENT_MIDDLE_CONSONANT,
		WORD_ELEMENT_ENDING_VOWEL,
		WORD_ELEMENT_ENDING_CONSONANT,
		NUM_WORD_ELEMENTS
	};

public:
	ProceduralNameGenerator_ClustersOnly( const char* nameTypeDefinitionName, const std::vector< std::string >& listOfExampleNames, bool allowFullMatches=false, bool allowWordMatches=false );
	virtual void GenerateProceduralName( std::string& out_generatedName, unsigned int randomSeed = SEED_NOT_PROVIDED );

private:
	virtual void ProcessSeedNames();
	virtual void ProcessSeedName( const std::string& seedName );
	void RegisterSeedClusterForWordElementType( const std::string& seedCluster, WordElementType wordElementType );
	void RegisterWordShape( const std::string& wordShape );
	WordElementType GetWordElementTypeForWordShapeCharacter( char wordShapeCharacter );

private:
	bool								m_allowFullMatches;
	bool								m_allowWordMatches;
	std::vector< std::string >			m_seedNames;
	std::vector< StringWithQuantity >	m_wordShapes;
	int									m_totalWordShapesCount;
	std::vector< StringWithQuantity >	m_letterClustersForElementType[ NUM_WORD_ELEMENTS ];
	int									m_totalClusterCountForElementType[ NUM_WORD_ELEMENTS ];
};


#endif // included_ProceduralNames


