/**
 * Diese Module sollte NUR von stimmzettelController angerufen werden
 */
var StimmzettelValidator = {};

// Globale Variabeln an der Stimmzettel die von die Abfrage und die Berechnung kommen
var StimmzettelNow = {};
var KopfstimmenAnalyseNow = null
var KandidatenNow = []
var IsRepraesentativeStatistikNow = false;
var AllePositionenNow = []
var ParteinNow = []
var StzErfasstNow = {};
var WahlrechtNow = {};
var AnzahlPositionenNow = null;
var InitNow = true;
var SchenellerfassungInputNow = null;
var LastSchnellerfassungErfasstNow = null
var SchnellerfassungsErrorNow = null;

//Globale Berechnung-Funktion die verteilt wird
var StimmenRechnerNow = {};

StimmzettelValidator.initValidator = function () {
	if (DEVELOP) console.log('validator called!');
	KandidatenNow = [];
	if (STIMMZETTEL_CONFIG.repraesentativeStatistik != undefined || STIMMZETTEL_CONFIG.repraesentativeStatistik != null) {
		IsRepraesentativeStatistikNow = STIMMZETTEL_CONFIG.repraesentativeStatistik;
	}

	STIMMZETTEL_CONFIG.kandidaten.forEach(function (k) {
		kandidat = new de.vote_it.stimmzettelerfassung.pojo.Kandidat();
		StimmzettelValidator.copy(k, kandidat);
		KandidatenNow.push(kandidat);
	});

	StzErfasstNow = StimmzettelValidator.convertToStzErfasst(JSONStimmzettel, KandidatenNow);

	WahlrechtNow = null;
	switch (STIMMZETTEL_CONFIG.wahlrecht) {
		case "Wahlrecht_BW":
			wahlrecht = new de.vote_it.stimmzettelerfassung.calculation.Wahlrecht_BW();
			break;
		case "Wahlrecht_BY":
			wahlrecht = new de.vote_it.stimmzettelerfassung.calculation.Wahlrecht_BY();
			break;
		case "Wahlrecht_HB":
			wahlrecht = new de.vote_it.stimmzettelerfassung.calculation.Wahlrecht_HB();
			break;
		case "Wahlrecht_HE":
			wahlrecht = new de.vote_it.stimmzettelerfassung.calculation.Wahlrecht_HE();
			break;
		case "Wahlrecht_NI":
			wahlrecht = new de.vote_it.stimmzettelerfassung.calculation.Wahlrecht_NI();
			break;
		case "Wahlrecht_RP":
			wahlrecht = new de.vote_it.stimmzettelerfassung.calculation.Wahlrecht_RP();
			break;
	}
	WahlrechtNow = wahlrecht;

	AnzahlPositionenNow = STIMMZETTEL_CONFIG.anzahlPositionen;

	dataStimmzettel = STIMMZETTEL_CONFIG.stimmzettel;
	stimmzettel = new de.vote_it.stimmzettelerfassung.pojo.Stimmzettel();
	stimmzettel.anzahlstimmen = dataStimmzettel.anzahlstimmen;
	stimmzettel.behoerde = dataStimmzettel.behoerde;
	stimmzettel.id = dataStimmzettel.id;
	stimmzettel.wahl = dataStimmzettel.wahl;
	STIMMZETTEL_CONFIG.parteien.forEach(function (p) {
		partei = new de.vote_it.stimmzettelerfassung.pojo.Partei();
		$.extend(true, partei, p);
		ParteinNow.push(partei);
	});

	STIMMZETTEL_CONFIG.allePositionen.forEach(function (pos) {
		position = new de.vote_it.stimmzettelerfassung.pojo.Stimmzettelpo();
		$.extend(true, position, pos);
		partei = new de.vote_it.stimmzettelerfassung.pojo.Partei();
		$.extend(true, partei, pos.partei);
		position.partei = partei;
		AllePositionenNow.push(position);
	});

	StzErfasstNow.stimmzettel = stimmzettel;
	StimmzettelNow = stimmzettel;

	StimmenRechnerNow = new de.vote_it.stimmzettelerfassung.calculation.StimmenRechner();
	StimmenRechnerNow = StimmenRechnerNow.constructor;
	InitNow = false;
}

