#ifndef _graphparsing_1ec_n5_DEPPARSER_H
#define _graphparsing_1ec_n5_DEPPARSER_H

#include <vector>
#include <unordered_set>

#include <include/learning/tree/lca.h>
#include "common/parser/depgraph.h"
#include "graphparsing_1ec_n5_weight.h"
#include "common/parser/depparser_base.h"
#include "graphparsing_1ec_n5_parser.h"

namespace graphparsing_1ec_n5 {
	class DepParser : public DepParserBase {
	private:
		static WordPOSTag empty_taggedword;
		static WordPOSTag start_taggedword;
		static WordPOSTag end_taggedword;

		StateItem m_lItems[MAX_SENTENCE_SIZE][MAX_SENTENCE_SIZE];
		WordPOSTag m_lSentence[MAX_SENTENCE_SIZE];
		std::vector<Arc> m_vecCorrectArcs;
		std::vector<Arc> m_vecTrainArcs;
		DependencyTree m_vecDependencyTree;
		LCA m_lcaTree;
		int m_nSentenceLength;

		tscore m_nRetval;
		tscore m_lFirstOrderScore[MAX_SENTENCE_SIZE << 1];

		int m_nDis, m_nDir;

		Word p_word, c_word;
		POSTag p_tag, c_tag;

		WordInt word_int;
		POSTagInt tag_int;

		POSTag p_1_tag, p1_tag, c_1_tag, c1_tag, b_tag;
		Word p_1_word, p1_word, c_1_word, c1_word;

		TwoWordsInt word_word_int;
		POSTagSet2Int tag_tag_int;
		WordPOSTagInt word_tag_int;

		POSTagSet3Int tag_tag_tag_int;
		WordPOSTagPOSTagInt word_tag_tag_int;
		POSTagSet4Int flag_word_tag_tag_int;
		POSTagSet3Int flag_tag_tag_int;
		WordWordPOSTagInt word_word_tag_int;

		POSTagSet4Int tag_tag_tag_tag_int;
		WordWordPOSTagPOSTagInt word_word_tag_tag_int;
		PathInt path_int;
		POSTagInt subcat_int;
		POSTagSet2Int subcat_tag_int,path_tag_int;
		LabelInt label_int;
		std::unordered_set<BiGram<int>> m_setFirstGoldScore;

		void update();
		void generate(DependencyGraph * retval, const DependencyGraph & correct);
		void goldCheck();

		tscore arcScore(const int & p, const int & c );
		void initFirstOrderScore(const int & d);

		void getOrUpdateStackScore(const int & p, const int & c, const int & amount = 0);
		void GetOneEndPointGraph(const DependencyGraph & correct);
	public:
		DepParser(const std::string & sFeatureInput, const std::string & sFeatureOut, int nState);
		~DepParser();
		void outans();
		void decode() override {};
		void decodeArcs() override{};
		void getTrainArcs();
		void getArc(int l, int r , int x = -1);
		void train(const DependencyGraph & correct, const int & round);
		void parse(const DependencyGraph & graph, DependencyGraph * retval);
		void work(DependencyGraph * retval, const DependencyGraph & correct);
	};
}

#endif
