#ifndef GRAMMAR_CASE_H_INCLUDED
#define GRAMMAR_CASE_H_INCLUDED

#include <string>
#include <map>
#include <set>
#include <vector>
#include <fstream>

#include "boost/algorithm/string.hpp"
#include "boost/property_tree/ptree.hpp"


enum NounGender
{
	NG_MALE = 0,
	NG_FEMALE,
	NG_NEUTRAL
};

enum NounGrammaticalCase
{
	NGC_P1_NOMINATIVE = 0,
	NGC_P2_GENITIVE,
	NGC_P3_DATIVE,
	NGC_P4_ACCUSATIVE,
	NGC_P5_INSTRUMENTAL,
	NGC_P6_PREPOSITIONAL,
	NGC_SIZE
};

enum NounCount
{
	NC_SINGULAR = 0,
	NC_PLURAL,
	NC_SIZE
};


struct GrammaticalTableRecord
{
	NounCount count;

	NounGrammaticalCase grammaticalCase;

	std::set<std::wstring> ending;
};

struct TranslationUnit
{
	std::wstring meaning;
	std::wstring comment;
	std::wstring example;
};

class WordHolder
{
private:
	std::wstring word;

protected:
	boost::property_tree::wptree properties;

	std::vector<TranslationUnit> translationUnitArr;

	void FillTranslationUnit(const std::vector<std::wstring>& lineArr, int startFrom);

public:

	void SetWord(const std::wstring& w);

	std::wstring GetWord() const;

	wchar_t GetLastChar() const;

	wchar_t GetPrevLastChar() const;

	wchar_t GetPrevPrevLastChar() const;

	bool operator<(const WordHolder& other) const;

	boost::property_tree::wptree GetProperties() const;

	boost::property_tree::wptree CreateTranslationPropertyTree() const;

	bool operator==(const WordHolder& other) const
	{
		return word == other.word;
	}

};

class WordModificatorInterface
{
protected:
	boost::property_tree::wptree modificatorTree;
public:

	virtual ~WordModificatorInterface()
	{
	}

	boost::property_tree::wptree GetModificators() const
	{
		return modificatorTree;
	}

	bool operator==(const WordModificatorInterface& other) const
	{
		return modificatorTree == other.modificatorTree;
	}
};

struct WordPairInterface
{
	virtual const WordModificatorInterface& wordModificator() const = 0;

	virtual const WordHolder& word() const = 0;

	virtual std::wstring getType() = 0;

	virtual ~WordPairInterface()
	{

	}

	bool operator==(const WordPairInterface& other) const
	{
		return wordModificator() == other.wordModificator() && word() == other.word();
	}

	bool operator!=(const WordPairInterface& other) const
	{
		return !operator==(other);
	}
};

std::wstring NounGenderToWString(NounGender g);

std::wstring NormalizeNounGenderString(std::wstring str);
NounGender WStringToNounGender(std::wstring str);

std::wstring NounCountToWString(NounCount nounCount);
NounCount WStringToNounCount(std::wstring str);
std::wstring NounGrammaticalCaseToWString(NounGrammaticalCase nounGrammaticalCase);
NounGrammaticalCase WStringToNounGrammaticalCase(std::wstring str);


bool charIsConsolant(wchar_t c); //except й

bool charIsVowel(wchar_t c);

bool charIsIFormConsolant(wchar_t c);
bool charIsUFormConsolant(wchar_t c);


#endif //GRAMMAR_CASE_H_INCLUDED