StimmzettelValidator.execute = function () {
	if (InitNow == true) { StimmzettelValidator.initValidator() }

	StimmzettelValidator.elaborateStzJSon();
}

/*
* Die Berechnungen werden auf StimmzettelJSON umgewandelt
*/
StimmzettelValidator.elaborateStzJSon = function () {
	if (DEVELOP) console.log('--------------------->JSON stimmzettel before the view<---------------------------------------------------');
	if (DEVELOP) console.log(JSONStimmzettel);	

	if (DEVELOP) console.log('--------------------->StimmzettelErfasst before the elaboration<-------------------------------------------');
	StzErfasstNow = StimmzettelValidator.convertToStzErfasst(JSONStimmzettel, KandidatenNow);
	if (DEVELOP) console.log(StzErfasstNow);

	/**
	 * Die stimmen werden HIER verarbeitet
	 */
	KopfstimmenAnalyseNow = StimmenRechnerNow.berechne(WahlrechtNow, StimmzettelNow, AnzahlPositionenNow, StzErfasstNow, KandidatenNow);

	/**
	 * Die Ergebnisse werden in den JSON stimmzettel hinzügefugt (VIEW)
	 */
	if (DEVELOP) console.log('--------------------------------> JSON stimmzettel in view <-------------------------------------------------');
	StimmzettelValidator.generateStimmzettelJson();	
}

/**
 * Diese Funktion generiert der View als Json-Objekt.
 */
