#include <fstream>

#include "graphparsing_1ec_n4_weight.h"
#include "common/token/word.h"
#include "common/token/pos.h"

namespace graphparsing_1ec_n4 {
	Weight::Weight(const std::string & sRead, const std::string & sRecord) :
		WeightBase(sRead, sRecord),
		m_mapPw("m_mapPw"),
		m_mapPp("m_mapPp"),
		m_mapPwp("m_mapPwp"),
		m_mapCw("m_mapCw"),
		m_mapCp("m_mapCp"),
		m_mapCwp("m_mapCwp"),

		m_mapP_1w("m_mapP_1w"),
		m_mapP_1p("m_mapP_1p"),
		m_mapP_1wp("m_mapP_1wp"),
		m_mapP1w("m_mapP1w"),
		m_mapP1p("m_mapP1p"),
		m_mapP1wp("m_mapP1wp"),
		m_mapC_1w("m_mapC_1w"),
		m_mapC_1p("m_mapC_1p"),
		m_mapC_1wp("m_mapC_1wp"),
		m_mapC1w("m_mapC1w"),
		m_mapC1p("m_mapC1p"),
		m_mapC1wp("m_mapC1wp"),

		m_mapP_1C("m_mapP_1C"),
		m_mapP1C("m_mapP1C"),
		m_mapPC_1("m_mapPC_1"),
		m_mapPC1("m_mapPC1"),

		m_mapPwpCwp("m_mapPwpCwp"),
		m_mapPpCwp("m_mapPpCwp"),
		m_mapPwpCp("m_mapPwpCp"),
		m_mapPwCwp("m_mapPwCwp"),
		m_mapPwpCw("m_mapPwpCw"),
		m_mapPwCw("m_mapPwCw"),
		m_mapPpCp("m_mapPpCp"),
		m_mapPpBpCp("m_mapPpBpCp"),
		m_mapPpPp1Cp_1Cp("m_mapPpPp1Cp_1Cp"),
		m_mapPp_1PpCp_1Cp("m_mapPp_1PpCp_1Cp"),
		m_mapPpPp1CpCp1("m_mapPpPp1CpCp1"),
		m_mapPp_1PpCpCp1("m_mapPp_1PpCpCp1"),
		m_mapP_1PC("m_mapP_1PC"),
		m_mapPP1C("m_mapPP1C"),
		m_mapPC_1C("m_mapPC_1C"),
		m_mapPCC1("m_mapPCC1"),

		m_mapPath("m_mapPath"),
		m_mapFPath("m_mapFPath"),
		m_mapPFPathCtag("m_mapPFPathCtag"),
		m_mapCFPathPtag("m_mapCFPathPtag"),
		m_mapLPath("m_mapLPath"),
		m_mapPsubcat("m_mapPsubcat"),
		m_mapCsubcat("m_mapCsubcat"),
		m_mapPsubcatCtag("m_mapPsubcatCtag"),
		m_mapCsubcatPtag("m_mapCsubcatPtag"),
		m_mapPC("m_mapPC"),
		m_mapCLabel("m_mapCLabel"),

		m_mapLW("m_mapLW"),
		m_mapRW("m_mapRW"),
		m_mapLW_1("m_mapLW_1"),
		m_mapRW1("m_mapRW1"),
		m_mapLCpPp("m_mapLCpPp"),
		m_mapLCpPw("m_mapLCpPw"),
		m_mapLCwPp("m_mapLCwPp"),
		m_mapLCwPw("m_mapLCwPw"),
		m_mapLSpPp("m_mapLSpPp"),
		m_mapLSwPp("m_mapLSwPp"),
		m_mapRSpPp("m_mapRSpPp"),
		m_mapRSwPp("m_mapRSwPp")

	{
		loadScores();
		std::cout << "load complete." << std::endl;
	}

	Weight::~Weight() = default;

