#ifndef VERB_H_INCLUDED
#define VERB_H_INCLUDED

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

#include "boost/algorithm/string.hpp"

#include "grammarCase.h"

namespace VB
{
	struct VerbRecord : public WordHolder
	{

		bool getCanBePrefixed() const;
		bool getCanBeNotPrefixed() const;
		bool getCanBePerfect() const;
		bool getCanBeImperfect() const;
			
		void SetAllFields();
		void SetAllFields(const std::vector<std::wstring>& lineArr);

		VerbRecord();

		VerbRecord(std::wstring line);

	};



	enum VerbParams
	{
		VP_INFINITIVE = 0,
		VP_PAST_MALE_SINGULAR,
		VP_PAST_FEMALE_SINGULAR,
		VP_PAST_NEUTER_SINGULAR,
		VP_PAST_PLURAL,
		VP_PRESENT_FIRSTPERSON_SINGULAR,
		VP_PRESENT_SECONDPERSON_SINGULAR,
		VP_PRESENT_THIRDPERSON_SINGULAR,
		VP_PRESENT_FIRSTPERSON_PLURAL,
		VP_PRESENT_SECONDPERSON_PLURAL,
		VP_PRESENT_THIRDPERSON_PLURAL,
		VP_SIZE
	};


	struct VerbStruct : public WordModificatorInterface
	{
		//VerbParams verbParams;
		//std::wstring selfEnding;

		//VerbRecord verbRecord;

		VerbStruct();

		VerbStruct(VerbParams iVerbParams, std::wstring iSelfEnding);

		//boost::property_tree::wptree GetModificators() const;

		//bool operator<(const VerbStruct& v) const;

	};

	struct VerbPair : public WordPairInterface
	{
	protected:

		VerbStruct modificator;
		VerbRecord wordRecord;

	public:

		VerbPair();

		VerbPair(VerbStruct iModificator, VerbRecord iWordRecord);

		virtual  const WordModificatorInterface& wordModificator() const;

		virtual  const WordHolder& word() const;

		virtual std::wstring getType();
	};

	extern std::vector<VerbRecord> VerbRecordArr;

	enum VerbConjunction
	{
		VC_FIRST_ET = 0,
		VC_FIRST_AT,
		VC_FIRST_OT,
		VC_FIRST_IT,
		VC_FIRST_YT,
		VC_FIRST_YAT,
		VC_SECOND_IT,
		VC_SECOND_ET,
		VC_SECOND_AT,
		VC_SIZE
	};

	struct VerbConjunctionTableRecord
	{
		VerbConjunction conjunction;

		std::wstring ending;
	};

	struct VerbParamsTableRecord
	{
		VerbParams verbParams;
		std::vector<VerbConjunctionTableRecord> verbConjunctionTable;
	};


	extern std::vector<VerbParamsTableRecord> VerbParamsTable;




	VerbParams WStringToVerbParams(std::wstring str);
	std::wstring VerbParamsToWString(VerbParams verbParams);
	VerbConjunction WStringToVerbConjunction(std::wstring str);

	bool VerbIsInDictionary(std::wstring verbInfinitive);
	VerbRecord GetVerbRecordFromDictionary(std::wstring verbInfinitive);

	std::wstring cutSelfEndingIfPossible(std::wstring& verb);

	std::vector<std::wstring> GetAllVerbEndingArr();


	struct VerbEndingDivision
	{
		std::wstring base;
		std::wstring ending;
		
		bool operator<(const VerbEndingDivision& other) const;
	};


	std::set<VerbEndingDivision> getPossibleVerbEndingDivisionSet(std::wstring verb);

	std::set<std::pair<VerbParams, VerbConjunction>> getAllPossibleVerbParamsAndConjunctions(std::wstring ending);

	std::wstring GetVerbInfinitive(std::wstring modifiedBase, VerbConjunction verbConjunction);

	void RecognizeVerb(std::wstring verb, std::vector<std::shared_ptr<WordPairInterface>>& wordPair);


	void LoadVerbConjunctionTable();

	void LoadFrequentWordSet();

	

} //namespace VB

#endif //VERB_H_INCLUDED