StimmzettelValidator.generateStimmzettelJson = function () {
	if (DEVELOP) console.log('--------------------------------------------> generate Stimmzettel JSON <-------------------------------------')
	if (DEVELOP) console.log('stimmzettelErfasst');
	if (DEVELOP) console.log(StzErfasstNow);
	if (StzErfasstNow.kandidatenstimmes.length == 0 && StzErfasstNow.kopfstimmes == 0 && (StzErfasstNow.ungueltigestimmen == null || isNaN(StzErfasstNow.ungueltigestimmen))) {
		if (DEVELOP) console.log('Reinit Stimmzettel...');
		stz = JSON.parse(JSON.stringify(JSONStimmzettelInit));	// reinit Stimmzettel
		JSONStimmzettel = stz;
		stz.hinweisText.enabled = false;
		return stz;
	} else {
		isValid = true
		if (StzErfasstNow.grundungueltigberchnet != null) { isValid = false }

		//Pfelge der Grüne Stimmen
		posToExclude = [];
		StzErfasstNow.kandidatenstimmes.forEach(function (k) {
			posToExclude.push("" + k.kandidat.getId());
		});
		JSONStimmzettel.kandidatSpalten.forEach(function (s) {
			if (posToExclude.find(o => o == s.kandidat)) {
			} else {
				s.selected = false;
			}
		});

		stimmenPerPos = [];

		for (key in StzErfasstNow) {
			if (key == "kopfstimmes") {
				//Set Kopfstimmen
				_arr = StzErfasstNow[key];
				_arr.forEach(function (item) {
					pos = item.stimmzettelpo.getId();
					el = JSONStimmzettel.kopfStimmen.filter(ks => parseInt(ks.stimmzettelpos) == pos);
					el.forEach(function (e) {
						e.clicked = true;
					});
				});
			}
			if (key == "kandidatenstimmes") {
				_arr = StzErfasstNow[key]; // für jede kandidatstimme
				_arr.forEach(function (item) {
					pos = item.stimmzettelpo.getId();
					kandidatId = item.kandidat.getId();
					stimmen = 0;

					//Set Streichen
					el = JSONStimmzettel.kandidatNamen.filter(ks => parseInt(ks.stimmzettelpos) == pos && parseInt(ks.kandidat) == kandidatId);
					el.forEach(function (e) {
						if (item.getGestrichen1() == "J") {
							if (e.nennung = "1") e.clicked = true;
						}
						if (item.getGestrichen2() == "J") {
							if (e.nennung = "2") e.clicked = true;
						}
						if (item.getGestrichen3() == "J") {
							if (e.nennung = "3") e.clicked = true;
						}
					});

					el = JSONStimmzettel.kandidatSpalten.filter(ks => parseInt(ks.stimmzettelpos) == pos && parseInt(ks.kandidat) == kandidatId);

					//Set X und Werte der Stimmen
					el.forEach(function (e) {
						if (e.spalte == "1" && (item.getSpalte1() == "X" || item.getSpalte1() == "x")) {
							e.clicked = true;
							e.value = "X";
						} else if (e.spalte == 5 && !isNaN(item.getSpalte1())) { e.clicked = true; e.value = item.getSpalte1() }

						if (e.spalte == "2" && (item.getSpalte2() == "X" || item.getSpalte2() == "x")) {
							e.clicked = true;
							e.value = "X";
						} else if (e.spalte == 5 && !isNaN(item.getSpalte2())) { e.clicked = true; e.value = item.getSpalte2() }

						if (e.spalte == "3" && (item.getSpalte3() == "X" || item.getSpalte3() == "x")) {
							e.clicked = true;
							e.value = "X";
						} else if (e.spalte == 5 && !isNaN(item.getSpalte3())) { e.clicked = true; e.value = item.getSpalte3() }

						if (e.spalte == "4" && (item.getSpalte4() == "X" || item.getSpalte4() == "x")) {
							e.clicked = true;
							e.value = "X";
						} else if (e.spalte == 5 && !isNaN(item.getSpalte4())) { e.clicked = true; e.value = item.getSpalte4() }

						if (e.spalte == "5" && (item.getSpalte5() == "X" || item.getSpalte5() == "x")) {
							e.clicked = true;
							e.value = "X";
						} else if (e.spalte == 5 && !isNaN(item.getSpalte5())) { e.clicked = true; e.value = item.getSpalte5() }

					});

					//Set Grüne
					green = StimmenRechnerNow.ermittleGueltigeStimmen(WahlrechtNow, item);
					i = 0;
					green.forEach(function (isGreen) {	 // make green or not					
						el = JSONStimmzettel.kandidatSpalten.filter(ks => parseInt(ks.stimmzettelpos) == pos && parseInt(ks.kandidat) == kandidatId);
						if (el[i] != undefined) {
							el[i].selected = isGreen;
						}
						i++;
					});

					//Berchne di Tot Stimmen x Partei/POS		
					el = stimmenPerPos.find(obj => obj.pos == pos)
					if (el === undefined) {
						let el = {};
						el.pos = pos;
						anzahlgueltig = item.anzahlgueltig || 0;
						anzahlungueltig = item.anzahlungueltig || 0;
						el.stimmen = anzahlgueltig + anzahlungueltig;
						stimmenPerPos.push(el);
						whl = JSONStimmzettel.wahlvorschlagMessages.find(wahlv => parseInt(wahlv.wahlvorschlag) === parseInt(pos));
						whl.stimmen = el.stimmen;
					} else {
						el.stimmen = el.stimmen + item.anzahlgueltig + item.anzahlungueltig;
						whl = JSONStimmzettel.wahlvorschlagMessages.find(wahlv => parseInt(wahlv.wahlvorschlag) === parseInt(pos));
						whl.stimmen = el.stimmen;
					}

				})
			}
		}

		//HINWEIS		
		JSONStimmzettel.hinweisText.text = StimmenRechnerNow.hinweisGueltig(StzErfasstNow);

		JSONStimmzettel.hinweisText.enabled = true;

		JSONStimmzettel.hinweisText.text1 = StimmenRechnerNow.hinweisVergebeneStimmen(wahlrecht, StimmzettelNow.getAnzahlstimmen(), StzErfasstNow);

		if (KopfstimmenAnalyseNow != undefined || KopfstimmenAnalyseNow != null) {
			JSONStimmzettel.hinweisText.text2 = de.vote_it.stimmzettelerfassung.calculation.StimmenRechner.KopfstimmenAnalyse["_$wrappers"][KopfstimmenAnalyseNow].hinweis;
		}

		JSONStimmzettel.hinweisText.text3 = StimmenRechnerNow.ermittleStimmabgabe(wahlrecht, ParteinNow, AllePositionenNow, KandidatenNow, StzErfasstNow);
		if (StzErfasstNow.getGrundungueltig() == null) {
			JSONStimmzettel.hinweisText.success = true;
		} else {
			JSONStimmzettel.hinweisText.text = StimmenRechnerNow.hinweisGueltig(StzErfasstNow)
			JSONStimmzettel.hinweisText.success = false;
		}

	}

	StzErfasstNow.stimmenBerechnet = false;
}
/**
 * Das Stimmzettel als JSON --> zu StimmzettelErfasst wird umwandelt
 * Pojo-Abhängig (Kann auch durch das Stimmzettelconfig gemacht werden): Idee die Menge der Daten von den Server begrenzen.
 */
