//---------------------------------------------------------------------------
#pragma hdrstop
#include "SkemaKontrol.h"
//-----------------------portal bytte funktioner------------------------------//
bool SkemaKontrol::VurderOgBytLektion(string ID, int blok, char type, int fra_col,
                              int fra_row, int til_col, int til_row)
{
	return BytInitialiser(ID, blok, type, fra_col, fra_row, til_col, til_row, 'u');
}
bool SkemaKontrol::VurderBytningAfLektion(string ID, int blok, char type, int fra_col,
                                  int fra_row, int til_col, int til_row)
{
	return BytInitialiser(ID, blok, type, fra_col, fra_row, til_col, til_row, 'v');
}

bool SkemaKontrol::BytInitialiser(string ID, int blok, char type, int fra_col,
                                  int fra_row, int til_col, int til_row, char form)
{
    fra.indsaet(fra_col, fra_row);
    til.indsaet(til_col, til_row);
    if(!KontrollerKoordinat(fra, blok) && !KontrollerKoordinat(til, blok))
      return false;

    switch(type)
    {
      case 'h':
        if(HS.HentSkema(ID, s.Hskema))
        {
          if(s.Hskema->HentLektion(lPtr, fra_col, fra_row))
          {
            if(lPtr.HoldID == ID && lPtr.blokstoerrelse == blok)
            {
              if(LS.HentSkema(lPtr.LaererID, s.Lskema) && LOS.HentSkema(lPtr.LokaleID, s.LOskema))
              {
                if(blok == 2 && !ErDobbeltLektion(s, fra))
                  return false;
                if(s.Hskema->HentLektion(lPtr2, til_col, til_row))
                {
                  s2.Hskema = s.Hskema;
                  if(lPtr2.HoldID == ID && lPtr2.blokstoerrelse == blok)
                  {
                    if(LS.HentSkema(lPtr2.LaererID, s2.Lskema) && LOS.HentSkema(lPtr2.LokaleID, s2.LOskema))
                    {
                      if(blok == 2 && !ErDobbeltLektion(s2, til))
                        return false;
                      else
                        return BytningAfLektion(lPtr, lPtr2, s, s2, fra, til, form);
                    }
                  }
                }
                else
                  return FlytningAfLektion(lPtr, s, fra, til, lPtr.blokstoerrelse, form);
              }
            }
          }
        }
        break;
      case 'l':
        if(LS.HentSkema(ID, s.Lskema))
        {
          if(s.Lskema->HentLektion(lPtr, fra_col, fra_row))
          {
            if(lPtr.LaererID == ID && lPtr.blokstoerrelse == blok)
            {
              if(HS.HentSkema(lPtr.HoldID, s.Hskema) && LOS.HentSkema(lPtr.LokaleID, s.LOskema))
              {
                if(blok == 2 && !ErDobbeltLektion(s, fra))
                  return false;
                 //if(LS.HentSkema(ID, s.Lskema))

                  if(s.Lskema->HentLektion(lPtr2, til_col, til_row))
                  {
                    s2.Lskema = s.Lskema;
                    if(lPtr2.LaererID == ID && lPtr2.blokstoerrelse == blok)
                    {
                      if(HS.HentSkema(lPtr2.HoldID, s2.Hskema) && LOS.HentSkema(lPtr2.LokaleID, s2.LOskema))
                      {
                        if(blok == 2 && !ErDobbeltLektion(s2, til))
                          return false;
                        else
                          return BytningAfLektion(lPtr, lPtr2, s, s2, fra, til, form);
                      }
                    }
                  }
                
                else
                  return FlytningAfLektion(lPtr, s, fra, til, lPtr.blokstoerrelse, form);
              }
            }
          }
        }
        break;
      case 'k':
        if(LOS.HentSkema(ID, s.LOskema))
        {
          if(s.LOskema->HentLektion(lPtr, fra_col, fra_row))
          {
            if(lPtr.LokaleID == ID && lPtr.blokstoerrelse == blok)
            {
              if(LS.HentSkema(lPtr.LaererID, s.Lskema) && HS.HentSkema(lPtr.HoldID, s.Hskema))
              {
                if(blok == 2 && !ErDobbeltLektion(s, fra))
                  return false;
                 //if(LOS.HentSkema(ID, s.LOskema))
                
                  if(s.LOskema->HentLektion(lPtr2, til_col, til_row))
                  {
                    s2.LOskema = s.LOskema;
                    if(lPtr2.LokaleID == ID && lPtr2.blokstoerrelse == blok)
                    {
                      if(LS.HentSkema(lPtr2.LaererID, s2.Lskema) && HS.HentSkema(lPtr2.HoldID, s2.Hskema))
                      {
                        if(blok == 2 && !ErDobbeltLektion(s2, til))
                          return false;
                        else
                          return BytningAfLektion(lPtr, lPtr2, s, s2, fra, til, form);
                      }
                    }
                  }

                else
                  return FlytningAfLektion(lPtr, s, fra, til, lPtr.blokstoerrelse, form);
              }
            }
          }
        }
        break;
    }
    return false;
    /*
    bool ErTom = false;
    fra.indsaet(fra_col, fra_row);
    til.indsaet(til_col, til_row);
    //Er den første lektion ikke tom..
    if(Initialiser(ID, lPtr, s1, type, fra_col, fra_row, ErTom))
    {
      if(lPtr.blokstoerrelse == blok)
      {
        //Er anden lektion ikke tom.
        if(Initialiser(ID, lPtr2, s2, type, til_col, til_row, ErTom) &&
           KontrollerKoordinat(til, lPtr.blokstoerrelse) &&
           KontrollerKoordinat(fra, lPtr2.blokstoerrelse))
        {
          //Byt lektioner.!
          if(lPtr2.blokstoerrelse == blok)
            return BytningAfLektion(lPtr, lPtr2, s1, s2, fra, til, form);
          else
            return false;
        }
        //Anden lektioner er tom, første er ikke.!
        else if(ErTom && KontrollerKoordinat(til, lPtr.blokstoerrelse))
          return FlytningAfLektion(lPtr, s, fra, til, lPtr.blokstoerrelse, form);
      }
      else return false;
    }
    //Hvis den første er tom, mens den anden ikke er det.
    else if(ErTom && Initialiser(ID, lPtr2, s2, type, til_col, til_row, ErTom) &&
            KontrollerKoordinat(fra, lPtr2.blokstoerrelse) &&
            lPtr2.blokstoerrelse == blok)
      return FlytningAfLektion(lPtr2, s2, til, fra, lPtr2.blokstoerrelse, form);
    return false;  */
}
void SkemaKontrol::BytLektion(string ID, char type, int fra_col, int fra_row,
                      int til_col, int til_row)
{
    fra.indsaet(fra_col, fra_row);
    til.indsaet(til_col, til_row);
    switch(type)
    {
      case 'h':                
        if(HS.HentSkema(ID, s.Hskema))
        {
          if(s.Hskema->HentLektion(lPtr, fra_col, fra_row))
          {
            //if(lPtr.HoldID == ID && lPtr.blokstoerrelse == blok)
            {
              if(LS.HentSkema(lPtr.LaererID, s.Lskema) && LOS.HentSkema(lPtr.LokaleID, s.LOskema))
              {
                //if(HS.HentSkema(ID, s.Hskema))

                  s2.Hskema = s.Hskema;
                  if(s2.Hskema->HentLektion(lPtr2, til_col, til_row))
                  {
                    //if(lPtr2.HoldID == ID && lPtr2.blokstoerrelse == blok)
                    {
                      if(LS.HentSkema(lPtr2.LaererID, s2.Lskema) && LOS.HentSkema(lPtr2.LokaleID, s2.LOskema))
                      {
                        //if(blok == 2 && !ErDobbeltLektion(s2, til))
                          //return false;
                        //else
                          BytLektion(lPtr, lPtr2, s, s2, fra, til);
                      }
                    }
                  }
                
                else
                  FlytLektion(lPtr, s, fra, til, lPtr.blokstoerrelse);
              }
            }
          }
        }
        break;
      case 'l':
        if(LS.HentSkema(ID, s.Lskema))
        {
          if(s.Lskema->HentLektion(lPtr, fra_col, fra_row))
          {
            //if(lPtr.LaererID == ID && lPtr.blokstoerrelse == blok)
            {
              if(HS.HentSkema(lPtr.HoldID, s.Hskema) && LOS.HentSkema(lPtr.LokaleID, s.LOskema))
              {
                //if(blok == 2 && !ErDobbeltLektion(s, fra))
                  //return false;
                //if(LS.HentSkema(ID, s.Lskema))

                  if(s.Lskema->HentLektion(lPtr2, til_col, til_row))
                  {
                    //if(lPtr2.LaererID == ID && lPtr2.blokstoerrelse == blok)
                    {
                      if(HS.HentSkema(lPtr2.HoldID, s2.Hskema) && LOS.HentSkema(lPtr2.LokaleID, s2.LOskema))
                      {
                        //if(blok == 2 && !ErDobbeltLektion(s2, til))
                          //return false;
                        //else
                          BytLektion(lPtr, lPtr2, s, s2, fra, til);
                      }
                    }
                  }

                else
                  FlytLektion(lPtr, s, fra, til, lPtr.blokstoerrelse);
              }
            }
          }
        }
        break;
      case 'k':
        if(LOS.HentSkema(ID, s.LOskema))
        {
          if(s.LOskema->HentLektion(lPtr, fra_col, fra_row))
          {
            //if(lPtr.LokaleID == ID && lPtr.blokstoerrelse == blok)
            {
              if(LS.HentSkema(lPtr.LaererID, s.Lskema) && HS.HentSkema(lPtr.HoldID, s.Hskema))
              {
                //if(blok == 2 && !ErDobbeltLektion(s, fra))
                  //return false;
                //if(LOS.HentSkema(ID, s.LOskema))

                  s2.LOskema = s.LOskema;
                  if(s2.LOskema->HentLektion(lPtr2, til_col, til_row))
                  {
                    //if(lPtr2.LokaleID == ID && lPtr2.blokstoerrelse == blok)
                    {
                      if(LS.HentSkema(lPtr2.LaererID, s2.Lskema) && HS.HentSkema(lPtr2.HoldID, s2.Hskema))
                      {
                        //if(blok == 2 && !ErDobbeltLektion(s2, til))
                          //return false;
                        //else
                          BytLektion(lPtr, lPtr2, s, s2, fra, til);
                      }
                    }
                  }

                else
                  FlytLektion(lPtr, s, fra, til, lPtr.blokstoerrelse);
              }
            }
          }
        }
        break;
    }
   //eturn false;
    /*bool ErTom = false;
    fra.indsaet(fra_col, fra_row);
    til.indsaet(til_col, til_row);
    if(Initialiser(ID, lPtr, s1, type, fra_col, fra_row, ErTom))
    {
      if(Initialiser(ID, lPtr2, s2, type, til_col, til_row, ErTom))
        BytLektion(lPtr, lPtr2, s1, s2, fra, til);
      else if(ErTom)
        FlytLektion(lPtr, s1, fra, til, lPtr.blokstoerrelse);
    }
    else if(ErTom && Initialiser(ID, lPtr2, s2, type, til_col, til_row, ErTom))
      FlytLektion(lPtr2, s2, til, fra, lPtr2.blokstoerrelse);  */
}
//----------------------------------------------------------------------------//
bool SkemaKontrol::BytningAfLektion(const lektion& lPtr1, const lektion& lPtr2,
                            const SkemaPtr& s1, const SkemaPtr& s2,
							const koord& fra, const koord& til,
                            char vType)
{
    int n ;
    //Kan ikke bytte en enkel lektion med en dobbelt.
   /* if(lPtr1.blokstoerrelse == 2 && !ErDobbeltLektion(s1, fra) ||
       lPtr1.blokstoerrelse == 1 && ErDobbeltLektion(s1, fra) ||
       lPtr2.blokstoerrelse == 2 && !ErDobbeltLektion(s2, til) ||
       lPtr2.blokstoerrelse == 1 && ErDobbeltLektion(s2, til))
      return false;
    if(lPtr1.blokstoerrelse == 2 && fra.col == til.col && fra.row == til.row+1 ||
       lPtr2.blokstoerrelse == 2 && fra.col == til.col && til.row == fra.row+1)
      return false;  */

    SletLektion(s2, til, lPtr2.blokstoerrelse);
    if(FlytningAfLektion(lPtr1, s1, fra, til, lPtr1.blokstoerrelse, 'v')) //kun vurder
    {
      LaegLektion(lPtr2, s2, til, lPtr2.blokstoerrelse);
      SletLektion(s1, fra, lPtr1.blokstoerrelse);
      if(FlytningAfLektion(lPtr2, s2, til, fra, lPtr2.blokstoerrelse, vType))
      {
        if(vType == 'u')      //vurder og derefter byt
          LaegLektion(lPtr1, s1, til, lPtr1.blokstoerrelse);  //lPtr2 er flyttet helt!
        else if(vType == 'v') //vurder kun
          LaegLektion(lPtr1, s1, fra, lPtr1.blokstoerrelse);
        return true;
      }
      LaegLektion(lPtr1, s1, fra, lPtr1.blokstoerrelse);
    }
    LaegLektion(lPtr2, s2, til, lPtr2.blokstoerrelse);
    return false;
}
void SkemaKontrol::BytLektion(const lektion& lPtr1, const lektion& lPtr2, const SkemaPtr& s1,
                      const SkemaPtr& s2, const koord& fra, const koord& til)
{
    /* SletLektion(s1, fra, lPtr1.blokstoerrelse);
     SletLektion(s2, til, lPtr2.blokstoerrelse);
     LaegLektion(lPtr1, s1, til, lPtr1.blokstoerrelse);
     LaegLektion(lPtr2, s2, fra, lPtr2.blokstoerrelse);  */
     for(int i = 0; i < lPtr2.blokstoerrelse; i++)
      {
        //NB: Man må ikke skifte lektioner 2 gange på et skema.. Derfor
        //tages der højde for dette v.h.a if sætningerne
        if(s1.Hskema != s2.Hskema)
          s2.Hskema->BytLektioner(fra.col, fra.row+i, til.col, til.row+i);
        s1.Hskema->BytLektioner(fra.col, fra.row+i, til.col, til.row+i);
        if(s1.Lskema != s2.Lskema)
          s2.Lskema->BytLektioner(fra.col, fra.row+i, til.col, til.row+i);
        s1.Lskema->BytLektioner(fra.col, fra.row+i, til.col, til.row+i);
        if(s1.LOskema != s2.LOskema)
          s2.LOskema->BytLektioner(fra.col, fra.row+i, til.col, til.row+i);
        s1.LOskema->BytLektioner(fra.col, fra.row+i, til.col+i, til.row+i);
      }
}
//----------------------------------------------------------------------------//
bool SkemaKontrol::FlytningAfLektion(const lektion& lPtr, const SkemaPtr& s,
							 const koord& fra, const koord& til,
                             int blok, char vType)
{
    SletLektion(s, fra, blok);
    if(ErLektionTom(s, til, blok))
    {
      if(VurderLektion(lPtr, s, til, blok))
      {
        if(vType == 'u') //vurder og flyt
          LaegLektion(lPtr, s, til, blok);
        else if(vType == 'v') //vurder kun!
          LaegLektion(lPtr, s, fra, blok);
        return true;
      }
    }
    LaegLektion(lPtr, s, fra, blok);
    return false;
}
void SkemaKontrol::FlytLektion(const lektion& lPtr, const SkemaPtr& s, const koord& fra,
                       const koord& til, int blok)
{
	/*SletLektion(s, fra, blok);
    LaegLektion(lPtr, s, til, blok); */
   for(int i = lPtr.blokstoerrelse-1 ; i >= 0; i--)
    {
      s.Hskema->FlytLektion(fra.col, fra.row+i, til.col, til.row+i);
      s.Lskema->FlytLektion(fra.col, fra.row+i, til.col, til.row+i);
      s.LOskema->FlytLektion(fra.col, fra.row+i, til.col, til.row+i);
    }  
}
//-----------------------------opret funktioner-------------------------------//
bool SkemaKontrol::OpretOgLaegLektion(string HoldID, string FagID, string LaererID,
                              string LokaleID, int blok, int col, int row)
{
    lPtr.udskriv();
    lPtr.indsaet(HoldID, FagID, LaererID, LokaleID, blok);

    if(HentSkemaPtr(lPtr))
    {
      k.indsaet(col, row);
      LaegLektion(lPtr, s, k, 1);
      return true;
    }
    return false;
}
bool SkemaKontrol::VurderOgLaegPLektion(string LaererID, int prioritet, int col, int row)
{
	if(KontrollerKoordinat(col, row))
      if(LS.HentSkema(LaererID, s.Lskema))
        return s.Lskema->LaegPLektion(prioritet, col, row);
    return false;
}
bool SkemaKontrol::OpretSkema(const string& ID, char type)
{
    //cout << ID;
    switch(type)
    {
	  case 'h': //hold
        return HS.NytSkema(ID);
        break;
      case 'l': //laerer
        return LS.NytSkema(ID);
        break;
      case 'k': //lokale
        return LOS.NytSkema(ID);
        break;
    }
    return false;
}
//-----------------------------Asscess funktioner-----------------------------//
bool SkemaKontrol::HentSkema(const string& ID, stack<LektionsData*>* Stack, char type)
{
    switch(type)
    {
      case 'h':
        if(HS.HentSkema(ID, s.Hskema))
        {
          s.Hskema->FyldSkemaPaaStack(*Stack);
          return true;
        }
        break;
      case 'l':
        if(LS.HentSkema(ID), s.Lskema)
        {
          s.Lskema->FyldSkemaPaaStack(*Stack);
          return true;
        }
        break;
      case 'k':
        if(LOS.HentSkema(ID, s.LOskema))
        {
          s.LOskema->FyldSkemaPaaStack(*Stack);
          return true;
        }
        break;
    }
    return false;
}
bool SkemaKontrol::HentNaesteSkema(stack<LektionsData*>& Stack, char type)
{
    switch(type)
    {
      case 'h':
        if(HS.HentNaesteSkema(s.Hskema))
        {
          s.Hskema->FyldSkemaPaaStack(Stack);
          return true;
        }
        break;
      case 'l':
        if(LS.HentNaesteSkema(s.Lskema))
        {
          s.Lskema->FyldSkemaPaaStack(Stack);
          return true;
        }
        break;
      case 'k':
        if(LOS.HentNaesteSkema(s.LOskema))
        {
          s.LOskema->FyldSkemaPaaStack(Stack);
          return true;
        }
        break;
    }
    return false;
}
bool SkemaKontrol::HentNaestePSkema(stack<PLektionsData*>& Stack, string& LaererID)
{
    if(LS.HentNaesteSkema(s.Lskema))
    {
      LaererID = s.Lskema->ID;
      s.Lskema->HentPSkema(Stack);
      return true;
    }
    return false;
}
bool SkemaKontrol::HentPSkema(stack<PLektionsData*>& Stack, const string& LaererID)
{
    if(LS.HentSkema(LaererID, s.Lskema))
    {
      s.Lskema->HentPSkema(Stack);
      return true;
    }
    return false;
}
//--------------------------------access funktioner---------------------------//
void SkemaKontrol::SletAlt()
{
	HS.SletAlt(1);
    LS.SletAlt(0);
    LOS.SletAlt(0);
}
void SkemaKontrol::Reset(char type)
{
    switch(type)
    {
      case 'h': HS.reset();
        break;
      case 'l': LS.reset();
        break;
      case 'k': LOS.reset();
        break;
    }
}
bool SkemaKontrol::ErLektionTom(string ID, char type, int col, int row)
{
    if(KontrollerKoordinat(col, row))
    {
      switch(type)
      {
        case 'h': //hold
          if(HS.HentSkema(ID, s.Hskema))
            return s.Hskema->ErTom(col, row);
          break;
        case 'l': //laerer
          if(LS.HentSkema(ID, s.Lskema))
            return s.Lskema->ErTom(col, row);
          break;
        case 'k': //lokale
          if(LOS.HentSkema(ID, s.LOskema))
            return s.LOskema->ErTom(col, row);
          break;
      }
    }
    return false;
}
bool SkemaKontrol::ErFagLektion(string HoldID, string FagID, int col, int row)
{
    if(HS.FindSkema(HoldID) && KontrollerKoordinat(col, row))
      if(HS.HentSkema(HoldID, s.Hskema))
        s.Hskema->ErFagLektion(FagID, col, row);
    return false;
}
bool SkemaKontrol::ErLektionDobbelt(string ID, char type, int col, int row)
{
    bool ErTom = false;
    if(KontrollerKoordinat(col, row))
    {
      k.indsaet(col, row);
      if(Initialiser(ID, lPtr, s, type, col, row, ErTom))
        return ErDobbeltLektion(s, k);
    }
    return false;
}
//--------------------------Initialiserings funktioner------------------------//
bool SkemaKontrol::Initialiser(string ID, lektion& Ptr, SkemaPtr& s, char type, int col, int row, bool& ErTom)
{
    ErTom = false;
    switch(type)
    {
      case 'h': //hold
        if(HS.HentSkema(ID, s.Hskema))
        {
          if(s.Hskema->HentLektion(Ptr, col, row))
            return LS.HentSkema(Ptr.LaererID, s.Lskema) &&
                   LOS.HentSkema(Ptr.LokaleID, s.LOskema) &&
                   GodkendLektion(Ptr, s, col, row);
          else
          {
            ErTom = true;
            return false;
          }
        }
        break;
      case 'l': //laerer
        if(LS.HentSkema(ID, s.Lskema))
        {
          if(s.Lskema->HentLektion(Ptr, col, row))
            return HS.HentSkema(Ptr.HoldID, s.Hskema) &&
                   LOS.HentSkema(Ptr.LokaleID, s.LOskema) &&
                   GodkendLektion(Ptr, s, col, row);
          else
          {
            ErTom = true;
            return false;
          }
        }
        break;
      case 'k': //lokale
        if(LOS.HentSkema(ID, s.LOskema))
        {
          if(s.LOskema->HentLektion(Ptr, col, row))
            return HS.HentSkema(Ptr.HoldID, s.Hskema) &&
                   LS.HentSkema(Ptr.LaererID, s.Lskema) &&
                   GodkendLektion(Ptr, s, col, row);
          else
          {
            ErTom = true;
            return false;
          }
        }
        break;
    }
    return false;
}
bool SkemaKontrol::GodkendLektion(const lektion& Ptr, const SkemaPtr& s, int col, int row)
{
	return s.Hskema->EnsLektion(Ptr, col, row) &&
           s.Lskema->EnsLektion(Ptr, col, row) &&
           s.LOskema->EnsLektion(Ptr, col, row);
}

