#include <fstream>
#include <string>
#include <iostream>
#include <ctime>
#include "triedy.h"
using namespace std;

int porovnaj(klient *k1, klient *k2, char kriterium)
{
	if (kriterium == '8') {
		if (k1->vrat_bonitu() < k2->vrat_bonitu())
			return -1;
		if (k1->vrat_bonitu() > k2->vrat_bonitu())
			return 1;
	}

	else if (kriterium == '6') {
		if (k1->vrat_pocet_uverov() < k2->vrat_pocet_uverov())
			return -1;
		if (k1->vrat_pocet_uverov() > k2->vrat_pocet_uverov())
			return 1;
	}

	else if (kriterium == '7') {
		if (k1->vrat_sumu_uverov() < k2->vrat_sumu_uverov())
			return -1;
		if (k1->vrat_sumu_uverov() > k2->vrat_sumu_uverov())
			return 1;
	}

	else if (kriterium == '5') {
		if (k1->vrat_plat() < k2->vrat_plat())
			return -1;
		if (k1->vrat_plat() > k2->vrat_plat())
			return 1;
	}

	else if (kriterium == '2') {
		int porovnanie = strcmp(k1->vrat_priezvisko(), k2->vrat_priezvisko());
		if (porovnanie != 0)
			return porovnanie;
	}

	else if (kriterium == '1') {
		int porovnanie = strcmp(k1->vrat_meno(), k2->vrat_meno());
		if (porovnanie != 0)
			return porovnanie;
	}

	else if (kriterium == '3') {
		int porovnanie = strcmp(k1->vrat_mesto(), k2->vrat_mesto());
		if (porovnanie != 0)
			return porovnanie;
	}

	else if (kriterium == '4') {
		int porovnanie = strcmp(k1->vrat_povolanie(), k2->vrat_povolanie());
		if (porovnanie != 0)
			return porovnanie;
	}

	else if (kriterium == '9') {
		if (k1->rc.vrat_vek() < k2->rc.vrat_vek())
			return -1;
		if (k1->rc.vrat_vek() > k2->rc.vrat_vek())
			return 1;
	}

	return 0;
}

void InsSort(klient **pole, int pocet, char kriterium)
{
	int i, j;
	for (i = 0; i<pocet; i++) {
		j = i;
		klient *pom = pole[j];
		while ((j>0) && (porovnaj(pole[j - 1], pom, kriterium)>0)) {
			pole[j] = pole[j - 1];
			j--;
		}
		pole[j] = pom;
	}
}

int zisti_pocet(klient **vsetci, int max, int min, int celkovo, char kriterium) {
	int i, kolko = 0;
	if (kriterium == '1') {
		for (i = 0; i < celkovo; i++) {
			if ((vsetci[i]->vrat_bonitu() >= min) && (vsetci[i]->vrat_bonitu() <= max))
				kolko++;
		}
	}
	else if (kriterium == '2') {
		for (i = 0; i < celkovo; i++) {
			if ((vsetci[i]->vrat_pocet_uverov() >= min) && (vsetci[i]->vrat_pocet_uverov() <= max))
				kolko++;
		}
	}
	else if (kriterium == '3') {
		for (i = 0; i < celkovo; i++) {
			if ((vsetci[i]->vrat_sumu_uverov() >= min) && (vsetci[i]->vrat_sumu_uverov() <= max))
				kolko++;
		}
	}
	else if (kriterium == '4') {
		for (i = 0; i < celkovo; i++) {
			if ((vsetci[i]->vrat_plat() >= min) && (vsetci[i]->vrat_plat() <= max))
				kolko++;
		}
	}
	else if (kriterium == '5') {
		for (i = 0; i < celkovo; i++) {
			if ((vsetci[i]->rc.vrat_vek_iba_rok() >= min) && (vsetci[i]->rc.vrat_vek_iba_rok() <= max))
				kolko++;
		}
	}
	return kolko;
}