StimmzettelValidator.convertToStzErfasst = function (stz, kandidaten) {
	stzErfasst = new de.vote_it.stimmzettelerfassung.pojo.Stimmzettelerfasst();
	stzErfasst.setBemerkung(stz.bemerkung);
	stzErfasst.setUngueltigestimmen(stz.ungueltigeStimmen);	
	kopfStimmen = [];
	kandidatStimmen = [];

	stz.kopfStimmen.forEach(function (s) {
		if (s.clicked == true) {
			ks = new de.vote_it.stimmzettelerfassung.pojo.Kopfstimme();
			stimmzettelpos = new de.vote_it.stimmzettelerfassung.pojo.Stimmzettelpo();
			stimmzettelpos.setId(s.stimmzettelpos);
			ks.setStimmzettelpo(stimmzettelpos);
			if (s.clicked == true) ks.setSpalte1("J");
			if (s.clicked1 == true) ks.setSpalte2("J");
			if (s.clicked2 == true) ks.setSpalte3("J");
			if (s.clicked3 == true) ks.setSpalte4("J");
			if (s.clicked4 == true) ks.setSpalte5("J");
			kopfStimmen.push(ks);
		}
	});

	storeKandidatIds = []
	stz.kandidatSpalten.forEach(function (s) {
		if (s.clicked == true) {
			idKandidat = parseInt(s.kandidat);
			exist = true;
			exist = storeKandidatIds.find(element => element == idKandidat);
			kandidatstimme = null;
			if (exist == undefined || exist == null) {
				kandidatstimme = new de.vote_it.stimmzettelerfassung.pojo.Kandidatenstimme();
				stimmzettelPo = new de.vote_it.stimmzettelerfassung.pojo.Stimmzettelpo();
				stimmzettelPo.setId(s.stimmzettelpos);
				kandidatstimme.setStimmzettelpo(stimmzettelPo);
				kandidat = kandidaten.find(element => element.id == idKandidat);
				kandidatstimme.setKandidat(kandidat);
				storeKandidatIds.push(idKandidat);
				StimmzettelValidator.addSpalten(s, kandidatstimme);
				kandidatStimmen.push(kandidatstimme);
			} else {
				kandidatstimme = kandidatStimmen.find(element => element.kandidat.id == idKandidat);
				StimmzettelValidator.addSpalten(s, kandidatstimme);
			}
		}
	});

	stz.kandidatNamen.forEach(function (s) {
		if (s.clicked == true) {
			idKandidat = parseInt(s.kandidat);
			exist = true;
			exist = storeKandidatIds.find(element => element == idKandidat);
			kandidatstimme = null;
			if (exist == undefined || exist == null) {
				kandidatstimme = new de.vote_it.stimmzettelerfassung.pojo.Kandidatenstimme();
				stimmzettelPo = new de.vote_it.stimmzettelerfassung.pojo.Stimmzettelpo();
				stimmzettelPo.setId(s.stimmzettelpos);
				kandidatstimme.setStimmzettelpo(stimmzettelPo);
				kandidat = kandidaten.find(element => element.id == idKandidat);
				kandidatstimme.setKandidat(kandidat);
				storeKandidatIds.push(idKandidat);
				StimmzettelValidator.addGestreichen(s, kandidatstimme);
				kandidatStimmen.push(kandidatstimme);
			} else {
				kandidatstimme = kandidatStimmen.find(element => element.kandidat.id == idKandidat);
				StimmzettelValidator.addGestreichen(s, kandidatstimme);
			}
		}
	});

	stzErfasst.kopfstimmes = kopfStimmen;
	stzErfasst.kandidatenstimmes = kandidatStimmen;

	var myDate = new Date(Date.now());
	stzErfasst.zeitstemplerfassung = myDate.getFullYear() + '-' + ('0' + (myDate.getMonth() + 1)).slice(-2) + '-' + ('0' + myDate.getDate()).slice(-2) + ' ' + myDate.getHours() + ':' + ('0' + (myDate.getMinutes())).slice(-2) + ':' + myDate.getSeconds() + '.' + myDate.getMilliseconds();
	return stzErfasst;
}

