//---------------------------------------------------------------------------
#pragma hdrstop
#include "AnalyseSkema.h"
#include <conio.h>
#include <iostream.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
//-------------------------------Pres funktioner------------------------------//
///Funktionen forsøger at presse alle lektioner på skemaet op ad.
void AnalyseSkema::PresSkemaOp()
{
    comm << "presser op";
    int start;
    if(SkemaType == 0)
      start = 4;
    else
      start = 0;

    //Først flyttes alle faglektioner
    if(SkemaType < 2)
      Flyt5FelterOp();

    //
    for(int i = start; i < 7; i++)
      PresVaerdiOp(0, VaerdiGrad[i]);
    for(int i = start; i < 7; i++)
      PresVaerdiOp(1, VaerdiGrad[i]);
}//
///Funktionen forsøger at flytte alle felter med værdierne 5 op i den
///kolonne som de ligger i.
void AnalyseSkema::Flyt5FelterOp()
{
    int fra_y(0);
    bool ok;
    bool enkel = false;
    for(int fra_x = 0; fra_x < user_max_x; fra_x++)
    {
      fra_y = 0;
      if(FindesICol(5, fra_x, fra_y))
      {
        ok = true;
        for(int til_y = 0; til_y < fra_y && ok; til_y++)
        {
          //hvis det er en enkelt lektion.
          if(fra_y > 0  && fra_y < user_max_y-1 && blok == 2 &&
             Askema[fra_x][fra_y-1] != 5 && Askema[fra_x][fra_y+1] != 5)
          {
            blok = 1;
            enkel = true;
          }
          //5 feltet byttes med felter med værdien 4 og 6.
          if(Askema[fra_x][til_y] == 4 &&
             KanBytteForVaerdi(5, fra_x, fra_y, fra_x, til_y) ||
             Askema[fra_x][til_y] == 6 &&
             KanBytteForVaerdi(5, fra_x, fra_y, fra_x, til_y))
          {
            //værdierne for felterne byttes.
            Askema[fra_x][fra_y] = 4;
            Askema[fra_x][til_y] = 5;
            comm << "Flytter 5 felt op";
            ok = false;

            //hvis det er et dobbelt analyse skema opdateres på det gamle skema.
            if(SkemaType == 2)
            {
              GamleSkema->IndskrivDobbeltVaerdi(Askema[fra_x][fra_y], fra_x, fra_y);
              GamleSkema->IndskrivDobbeltVaerdi(Askema[fra_x][til_y], fra_x, til_y);
            }
          }
          if(enkel)
          {
            blok = 2;
            enkel = false;
          }
        }
      }
    }
}//
///FUnktionen forsøger at presse en bestemt værdi på analyse skemaet op på hele
///skemaet. Typen giver udtryk for om der skal byttes med vaerdier forskeligt fra 4,
///eller med vaerdier lig 4.
void AnalyseSkema::PresVaerdiOp(int type, int vaerdi)
{
    int til_x(0), til_y(0), fra_x, fra_y;
    bool ok;
    for(fra_y = user_max_y-1; fra_y > 0; fra_y--)
    {
      for(fra_x = 0; fra_x < user_max_x; fra_x++)
      {
        //hvis en tilsvarende værdi findes på skemaet.
        if(Askema[fra_x][fra_y] == vaerdi)
        {
          ok = true;
          //der ledes efter et felt som den kan flyttes med.
          for(til_y = 0; til_y < fra_y && ok; til_y++)
          {
            for(til_x = 0; til_x < user_max_x && ok; til_x++)
            {
              //hvis der ønskes byttet med felter forskellig fra 4.
              if(type == 0)
              {
                for(int i = 1; i < BytteVaerdier[vaerdi-1][0]; i++)
                {
                  //hvis en af dem kan bytte.!
                  if(Askema[til_x][til_y] == BytteVaerdier[vaerdi-1][i] &&
                     KanBytteForVaerdi(vaerdi, fra_x, fra_y, til_x, til_y) ||
                     Askema[til_x][til_y] == 6 &&
                     KanBytteForVaerdi(vaerdi, fra_x, fra_y, til_x, til_y))
                  {
                    //værdierne på skemaerne ændres.
                    Askema[fra_x][fra_y] = 4;
                    if(Askema[til_x][til_y] != 6)
                      Askema[til_x][til_y] += vaerdi;
                    else
                      Askema[til_x][til_y] = vaerdi;

                    //hvis det er et dobbelt analyse skema. skal det gamle opdateres.
                    if(SkemaType == 2)
                    {
                      GamleSkema->IndskrivDobbeltVaerdi(Askema[fra_x][fra_y], fra_x, fra_y);
                      GamleSkema->IndskrivDobbeltVaerdi(Askema[til_x][til_y], til_x, til_y);
                    }
                    ok = false;
                  }
                }
              }
              //hvis der ønskes byttet med tomme felter i stedet.
              if(type == 1)
              {
                //hvis der kan byttes med et tomt felt
                if(Askema[til_x][til_y] == 4 &&
                   KanBytteForVaerdi(vaerdi, fra_x, fra_y, til_x, til_y))
                {
                  //felternes værdier ændres.
                  Askema[fra_x][fra_y] = 4;
                  Askema[til_x][til_y] = vaerdi;
                  ok = false;
                  comm << "bytter";

                  //hvis skemaet er et dobbelt analyse skema opdateres på det gamle.
                  if(SkemaType == 2)
                  {
                    GamleSkema->IndskrivDobbeltVaerdi(Askema[fra_x][fra_y], fra_x, fra_y);
                    GamleSkema->IndskrivDobbeltVaerdi(Askema[til_x][til_y], til_x, til_y);
                  }
                }
              }
            }
          }
        }
      }
    }
}//
//--------------------------Skab fri plads funktioner-------------------------//
///Funktionen forsøger at skabe frie lektioner ved flytte lektioner der ligger
///opad enkelte felter med værdien 6. NB funktionen stopper selv når der er
///skabt det antallet af frie lektioner således at planlagte lektioner kan
///blive opfyldt. HVis dette sker returneres en sandhedsværdi herfor
bool AnalyseSkema::SkabFrieDobbeltLektioner()
{
    comm << "skaber frie DobbeltLektioner:";
    int til_x(0), til_y(0), fra_x(0), fra_y(0), vaerdi;
    bool ok = false;
    int LagteLektionerGem = LagteLektioner;

    // -2 for dobbelt lektioner.
    while(fra_x < user_max_x && LagteLektionerGem <= PlanlagteLektioner-2)
    {
      fra_y = 0;
      //hvis 4 og 5 ikke eksistere i kolonnen.
      if(!FindesICol(5,fra_x,fra_y) && !FindesICol(4, fra_x, fra_y))
      {
        fra_y = 0;
        //hvis der findes en enkelt felt med værdien 6 i kolonnen.
        if(FindesICol(6,fra_x,fra_y) &&
           Askema[fra_x][fra_y+1] != 6 && Askema[fra_x][fra_y+1] != 4 &&
           Askema[fra_x][fra_y-1] != 6 && Askema[fra_x][fra_y-1] != 4)
        {
          ok = false;
          //lektionen ovenfor 6 feltet
          if(fra_y - 1 >= 0)
          {
            vaerdi = Askema[fra_x][fra_y-1];
            //lektionen ovenfor forsøges byttet væk, hvor som helst.
            if(BytMedUdvalgteFelter(vaerdi, fra_x, fra_y-1,
                                    BytteVaerdier[vaerdi-1],
                                    BytteVaerdier[vaerdi-1][0]) ||
               BytMed6Felter(vaerdi, fra_x, fra_y-1, fra_x, fra_y))
              ok = true;
          }
          //lektionen nedenfor 6 feltet.
          if(fra_y + 1 < user_max_y && !ok)
          {
            vaerdi = Askema[fra_x][fra_y+1];
            //hvis lektionen nedenfor kan byttes væk...
            if(BytMedUdvalgteFelter(vaerdi, fra_x, fra_y+1,
                                    BytteVaerdier[vaerdi-1],
                                    BytteVaerdier[vaerdi-1][0]) ||
               BytMed6Felter(vaerdi, fra_x, fra_y+1, fra_x, fra_y))
              ok = true;
          }
          //hvis noget er blevet flyttet.
          if(ok)
          {
            comm << "danner dobbelt lektion i";
            Askema[fra_x][fra_y] = 4;
            LagteLektionerGem -= 2;
            if(LagteLektionerGem == PlanlagteLektioner)
              return true;
          }
        }
      }
      fra_x++;
    }
    return false;
}//
///Funktionen forsøger at skabe frie lektioner på kolonner uden 5 felter.
///Funktionen forsøger at skaber det antal frie lektioner som mangler at
///blive lagt. Hvis det opnåes skabe det fornødne antal frie lektioner
///returneres en sandhedsværdi herfor.
bool AnalyseSkema::SkabFrieLektioner()
{
    comm << "skaber frie lektioner";
    int x(0), y(0), vaerdi;
    bool ok;
    int LagteLektionerGem = LagteLektioner;
    int ForbudteKolonner[5]; //= {-1,-1,-1,-1,-1};

    //de kolonner som indeholder 5 felter noteres i et array.
    for(x = 0; x < user_max_x; x++)
    {
      y = 0;
      if(FindesICol(5,x,y))
        ForbudteKolonner[x] = -1;
      else
        ForbudteKolonner[x] = x;
    }

    int start;
    if(SkemaType == 0)
      start = 4;
    else
      start = 0;

    for(int i = start; i < 7 && LagteLektionerGem <= PlanlagteLektioner-blok; i++)
    {
      //en værdi vælges som der ønskes byttet på skemaet for at få frie lektioner.!
      vaerdi = VaerdiGrad[i];
      for(int n = 0; n < user_max_x; n++)
      {
        //hvis det ikke er en kolonne der indeholder 5.
        if(ForbudteKolonner[n] != -1)
        {
          x = ForbudteKolonner[n];
          ok = true;
          for(y = 0; y < user_max_y && ok; y++)
          {
            //hvis en tilsvarende værdi findes på skemaet forsøges den at
            //blive byttet med hvilket som helst felt på skemaet.
            if(Askema[x][y] == vaerdi && BytBestemtFelt(x, y))
            {
              comm << "danner fri lektion i";
              LagteLektionerGem += blok;
              ok = false;
              ForbudteKolonner[n] = -1;
              if(PlanlagteLektioner == LagteLektionerGem)
                return true;
            }
          }
        }
      }
    }
    return false;
}//
//---------------------------bytte funktioner---------------------------------//
///Funktionen forsøger at bytte feltet angivet med koordinatet væk til
///et felt som den har mulighed for at bytte med beskrevet i bytteværdierne.
///Funktionen stopper i det øjeblik den har kunne bytte feltet angivet
///i koordinatet væk. Hvis dette sker returneres en sandhedsværdi.
bool AnalyseSkema::BytBestemtFelt(int fra_x, int fra_y)
{
    int til_x(0), til_y(0);

    if(KontrollerKoordinat(fra_x, fra_y) &&
       Askema[fra_x][fra_y] != 4 &&
       Askema[fra_x][fra_y] != 5 &&
       Askema[fra_x][fra_y] != 6)
    {
      int vaerdi = Askema[fra_x][fra_y];
      // - blok angiver om det er enkelt eller dobbelt lektioner!!
      if(LagteLektioner <= PlanlagteLektioner-blok)
      {
        //først byttes med frie 6 felter.!
        if(BytMed6Felter(vaerdi, fra_x, fra_y))
          return true;
        //der næst byttes med værdiens bytte værdier.! DVs det værdier som
        //der er mulighed for at bytte med.
        if(BytMedUdvalgteFelter(vaerdi, fra_x, fra_y,
                                BytteVaerdier[vaerdi-1],
                                BytteVaerdier[vaerdi-1][0]))
          return true;
      }
    }
    return false;
}//
///Funktionen forsøger at bytte en bestemt værdi fra et givent koordinat med
///en række bytte tal. FOr hvert enkelt felt på skemaet vurderes om dennes
///værdi tilhører bytte tallene. Hvis dette er tilfældet forsøges en bytning
///(antal = antallet af bytte værdier i arrayet "byttetal")
///Funktionen stopper dersom den har kunnet bytte feltet væk samt
///returnere herefter en sandhedsværdi.
bool AnalyseSkema::BytMedUdvalgteFelter(int vaerdi, int fra_x, int fra_y,
                                        int* byttetal, int antal)
{
    int til_x(0), til_y(0);
    while(til_y < user_max_y)
    {
      til_x = 0;
      while(til_x < user_max_x)
      {
        //alle bytte værdier gennemløbes for den enkelte koordinat.
        for(int i = 1; i < antal; i++)
        {
          //Hvis feltet er identisk med en af bytte værdierne
          if(Askema[til_x][til_y] == byttetal[i])
          {
            //hvis det kan lade sig gøre at bytte med det fundne felt.
            if(KanBytteForVaerdi(vaerdi, fra_x, fra_y, til_x, til_y))
            {
              //værdierne skiftes på de 2 felter
              Askema[fra_x][fra_y] = 4;
              Askema[til_x][til_y] += vaerdi; //regne regle: 7 + 1 = 8....
              //hvis skemaet er et dobbelt analyse skema opdateres på det gamle.
              if(SkemaType == 2)
              {
                GamleSkema->IndskrivDobbeltVaerdi(Askema[fra_x][fra_y], fra_x, fra_y);
                GamleSkema->IndskrivDobbeltVaerdi(Askema[til_x][til_y], til_x, til_y);
              }
              return true;
            }
          }
        }
        til_x++;
      }
      til_y++;
    }
    return false;
}//
///Funktionen forsøger at bytter en given værdi i et bestemt felt, med
///hvilken som helst felt med værdien 6. Funktionen stopper dersom den
///har fundet en som kan byttes samt returnere en sandhedsværdi herfor.
bool AnalyseSkema::BytMed6Felter(int vaerdi, int fra_x, int fra_y,
                                 int ikke_x, int ikke_y)
{
    int til_x(0), til_y(0);

    //sålænge der findes et felt med værdien 6
    while(NaesteVaerdi(6, til_x, til_y))
    {
      //hvis værdien kan byttess med det fundne 6 felt.
      if(til_x != ikke_x && til_y != ikke_y &&
         KanBytteForVaerdi(vaerdi, fra_x, fra_y, til_x, til_y))
      {
        //felternes værdier byttes om.
        Askema[fra_x][fra_y] = 4;
        Askema[til_x][til_y] = vaerdi;
        //hvis det er et dobbelt analyse skema opdateres det gamle.
        if(SkemaType == 2)
        {
          GamleSkema->IndskrivDobbeltVaerdi(Askema[fra_x][fra_y], fra_x, fra_y);
          GamleSkema->IndskrivDobbeltVaerdi(Askema[til_x][til_y], til_x, til_y);
        }
        return true;
      }
      til_y++;
    }
    return false;
}//
//---------------------------------Lægge funktion-----------------------------//
///Funktionen forsøger at lægge det antal lektioner som mangler at blive lagt
///i alle felter med værdien 4. Hvis funktionen opnår at lægge alle dem som
///mangler stopper den og returnere en sandhedsværdi. Det bør nævnes at
///funktionen kræver at alle felter med 4 forinden er blevet vurderet således
///at der kun er dem tilbage hvor der kan ligge nogen faglektioner...!!
///NB: funktionen kan lægge for både dobbelt og enkelt lektioner.
///LL angiver det antal som lægges under processen.
bool AnalyseSkema::LaegFagLektioner(int& LL)
{
    int x(0), y(0);

    for(y = 0; y < user_max_y; y++)
    {
      for(x = 0; x < user_max_x && LagteLektioner <= PlanlagteLektioner-blok; x++)
      {
        //hvis en 4 felt findes.
        if(Askema[x][y] == 4 )
        {
          LagteLektioner += blok;
          //fag lektione lægges alt efter blokken.
          for(int i = 0; i < blok; i++)
          {
            Port->OpretOgLaegLektion(HoldID, FagID, LaererID, LokaleID, blok, x, y+i);
            LL++;
          }

          //hvis det er et HLP eller et HLPL skema.
          if(SkemaType < 2)
            for(int i = 0; i < blok; i++)
              Askema[x][y+i] = 5;
          //hvis det er et dobbelt analyse skema.
          else
          {
            Askema[x][y] = 5;
            GamleSkema->Askema[x][y] = 5;
            GamleSkema->Askema[x][y+1] = 5;
          }
          if(LagteLektioner == PlanlagteLektioner)
            return true;
        }
      }
    }
    return false;
}//
//-------------------------------Søge funktioner------------------------------//
///Funktionen alle ikke egnede frie (4) lektioner på skemaet, således at der
///kun er dem tilbage hvorpå der kan ligge en dobbelt lektion.
///Funktionen forudsætter at alle frie felter der ligger i kolonner med
///faglektioner har fået ændret deres værdi til 6.!
void AnalyseSkema::FjernIkkeEgnedeDobbeltFagLektioner()
{
    int x(0), y(0);

    while(x < user_max_x)
    {
      y = 0;
      //sålænge der findes 4 i kolonnen.
      while(y < user_max_y && FindesICol(4, x, y))
      {
        //hvis det er en dobbelt lektion.
        if(y < user_max_y-1 && Askema[x][y+1] == 4)
        {
          //resten af 4 felterne i kolonnen ændres til 6 felter.
          AendreVaerdiICol(4, 6, x, y+2);
          //der skippes videre til næste kolonne.!
          y = user_max_y-1;
        }
        //hvis det er en enkelt fri lektion, ændres denne til 6 og der forsættes
        //i samme kolonne.
        else
          Askema[x][y] = 6;
        y++;
      }
      x++;
    }
}//
///Funktionen fjerne alle ikke egnede frie felter som ikke kan benyttes til
///enkelt lektioner. Det forudsættes at alle frie lektioner der ligger i
///kolonner med fag lektioner har fået ændret deres værdi til 6.
void AnalyseSkema::FjernIkkeEgnedeEnkeltFagLektioner()
{
    int x(0), y(0);
    while(x < user_max_x)
    {
      //det første 4 felt i hver kolonne bibeholdes. resten ændres til 6.
      if(FindesICol(4, x, y))
        AendreVaerdiICol(4, 6, x, y+1);
      x++;
      y = 0;
    }
}//
///Funktionen ændre de frie felter som ligger på kolonner med faglektioner
///til værdien 6. Det forudsættes at der forinden er søgt efter de faglektioner
///som måtte eksistere på skemaet.
void AnalyseSkema::FindFrieFagLektioner()
{
    int x(0), y(0);
    for(x = 0; x < user_max_x; x++)
    {
      //alle 4 felter ændres til 6 hvis 5 eksistere i kolonnen.
      if(FindesICol(5, x, y))
        AendreVaerdiICol(4, 6, x, 0);
      y = 0;
    }
}//
///Funktionen lokalisere faglektioner på skemaet i henholdsvis felter med
///¨værdien 10 eller 3. HVis et felt er en fag lektion ændres dens værdi til 5.
void AnalyseSkema::FindFagLektioner()
{
    int x(0), y(0), FagLektion(0), count(0);
    if(SkemaType == 0)
      FagLektion = 3;
    else
      FagLektion = 10;

    while(NaesteVaerdi(FagLektion, x, y))
    {
      //hvis det er en fag lektion...
      if(Port->ErFagLektion(HoldID, FagID, x, y))
      {
         Askema[x][y] = 5;
         count++;
      }
      y++;
    }
    //Hvis det er et HLPL skema forsøges det at finde faglektioner også
    //i felter med værdien 3. Dette skyldes at det lokale ID'et kan skifte
    //fra gang til gang.
    if(SkemaType == 1)
    {
      FagLektion = 3; //idet lokalet kan svinge i en HLPL relation.
      x = 0; y = 0;
      while(NaesteVaerdi(FagLektion, x, y))
      {
        if(Port->ErFagLektion(HoldID, FagID, x, y))
        {
           Askema[x][y] = 5;
           count++;
        }
        y++;
      }
	}
    TidligereLagt = count;
}//
///Funktionen finder koordinatet på givne søgte værdi.
///Man kan sætte det koordinat som søgningen skal starte fra v.h.a
///det overførte koordinat.
bool AnalyseSkema::NaesteVaerdi(int vaerdi, int& x, int& y)
{
    if(y > user_max_y)
      y = 0;
    if(y == user_max_y)
    {
      x++;
      y = 0;
    }

    if(KontrollerKoordinat(x, y) && KontrollerVaerdi(vaerdi))
    {
      while(x < user_max_x)
      {
        while(y < user_max_y)
        {
          if(Askema[x][y] == vaerdi)
            return true;
          y++;
        }
        x++;
        y = 0;
      }
    }
    return false;
}//
//----------------------------access funktion---------------------------------//
///Funktionen optæller antallet af en bestemt værdi på skemaet.
int AnalyseSkema::AntalAfVaerdi(const int& vaerdi)
{
    int i = 0;
    int x(0), y(0);
    while(NaesteVaerdi(vaerdi, x, y))
    {
      i++;
      y++;
    }
    return i;
}//
///Funktionen ændre alle felter med en given værdi i en bestemt kolonne.
void AnalyseSkema::AendreVaerdiICol(int fra_vaerdi, int til_vaerdi, int x, int y)
{
    for(y = y; y < user_max_y; y++)
      if(Askema[x][y] == fra_vaerdi)
        Askema[x][y] = til_vaerdi;
}//
///Funktionen indskriver en bestemt vætdi i et givent koordinat.
void AnalyseSkema::IndskrivVaerdi(int vaerdi, int x, int y)
{
    if(vaerdi >= 0 && vaerdi <= 10 &&
       x < user_max_x && x >= 0 &&
       y < user_max_y && y >= 0)
      Askema[x][y] = vaerdi;
}//
///FUnktionen indskriver en dobbelt lektion på skemaet.
void AnalyseSkema::IndskrivDobbeltVaerdi(int vaerdi, int x, int y)
{
    Askema[x][y] = vaerdi;
    Askema[x][y+1] = vaerdi;
}//
//----------------------------kontrol funktioner------------------------------//
///Funktionen vurdere om et felt er en den første del af en dobbelt lektion i et
///givent koordinat.
bool AnalyseSkema::ErVaerdiDobbeltLektion(int vaerdi, int x, int y)
{
    if(vaerdi == 5)
      return true;
    else if(y < user_max_y-1 && Askema[x][y+1] == vaerdi)
    {
      switch(vaerdi)
      {
        case 1:
          return Port->ErLektionDobbelt(HoldID, 'h',x, y);
        case 2:
          return Port->ErLektionDobbelt(LaererID, 'l',x, y);
        case 3:
          return(Port->ErLektionDobbelt(HoldID,'h', x, y) &&
                 Port->ErLektionDobbelt(LaererID, 'l', x, y));
        case 4:
        case 6:
          return true;
        case 7:
          return Port->ErLektionDobbelt(LokaleID, 'k',x, y);
        case 8:
          return(Port->ErLektionDobbelt(HoldID, 'h', x, y) &&
                 Port->ErLektionDobbelt(LokaleID, 'k', x, y));
        case 9:
          return(Port->ErLektionDobbelt(LokaleID, 'k', x, y) &&
                 Port->ErLektionDobbelt(LaererID, 'l',x, y));
        case 10:
          return(Port->ErLektionDobbelt(LokaleID, 'k',x, y) &&
                 Port->ErLektionDobbelt(HoldID, 'h', x, y) &&
                 Port->ErLektionDobbelt(LaererID, 'l', x, y));
      }
    }
    return false;
}//
///Funktionen vurdere om lektionerne i 2 givne koordinater kan byttes.
///Hvis de kan det byttes de.... Bytningen foretages udfra den givne værdi.
///Hvis bytningen har fundet sted returneres en sandhedsværdi.
bool AnalyseSkema::KanBytteForVaerdi(int vaerdi, int fra_x, int fra_y,
                                     int til_x, int til_y)
{
    bool ok = false;
    switch(vaerdi)
    {
      case 5:
        if(SkemaType == 0)
          vaerdi = 3;
        else
          return false; //vaerdi = 10;
      case 1:
        return Port->VurderOgBytLektion(HoldID, blok, 'h', fra_x, fra_y, til_x, til_y);
      case 2:
        return Port->VurderOgBytLektion(LaererID, blok, 'l',fra_x, fra_y, til_x, til_y);
      case 3:
        ok = (Port->VurderBytningAfLektion(HoldID, blok, 'h', fra_x, fra_y,
                                             til_x, til_y) &&
              Port->VurderBytningAfLektion(LaererID, blok, 'l', fra_x,
                                             fra_y, til_x, til_y));
        if(ok)
        {
          Port->BytLektion(HoldID, blok, 'h', fra_x, fra_y, til_x, til_y);
          Port->BytLektion(LaererID, blok, 'l', fra_x, fra_y, til_x, til_y);
        }
        return false;
      case 7:
        return Port->VurderOgBytLektion(LokaleID, blok, 'k', fra_x, fra_y,
                                          til_x, til_y);
      case 8:
        ok = (Port->VurderBytningAfLektion(HoldID, blok, 'h',fra_x, fra_y,
                                                 til_x, til_y) &&
              Port->VurderBytningAfLektion(LokaleID, blok, 'k', fra_x, fra_y,
                                             til_x, til_y));
        if(ok)
        {
          Port->BytLektion(HoldID, blok, 'h', fra_x, fra_y, til_x, til_y);
          Port->BytLektion(LokaleID, blok, 'k', fra_x, fra_y, til_x, til_y);
          return true;
        }
        return false;
      case 9:
        ok = (Port->VurderBytningAfLektion(LokaleID, blok, 'k', fra_x,
                                             fra_y, til_x, til_y) &&
              Port->VurderBytningAfLektion(LaererID, blok, 'l', fra_x,
                                             fra_y, til_x, til_y));
        if(ok)
        {
          Port->BytLektion(LokaleID, blok, 'k', fra_x, fra_y, til_x, til_y);
          Port->BytLektion(LaererID, blok, 'l', fra_x, fra_y, til_x, til_y);
          return true;
        }
        return false;
      case 10:
        ok = (Port->VurderBytningAfLektion(HoldID, blok, 'h', fra_x, fra_y,
                                             til_x, til_y) &&
              Port->VurderBytningAfLektion(LaererID, blok, 'l', fra_x, fra_y,
                                             til_x, til_y) &&
              Port->VurderBytningAfLektion(LokaleID, blok, 'k', fra_x, fra_y,
                                             til_x, til_y));
        if(ok)
        {
          Port->BytLektion(HoldID, blok, 'h', fra_x, fra_y, til_x, til_y);
          Port->BytLektion(LaererID, blok, 'l', fra_x, fra_y, til_x, til_y);
          Port->BytLektion(LokaleID, blok, 'k', fra_x, fra_y, til_x, til_y);
          return true;
        }
        return false;
    }
    return false;
}//
///Funktionen vurdere om en given værdi eksistere i en bestemt kolonne.
///Funktionen returnere en sandhedsværdi herfor samt koordinatet
///for den søgte værdi.
bool AnalyseSkema::FindesICol(int vaerdi, int x, int& y)
{
    if(y < 0 || y >= user_max_y)
      y = 0;

    if(vaerdi >= 0 && vaerdi <= 10 && x >= 0 && x < user_max_x)
    {
      while(y < user_max_y)
      {
        if(Askema[x][y] == vaerdi)
          return true;
        y++;
      }
    }
    y = 0;
    return false;
}//
///Funktionen kontrollere det overførte koordinat om det ligger indenfor
///de fastsatte grænser.
bool AnalyseSkema::KontrollerKoordinat(const int& x, const int& y)
{
    return y >= 0 && y < user_max_y && x >= 0 && x < user_max_x;
}//
///Funktionen kontrollere om værdien er god nok.
bool AnalyseSkema::KontrollerVaerdi(const int& vaerdi)
{
    return vaerdi >= 0 && vaerdi <= 10;
}//
//--------------------------Opret skema funktioner----------------------------//
///Funktionen laver et dobbelt analyse skema udfra et andet almindeligt skema.
void AnalyseSkema::LavDobbeltLektionsSkema(AnalyseSkema* a)
{
    GamleSkema = a; //en pointer til grundskemaet kopieres ind.

    for(int x = 0; x < user_max_x; x++)
    {
      for(int y = 0; y < user_max_y; y++)
      {
        if(ErVaerdiDobbeltLektion(Askema[x][y], x, y))
          Askema[x][y] = Askema[x][y];
        else
          Askema[x][y] = -1;
      }
    }
    SkemaType = 2;
}//
///Funktionen laver et HLP skema.
void AnalyseSkema::LavHLPSkema()
{
    bool HoldOk = false;
    bool LaererOk = false;

    for(int x = 0; x < user_max_x; x++)
    {
      for(int y = 0; y < user_max_y; y++)
      {
        HoldOk = Port->ErLektionTom(HoldID,'h',x, y);
        LaererOk = Port->ErLektionTom(LaererID, 'l', x, y);

        if(!HoldOk && !LaererOk)
          Askema[x][y] = 3;
        else if(!HoldOk)
          Askema[x][y] = 1;
        else if(!LaererOk)
          Askema[x][y] = 2;
      }
    }
    SkemaType = 0;
}//
///Funktionen laver et HLPL skema.-
void AnalyseSkema::LavHLPLSkema()
{
    bool HoldOk = false;
    bool LaererOk = false;
    bool LokaleOk = false;

    for(int x = 0; x < user_max_x; x++)
    {
      for(int y = 0; y < user_max_y; y++)
      {
        HoldOk = Port->ErLektionTom(HoldID, 'h', x, y);
        LaererOk = Port->ErLektionTom(LaererID, 'l', x, y);
        LokaleOk = Port->ErLektionTom(LokaleID, 'k', x, y);

        if(!HoldOk && !LaererOk && !LokaleOk)
          Askema[x][y] = 10;
        else if(!HoldOk && !LaererOk)
          Askema[x][y] = 3;
        else if(!LaererOk && !LokaleOk)
          Askema[x][y] = 9;
        else if(!HoldOk && !LokaleOk)
          Askema[x][y] = 8;
        else if(!HoldOk)
          Askema[x][y] = 1;
        else if(!LaererOk)
          Askema[x][y] = 2;
        else if(!LokaleOk)
          Askema[x][y] = 7;
      }
    }
    SkemaType = 1;
}//
//---------------------------udskrivs funktion--------------------------------//
ostream& operator <<(ostream& ud, const AnalyseSkema a)
{
    ud << "\t1\t2\t3\t4\t5" << endl;
    for (int y = 0; y < a.user_max_y; y++)
    {
      ud << endl << "t " << (y+1) << " :\t";
      for (int x = 0; x < a.user_max_x; x++)
        ud << a.Askema[x][y] << ": " << x <<","<< y <<"\t";
    }
    return ud;
}
//----------------------------------------------------------------------------//
///Konstruktør.
AnalyseSkema::AnalyseSkema(Portal* Port_, string HoldID_, string FagID_, string LaererID_,
                           string LokaleID_, int blok_, int PlanLagteLektioner_,
                           int user_max_x_, int user_max_y_)
{
    user_max_x = user_max_x_;
    user_max_y = user_max_y_;

    HoldID = HoldID_;
    FagID = FagID_;
    LaererID = LaererID_;
    LokaleID = LokaleID_;
    Port = Port_;
    blok = blok_;
    PlanlagteLektioner = PlanLagteLektioner_;
    LagteLektioner = 0;
    TidligereLagt = 0;
    SkemaType = 0;

    for (int i = 0; i < user_max_y ; i++)
      for (int j = 0; j < user_max_x; j++)
        Askema[j][i] = 4;

    //Mapning af de forskellige bytte værdier.
    BytteVaerdier[0][0] = 4;  // 1 => 2, 7, 9
    BytteVaerdier[0][1] = 2;
    BytteVaerdier[0][2] = 7;
    BytteVaerdier[0][3] = 9;
    BytteVaerdier[1][0] = 4;  // 2 => 1, 7, 8
    BytteVaerdier[1][1] = 1;
    BytteVaerdier[1][2] = 7;
    BytteVaerdier[1][3] = 8;
    BytteVaerdier[2][0] = 2;  // 3 => 7
    BytteVaerdier[2][1] = 7;
    BytteVaerdier[6][0] = 3;  // 7 => 1, 2
    BytteVaerdier[6][1] = 1;
    BytteVaerdier[6][2] = 2;
    BytteVaerdier[7][0] = 2;  // 8 => 2
    BytteVaerdier[7][1] = 2;
    BytteVaerdier[8][0] = 2;  // 9 => 1
    BytteVaerdier[8][1] = 1;
    BytteVaerdier[9][0] = 1;

    VaerdiGrad[0] = 10;
    VaerdiGrad[1] = 9;
    VaerdiGrad[2] = 8;
    VaerdiGrad[3] = 7;
    VaerdiGrad[4] = 3;
    VaerdiGrad[5] = 1;
    VaerdiGrad[6] = 2;
}//
///Copy kontruktør.
AnalyseSkema::AnalyseSkema(const AnalyseSkema& a)
{
    FagID = a.FagID;
    LaererID = a.LaererID;
    LokaleID = a.LokaleID;
    HoldID = a.HoldID;

    PlanlagteLektioner = a.PlanlagteLektioner;
    LagteLektioner = a.LagteLektioner;

    user_max_x = a.user_max_x;
    user_max_y = a.user_max_y;

    SkemaType = a.SkemaType;
    blok = a.blok;
    Port = a.Port;

    //skema kopieres.
    for(int x = 0; x < user_max_x; x++)
      for(int y = 0; y < user_max_y; y++)
        Askema[x][y] = a.Askema[x][y];

    //byttevaerdier kopieres.
    for(int x = 0; x < 11; x++)
      for(int y = 0; y < 4; y++)
        BytteVaerdier[x][y] = a.BytteVaerdier[x][y];

    //GradVaerdier kopieres.
    for(int i = 0; i < 7; i++)
      VaerdiGrad[i] = a.VaerdiGrad[i];
}//
//----------------------------------------------------------------------------//
