#include <iostream>
#include <fstream>
#include <list>
#include <string>
#include <conio.h>
#include <iomanip>

#ifdef _WIN32
#define os 1 // Windows
#else
#define os 0 // Övriga operativsystem
#endif

using namespace std;

struct struktur {
       char namn[40];
       char tele[40];
}; // Skapar en tom struktur

void listamatain(list<struktur> &lista);
void listavisa(list<struktur> lista);
void listasok(list<struktur> lista, bool namn);
void listatabort(list<struktur> &lista);
void listasortera(list<struktur> &lista);

void skrivfil(list<struktur> &lista);
void lasfil(list<struktur> &lista);


void menyaterga(list<struktur> lista);
void meny(list<struktur> lista);

void menyskrivut();
void rensa();
void listarubrik();

int main() {
    
    list<struktur> lista; // Skapa en ny lista med strukturens innehåll
    rensa(); // Fixar färgerna och rensar skärmen;
    meny(lista); // Anropar meny funktionen och skicka vidare listan

return 0;
}


void meny(list<struktur> lista) {
    cout << "   1. Ny kontakt\n   2. Ta bort kontakt\n   3. Spara kontakter i en fil\n   4. H\x84mta kontakter fr\x86n en fil\n   5. S\x94k kontakter\n   6. Sortera kontakter\n   7. Ta bort alla kontakter\n   8. Visa alla kontakter\n   0. Avsluta\n\n   ";

    char val;
    cout << "Ange val: ";
    cin >> val;

    rensa(); // Rensa skärmen
 
         switch (val) {
              case '0':
                   exit(0); // Avsluta programmet
              case '1':
                   listamatain(lista);
                   break;
              case '2':
                   
                   listatabort(lista);

                   break;
              case '3':
                   skrivfil(lista);
                   break;
              case '4':
                   lasfil(lista);
                   break;
              case '5':
                   listasok(lista,0); // Sök efter telefonummer
                   break;
              case '6':
                    listasortera(lista); // Sök efter namn
                   break;
              case '7':
                   lista.clear();// Ingen break här låt de gå vidare till listavisa;
                   
              case '8':
                   listavisa(lista);
                   break;
              case '9':
                   break;
              default:
                   meny(lista);
         }
       
    menyaterga(lista);

}

void menyaterga(list<struktur> lista) {

    cout << "\n   Tryck p\x86 valfri tangent f\x94r att \x86terg\x86 till menyn ...";
    getch(); // Pausa och kan användas för att läsa in tangentbordstryckningar
    rensa(); // Rensa skärmen
    meny(lista); // Anropa main;

}
 
void listarubrik() {
     cout << "   (NAMN)                                  (TELEFONNUMMER)\n\n";
}

void rensa() {

// Om det är windows kör clear annars cls
    if (os == 1){
        system("cls");
        system("color 9F"); // Fungerar endast med NT version windows tror jag :p annars kan man bara kopiera color.exe filen till mappen
    }else{
        system("clear");
    }
  
  // Skriv ut rubrik
    cout << "\n  ============================== TELEFONBOK 1.0 ==============================\n\n";

}

void listavisa(list<struktur> lista) {
     
    if (lista.empty()) {
        cout << "   Listan \x84r tom!\n\n";
    }else{
          
        listarubrik();
    
        list<struktur>::iterator it;
        it = lista.begin();
    

          while (it != lista.end()) {
               cout.setf(ios::left, ios::adjustfield);
               cout << "   " << setw(40) << (*it).namn << (*it).tele << "\n";
               it++;
            }
    }

}