StimmzettelValidator.addSpalten = function (s, kandidatstimme) {
	if (s.spalte == "1") kandidatstimme.setSpalte1(s.value);
	else if (s.spalte == "2") kandidatstimme.setSpalte2(s.value);
	else if (s.spalte == "3") kandidatstimme.setSpalte3(s.value);
	else if (s.spalte == "4") kandidatstimme.setSpalte4(s.value);
	else if (s.spalte == "5") kandidatstimme.setSpalte5(s.value);
}

StimmzettelValidator.addGestreichen = function (s, kandidatstimme) {
	if (s.nennung == "1") kandidatstimme.setGestrichen1("J");
	else if (s.nennung == "2") kandidatstimme.setGestrichen2("J");
	else if (s.nennung == "3") kandidatstimme.setGestrichen3("J");
}

/**
 * Pojo-Abhängig
 * Utility Klasse zu kopieren zu erfüllen die Pojo-Objekte
 */
StimmzettelValidator.copy = function (mainObj, objCopy) {
	let key;
	for (key in mainObj) {
		if (key == "stimmzettelpo") {
			stimmzettelPo = new de.vote_it.stimmzettelerfassung.pojo.Stimmzettelpo();
			stimmzettelPo = Object.assign(stimmzettelPo, mainObj[key]);
			objCopy[key] = stimmzettelPo;
		} else {
			objCopy[key] = mainObj[key];
		}
	}
	return objCopy;
}

StimmzettelValidator.ungueltigeStimmen = function (ung) {
	if (DEVELOP) console.log('ungueltige stimmen called!');
	JSONStimmzettel.ungueltigeStimmen = ung;
	StimmzettelValidator.execute(JSONStimmzettel);
	
	KopfstimmenAnalyseNow = StimmenRechnerNow.berechne(WahlrechtNow, StimmzettelNow, AnzahlPositionenNow, StzErfasstNow, KandidatenNow);

	StimmzettelValidator.generateStimmzettelJson(StzErfasstNow, StimmenRechnerNow, WahlrechtNow);

	StimmzettelController.renderStimmzettel(JSONStimmzettel);
}

StimmzettelValidator.schnellerfassung = function (nomessage) {
	StimmzettelValidator.initValidator();
	if (typeof nomessage === 'undefined') {
		nomessage = false;
	}
	schnellerfassungsTools = new de.vote_it.stimmzettelerfassung.calculation.SchnellerfassungsTools();

	schnellerfassteKandidatenstimme = [];
	schnellerfassteKopfstimmen = [];
	el = document.getElementById("schnellerfassung-input");
	var schnellerfassung = el.value;

	SchnellerfassungsErrorNow = schnellerfassungsTools.constructor.parse(WahlrechtNow, AllePositionenNow, KandidatenNow, IsRepraesentativeStatistikNow, StzErfasstNow
		, schnellerfassteKandidatenstimme, schnellerfassteKopfstimmen, schnellerfassung);

	if (SchnellerfassungsErrorNow !== "") {
		SchenellerfassungInputNow = null
		if (schnellerfassung.length !== 0) {//Schift-Enter Fall empty string
			if (nomessage === false) {
				$('#schnellerfassung-input-error-main').remove();
				$('#schnellerfassung-error').addClass("alert alert-danger alert-schnellerfassung").text(SchnellerfassungsErrorNow);
				$('#schnellerfassung-input').removeClass("form-control is-invalid");
				$('#schnellerfassung-input').addClass("form-control is-invalid");
			}
		}
	}
	else {
		$('#schnellerfassung-input').removeClass("form-control is-invalid");
		$('#schnellerfassung-input').addClass("form-control is-valid");
		SchenellerfassungInputNow = true
	}

	KopfstimmenAnalyseNow = StimmenRechnerNow.berechne(WahlrechtNow, StimmzettelNow, AnzahlPositionenNow, StzErfasstNow, KandidatenNow);

	StimmzettelValidator.generateStimmzettelJson(StzErfasstNow, StimmenRechnerNow, WahlrechtNow);

	StimmzettelController.renderStimmzettel(JSONStimmzettel);

	if (SchnellerfassungsErrorNow == "") {
		$("#schnellerfassung-input").val("")
	}
}

