// Templates: Suchen in Notenliste
//
// Aufruf: noten
//
// Klaus Kusche, 2011

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <string>

using namespace std;

string name[] = { "Franz", "Xaver", "Kevin", "Michael", "Felix", "Andreas" };
int matNr[] = { 1234, 5678, 9876, 3210, 1111, 9999 };
double noten[] = { 6.0, 1.3, 3.6, 1.5, 3.6, 2.0 };

const int anzahl = sizeof(noten) / sizeof(noten[0]);

void print(int i)
{
  cout << setw(20) << left << name[i]
       << right << " (" << matNr[i] << ") :"
       << setw(4) << fixed << setprecision(1) << showpoint << noten[i] << endl;
}

template <typename T>
void find(T array[])
{
  T value;
  bool found = false;
  
  cout << "Suchwert ==> ";
  cin >> value;
  for (int i = 0; i < anzahl; ++i) {
    if (array[i] == value) {
      print(i);
      found = true;
    }
  }
  if (!found) {
    cout << "Nichts gefunden!" << endl;
  }
}

template <typename T>
void list(T array[])
{
  bool gedruckt[anzahl];

  for (int i = 0; i < anzahl; ++i) {
    gedruckt[i] = false;
  }
  
  for (int i = 0; i < anzahl; ++i) {
    int j;
    // 1.) Suche das erste noch nicht gedruckte Element j
    for (j = 0; gedruckt[j]; ++j) {}
    int minPos = j;
    // 2.) Schau, ob es noch ein kleineres nicht gedrucktes Element gibt
    for (++j; j < anzahl; ++j) {
      if (!gedruckt[j] && (array[j] < array[minPos])) {
        minPos = j;
      }
    }
    print(minPos);
    gedruckt[minPos] = true;
  }
}

int main(void)
{
  char inp;

  for (;;) {
    cout << "Suche nach (n)ame, (m)atrikelnummer oder (b)enotung\n"
            "Liste nach (N)ame, (M)atrikelnummer oder (B)enotung\n"
            "Jede andere Eingabe: Ende ==> ";
    cin >> inp;
    switch (inp) {
      case 'n':
        find(name);
        break;
      case 'm':
        find(matNr);
        break;
      case 'b':
        find(noten);
        break;
      case 'N':
        list(name);
        break;
      case 'M':
        list(matNr);
        break;
      case 'B':
        list(noten);
        break;
      default:
        exit(EXIT_SUCCESS);
        break;
    }
  }
}