void listasok(list<struktur> lista, bool namn) {
     
     list<struktur>::iterator it;
     it = lista.begin();
        
     int traffar = 0;
     
     
     if (namn == 1) {   
                
        string namn;
        cout << "   Ange s\x94kbar namn: ";
        cin >> namn;
        rensa();
        
            while (it != lista.end()) {
               cout.setf(ios::left, ios::adjustfield);
                
                if (traffar == 0) {
                   listarubrik();
                }    
                        
                    if ((*it).namn == namn) {                     
                        cout << "   " << setw(40) << (*it).namn << (*it).tele << "\n";
                    }
                    
               traffar++;
               it++;
            }
        
     }else{
           
           string tele;
           cout << "   Ange s\x94kbar telefonnummer: ";
           cin >> tele;
           rensa();
           
           while (it != lista.end()) {
               cout.setf(ios::left, ios::adjustfield);
                    
                      
                if (traffar == 0) {
                   listarubrik();
                }  
                    
                    if ((*it).tele == tele) {
                        cout << "   " << setw(40) << (*it).namn << (*it).tele << "\n";
                    }
                    
               traffar++;
               it++;
            }
     }
     
     if (traffar == 0) {
        cout << "\n   (S\x94kningen gav inga resultat!)\n";
     }
}

void listamatain(list<struktur> &lista) {
     
    char val;
    int antal = 0;
    
    struktur data; // Skapa ny struktur
     
    while (antal == 0 || val == 'j' || val == 'J') { 
          
          cout << "   Ange namn: ";
          cin >> data.namn;  // Mata in värdet i strukturen
          cout << "   Ange telefonnummer: ";
          cin >> data.tele; // Mata in värdet i strukturen
    
          lista.push_back(data); // skjut in värdet från strukturen längst in i listan
    
          cout << "\n   Vill du mata in fler uppgifter i listan? (j/n): ";
          cin >> val;
          cout << "\n";
          antal++;
    } 
    
    
}

void listatabort(list<struktur> &lista) {

     string namn;
     cout << "   Ange namn: ";
     cin >> namn;
     
     bool hitta = 0;
     
     list<struktur>::iterator it;
     it = lista.begin(); // 1
    
        while (it != lista.end()) { // Loopa till slutet av listan.
            
            if ((*it).namn == namn) { // Om nått namn i listan stämmer med inmatade namnet
               
               lista.erase(it); // ta bort från lista
               it--; // gör minus när post tas bort (antal poster) annars krashar programmet
               
               hitta = 1;
            }
            
            it++; // plussa på (antal poster)
        }
               
            if (hitta == 0) {
               cout << "\n   (Kunde inte hitta namnet i listan!)\n";
            }else{
               cout << "\n   (Uppgifterna har tagits bort fr\x86n listan!)\n";
               cout << "\n   Vill du ta bort fler uppgifter fr\x86n listan? (j/n): ";
               
               char val;
               cin >> val;
               
               cout << "\n";
               
                    if (val == 'j') {
                       cout << "\n";
                       listatabort(lista); // Börja om på nytt anropa ta bort sidan
                    }
               
            }
    
}

void skrivfil(list<struktur> &lista) {
     
     fstream binary_file("lista.dat",ios::out|ios::binary|ios::app); 
     
     list<struktur>::iterator it;
     it = lista.begin();
     
      while (it != lista.end()) {
     binary_file.write((const char*)&(*it), sizeof(struktur));
     it++;
     }
          //binary_file.write(reinterpret_cast<char *>&(*lista.begin()),sizeof(struktur));
          binary_file.close();

}

void lasfil(list<struktur> &lista) {
             fstream binary_file("lista.dat",ios::binary|ios::in);
             
             list<struktur>::iterator it;
             it = lista.begin();
             
             while (it != lista.end()) {
             binary_file.read((char*)&(it), sizeof(struktur));
             lista.push_back(*it);
             it++;
             }
             
             binary_file.close();
}

void listasortera(list<struktur> &lista) {
     cout << "   Ar du saker pa att du vill sortera listan? (j/n): ";
     
     list<struktur>::iterator it;
     it = lista.begin()++; // Borja från 2
     
     list<struktur>::iterator it2;
     
     while (it != lista.end()) { // Loop till slutet av lista1
           
           it2 = lista.end(); // borja från slutet på lista 2
           
              while (it2 != it && (*it2).namn < (*it).namn) {
                 it2--;
              }
           
           lista.insert(it2, *it); 
           lista.erase(it++);
     }        
         
}
