//----------------------------------------------------------------------------//
#pragma hdrstop
#include "KontrolListe.h"
//-------------------------------Gem funktioner-------------------------------//
///Funktionen gemmer den liste til databasen som angives ved typen. Det bør
///bemærkes at funktionen kun kan gemme liste nr 7 og 8.
bool KontrolListe::Gem(int type)
{
    bool ok = true;
    string s;
    int i, j;

    if(Kilde == 'f')
      db->Navn(Navn[type-1],"test");

    db->StartTransaction();
	switch(type)
    {
      case 1: case 2: case 3: case 4: case 5: case 6:
      case 9:
        for(i = 0; i < Lister[type-1].Brugt && ok ; i++)
        {
          db->IndsaetI("test");
          for(j = 0; j < 5; j++)
            db->Indsaet(Lister[type-1].Liste[i].StringSlot[j]);
          for(j = 0; j < 4; j++)
            db->Indsaet(Lister[type-1].Liste[i].IntSlot[j]);
          db->Indsaet(Lister[type-1].Liste[i].DoubleSlot[0]);
          db->Indsaet(Lister[type-1].Liste[i].DoubleSlot[1]);
          ok = db->Indsaet();
          if(!ok)
          {
            db->Rollback();
            return false;
          }
        }
        break;
      case 7:
        for(i = 0; i < Lister[type-1].Brugt && ok; i++)
        {
          if(Kilde == 'd')
          {
            s  = "Update LokaleHoldRelation set LokaleID_LoHR = '";
            s += Lister[type-1].Liste[i].StringSlot[1] + "' ";
            s += "where HoldID_LoHR  ='" + Lister[type-1].Liste[i].StringSlot[0] + "'";
            ok = db->ExecSql(s);
            if(!ok)
            {
              db->Rollback();
              return false;
            }
          }
          else if(Kilde == 'f')
          {
            db->IndsaetI("test");
            db->Indsaet(Lister[type-1].Liste[i].StringSlot[0]);
            db->Indsaet(Lister[type-1].Liste[i].StringSlot[1]);
            ok = db->Indsaet();
            if(!ok)
              return false;
          }
        }
        break;
      case 8:
        for(i = 0; i < Lister[type-1].Brugt && ok; i++)
        {
          if(Kilde == 'd')
          {
            s  = "Update HoldLaererRelation set LaererID_HLR = '";
            s += Lister[type-1].Liste[i].StringSlot[2] + "' ";
            s += "where HoldID_HLR ='" + Lister[type-1].Liste[i].StringSlot[0] + "' AND ";
            s += "FagID_HLR ='" + Lister[type-1].Liste[i].StringSlot[1] + "' ";
            ok = db->ExecSql(s);
            if(!ok)
            {
              db->Rollback();
              return false;
            }
          }
          else if(Kilde == 'f')
          {
            db->IndsaetI("test");
            db->Indsaet(Lister[type-1].Liste[i].StringSlot[0]);
            db->Indsaet(Lister[type-1].Liste[i].StringSlot[1]);
            db->Indsaet(Lister[type-1].Liste[i].StringSlot[2]);
            ok = db->Indsaet();
            if(!ok)
              return false;
          }
        }
        break;
    }
    db->Commit();
    return true;
}//
//-------------------------Kontrol af HL og LHR listerne----------------------//
///Funktionen finder en fag lærer til et hold som mangler en i et bestemt fag.
///Dette gøres for alle mangelfulde relationer på hold lærer listen.
bool KontrolListe::FindLaererTilHold()
{
    int mangler(0);
    bool ok;
    bool fejl = false;
    int s1, s2, f1(0), f2(0);

    //lærer fagprofilen sorteres efter FagID.
    Lister[9-1].SorterKL(2);

    //De mangelfulde relationer på hold lærer listen udskilles til starten.
	obj.StringSlot[2] = "tom";
    int index1 = Lister[8-1].Udskil(3, obj, 'b');

    if(index1 == 0) //der er ikke nogen mangelfulde relationer.!
      return true;
    else if(comm.AcceptBox("Ikke alle hold har fået tildelt en fast lærer i alle fag\n ønskes en randomiseret tildeling?"))
    {
      //brugeren har givet sin accept til at forsætte med tildelingen.!
      //Den resterende del af hold lære listen sorteres i faldende orden, m.h.t
      //lærerID'et.(3).
      Lister[8-1].SorterDel(3, index1, (Lister[8-1].Brugt-index1), 0);

      //finder lærer til de hold der mangler
      for(int i = index1-1; i >= 0; i--)
      {
        //Den sektion indeholdende faget findes på lærer fag profilen
        obj.StringSlot[1] = Lister[8-1].Liste[i].StringSlot[1]; //FagID kopieres
        if(Lister[9-1].SektionSoegning(2, obj, s1, s2))
        {
          ok = true;
          //alle lærene i sektionen løbes igennem for at se om en af dem kan bruges.
          while(s1 < s2+1 && ok)
          {
            //lærerID kopieres fra lærer fag profilen..
            obj.StringSlot[2] = Lister[9-1].Liste[s1].StringSlot[0];

            //der optælles i resten af LærerHoldRelationen hvormange
            //hold den enkelte lærer har
            f1 = index1;
            f2 = Lister[8-1].Brugt-index1;
            if(Lister[8-1].SektionSoegning(3, obj, f1, f2, 'd') &&
               Lister[8-1].Optael(3, obj, f1, f2+1) < Lister[9-1].Liste[s1].IntSlot[0] ||
               Lister[9-1].Liste[s1].IntSlot[0] > 0)
            {
              Lister[8-1].Liste[i].StringSlot[2] = obj.StringSlot[2];
              Lister[9-1].Liste[s1].IntSlot[0]--; //læren kan nu have færre hold
              ok = false;
            }
            else
              s1++;
          }
          if(s1 == s2+1)
            fejl = true;
        }
      }
      return(!fejl);
    }
    return false;
}//
///Funktionen finder et lokale til et hold som mangler et stamlokale, på
///lokale hold relationen.
bool KontrolListe::FindLokalerTilHold()
{
    int index1, index2, mangler(0);

    //De mangelfulde relationer på lokale hold relationen udskilles til start.
    obj.StringSlot[1] = "tom";
    index1 = Lister[7-1].Udskil(2, obj, 'b');

    if(index1 == 0) //ingen relationer mangler et stamlokale.
      return true;
    else if(comm.AcceptBox("Ikke alle hold har fået tildelt et fast lokale\n ønskes en randomiseret tildeling?"))
    {
      //Hvis brugeren acceptere tildelingen ....

      //Den resterende del af Lokale hold listen sorteres efter LokaleID.
      Lister[7-1].SorterDel(2, index1, (Lister[7-1].Brugt-index1), 0);

      //Stam lokaler udskilles på lokale listen
      obj.StringSlot[1] = StamLokale;
      index2 = Lister[5-1].Udskil(2, obj, 'b');
      if(index2 ==  0) //der er ingen stamlokaler at tildele
      {
        comm.FejlBox("Fejl: Der er ikke nok ledige stamlokaler","Genereringen er stoppet!");
        return false;
      }
      //hvert stamlokale på lokale listen undersøges om det eksistere på
      //den resterende del af lokale hold listen. Hvis det gør.. er det ikke frit.
      for(int i = 0; i < index2 && mangler < index1; i++)
	  {
        //et muligt frit stamlokale lokaliseres
        obj.StringSlot[1] = Lister[5-1].Liste[i].StringSlot[0];

        //hvis Lokalet ikke findes på lokale hold listen kan det bruges
        //NB: der skal kun søges i det resterende del af listen. derfor (Brugt-index)
        if(!Lister[7-1].Find(2, obj, index1, (Lister[7-1].Brugt-index1)))
        {
          //Et frit lokale er fundet og kopieres ind på lokale hold realtionen.
          Lister[7-1].Liste[mangler].StringSlot[1] = obj.StringSlot[1];

          //der ledes efter holdet på hold listen idet, antalle af planlagte
          //lektioner skal påføres lokalet på lokale listen!. (dette kan ikke
          //lade sig gøre under lokale liste indlæsningen.
          obj.StringSlot[0] = Lister[7-1].Liste[mangler].StringSlot[0];
          if(Lister[1-1].Hent(dPtr, obj, 1))
            Lister[5-1].Liste[i].IntSlot[0] = dPtr->IntSlot[0];
          else
            Lister[5-1].Liste[i].IntSlot[0] = 0;
          mangler++;
        }
      }
      return mangler == index1;
    }
    return false;
}//
//----------------------------Hent funktioner---------------------------------//
///Funktionen finder et egnet lokale til en bestemt lokaletype.
bool KontrolListe::FindLokaleTilLokaleType(string LokaleTypeID, string& LokaleID)
{
	int i, s1(0), s2(0);

    //Lokaletypen udskilles til starten i lokalelisten.
    obj.StringSlot[1] = LokaleTypeID;
    int index = Lister[5-1].Udskil(2, obj, 'b');

    if(index > 0) //hvis der er nogen specielle lokale typer.
    {
      s1 = 0;
      s2 = index;
      //hvis der er mere end et lokale til typen sorteres de efter lagte lektioner
      //i stigende orden.
      if(s1 < s2-1)
        Lister[5-1].SorterDel(7, 0, index, 0);

      //Det første lokale vælges indenfor det udvalgte interval.
      LokaleID = Lister[5-1].Liste[s1].StringSlot[0];
      Lister[6-1].HentPejerPaa(dPtr);
      dPtr->StringSlot[4] = LokaleID; //lokaleID'et anføres på lægge listen.

      //Lokale listen sorteres tilbage, da resten af lægningen skal benytte
      //denne sorteret efter lokaleID'et.
      Lister[5-1].SorterKL(1);

      //Efter at lokale listen er blevet sorteret tilbage bestemmes Lokalets
      //plads i denne opstilling, idet der skal indføres en pointere til objektet
      //under lægge listen.
      obj.StringSlot[0] = LokaleID;
      Lister[5-1].LinearSoegning(1, obj, index);
      dPtr->d[4] = &Lister[5-1].Liste[index];
      return true;
    }
    Lister[5-1].SorterKL(1);
    return false;
}//
///Funktionen returnere den næste på lægge listen indenfor den angivne del.
///Der returneres endvidere en sandhedsværdi for om der er mere at hente.
bool KontrolListe::HentNaestePaLaeggeListen(string& HoldID, string& FagID,
					string& LaererID, string& LokaleTypeID, string& LokaleID,
                    int& blok, char del, int& PlanLagteLektioner)
{
    bool ok = true;
    do
    {
      //Det næste objekt på lægge listen hentes.
	  if(del == 'b' && Lister[6-1].PejerPaa < Oplads)
        ok = Lister[6-1].HentNaeste(dPtr);
      else if(del == 's')
        ok = Lister[6-1].HentNaeste(dPtr);
      else
        ok = false;

      //hvis der er flere objekter tilbage på listen, og dennes V værdi er
      //større end nul samt at dens styrke er mindre end den af brugen
      //bestemte størrelse.
      if(ok && dPtr->DoubleSlot[1] > 0 && dPtr->IntSlot[2] < Styrke)
      {
        dPtr->IntSlot[2]++; //Holder styr på hvormange gange realtionen er forsøgt lagt!
        //Relationens parametere kopieres ind i de overførte variable.
        HoldID = dPtr->StringSlot[0];
        FagID = dPtr->StringSlot[1];
        LaererID = dPtr->StringSlot[2];
        LokaleTypeID = dPtr->StringSlot[3];
        LokaleID = dPtr->StringSlot[4];
        blok = dPtr->IntSlot[0];
        //kun dem der mangler at blive lagt.!
        PlanLagteLektioner = dPtr->d[1]->IntSlot[0] - dPtr->IntSlot[1];
        return true;
      }
    }while(ok);
    return false;
}//
///Funktionen henter den næste streng på en given liste (type) i et givent
///StringSlot nummer.
bool KontrolListe::HentNaeste(string& str, int type, int nr)
{
	if(Lister[type-1].HentNaeste(dPtr))
    {
     str = dPtr->StringSlot[nr];
     return true;
    }
    return false;
}//
///Funktionen henter næste objekt på et given liste nummer(type).
bool KontrolListe::HentNaeste(data*& ptr, int type)
{
	if(Lister[type-1].HentNaeste(dPtr))
    {
     ptr = dPtr;
     return true;
    }
    return false;
}//
///Funktionen fylder ID'er fra en given type liste på en stack der returneres.
stack<string>* KontrolListe::FyldListePaaStack(char type)
{
    switch(type)
    {
      case 'h':
        delete HoldListe;
        HoldListe = new stack<string>;
        for(i = 0; i < Lister[1-1].Brugt; i++)
          HoldListe->push(Lister[1-1].Liste[i].StringSlot[0]);
        return HoldListe;
      case 'l':
        delete LaererListe;
        LaererListe = new stack<string>;
        for(i = 0; i < Lister[3-1].Brugt; i++)
          LaererListe->push(Lister[3-1].Liste[i].StringSlot[0]);
        return LaererListe;
      case 'k':
        delete LokaleListe;
        LokaleListe = new stack<string>;
        for(i = 0; i < Lister[5-1].Brugt; i++)
          LokaleListe->push(Lister[5-1].Liste[i].StringSlot[0]);
        return LokaleListe;
    }
    return NULL;
}//
///Funktionen fylder en given type liste på en stack m.h.t ID'er.
///alt efter udfaldet returneres en sandhedsværdi.
bool KontrolListe::FyldListePaaStack(stack<string>& Stack, char type)
{
    int i;
    switch(type)
    {
      case 'h':
        if(Lister[1-1].Brugt > 0)
        {
          for(i = 0; i < Lister[1-1].Brugt; i++)
            Stack.push(Lister[1-1].Liste[i].StringSlot[0]);
          return true;
        }
        break;
      case 'l':
        if(Lister[3-1].Brugt > 0)
        {
          for(i = 0; i < Lister[3-1].Brugt; i++)
            Stack.push(Lister[3-1].Liste[i].StringSlot[0]);
          return true;
        }
        break;
      case 'k':
        if(Lister[5-1].Brugt > 0)
        {
          for(i = 0; i < Lister[5-1].Brugt; i++)
            Stack.push(Lister[5-1].Liste[i].StringSlot[0]);
          return true;
        }
        break;
    }
    return false;
}//
//------------------------Funktioner til at beregne indekser------------------//
///Funktionen beregner indekset for en given liste, i en bestemt del af lægge listen.
void KontrolListe::BeregnIndex(int type, char del)
{
    ResetOgKlargoer(del); //indstiller i til det rette indeks alt efter delen.!

    while(del == 'b' && i < Oplads || del == 's' && i < Lister[6-1].Brugt)
    {
      //næste objekt fra lægge listen hentes.
      Lister[6-1].HentNaeste(dPtr);
      switch(type)
      {
        case 2: BeregnIndex(dPtr, type);                //F index
          break;
        case 6: BeregnIndex(dPtr, type, del);           //V index
          break;
        case 1:                                         //H index
        case 3:                                         //L index
        case 4:                                         //special LO index
        case 5: BeregnIndex(dPtr->d[type-1], type);     //LO index
          break;
      }
      i++;
    }
}//
///Funktionen beregner det endelige indeks for et bestemt objekt på en given
///liste (type) i en given del af lægge listen.
void KontrolListe::BeregnIndex(data*& dPtr, int type, char del)
{
	switch(type)
    {
      case 1: //hold index (H = PL / (SL - LL))
        if(SL - dPtr->IntSlot[1] == 0)
          dPtr->DoubleSlot[0] = 0;
        else  //dPtr = objekt af hold listen.
        {
          dPtr->DoubleSlot[0] = double(dPtr->IntSlot[0]) / double(SL - dPtr->IntSlot[1]);
          cout << dPtr->DoubleSlot[0] << " ";
        }
        break;
      case 2: //fag index (F = (PL - LL) / (SL - holdLL) + (SL - lærerLL))
        if((SL - dPtr->d[0]->IntSlot[1]) + ( SL - dPtr->d[2]->IntSlot[1]) == 0)
          dPtr->DoubleSlot[0] = 0;
        else  //dPtr = objekt af lægge listen.
          dPtr->DoubleSlot[0] = double(dPtr->d[1]->IntSlot[0] - dPtr->IntSlot[1]) /
          ((SL - dPtr->d[0]->IntSlot[1]) + ( SL - dPtr->d[2]->IntSlot[1]));
        break;
      case 3: //lærer index (L = PL / (SL - LL))
        if(SL - dPtr->IntSlot[1] == 0)
          dPtr->DoubleSlot[0] = 0;
        else  //dPtr = objekt af lærer listen.
          dPtr->DoubleSlot[0] = double(dPtr->IntSlot[0]) / (SL - dPtr->IntSlot[1]);
        break;
      case 4: //lokaletype indexs (LO = PL / (SL * Antal Lokaler - LL)
        if((SL * dPtr->IntSlot[0]) - dPtr->IntSlot[2] == 0)
          dPtr->DoubleSlot[0] = 0;
        else  //dPtr = objekt af lokaletype listen
          dPtr->DoubleSlot[0] = double(dPtr->IntSlot[1]) / ((SL * dPtr->IntSlot[0]) - dPtr->IntSlot[2]);
        break;
      case 5:  //lokale index (LO = PL / (SL - LL))
        if(SL - dPtr->IntSlot[1] == 0)
          dPtr->DoubleSlot[0] = 0;
        else   //dPtr = objekt af lokale listen.
          dPtr->DoubleSlot[0] = double(dPtr->IntSlot[0]) / (SL - dPtr->IntSlot[1]);
        break;
      case 6: //v index  (V = H * F * L * LO * blok)
        if(del == 'b')
          dPtr->DoubleSlot[1] = dPtr->d[0]->DoubleSlot[0] * dPtr->d[2]->DoubleSlot[0] *
          dPtr->d[3]->DoubleSlot[0] * dPtr->DoubleSlot[0] * dPtr->IntSlot[0];
        else  //dPtr = objekt af lægge listen.!
          dPtr->DoubleSlot[1] = dPtr->d[0]->DoubleSlot[0] * dPtr->d[2]->DoubleSlot[0] *
          dPtr->d[4]->DoubleSlot[0] * dPtr->DoubleSlot[0] * dPtr->IntSlot[0];
        break;
    }
}//
//------------------Funktioner til at tilføje de lagte lektioner--------------//
///Funktionen opdatere antallet af lagte lektioner på den relation på lægge listen
///som er forsøgt lagt.
void KontrolListe::OpdaterLagteLektioner(int LagteLektioner, char del)
{
    Lister[6-1].PejerPaa--; //Pejer på tælles en ned, da den altid er en større.
	Lister[6-1].HentPejerPaa(dPtr);

    dPtr->d[0]->IntSlot[1] += LagteLektioner;
    dPtr->IntSlot[1] += LagteLektioner;
    dPtr->d[2]->IntSlot[1] += LagteLektioner;
    dPtr->d[4]->IntSlot[1] += LagteLektioner;
    if(del == 'b')
      dPtr->d[3]->IntSlot[1] += LagteLektioner;
    Lister[6-1].PejerPaa++;
}//
///Funktionen beregner alle de lagte lektioner for en bestemt type i enten
///special lokaletype delen eller stamlokale delen af læggelisten ('b', 's')
void KontrolListe::BeregnLagteLektioner(int type, char del)
{
    ResetOgKlargoer(del); //indstiller i til det rette indeks alt efter delen.!

    if(type != 4)
    {
      while(del == 'b' && i < Oplads || del == 's' && i < Lister[6-1].Brugt)
      {
        Lister[6-1].HentNaeste(dPtr);
        switch(type)
        {
          case 1:                                                  //Hold
          case 3:                                                  //Lærer
          case 5: TilfoejLagteLektioner(dPtr->d[type-1], type);    //Lokale
            break;
          case 2: TilfoejLagteLektioner(dPtr, type);               //Fag
            break;
        }
        i++;
      }
    }
    //Lokale type listen er speciel idet den beregnes gennem lokale listen.!
    else if(type == 4)                                             //LokaleType
    {
      Lister[type-1].NulstilLokaleType();
      Lister[5-1].reset();
      while(Lister[5-1].HentNaeste(dPtr))
        if(dPtr->StringSlot[1] != StamLokale)
          TilfoejLagteLektioner(dPtr, 5);
    }
}//
///Funktionen henter de lagte lektioner for et bestemt skema ude i planen, og
///indfører dette herefter på objektet der overføres.
void KontrolListe::TilfoejLagteLektioner(data*& dPtr, int type)
{
	switch(type)
    {
      case 1:  //hold                     (dPtr = pointer objekt af Hold listen)
        dPtr->IntSlot[1] = Port->SkemalagteLektioner(dPtr->StringSlot[0], 'h');
        break;
      case 2:  //fag på lægge liste (dPtr = pointe objekt af LæggeListen)
        //dPtr er ikke et objekt af fagListen, idet de lagte
        //lektioner lægger sig til den pågældende relation på lægge listen!
        dPtr->IntSlot[1] = Port->LagteFagLektioner(dPtr->StringSlot[0],
                                                   dPtr->StringSlot[1]);
        dPtr->IntSlot[2] = 0;
        break;
      case 3:  //lærer                    (dPtr = pointer objekt af LærerListen)
        dPtr->IntSlot[1] = Port->SkemalagteLektioner(dPtr->StringSlot[0], 'l');
        //De prioriterede lektioner med -3 tælles med som lagte lektioner
        dPtr->IntSlot[1] += Port->LagtePLektioner(dPtr->StringSlot[0]);
        break;
      case 4:  //LokaleType                        (beregnes igennem case 5...!)
        break;
      case 5:  //lokale                  (dPtr = pointer objekt af LokaleListen)
        dPtr->IntSlot[1] = Port->SkemalagteLektioner(dPtr->StringSlot[0], 'k');
        //Lokaletype objektet som d[0] peger på optælles tilsvarende
        if(dPtr->d[0] != NULL)
        {
          if(dPtr->d[0]->IntSlot[2] == -1)  //Bug fix..!
            dPtr->d[0]->IntSlot[2] = 0;
          dPtr->d[0]->IntSlot[2] += dPtr->IntSlot[1];
        }
        break;
    }
}//
//-------------------------------Indlæsning funktioner------------------------//
///Funktionen indlaeser en liste hvor typen angiver liste nummeret
bool KontrolListe::Indlaes(int type)
{
    string str[5];
    int tal[4];
    bool ok;
    int i;
    obj.slet();

     //Lokale listen skal have sorteret lokaletype, hold og hold lokale listen.
    if(type == 5)
    {
      Lister[4-1].SorterKL(1);
      Lister[1-1].SorterKL(1);
      Lister[7-1].SorterKL(2);
    }
    //lægge listen skal have sorteret alle lister.!
    else if(type == 6)
      for(i = 0; i < 5; i++)
        Lister[i].SorterKL(1);

    ok = db->StartIndlaesning(SQLstatements(type));
    if(type != 4)
    {
      while(ok)
      {
        switch(type)
        {
          case 1: //Hold
            if(db->FindString(str[0], "HoldID") && db->FindInt(tal[0], "AntalTimer"))
            {
              obj.StringSlot[0] = str[0];
              obj.IntSlot[0]    = tal[0];
            }
            else ok = false;
            break;
          case 2: //Fag
            if(db->FindString(str[0], "FagID") && db->FindString(str[1], "Lokaletype") &&
               db->FindInt(tal[0], "Timer") && db->FindInt(tal[1], "Hold"))
            {
              obj.StringSlot[0] = str[0];
              obj.IntSlot[0]    = tal[0];
              obj.StringSlot[1] = str[1];
              obj.IntSlot[1]    = tal[1];
            }
            else ok = false;
            break;
          case 3: //lærer
            if(db->FindString(str[0], "LaererID") && db->FindInt(tal[0], "Timer"))
            {
              obj.StringSlot[0] = str[0];
              obj.IntSlot[0]    = tal[0];
            }
            else ok = false;
            break;
          case 5: //Lokale
            if(db->FindString(str[0], "LokaleID") && db->FindString(str[1], "LokaleType"))
            {
       		  obj.StringSlot[0] = str[1];
              //hvis det er et specielt lokale!
        	  if(str[1] != StamLokale)
        	  {
          	    if(Lister[4-1].Hent(dPtr, obj, 1))
          	    {
                  //Planlagtelektioner beregnes udfra Lokaletypen
              	  obj.IntSlot[0] = dPtr->IntSlot[1] / dPtr->IntSlot[0];
            	  obj.d[0] = dPtr;
          	    }
          	    else //Lokaletypen findes ikke på lokaletype listen (fejl!)
          	    {
              	  obj.d[0] = NULL;
            	  obj.IntSlot[0] = 0;
          	    }
              }
              //hvis det er et stamlokale
              else
              {
                obj.d[0] = NULL;
                obj.StringSlot[1] = str[0];
                //Holdet som har lokalet findes på lokale hold listen.
                if(Lister[7-1].Hent(dPtr, obj, 2))
                {
                  obj.StringSlot[0] = dPtr->StringSlot[0];
                  if(Lister[1-1].Hent(dPtr, obj, 1))
                    obj.IntSlot[0] = dPtr->IntSlot[0];
                  else
                    obj.IntSlot[0] = 0;
                }
                else
                  obj.IntSlot[0] = 0;
              }
              obj.StringSlot[0] = str[0];
              obj.StringSlot[1] = str[1];
            }
            else ok = false;
            break;
          case 6:  //lægge liste
            if(db->FindString(str[0], "HoldID") && db->FindString(str[1], "FagID") &&
               db->FindString(str[2], "LaererID") && db->FindString(str[3], "LokaleType") &&
               db->FindString(str[4], "LokaleID") && db->FindInt(tal[0], "Bloksize"))
            {
              if(str[3] != StamLokale)
                str[4] = "tom";
              //pointere findes til Holdet, faget, læren, lokalet samt lokaletypen
              for(i = 0; i < 5; i++)
              {
                obj.StringSlot[0] = str[i];
                if(Lister[i].Hent(dPtr, obj, 1))
                  obj.d[i] = dPtr;
                else
                  obj.d[i] = NULL;
              }
              for(i = 0; i < 5; i++)
                obj.StringSlot[i] = str[i];
              obj.IntSlot[0] = tal[0];
              obj.IntSlot[2] = 0;
            }
            else ok = false;
            break;
          case 7: //Lokale hold liste
            if(db->FindString(str[0], "HoldID") && db->FindString(str[1], "LokaleID"))
            {
              obj.StringSlot[0] = str[0];
              obj.StringSlot[1] = str[1];
            }
            else ok = false;
            break;
          case 8: //Hold lærer liste
            if(db->FindString(str[0], "HoldID") && db->FindString(str[1], "FagID") &&
               db->FindString(str[2], "LaererID"))
            {
              obj.StringSlot[0] = str[0];
              obj.StringSlot[1] = str[1];
              obj.StringSlot[2] = str[2];
            }
            else ok = false;
            break;
          case 9: //Lærer fag profil
            if(db->FindString(str[0], "LaererID") && db->FindString(str[1], "FagID") &&
               db->FindInt(tal[0], "AntalHold"))
            {
              obj.StringSlot[0] = str[0];
              obj.StringSlot[1] = str[1];
              obj.IntSlot[0] = tal[0];
            }
            else ok = false;
            break;
        }
        if(ok) //objektet lægges på listen og næste hentes i databasen.
          ok = (Lister[type-1].Indsaet(obj) && db->FindNaeste());
      }
      return true;
    }
    else if(type == 4) //LokaleType liste
    {
      //Lokale type listen indlæses i 2 dele som herefter kombineres.
      while(ok && db->FindString(str[0], "LokaleType") &&
            db->FindInt(tal[0], "Antal_Lokaler"))
      {
        obj.StringSlot[0] = str[0];
        obj.IntSlot[0]    = tal[0];
        ok = (Lister[type-1].Indsaet(obj) && db->FindNaeste());
      }

      Lister[type-1].SorterKL(1); //listen sorteres,
      ok = db->StartIndlaesning(SQLstatements(type*10));
      obj.slet();
      while(ok && db->FindString(str[0], "LokaleType") &&
            db->FindInt(tal[1], "Antal_Timer"))
      {
        obj.StringSlot[0] 	  = str[0];
        //det tilsvarende objekt lokaliseres på listen.
        if(Lister[type-1].Hent(dPtr, obj, 1)) //evt step søgning!!!
          dPtr->IntSlot[1] = tal[1];
        obj.slet();
        ok = db->FindNaeste();
      }
      return true;
    }
    return false;
}//
///Funktionen Returnere det SQl statement som danner den pågældende liste
string KontrolListe::SQLstatements(int type) //Type 1 til  9 (Listerne!)
{
    string s;

    if(Kilde == 'd') //databasen
    {
      switch(type)
      {
        case 1: //Hold liste
          s  = "SELECT HoldID_AHo AS HoldID, SUM(Timer_AFa) AS AntalTimer ";
	      s += "FROM Hold, Holdliste, Fag, Fagprofil ";
		  s += "WHERE Hold_THo = HoldID_AHo AND FagID_Fp = FagID_Afa AND ";
          s += "Type_AHo = Type_FP And timefagfordelingID_THo = '" + TFF + "' ";
          s += "GROUP BY HoldID_AHo ";
          break;
        case 2: //Fag liste
          s  = "SELECT DISTINCT FagID_Afa AS FagID, Lokaletype_Afa AS Lokaletype, ";
    	  s += "Timer_AFa AS Timer, AntalHold_LFP AS Hold FROM Fag, Fagliste, LaererFagProfil ";
    	  s += "WHERE TimeFagFordelingID_LFP = '" + TFF + "' AND FagID_TFa = FagID_AFa AND ";
    	  s += "FagID_TFa = FagID_LFP ";
          s += "ORDER BY FagID_AFa ";
          break;
        case 3: //Lærer liste
          s = "SELECT LaererID_HLR AS LaererID, SUM(Timer_AFa) AS Timer ";
          s += "FROM HoldLaererRelation, Fag WHERE PlanID_HLR = '" + PlanID + "' ";
          s += "AND FagID_HLR = FagID_AFa ";
          s += "GROUP BY LaererID_HLR";
          break;
	    case 4: //LokaleType liste (første del)
          s  = "SELECT	Lokaletype_ALo AS LokaleType, COUNT(Lokaletype_ALo) AS Antal_Lokaler ";
          s += "FROM Lokale, LokalePlan ";
          s += "WHERE Lokaletype_ALo != '" + StamLokale + "' And ";
          s += "LokaleID_ALo = LokaleID_LP And PlanID_LP = '" + PlanID + "' ";
          s += "GROUP BY Lokaletype_ALo";
		  break;
        case 40://LokaleType liste (anden del)
          s  = "SELECT	Lokaletype_AFa AS LokaleType, SUM(Timer_AFa) AS Antal_Timer ";
          s += "FROM Fag, HoldLaererRelation ";
          s += "WHERE Lokaletype_AFa != '" + StamLokale + "' AND ";
          s += "FagID_HLR = FagID_AFa And PlanID_HLR = '" + PlanID + "' ";
          s += "GROUP BY Lokaletype_AFa";
		  break;
        case 5: //Lokale liste
		  s  = "SELECT LokaleID_LP as LokaleID, Lokaletype_ALo as Lokaletype ";
		  s += "FROM Lokaleplan, Lokale ";
		  s += "WHERE LokaleID_ALo = LokaleID_LP AND PlanID_LP = '" + PlanID + "' ";
		  s += "ORDER BY LokaleID_LP";
		  break;
        case 6: //Lægge liste
       	  s  = "SELECT DISTINCT HoldID_HLR AS HoldID, FagID_HLR AS FagID, ";
    	  s += "LaererID_HLR AS LaererID, Lokaletype_AFa AS LokaleType, LokaleID_LoHR ";
    	  s += "AS LokaleID, Blokstoerrelse_LFP AS Bloksize ";
          s += "FROM LaererFagProfil, Fag, HoldLaererRelation, LokaleHoldRelation ";
          s += "WHERE PlanID_HLR = '"+ PlanID + "' AND ";
    	  s += "TimeFagFordelingID_LFP = '" + TFF + "' AND FagID_HLR = FagID_AFa AND ";
    	  s += "FagID_HLR = FagID_LFP AND HoldID_HLR = HoldID_LoHR ORDER BY HoldID_HLR ";
		  break;
        case 7: //Lokale hold relations liste
    	  s  = "SELECT HoldID_LoHR AS HoldID, LokaleID_LoHR AS LokaleID ";
    	  s += "FROM LokaleHoldRelation ";
          s += "WHERE PlanID_LoHR = '" + PlanID + "' ";
          s += "ORDER BY HoldID_LoHR ";
		  break;
   		case 8: //Hold lærer relation.
          s  = "SELECT HoldID_HLR AS HoldID, LaererID_HLR AS LaererID, ";
          s += "FagID_HLR AS FagID ";
          s += "FROM HoldLaererRelation ";
    	  s += "WHERE PlanID_HLR = '" +  PlanID+ "' ";
          s += "ORDER BY HoldID_HLR";
		  break;
        case 9: //Lærer fag profil
          s  = "Select LaererID_LFP AS LaererID, FagID_LFP AS FagID, ";
          s += "AntalHold_LFP AS AntalHold ";
          s += "From LaererFagProfil ";
          s += "Where TimeFagFordelingID_LFP = '" + TFF + "' ";
          s += "Order by FagID_LFP";
          break;
      }
      return s;
    }
    else if(Kilde == 'f') //Fil system
    {
      switch(type)
      {
        case 1: return "HoldListe.txt";
        case 2: return "FagListe.txt";
        case 3: return "LaererListe.txt";
        case 4: return "LokaleTypeListe1.txt";
        case 40: return "LokaleTypeListe2.txt";
        case 5: return "LokaleListe.txt";
        case 6: return "LaeggeListe.txt";
        case 7: return "LokaleHoldRelationListe.txt";
        case 8: return "HoldLaererRelationListe.txt";
        case 9: return "LaererFagProfil.txt";
      }
    }
}//
//----------------------------optællings funktioner---------------------------//
///Funktionen returnere antallet af planlagte lektioner for et objekt med et
///givent ID på en bestemt type liste.
int KontrolListe::PlanlagteLektioner(const string ID, char type)
{
	switch(type)
    {
      case 'h':
        obj.StringSlot[0] = ID;
        if(Lister[1-1].Hent(dPtr, obj, 1))
          return dPtr->IntSlot[0];
        break;
      case 'l':
        obj.StringSlot[0] = ID;
        if(Lister[3-1].Hent(dPtr, obj, 1))
          return dPtr->IntSlot[0];
        break;
      case 'k':
        obj.StringSlot[0] = ID;
        if(Lister[5-1].Hent(dPtr, obj, 1))
          return dPtr->IntSlot[0];
        break;
    }
    return 0;
}//
///Funktionen beregner det totale antal af planlagte lektioner i hele planen.
int KontrolListe::BeregnTotalePlanlagteLektioner()
{
    int sum(0);
    for(int i = 0; i < Lister[6-1].Brugt; i++)
      if(Lister[6-1].Liste[i].d[1]->IntSlot[0] != -1)
         sum += Lister[6-1].Liste[i].d[1]->IntSlot[0];
    return sum;
}//
///Funktionen beregner det totale antal af lagte lektioner.!
int KontrolListe::BeregnTotaleLagteLektioner()
{
    int sum(0);
    for(int i = 0; i < Lister[6-1].Brugt; i++)
      if(Lister[6-1].Liste[i].IntSlot[1] != -1)
        sum += Lister[6-1].Liste[i].IntSlot[1];
    return sum;
}//
//--------------------------------Små funktioner------------------------------//
///Funktionen sortere lægge listen udfra faldende V værdier i en given del af denne.
void KontrolListe::SorterVvaerdi(char del)
{
    if(del == 'b') //Special lokaler (b = begyndelse)
    {
	  Lister[6-1].SorterDel(11, 0, Oplads, 1); //11 = V indeks
      Lister[6-1].reset();
    }
    else if(del == 's') //Stam lokaler (s = slut del)
    {
      Lister[6-1].SorterDel(11, Oplads, (Lister[6-1].Brugt), 1);
      Lister[6-1].reset(Oplads);
    }
}//
///Funktionen opdeler lægge listen i stamlokaler (til slut s) og special lokaler
///til begyndelsen (b).
bool KontrolListe::OpdelEfterSpecialLokaler()
{
    Lister[6-1].Udskriv();
    getch();

    obj.StringSlot[3] = StamLokale;
    Oplads = Lister[6-1].Udskil(4, obj, 's');
    if(Oplads == 0)
      return false;
    return true;
}//
///Funktionen resetter en given type liste
void KontrolListe::Reset(int type)
{
	Lister[type-1].reset();
}//
///Funktionen indstiller lægge listen således at "Pejer på" under klynge listen
///kommer til at pege på den første plads i den del man ønsker at arbejde med.
///Herefter indstilles den private variabel i, til at pege på den samme plads.
void KontrolListe::ResetOgKlargoer(char del)
{
    if(del == 'b')
    {
      Lister[6-1].reset();
      i = 0;
    }
    else if(del == 's')
    {
      Lister[6-1].reset(Oplads);
      i = Oplads;
    }
}//
///Funktionen sletter en given liste
void KontrolListe::SletListe(int type)
{
	Lister[type-1].Brugt = 0;
}//
//------------------------------Udskrivs funktion-----------------------------//
void KontrolListe::Udskriv(int type)
{
    cout << "\nUdskriver Liste: " << Navn[type-1] << endl;
    if(type >= 1)
      Lister[type-1].Udskriv();
}
//----------------------------------------------------------------------------//
///Konstruktør
KontrolListe::KontrolListe(Portal* Port_, SqlKlasse* db_, char Kilde_, int col,
                             int row, const string& PlanID_, const string& TFF_)
{
    SL = 8 * 5;  //max row + col.
    Styrke = 4;
    Port = Port_;
    db = db_;
    TFF = TFF_;
    PlanID = PlanID_;
    Kilde = Kilde_;
    db->SkiftStatus(Kilde);
    StamLokale = "Stamlokale";

    //Navne liste på de enkelte lister.,
    Navn[0] = "Hold";
    Navn[1] = "fag";
    Navn[2] = "laerer";
    Navn[3] = "LokaleType";
    Navn[4] = "lokale";
    Navn[5] = "lægge";
    Navn[6] = "HoldLOkale";
    Navn[7] = "holdLaerer";
    Navn[8] = "Laerer Fagprofil";
}//
//----------------------------------------------------------------------------//