	void Weight::loadScores() {

		if (m_sReadPath.empty()) {
			return;
		}
		std::ifstream input(m_sReadPath);
		if (!input) {
			return;
		}

		input >> TWord::getTokenizer();

		input >> TPOSTag::getTokenizer();

		input >> m_mapPw;
		input >> m_mapPp;
		input >> m_mapPwp;

		input >> m_mapCw;
		input >> m_mapCp;
		input >> m_mapCwp;

		input >> m_mapP_1w;
		input >> m_mapP_1p;
		input >> m_mapP_1wp;
		input >> m_mapP1w;
		input >> m_mapP1p;
		input >> m_mapP1wp;
		input >> m_mapC_1w;
		input >> m_mapC_1p;
		input >> m_mapC_1wp;
		input >> m_mapC1w;
		input >> m_mapC1p;
		input >> m_mapC1wp;

		input >> m_mapP_1C;
		input >> m_mapP1C;
		input >> m_mapPC_1;
		input >> m_mapPC1;

		input >> m_mapPwpCwp;
		input >> m_mapPpCwp;
		input >> m_mapPwpCp;
		input >> m_mapPwCwp;
		input >> m_mapPwpCw;
		input >> m_mapPwCw;
		input >> m_mapPpCp;

		input >> m_mapPpBpCp;
		input >> m_mapPpPp1Cp_1Cp;
		input >> m_mapPp_1PpCp_1Cp;
		input >> m_mapPpPp1CpCp1;
		input >> m_mapPp_1PpCpCp1;
		input >> m_mapP_1PC;
		input >> m_mapPP1C;
		input >> m_mapPC_1C;
		input >> m_mapPCC1;

		input >> m_mapPath;
		input >> m_mapFPath;
		input >> m_mapPFPathCtag;
		input >> m_mapCFPathPtag;
		input >> m_mapLPath;
		input >> m_mapPsubcat;
		input >> m_mapCsubcat;
		input >> m_mapPsubcatCtag;
		input >> m_mapCsubcatPtag;
		input >> m_mapPC;
		input >> m_mapCLabel;

		input >> m_mapLW;
		input >> m_mapRW;
		input >> m_mapLW_1;
		input >> m_mapRW1;
		input >> m_mapLCpPp;
		input >> m_mapLCpPw;
		input >> m_mapLCwPp;
		input >> m_mapLCwPw;
		input >> m_mapLSpPp;
		input >> m_mapLSwPp;
		input >> m_mapRSpPp;
		input >> m_mapRSwPp;

		input.close();
	}

	void Weight::saveScores(TDepLabel &DepLabel) const {

		if (m_sRecordPath.empty()) {
			return;
		}
		std::ofstream output(m_sRecordPath);
		if (!output) {
			return;
		}

		output << TWord::getTokenizer();

		output << TPOSTag::getTokenizer();

		output << m_mapPw;
		output << m_mapPp;
		output << m_mapPwp;

		output << m_mapCw;
		output << m_mapCp;
		output << m_mapCwp;

		output << m_mapP_1w;
		output << m_mapP_1p;
		output << m_mapP_1wp;
		output << m_mapP1w;
		output << m_mapP1p;
		output << m_mapP1wp;
		output << m_mapC_1w;
		output << m_mapC_1p;
		output << m_mapC_1wp;
		output << m_mapC1w;
		output << m_mapC1p;
		output << m_mapC1wp;

		output << m_mapP_1C;
		output << m_mapP1C;
		output << m_mapPC_1;
		output << m_mapPC1;

		output << m_mapPwpCwp;
		output << m_mapPpCwp;
		output << m_mapPwpCp;
		output << m_mapPwCwp;
		output << m_mapPwpCw;
		output << m_mapPwCw;
		output << m_mapPpCp;

		output << m_mapPpBpCp;
		output << m_mapPpPp1Cp_1Cp;
		output << m_mapPp_1PpCp_1Cp;
		output << m_mapPpPp1CpCp1;
		output << m_mapPp_1PpCpCp1;
		output << m_mapP_1PC;
		output << m_mapPP1C;
		output << m_mapPC_1C;
		output << m_mapPCC1;

		output << m_mapPath;
		output << m_mapFPath;
		output << m_mapPFPathCtag;
		output << m_mapCFPathPtag;
		output << m_mapLPath;
		output << m_mapPsubcat;
		output << m_mapCsubcat;
		output << m_mapPsubcatCtag;
		output << m_mapCsubcatPtag;
		output << m_mapPC;
		output << m_mapCLabel;

		output << m_mapLW;
		output << m_mapRW;
		output << m_mapLW_1;
		output << m_mapRW1;
		output << m_mapLCpPp;
		output << m_mapLCpPw;
		output << m_mapLCwPp;
		output << m_mapLCwPw;
		output << m_mapLSpPp;
		output << m_mapLSwPp;
		output << m_mapRSpPp;
		output << m_mapRSwPp;
		output.close();
	}