void filtruj(klient **vsetci, int max, int min, int celkovo, int pocet_splnajucich, klient **pole_splnajucich, char kriterium) {
	int i, j = 0;
	if (kriterium == '1') {
		for (i = 0; i < celkovo; i++) {
			if ((vsetci[i]->vrat_bonitu() >= min) && (vsetci[i]->vrat_bonitu() <= max)) {
				pole_splnajucich[j] = vsetci[i];
				j++;
			}
			if (j == pocet_splnajucich)
				break;
		}
	}

	if (kriterium == '2') {
		for (i = 0; i < celkovo; i++) {
			if ((vsetci[i]->vrat_pocet_uverov() >= min) && (vsetci[i]->vrat_pocet_uverov() <= max)) {
				pole_splnajucich[j] = vsetci[i];
				j++;
			}
			if (j == pocet_splnajucich)
				break;
		}
	}

	if (kriterium == '3') {
		for (i = 0; i < celkovo; i++) {
			if ((vsetci[i]->vrat_sumu_uverov() >= min) && (vsetci[i]->vrat_sumu_uverov() <= max)) {
				pole_splnajucich[j] = vsetci[i];
				j++;
			}
			if (j == pocet_splnajucich)
				break;
		}
	}

	if (kriterium == '4') {
		for (i = 0; i < celkovo; i++) {
			if ((vsetci[i]->vrat_plat() >= min) && (vsetci[i]->vrat_plat() <= max)) {
				pole_splnajucich[j] = vsetci[i];
				j++;
			}
			if (j == pocet_splnajucich)
				break;
		}
	}

	if (kriterium == '5') {
		for (i = 0; i < celkovo; i++) {
			if ((vsetci[i]->rc.vrat_vek_iba_rok() >= min) && (vsetci[i]->rc.vrat_vek_iba_rok() <= max)) {
				pole_splnajucich[j] = vsetci[i];
				j++;
			}
			if (j == pocet_splnajucich)
				break;
		}
	}
}

void vypis_vsetko(klient **pole, int pocet) {
	int i;
	char disciplina[10];
	for (i = 0; i < pocet; i++) {
		if (pole[i]->vrat_splacal_nacas() == 1)
			strcpy(disciplina, "vyborna");
		else if (pole[i]->vrat_splacal_nacas() == 2)
			strcpy(disciplina, "priemerna");
		else
			strcpy(disciplina, "slaba");

		cout << "Klient c." << " " << i + 1 << "\n";
		cout << "Meno: " << pole[i]->vrat_meno() << "\n";
		cout << "Priezvisko: " << pole[i]->vrat_priezvisko() << "\n";
		cout << "Adresa: " << pole[i]->vrat_ulicu();
		cout << ", " << pole[i]->vrat_mesto() << "\n";
		cout << "Povolanie: " << pole[i]->vrat_povolanie() << "\n";
		cout << "Mesacna mzda: " << pole[i]->vrat_plat() << " eur\n";
		cout << "Pocet uverov: " << pole[i]->vrat_pocet_uverov() << "\n";
		cout << "Suma uverov: " << pole[i]->vrat_sumu_uverov() << " eur\n";
		cout << "Bonita: " << pole[i]->vrat_bonitu() << " bodov (max. 100)\n";
		cout << "Platobna disciplina: " << disciplina << "\n";
		cout << "______________________________\n";
	}
}

void vystup_do_suboru(klient **pole, int pocet) {
	int i;
	const char* pripona = "csv";
	time_t t = time(0);
	struct tm * teraz = localtime(&t);
	char nazov[80];

	strftime(nazov, 80, "%a %d. %b. %Y, %H.%M.", teraz);
	strcat(nazov, pripona);
	std::ofstream out;
	out.open(nazov);

	if (!out) {
		cout << "Vystupny subor sa nepodarilo vytvorit. Vystup do suboru nebol vykonany.";
		return;
	}
	out << "rodne cislo,meno,priezvisko,ulica a cislo,mesto,povolanie,mesacna mzda,pocet uverov,suma uverov,bonita,platobna disciplina\n";
	for (i = 0; i < pocet; i++) {
		out << pole[i]->rc.vrat_rc() << "," << pole[i]->vrat_meno() << "," << pole[i]->vrat_priezvisko() << "," << pole[i]->vrat_ulicu() << "," << pole[i]->vrat_mesto() << "," << pole[i]->vrat_povolanie() << "," << pole[i]->vrat_plat() << "," << pole[i]->vrat_pocet_uverov() << "," << pole[i]->vrat_sumu_uverov() << "," << pole[i]->vrat_bonitu() << "," << pole[i]->vrat_splacal_nacas() << "\n";
	}
}

