/*
    Copyright (C) 2012 Bartosz Broda, Jacek Bochenek, Łukasz Biłeńkij, 
    Damian Jaworski, Wojciech Mazur, Dominik Piasecki, Maciej Piasecki, 
    Radosław Ramocki
    
    This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.

    This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. 

    See the LICENSE and COPYING files for more details.
*/

#ifndef LEXICALUNITS_MAKRO_H
#define LEXICALUNITS_MAKRO_H
#include "../lex_headers.h"
#include "UnitStub.h"
#include "../LexicalUnit.h"

namespace LexicalUnits
{

	namespace MEParser
	{

		class Makro
		{
		public:
			/**
			Parses extracted makro from file description of ME. Parameters are related directly to that file, ie:
			\code
			<m>
			<name>AdjSubstFlex</name>
			<var>$A,$S</var>
			<con>
			or(
			and(
			equal(base[0],{$A}),
			equal(flex[0],{adj}),
			equal(base[1],$S),
			in(flex[1],{subst,ger,depr}),
			agrpp(0,1,{nmb,gnd,cas},3)
			),
			and(
			equal(base[0],$S),
			in(flex[0],{subst,ger,depr}),
			equal(base[1],$A),
			equal(flex[1],{adj}),
			agrpp(0,1,{nmb,gnd,cas},3)
			)
			)
			</con>
			</m>
			\endcode
			\param name string between name tag
			\param var strng between var tag
			\param conlines lines of text between con tag
			*/
			Makro (const std::string & name,const std::string & var, std::vector<std::string> conlines);

			/**
			* Instantiates given stub.
			*/ 
			LexicalUnitPtr InstantiateUnit ( UnitStubPtr pStub );

		private:
			/// Makro's name
			std::string m_sMakroName;
			/// Lines of JOSKIPI operator
			std::vector<std::string> m_vCondition;
			/**
			* Vector of pairs varname -> mask. Order of variables is the same as
			* in var parameter of Makro constructor.
			*/ 
            std::vector<std::pair<std::string, Corpus::CTag> > m_vVarToMask;
            std::map<std::string, size_t> tokens;
			std::map<std::string, size_t> m_vVarToBase;
			static boost::regex m_EqualBaseRegex;

			static boost::regex m_EqualInFlexRegex;

			/**
			* Logic for Makro constructor.
			*/ 
			void Parse (const std::string &  name, const std::string &  var, std::vector<std::string> conlines);

			/**
			* Extracts mask for variables from condition lines.
			*/ 
			void ExtractVarsMask ( const std::string & vars );

			/**
			Creates FixME or FlexME out of stub.
			*/
			LexicalUnitPtr CreateFlexOrFixUnit ( UnitStubPtr pStub );
		};//class Makro

		typedef boost::shared_ptr<Makro> MakroPtr;
	}//namespace MEParser
}//namespace LexicalUnits

#endif //LEXICALUNITS_MAKRO_H