//---------------------------basis funktioner---------------------------------//
bool SkemaKontrol::HentLektion(lektion& Ptr, const SkemaPtr& s, const koord& k)
{
    if(!s.Hskema->HentLektion(Ptr, k.col, k.row))
      if(!s.Lskema->HentLektion(Ptr, k.col, k.row))
        if(!s.LOskema->HentLektion(Ptr, k.col, k.row))
          return false;
    return true;
}
bool SkemaKontrol::VurderLektion(const lektion& ptr, const SkemaPtr& s, const koord& k,
                         int blok)
{
    bool ok = true;
    int i;
    for(i = 0; i < blok && ok; i++)
      ok = (s.Hskema->Vurder(ptr, k.col, k.row+i) &&
            s.Lskema->Vurder(k.col, k.row+i) &&
            s.LOskema->Vurder(k.col, k.row+i));
    if(ok && i == blok)
      return true;
    return false;
}
bool SkemaKontrol::HentSkemaPtr(const lektion& ptr)
{
    return LOS.HentSkema(ptr.LokaleID, s.LOskema) &&
           LS.HentSkema(ptr.LaererID, s.Lskema) &&
           HS.HentSkema(ptr.HoldID, s.Hskema);
}
void SkemaKontrol::LaegLektion(const lektion& ptr, const SkemaPtr& s,
                       const koord& k, int blok)
{
    for(int i = 0; i < blok; i++)
      s.Hskema->LaegLektion(ptr, *s.Lskema, *s.LOskema, k.col, k.row+i);
}
void SkemaKontrol::SletLektion(const SkemaPtr& s, const koord& k, int blok)
{

    for(int i = 0; i < blok; i++)
    {
      //lektionen hentes op, så den kan slettes rigtigt efter at den
      //er blevet fjernet på skemaerne!
      s.Hskema->SletLektion(k.col, k.row+i);
      s.Lskema->SletLektion(k.col, k.row+i);
      s.LOskema->SletLektion(k.col, k.row+i);
    }
}
//-----------------------Optællingsberegnings funktioner----------------------//
int SkemaKontrol::BeregnTotaleLagteLektioner()
{
	int sum(0);
    HS.reset();
    while(HS.HentNaesteSkema(s.Hskema))
      sum += s.Hskema->OptaelAlleLektioner();
    return sum;
}
double SkemaKontrol::BeregnVariansFor(const string& ID, char type)
{
    switch(type)
    {
      case 'h':
        if(HS.HentSkema(ID, s.Hskema))
          return s.Hskema->BeregnVarians();
        break;
      case 'l':
        if(LS.HentSkema(ID, s.Lskema))
          return s.Lskema->BeregnVarians();
        break;
      case 'k':
        if(LOS.HentSkema(ID, s.LOskema))
          return s.LOskema->BeregnVarians();
        break;
    }
    return 0;
}
double SkemaKontrol::TotaleVarians()
{
    Varians V;
    V.Nulstil();
    HS.reset();
    while(HS.HentNaesteSkema(s.Hskema))
      V.Indsaet(s.Hskema->BeregnVarians());
    return V.BeregnVarians();
}
int SkemaKontrol::AntalMellemLektioner()
{
    int sum(0);
    HS.reset();
    while(HS.HentNaesteSkema(s.Hskema))
      sum += s.Hskema->AntalMellemLektioner();
    return sum;
}
int SkemaKontrol::SkemalagteLektioner(string ID, char type)
{
	switch(type)
    {
      case 'h': //Hold
        if(HS.HentSkema(ID, s.Hskema))
          return s.Hskema->OptaelAlleLektioner();
        break;
      case 'l': //Laerer
        if(LS.HentSkema(ID, s.Lskema))
          return s.Lskema->OptaelAlleLektioner();
        break;
      case 'k': //lokaler
        if(LOS.HentSkema(ID, s.LOskema))
          return s.LOskema->OptaelAlleLektioner();
        break;
    }
    return 0;
}
int SkemaKontrol::LagteFagLektioner(string HoldID, string FagID)
{
	if(HS.HentSkema(HoldID, s.Hskema))
      return s.Hskema->OptaelFagLektion(FagID);
	return 0;
}
int SkemaKontrol::LagtePLektioner(string LaererID)
{
   if(LS.HentSkema(LaererID, s.Lskema))
      return s.Lskema->OptaelPrioriteredeLektioner();
    return 0;
}
//------------------------------kontrol funktioner----------------------------//
bool SkemaKontrol::KontrollerSkemaer(int& fejl, char type)
{
    stack<LektionsData*> Stack;
    LektionsData* l;
    fejl = 0;
    switch(type)
    {
      case 'h':
        HS.reset();
        while(HS.HentNaesteSkema(s.Hskema))
          s.Hskema->FyldSkemaPaaStack(Stack);
        break;
      case 'l':
        LS.reset();
        while(LS.HentNaesteSkema(s.Lskema))
          s.Lskema->FyldSkemaPaaStack(Stack);
        break;
      case 'k':
        LOS.reset();
        while(LOS.HentNaesteSkema(s.LOskema))
          s.LOskema->FyldSkemaPaaStack(Stack);
        break;
    }

    while(!Stack.tom())
    {
      l = Stack.pop();

      switch(type)
      {
        case 'h':
          if(!HS.HentSkema(l->HoldID)->EnsLektion(l->HoldID, l->FagID,
             l->LaererID, l->LokaleID, l->Blok, l->col, l->row))
            fejl++;
          break;
        case 'l':
          if(!LS.HentSkema(l->LaererID)->EnsLektion(l->HoldID, l->FagID,
             l->LaererID, l->LokaleID, l->Blok, l->col, l->row))
            fejl++;
          break;
        case 'k':
          if(!LOS.HentSkema(l->LokaleID)->EnsLektion(l->HoldID, l->FagID,
             l->LaererID, l->LokaleID, l->Blok, l->col, l->row))
            fejl++;
          break;
      }
      delete l;
    }
    return fejl == 0;

}
bool SkemaKontrol::ErDobbeltLektion(const SkemaPtr& s, const koord& k)
{
    return(s.Hskema->ErDobbelt(k.col, k.row) &&
           s.Lskema->ErDobbelt(k.col, k.row) &&
           s.LOskema->ErDobbelt(k.col, k.row));
}
bool SkemaKontrol::ErLektionTom(const SkemaPtr& s, const koord& k, int blok)
{
    bool ok = true;
    int i;
    for(i = 0; ok && i < blok; i++)
      ok = (s.Hskema->ErTom(k.col, k.row+i) &&
            s.Lskema->ErTom(k.col, k.row+i) &&
            s.LOskema->ErTom(k.col, k.row+i));

    if(ok && i == blok)
      return true;
    return false;
}
//---------------------------Kontrol af Koordinater---------------------------//
bool SkemaKontrol::KontrollerKoordinat(const koord& k, const int& blok)
{
    bool ok = true;
    int i;
    for(i = 0; ok && i < blok; i++)
	 ok = (k.col >= 0 && k.col < user_max_col &&
           k.row+i >= 0 && k.row+i < user_max_row);

    if(ok && i == blok)
      return true;
    else
      return false;
}
inline bool SkemaKontrol::KontrollerKoordinat(const koord& k)
{
	return(k.col >= 0 && k.col < user_max_col && k.row >= 0 && k.row < user_max_row);
}
inline bool SkemaKontrol::KontrollerKoordinat(const int& col, const int& row)
{
	return(col >= 0 && col < user_max_col && row >= 0 && row < user_max_row);
}
//------------------------------Udskrivs funktioner---------------------------//
void SkemaKontrol::UdskrivAlleSkemaer()
{
	HS.Udskriv();
    getch();
    LS.Udskriv();
    getch();
    LOS.Udskriv();
}
void SkemaKontrol::UdskrivSkema(const string& ID, char type)
{
    cout << ID << endl;
    switch(type)
    {
      case 'h': HS.HentSkema(ID)->Udskriv();
        break;
      case 'l': LS.HentSkema(ID)->Udskriv();
        break;
      case 'k': LOS.HentSkema(ID)->Udskriv();
        break;
    }
}
void SkemaKontrol::UdskrivPSkema(const string& ID)
{
	if(LS.FindSkema(ID))
      LS.HentSkema(ID)->UdskrivPSkema();
}
//----------------------------------------------------------------------------//
//konstruktør
SkemaKontrol::SkemaKontrol(int user_max_col_, int user_max_row_)
{
    if(user_max_col_ <= max_col && user_max_col_ >= 0 &&
       user_max_row_ <= max_row && user_max_row_ >= 0)
    {
	  user_max_col = user_max_col_;
      user_max_row = user_max_row_;
    }
    else
    {
      user_max_col = max_col;
      user_max_row = max_row;
    }
    count = 0;
}
//----------------------------------------------------------------------------//
/* bool SkemaKontrol::VurderOgSletLektion(string ID, int blok, char type, int col, int row)
{
    k.indsaet(col, row);
    if(KontrollerKoordinat(k, blok))
    {
      if(Initialiser(ID, lPtr, s, type, col, row))
      {
        SletLektion(s, k, blok);
        return true;
      }
    }
    return false;
}   */
//------------------------------flyt funktioner-------------------------------//
/*
bool SkemaKontrol::VurderOgFlytLektion(string ID, int blok, char type, int fra_col,
                               int fra_row, int til_col, int til_row)
{
    fra.indsaet(fra_col, fra_row);
    til.indsaet(til_col, til_row);
    if(KontrollerKoordinat(fra, blok) && KontrollerKoordinat(til, blok))
      if(Initialiser(ID, type, fra_col, fra_row))
        return FlytningAfLektion(lPtr, s, fra, til, blok, 'u');
    return false;
}
bool SkemaKontrol::VurderFlytningAfLektion(string ID, int blok, char type, int fra_col,
                                   int fra_row, int til_col, int til_row)
{
    fra.indsaet(fra_col, fra_row);
    til.indsaet(til_col, til_col);
    if(KontrollerKoordinat(fra, blok) && KontrollerKoordinat(til, blok))
      if(Initialiser(ID, type, fra_col, fra_row))
        return FlytningAfLektion(lPtr, s, fra, til, blok, 'v');
    return false;
}
void SkemaKontrol::FlytLektion(string ID, int blok, char type, int fra_col, int fra_row,
                       int til_col, int til_row)
{
    fra.indsaet(fra_col, fra_row);
    til.indsaet(til_col, til_row);
    //if(KontrollerKoordinat(fra, blok) && KontrollerKoordinat(til, blok))//kan fjernes
      if(Initialiser(ID, type, fra_col, fra_row))
        FlytLektion(s, fra, til, blok);
}    */
/*bool SkemaKontrol::OpretVurderOgLaegLektion(string HoldID, string FagID, string LaererID,
							        string LokaleID, int blok, int col, int row)
{
    k.indsaet(col, row);
    if(KontrollerKoordinat(k, blok))
    {
      lPtr.indsaet(HoldID, FagID, LaererID, LokaleID, blok);
      HentSkemaPtr(lPtr);
      if(VurderLektion(lPtr, s, k, blok))
      {
        LaegLektion(lPtr, s, k, blok);
        return true;
      }
    }
    return false;
}
bool SkemaKontrol::VurderLaegningAfLektion(string HoldID, string FagID, string LaererID,
							        string LokaleID, int blok, int col, int row)
{
    k.indsaet(col, row);
    if(KontrollerKoordinat(k, blok))
    {
      lPtr.indsaet(HoldID, FagID, LaererID, LokaleID, blok);
      HentSkemaPtr(lPtr);
      return VurderLektion(lPtr, s, k, blok);
    }
    return false;
}
*/









