/**
* Funksjonene i klassen 'kunder' og deres definisjoner. 
* @file kunder.cpp
* @author Abdulsamad Sheikh, Jamal Hussein & Ole Bjørn Halvorsen.
*/
#include "kunder.h"
#include "kunde.h"
#include <iostream>             //  cout, cin
#include <fstream>              //  ifstream, ofstream
#include <string>               //  String
#include <list>                 //  List
#include <algorithm>
#include "LesData3.h"           //  Verktøykasse for innlesing
#include "enum.h"
#include "kategori.h"
#include "kategorier.h"

using namespace std;

extern Kunder     gKundebase;
extern Kategorier gKategoribase;

/**
*En constructor som oppretter Kunder-objekt
*/
Kunder::Kunder(){}

Kunder::~Kunder() {}

bool Kunder::finnKunde(int nr, const kjopOgSalg kOgS) {
    for (const auto &val : gKunder) {
        if (val->getKundeNr() == nr) {
            val->plussKjopOgSalg(kOgS);
            return true;
        }
    }
    return false;
}

/**
*Funksjonen fjerner en kunde, hvis kundenummeret deres eksisterer
*@param nr -  kundenummeret som skal fjernes
*/
void Kunder::fjernKunde(int nr) {
    if (nr <= 0) {
        cout << "Ingen kunder har blitt slettet";
        return;
    }

    auto temp = find_if(gKunder.begin(), gKunder.end(),
                        [nr](const auto &val) { return (val->getKundeNr() == nr); });

    if (temp == gKunder.end()) {
        return;
    }

    cout << "Er du sikker på at du vil slette kunden?";
    skrivUtEnKunde(nr);
    char tegn = lesChar("\nJ/N ?");
    //Forsikrer oss om vi vil slette kunden eller ikke
    if (tegn == 'J') {
        gKategoribase.slettTing(nr);
        gKunder.erase(temp);
    //Sletter kunden hvis 'Ja'
    } else {
        cout << "Kunde ble ikke slettet";
    }

    skrivUtKunder();
}



/**
*En switch-løkke som lar oss velge mellom de forskjellige kommandoene
*/
void Kunder::handling() {
    char valg = lesChar("Kundekommando: 'N'(y) 'A'(lle) 'S'(krivEn) eller 'F'(jern)");
    int nr;

    switch (valg) {
        case 'N':
            nyKunde();
            break;

        case 'A':
            skrivUtKunder();
            break;

        case 'S':
            nr = lesInt("Kundenummer", 0, sisteNr);
            skrivUtEnKunde(nr);
            break;

        case 'F':
            nr = lesInt("Kundenummer", 0, sisteNr);
            fjernKunde(nr);
            break;
    }
}

int Kunder::getSisteNr(){
  return sisteNr;
}

/**
* Leser fra  'KUNDER.DTA'.
*/
void Kunder::lesFraFil() {
    ifstream innfil("KUNDER.DTA");
    cout << "Leser fra filen 'KUNDER.DTA'";

    if (!innfil) {
        cout << "Kunne ikke finne filen";
        return;
    }

    int antKunder = 0, kundenr = 0;
    innfil >> antKunder >> kundenr;

    for (int i = 0; i < antKunder; ++i) {
        Kunde* kundeNy = new Kunde(innfil, kundenr);
        gKunder.push_back(kundeNy);
        sisteNr++;
        innfil >> kundenr;
    }

    innfil.close();
}

/**
* En funksjon som oppretter en ny kunde og tildeler den et nummer. Nummeret er er et tall hæyere enn siste nummer.
* Kundens data leses og sorteres inn i datastrukturen.
*
* @see Kunde::Kunde(int nr)
* @see Kunde::lesData()
*/
void Kunder::nyKunde(){
  Kunde* kundeNy = new Kunde(sisteNr);
  kundeNy->lesData();
  gKunder.push_back(kundeNy);
  sisteNr++;
}


/**
*En funksjon som skriver ut alle kunder sammen med deres detaljer
*@see Kunde::skrivData
*/
void Kunder::skrivUtKunder() const {
    int i = 0;
    cout << "\nSiste kundenummer: " << sisteNr
         << "\nTotalt antall kunder: " << gKunder.size();

    for (const auto &val : gKunder) {
        val->skrivData();
        i++;

        if (i % 20 == 0) {
            cout << "\tSkriv hva som helst for neste...";
            getchar();
        }
    }
    
}


/**
*En funksjon som skriver ut en kundes data/detaljer
*@param nr - kundenummeret som skal skrives ut
*@see Kunde::getKundeNr()
*@see Kunde::skrivDetaljer()
*/
void Kunder::skrivUtEnKunde(int nr) const {
    if (gKunder.size() > 0) {
        for (const auto &val : gKunder) {
            int temp = val->Kunde::getKundeNr();
            if (nr == temp) {
                val->Kunde::skrivDetaljer();
            }
        }
    } else {
        cout << "Ingen registrerte kunder";
    }
}

/**
*En funksjon som skriver datamedlemmene til klassenn til filen KUNDER.DTA.
*@see Kunde::skrivTilFil
*/
void Kunder::skrivTilFil() {
    ofstream utfil("KUNDER.DTA");
    cout << "Skriver til filen 'KUNDER.DTA'";
    utfil << gKunder.size() << "\n";

    for (const auto &val : gKunder) {
        val->skrivTilFil(utfil);
    }
    utfil << sisteNr;
}