	void Weight::computeAverageFeatureWeights(const int & round) {
		m_mapPw.computeAverage(round);
		m_mapPp.computeAverage(round);
		m_mapPwp.computeAverage(round);

		m_mapCw.computeAverage(round);
		m_mapCp.computeAverage(round);
		m_mapCwp.computeAverage(round);

		m_mapP_1w.computeAverage(round);
		m_mapP_1p.computeAverage(round);
		m_mapP_1wp.computeAverage(round);
		m_mapP1w.computeAverage(round);
		m_mapP1p.computeAverage(round);
		m_mapP1wp.computeAverage(round);
		m_mapC_1w.computeAverage(round);
		m_mapC_1p.computeAverage(round);
		m_mapC_1wp.computeAverage(round);
		m_mapC1w.computeAverage(round);
		m_mapC1p.computeAverage(round);
		m_mapC1wp.computeAverage(round);

		m_mapP_1C.computeAverage(round);
		m_mapP1C.computeAverage(round);
		m_mapPC_1.computeAverage(round);
		m_mapPC1.computeAverage(round);


		m_mapPwpCwp.computeAverage(round);
		m_mapPpCwp.computeAverage(round);
		m_mapPwpCp.computeAverage(round);
		m_mapPwCwp.computeAverage(round);
		m_mapPwpCw.computeAverage(round);
		m_mapPwCw.computeAverage(round);
		m_mapPpCp.computeAverage(round);
		m_mapPpBpCp.computeAverage(round);
		m_mapPpPp1Cp_1Cp.computeAverage(round);
		m_mapPp_1PpCp_1Cp.computeAverage(round);
		m_mapPpPp1CpCp1.computeAverage(round);
		m_mapPp_1PpCpCp1.computeAverage(round);
		m_mapP_1PC.computeAverage(round);
		m_mapPP1C.computeAverage(round);
		m_mapPC_1C.computeAverage(round);
		m_mapPCC1.computeAverage(round);

		m_mapPath.computeAverage(round);
		m_mapFPath.computeAverage(round);
		m_mapPFPathCtag.computeAverage(round);
		m_mapCFPathPtag.computeAverage(round);
		m_mapLPath.computeAverage(round);
		m_mapPsubcat.computeAverage(round);
		m_mapCsubcat.computeAverage(round);
		m_mapPsubcatCtag.computeAverage(round);
		m_mapCsubcatPtag.computeAverage(round);
		m_mapPC.computeAverage(round);
		m_mapCLabel.computeAverage(round);

		m_mapLW.computeAverage(round);
		m_mapRW.computeAverage(round);
		m_mapLW_1.computeAverage(round);
		m_mapRW1.computeAverage(round);

		m_mapLCpPp.computeAverage(round);
		m_mapLCpPw.computeAverage(round);
		m_mapLCwPp.computeAverage(round);
		m_mapLCwPw.computeAverage(round);
		m_mapLSpPp.computeAverage(round);
		m_mapLSwPp.computeAverage(round);
		m_mapRSpPp.computeAverage(round);
		m_mapRSwPp.computeAverage(round);
	}
}