void min_max_hodnota(klient **pole, int pocet, char volba) {
	int i, min, max;
	char kriterium[15];

	if (volba == '1') {
		strcpy(kriterium, "bonita");
		min = max = pole[0]->vrat_bonitu();
		for (i = 0; i < pocet; i++) {
			if (pole[i]->vrat_bonitu() > max)
				max = pole[i]->vrat_bonitu();
			else if (pole[i]->vrat_bonitu() < min)
				min = pole[i]->vrat_bonitu();
		}
	}

	else if (volba == '2') {
		strcpy(kriterium, "pocet uverov");
		min = max = pole[0]->vrat_pocet_uverov();
		for (i = 0; i < pocet; i++) {
			if (pole[i]->vrat_pocet_uverov() > max)
				max = pole[i]->vrat_pocet_uverov();
			else if (pole[i]->vrat_pocet_uverov() < min)
				min = pole[i]->vrat_pocet_uverov();
		}
	}

	else if (volba == '3') {
		strcpy(kriterium, "suma uverov");
		min = max = pole[0]->vrat_sumu_uverov();
		for (i = 0; i < pocet; i++) {
			if (pole[i]->vrat_sumu_uverov() > max)
				max = pole[i]->vrat_sumu_uverov();
			else if (pole[i]->vrat_sumu_uverov() < min)
				min = pole[i]->vrat_sumu_uverov();
		}
	}

	else if (volba == '4') {
		strcpy(kriterium, "mesacna mzda");
		min = max = pole[0]->vrat_plat();
		for (i = 0; i < pocet; i++) {
			if (pole[i]->vrat_plat() > max)
				max = pole[i]->vrat_plat();
			else if (pole[i]->vrat_plat() < min)
				min = pole[i]->vrat_plat();
		}
	}

	else if (volba == '5') {
		strcpy(kriterium, "vek");
		min = max = pole[0]->rc.vrat_vek_iba_rok();
		for (i = 0; i < pocet; i++) {
			if (pole[i]->rc.vrat_vek_iba_rok() > max)
				max = pole[i]->rc.vrat_vek_iba_rok();
			else if (pole[i]->rc.vrat_vek_iba_rok() < min)
				min = pole[i]->rc.vrat_vek_iba_rok();
		}
	}

	cout << "\nPre kriterium \"" << kriterium << "\" sa v subore nachadzaju hodnoty v intervale od " << min << " do " << max << ".\n";
}


