//---------------------------------------------------------------------------
//#include <vcl\vcl.h>
#pragma hdrstop
#include <conio.h>
#include "skema.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------Vurder funktioner--------------------------------//
///Funktionen vurdere om lektionen er tom og returnere en sandhedsværdi for det.
bool skema::VurderGrund(int col, int row)
{
    return(skema[col][row] == NULL);
}//
///Funktionen vurdere om den overførte lektion er identisk med lektionen på et
///givent sted på skemaet. Herefter returneres en sandhedsværdi.
bool skema::EnsLektion(const lektion& l, int col, int row)
{
	if(skema[col][row] != NULL)
      return skema[col][row]->EnsLektion(l.HoldID, l.FagID, l.LaererID, l.LokaleID, l.blokstoerrelse);
    return false;
}//
///Funktionen vurdere om den overførte lektion i form af attributter er identisk
///med lektionen på et givent sted på skemaet. Herefter returneres en sandhedsværdi.
bool skema::EnsLektion(const string& HoldID, const string& FagID, const string& LaererID,
						const string& LokaleID, const int blok, int col, int row)
{
    if(skema[col][row] != NULL)
      return skema[col][row]->EnsLektion(HoldID, FagID, LaererID, LokaleID, blok);
    return false;
}//
//-----------------------------Update funktioner------------------------------//
///Funktionen fjerner en lektion fra skemaet. Den sletter den ikke fra heapen.
void skema::SletLektion(int col, int row)
{
    skema[col][row] = NULL;
}//
///Funktionen lægger en pointer til en lektion på skemaet i et givent koordinat.
void skema::LaegLektion(lektion* Lptr, int col, int row)
{
	skema[col][row] = Lptr;
}//
///Funktionen bytter 2 pointere på skemaet med hinanden.
void skema::BytLektioner(int fra_col, int fra_row, int til_col, int til_row)
{
    dummy = skema[fra_col][fra_row];
    skema[fra_col][fra_row] = skema[til_col][til_row];
    skema[til_col][til_row] = dummy;
}//
///Funktionen flytter 1 pointere på skemaet over til et andet koordinat.
void skema::FlytLektion(int fra_col, int fra_row, int til_col, int til_row)
{
    skema[til_col][til_row] = skema[fra_col][fra_row];
    skema[fra_col][fra_row] = NULL;
}//
//-----------------------------access funktioner------------------------------//
///Funktionen returnere en given lektion i et bestemt koordinat via den referede
///lektion i kaldet. Funktionen giver udtryk for om der en lektion eller ej
///v.h.a den returnerede sandhedsværdi.
bool skema::HentLektion(lektion& lPtr, int col, int row)
{
    if(skema[col][row] != NULL)
    {
      lPtr = *skema[col][row];
      return true;
    }
    return false;
}//
///Funktionen laver en kopi af hver lektion over i en ny klasse kaldt
///"LektionsData", herefter fyldes disse kopier på den overførte stack.
bool skema::FyldSkemaPaaStack(stack<LektionsData*>& Stack)
{
    bool ok = false;

    for(int i = max_col-1; i >= 0; i--)
    {
      for(int j = max_row-1; j >= 0; j--)
      {
        if(skema[i][j] != NULL)
        {
          //speciel kopi tages af lektionen..
          StackData = new LektionsData(*skema[i][j], i, j);
          //kopien puttes på den overførte stack.
          Stack.push(StackData);
          ok = true;
        }
      }
    }
    return ok;
}//
//-----------------------------kontrol funktioner-----------------------------//
///Funktionen kontrollere om der ligger en dobbelt lektion med udgangpunkt i
///det overførte koordinat. Herefter returneres resultatet som en sandhedsværdi.
bool skema::ErDobbelt(int col, int row)
{
    if(!ErTom(col, row) && !ErTom(col, row + 1) &&
         skema[col][row]->blokstoerrelse == 2 &&
         skema[col][row + 1]->blokstoerrelse == 2 &&
         skema[col][row]->FagID == skema[col][row + 1]->FagID)
	    return true;
    return false;
}//
///Funktionen vurdere om skemaet har en tom lektion i det overførte koordinat.
bool skema::ErTom(int col, int row)
{
    return(skema[col][row] == NULL);
}//
//------------------------------Beregnings funktioner-------------------------//
///Funktionen optæller alle lektioner på skemaet, og returnere dette antal.
int skema::OptaelAlleLektioner()
{
    int count = 0;
    for(int i = 0; i < max_col; i++)
      for(int j = 0; j < max_row; j++)
        if(skema[i][j] != NULL)
          count++;
    return count;
}//
///Funktionen optæller alle mellem lektioner på skemaet, og returnere dette.
int skema::AntalMellemLektioner()
{
    int sum(0), row_gem(0), row(0);
    for(int col = 0; col < max_col; col++)
    {
      //tomme lektioner først på dagen skal ikke tælles med
      //f.eks hvis vedkommende møder tidligere den dag..
      if(skema[col][0] == NULL)
        FlereLektionerIKolonne(col, row);
      else
        row = 0;

      while(row < max_row)
      {
        if(skema[col][row] == NULL)
        {
          row_gem = row;
          if(FlereLektionerIKolonne(col, row+1))
            sum += (row - row_gem+1);
        }
        row++;
      }
    }
    return sum;
}//
///Funktionen vurdere om der er flere lektioner tilbage i en given kolonne.
///funktionen returnere inddirekte rækken hvor processen stopper!.
bool skema::FlereLektionerIKolonne(int col, int& row)
{
    for(row = row; row < max_row; row++)
      if(skema[col][row] != NULL)
        return true;
    return false;
}//
///Funktionen beregner og returnere variansen (CV%) af længden af de enkelte dage
///Helt tomme dage tæller ikke med.!
double skema::BeregnVarians()
{
    Varians V;
    int Tid(0);
    V.Nulstil();
    for(int col = 0; col < max_col; col++)
    {
      Tid = FindSidsteLektion(col);
      if(Tid == 0 && skema[col][0] != NULL || Tid > 0)
        V.Indsaet(FindSidsteLektion(col));
    }
    return V.BeregnVarians();
}//
///Funktionen finder række nummeret på den sidste lektion i en given kolonne.
int skema::FindSidsteLektion(int col)
{
    int row(0);
    for(row = max_row-1; skema[col][row] == NULL && row >= 0; row--);
    return  row;
}//
//-------------------------------Slet funktion--------------------------------//
///Funktionen sletter hele skemaet, hvorunder lektionerne frigives på heapen.
void skema::SletSkema(int type)
{
	for(int i = 0; i < max_col; i++)
    {
      for(int j = 0; j < max_row; j++)
      {
        if(skema[i][j] != NULL)
        {
          if(type == 1)
            delete skema[i][j];
          skema[i][j] = NULL;
        }
      }
    }
}//
//----------------------------Udskrivs funktion-------------------------------//
///Funktionen udskriver alle de lektioner som ligger på skemaet.!
void skema::Udskriv()
{
	for(int i = 0; i < max_col; i++)
      for(int j = 0; j < max_row; j++)
        if(skema[i][j] != NULL)
        {
          cout << i << "," << j << " ";
          skema[i][j]->udskriv();
        }
}//
//----------------------------------------------------------------------------//
///konstruktør
skema::skema(string ID_)
{
    ID = ID_;
    for(int i = 0; i < max_col; i++)
      for(int j = 0; j < max_row; j++)
        skema[i][j] = NULL;
}//
///default konstruktør
skema::skema()
{
    for(int i = 0; i < max_col; i++)
      for(int j = 0; j < max_row; j++)
        skema[i][j] = NULL;
}//
///delete konstruktør
skema::~skema()
{
    delete [] skema;
}//
//----------------------------------------------------------------------------//


