/*
    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 ARCH2HAL_ARCHITECT_H
#define ARCH2HAL_ARCHITECT_H
#include "arch_headers.h"
#include "LexicalUnit.h"

namespace hal_architect
{
	struct Triplets
	{
		size_t lexId;
		size_t headId;
		std::set<size_t> constituents;

	};


	class Architect
	{
		public:
			Architect();
			void Start();
		private:
			Corpus::CSentence* TransformSenetenceOnCurrentPosiotion ( Corpus::CSentence* old, Triplets &t, size_t
			        &removedBeforeCurrentPos, LexicalUnits::LexicalUnitPtr lu );

			void ProcessDocuments();
			void ProcessBinaryCorpus();
			void ProcessBinaryCorpusBySentence();
			void ProcessBinaryCorpusByToken();
			void ProcessSingleDocument(Corpus::Tokenisation::CCorpusTokenReader &reader);
			void ProcessSingleDocSentenceContext(Corpus::Tokenisation::CCorpusTokenReader &reader);
			void ProcessSingleDocHalContext(Corpus::Tokenisation::CCorpusTokenReader &reader);
			void ProcessSingleDocWindowContext(Corpus::Tokenisation::CCorpusTokenReader &reader);
			void ProcessSentence ( Corpus::CSentence* sentence );
			void Initalize();


			void CheckSentence ( Corpus::CSentence * &sentence, std::map<size_t, size_t>  &relevantRows,
			                     std::map<size_t, size_t> &relevantColumns);
			void FindAllOccurrences(Corpus::CSentence *sentence, std::set<size_t> &relevantLUs);
			void FindAllPotentialForPosition(Corpus::CSentence *sentence, std::set<size_t> & relevantLUs,
											 std::vector< Triplets >  &foundLUs);
			bool ChooseLU(int pos, std::map<size_t, size_t>  &relevantRows,
					std::map<size_t, size_t> &relevantColumns, 	Triplets &t, std::vector< Triplets >  &foundLUs, LexicalUnits::LexicalUnitPtr &lu); 
			
			void CountCoocurrences( Corpus::CSentence * &sentence, std::map<size_t, size_t>  &relevantRows, 
					std::map<size_t, size_t> &relevantColumns );
			void CountCoocurrencesEveryWithEvery( Corpus::CSentence * &sentence, std::map<size_t, size_t>  &relevantRows, 
					std::map<size_t, size_t> &relevantColumns );
			void CountCoocurrencesForWindowCenter( Corpus::CSentence * &sentence, std::map<size_t, size_t>  &relevantRows, 
					std::map<size_t, size_t> &relevantColumns );
			void CountCoocurrencesForHALWindow( Corpus::CSentence * &sentence, std::map<size_t, size_t>  &relevantRows, 
					std::map<size_t, size_t> &relevantColumns );

			Matrices::CRSMatrixPtr m_pMatrix;
			std::map<size_t, size_t> m_mUnit2Row;
			std::map<size_t, size_t> m_mUnit2Column;
			std::multimap<int, size_t> m_mBase2PotentialUnit;
			
			size_t m_stTokenCount;
			size_t m_stLexicalUnitCount;

			double (*m_pDistFunct)(size_t);
	};

	double DistanceOne(size_t);
}//namespace architect

#endif //ARCH2_ARCHITECT_H