int main()
{
	int pocet = 0;
	int min, max, pocet_najdenych;
	char volba;
	ifstream in;
	in.open("klienti.csv");
	if (!in)
	{
		cout << "Subor sa nepodarilo otvorit";
		return 0;
	}
	while (!in.eof())
	{
		if (in.get() == '\n')
			pocet++;
	}

	klient **klienti = new klient*[pocet];
	in.clear();
	in.seekg(0);

	char meno[20], priezvisko[20], mesto[20], ulica[30], povolanie[20], rc[12];
	char plat_c[5], pocet_uverov_c[3], suma_uverov_c[7], bonita_c[4], splacal_nacas_c[2];
	int plat, pocet_uverov, suma_uverov, bonita, splacal_nacas;

	char pom[150];
	int i = 0, j = 0, k = 0;
	in.getline(pom, 150);

	for (i = 0; i < pocet; i++) {
		in.getline(pom, 100);
		while (pom[k] != ',') {
			rc[j] = pom[j];
			j++;
			k++;
		}
		rc[j] = '\0';

		k++;
		j = 0;
		while (pom[k] != ',') {
			meno[j] = pom[k];
			j++;
			k++;
		}
		meno[j] = '\0';

		k++;
		j = 0;
		while (pom[k] != ',') {
			priezvisko[j] = pom[k];
			j++;
			k++;
		}
		priezvisko[j] = '\0';

		k++;
		j = 0;
		while (pom[k] != ',') {
			ulica[j] = pom[k];
			j++;
			k++;
		}
		ulica[j] = '\0';

		k++;
		j = 0;
		while (pom[k] != ',') {
			mesto[j] = pom[k];
			j++;
			k++;
		}
		mesto[j] = '\0';

		k++;
		j = 0;
		while (pom[k] != ',') {
			povolanie[j] = pom[k];
			j++;
			k++;
		}
		povolanie[j] = '\0';

		k++;
		j = 0;
		while (pom[k] != ',') {
			plat_c[j] = pom[k];
			j++;
			k++;
		}
		plat_c[j] = '\0';
		plat = atoi(plat_c);

		k++;
		j = 0;
		while (pom[k] != ',') {
			pocet_uverov_c[j] = pom[k];
			j++;
			k++;
		}
		pocet_uverov_c[j] = '\0';
		pocet_uverov = atoi(pocet_uverov_c);

		k++;
		j = 0;
		while (pom[k] != ',') {
			suma_uverov_c[j] = pom[k];
			j++;
			k++;
		}
		suma_uverov_c[j] = '\0';
		suma_uverov = atoi(suma_uverov_c);

		k++;
		j = 0;
		while (pom[k] != ',') {
			bonita_c[j] = pom[k];
			j++;
			k++;
		}
		bonita_c[j] = '\0';
		bonita = atoi(bonita_c);

		k++;
		j = 0;
		while (pom[k] != '\0') {
			splacal_nacas_c[j] = pom[k];
			j++;
			k++;
		}
		splacal_nacas_c[j] = '\0';
		splacal_nacas = atoi(splacal_nacas_c);

		j = 0;
		k = 0;

		klienti[i] = new klient();  //alokovanie miesta na objekt na mieste kam ukazuje ukazovatel z pola ukazovatelov

		klienti[i]->nastav_meno(meno);
		klienti[i]->nastav_priezvisko(priezvisko);
		klienti[i]->nastav_ulicu(ulica);
		klienti[i]->nastav_mesto(mesto);
		klienti[i]->nastav_povolanie(povolanie);
		klienti[i]->nastav_plat(plat);
		klienti[i]->nastav_pocet_uverov(pocet_uverov);
		klienti[i]->nastav_sumu_uverov(suma_uverov);
		klienti[i]->nastav_bonitu(bonita);
		klienti[i]->nastav_splacal_nacas(splacal_nacas);
		klienti[i]->rc.nastav_rc(rc);
	}
	while (1) {
		cout << "\nBolo nacitanych " << pocet << " zaznamov o klientoch banky.\n\nZelate si tieto zaznamy filtrovat?\nVyberte si jednu z moznosti a zadajte prislusny znak.\n";
		cout << "A - ano\nN - nie\nU - ukoncit program\n";
		cin >> volba;
		while ((volba != 'A') && (volba != 'N') && (volba != 'a') && (volba != 'n') && (volba != 'u') && (volba != 'U')) {
			cout << "\nNeplatny vstup! Prosim zadajte A, N alebo U.\n";
			cin >> volba;
		}
		if (volba == 'a' || volba == 'A') {
			cout << "\nPodla akeho kriteria chcete zaznamy filtrovat?\nPre vyber zadajte cislo zelanej moznosti.\n1. bonita\n2. pocet uverov\n3. suma uverov\n4. mesacna mzda\n5. vek klienta\n ";
			cin >> volba;
			while ((volba != '1') && (volba != '2') && (volba != '3') && (volba != '4') && (volba != '5')) {
				cout << "\nNeplatny vstup! Prosim zadajte cislo v intervale 1 az 5.\n";
				cin >> volba;
			}
			min_max_hodnota(klienti, pocet, volba);
			cout << "Zadajte minimalnu a maximalnu hodnotu ako dve cele cisla oddelene medzerou (napr. 10 20): ";
			cin >> min >> max;
			pocet_najdenych = zisti_pocet(klienti, max, min, pocet, volba);
			klient **najdeni = new klient*[pocet_najdenych];
			for (i = 0; i < pocet_najdenych; i++) {
				najdeni[i] = new klient();
			}
			cout << "\nZadanemu kriteriu vyhovuje " << pocet_najdenych << " zaznamov.\n";
			if (pocet_najdenych == 0) {
				cout << "\nProgram nema zaznamy na usporiadanie, preto sa vracia na zaciatok.\n\n";
				continue;
			}
			filtruj(klienti, max, min, pocet, pocet_najdenych, najdeni, volba);
			cout << "\nZadajte kriterium pre usporiadanie zaznamov:\nPre vyber zadajte cislo zelanej moznosti.\n1. meno\n2. priezvisko\n3. mesto\n4. povolanie\n5. mesacny plat\n6. pocet uverov\n7. suma uverov\n8. bonita\n9. vek klienta\n";
			cin >> volba;
			while ((volba != '1') && (volba != '2') && (volba != '3') && (volba != '4') && (volba != '5') && (volba != '6') && (volba != '7') && (volba != '8') && (volba != '9')) {
				cout << "Neplatny vstup! Prosim zadajte cislo v intervale 1 az 9.\n";
				cin >> volba;
			}
			InsSort(najdeni, pocet_najdenych, volba);
			vypis_vsetko(najdeni, pocet_najdenych);
			vystup_do_suboru(najdeni, pocet_najdenych);
		}
		else if (volba == 'n' || volba == 'N') {
			cout << "\nZadajte kriterium pre usporiadanie zaznamov:\n1. meno\n2. priezvisko\n3. mesto\n4. povolanie\n5. mesacny plat\n6. pocet uverov\n7. suma uverov\n8. bonita\n9. vek klienta\n";
			cin >> volba;
			while ((volba != '1') && (volba != '2') && (volba != '3') && (volba != '4') && (volba != '5') && (volba != '6') && (volba != '7') && (volba != '8') && (volba != '9')) {
				cout << "Neplatny vstup! Prosim zadajte cislo v intervale 1 az 9.\n";
				cin >> volba;
			}
			InsSort(klienti, pocet, volba);
			vystup_do_suboru(klienti, pocet);
			vypis_vsetko(klienti, pocet);
		}

		else if (volba == 'u' || volba == 'U')
			return 0;
	}
	return 0;
}
