//---------------------------------------------------------------------------
#pragma hdrstop
#include "Portal.h"
//-----------------------------Afslutnings funktion---------------------------//
///Funktionen printer det skema som hører til ID'et indenfor typen
bool Portal::PrintSkema(const string& ID, char type)
{
	stack<LektionsData*>* ListeX = new stack<LektionsData*>;
    LektionsData* l;

    Export.NulstilTemp();
    SkemaKPtr->HentSkema(ID, ListeX, type);
    while(!ListeX->tom())
    {
      l = ListeX->pop();
      Export.IndsaetPaaPlan(l->HoldID, l->FagID, l->LaererID, l->LokaleID, l->col, l->row+1);
      delete l;
    }
    Export.SkemaTilPrinter(ID);
    delete ListeX;
    return true;
}//
///Funktionen exportere enten hold, lærer eller lokale skemaerne til en
///samlet fil.
bool Portal::GemSkemaerPaaFil(char type)
{
    stack<LektionsData*> Liste;
    LektionsData* l;
    bool ok = false;
    switch(type)
    {
	  case 'h': Export.Ny("HoldSkemaer");
        break;
      case 'l': Export.Ny("LaererSkemaer");
	    break;
      case 'k': Export.Ny("LokaleSkemaer");
        break;
    }

    SkemaKPtr->Reset(type);
    while(SkemaKPtr->HentNaesteSkema(Liste, type))
    {
      Export.NulstilTemp();
      while(!Liste.tom())
      {
        l = Liste.pop();
        Export.IndsaetPaaPlan(l->HoldID, l->FagID, l->LaererID, l->LokaleID, l->col, l->row+1);
      }
      if(ok)
      {
        switch(type)
        {
          case 'h': Export.SkemaTilFil("HoldSkemaer", l->HoldID, 'a');
           break;
          case 'l': Export.SkemaTilFil("LaererSkemaer", l->LaererID, 'a');
            break;
          case 'k': Export.SkemaTilFil("LokaleSkemaer", l->LokaleID, 'a');
            break;
        }
      }
    }
}//
///Funktionen gemme alt hvad der ligger af lektioner på holdskemerne til databasen,
///samt alle de prioriteter der ligger på lærenes skemaer.
bool Portal::GemSkemaer()
{
    Tid t, Total;
    double Tid(0);
    string HoldID, s;
    bool ok = true;
    stack<LektionsData*> Stack;
    LektionsData* l;

    //De gamle lektioner i databasen slettes.
    comm.NulstilSpecifikation("Gemning");
    ++Total;
    ++t;
    db->StartTransaction();
    if(Kilde == 'd')
    {
      s  = "delete from Lektion where PlanID_Le in (";
      s += "select PlanID_Le from Lektion where PlanID_Le = '" + PlanID + "')";
      if(!db->ExecSql(s))
      {
        db->Rollback();
        comm.FejlBox("Gamle lektioner kunne ikke slettes!");
        return false;
      }
      //Navnet på lektions tabellen som der skal indsættes i..!
      s = "Lektion";
    }
    else if(Kilde == 'f')
      s = "LektionsListeGem";
    --t;
    t >> Tid;
    comm.IndsaetISpecifikation(Tid, "Sletning af lektioner:", 1);

    SkemaKPtr->Reset('h');
    ++t;
    while(SkemaKPtr->HentNaesteSkema(Stack, 'h'))
    {
      while(!Stack.tom())
      {
        l = Stack.pop();
        db->IndsaetI(s);
        db->Indsaet(PlanID);
        db->Indsaet(l->HoldID);
        db->Indsaet(l->FagID);
        db->Indsaet(l->LaererID);
        db->Indsaet(l->LokaleID);
        db->Indsaet(l->Blok);
        db->Indsaet(l->col);
        db->Indsaet(l->row);
        ok = db->Indsaet();
        delete l;
        if(!ok)
        {
          db->Rollback();
          comm.FejlBox("Lektionerne kunne ikke gemmes");
          return false;
        }
      }
    }
    db->Commit();
    int* PSkema;
    --t;
    t >> Tid;
    comm.IndsaetISpecifikation(Tid, "Gemning af nye lektioner: ", 2);
    ++t;
    db->StartTransaction();
    if(Kilde == 'd')
    {
      //delete statement for sletning af prioriteteter
      s  = "delete from Tidsprioritet where PlanID_Ti in (";
      s += "select PlanID_Ti from Tidsprioritet where PlanID_Ti = '" + PlanID + "')";
      if(!db->ExecSql(s))
      {
        db->Rollback();
        comm.FejlBox("Gamle LektionsPrioriteter kunne ikke slettes");
        return false;
      }
     s = "Tidsprioritet";
    }
    else if(Kilde == 'f') s = "TidsPrioritetGem.txt";

    --t;
    t >> Tid;
    comm.IndsaetISpecifikation(Tid, "Sletning af Prioriteter: ", 3);
    ++t;

    ok = true;
    stack<PLektionsData*> PStack;
    string LaererID;
    PLektionsData* pl;
    SkemaKPtr->Reset('l');
    while(SkemaKPtr->HentNaestePSkema(PStack, LaererID))
    {
      if(!PStack.tom())
      {
        while(!PStack.tom() && ok)
        {
          pl = PStack.pop();
          db->IndsaetI(s);
          db->Indsaet(PlanID);
          db->Indsaet(LaererID);
          db->Indsaet(pl->Prio);
          db->Indsaet(pl->col);
          db->Indsaet(pl->row);
          ok = db->Indsaet();
          delete pl;
          if(!ok)
          {
            db->Rollback();
            comm.FejlBox("Lektions prioriteterne kunne ikke gemmes");
            return false;
          }
        }
      }
    }
    db->Commit();
    --t;
    t >> Tid;
    comm.IndsaetISpecifikation(Tid, "Gemning af nye Prioriteter: ", 4);
    --Total;
    Total >> Tid;
    comm.IndsaetISpecifikation(Tid, "Total: ", 5);
    return true;
}//
//-------------------------Initialiserings funktioner-------------------------//
//Funktionen benyttes førend alle skemaerne oprettes. Det er af disse stacks
//hvor navnene kommer fra...
void Portal::Initialisering(stack<string>* HoldListe_, stack<string>* LaererListe_,
                        stack<string>* LokaleListe_)
{
    HoldListe = HoldListe_;
    LaererListe = LaererListe_;
    LokaleListe = LokaleListe_;
}
//Funktionen styrer hele indlæsnings proceduren. DVS at hvad der har med
//oprettelse af skemaer samt indlæsning af lektioner at gøre. Denne kalder
//derfor "OpretAlleSkemaerFor" og "HentLektioner"
bool Portal::KlargoerOgHentSkemaer()
{
    return OpretAlleSkemaerFor('h') &&
           OpretAlleSkemaerFor('l') &&
           OpretAlleSkemaerFor('k') &&
           HentLektioner() &&
           HentPLektioner();
}//
///Funktionen henter fra databasen alle prioriteter ind og placere dem på
///lærere skemaerne.
bool Portal::HentPLektioner()
{
    string LaererID, s;
    int prio, col, row;
    bool ok = true;

    if(PlanID != "tom")
    {
      if(Kilde == 'd')
        s = ("select * from TidsPrioritet where PlanID_Ti = '" + PlanID + "'");
      else if(Kilde == 'f')
        s = "TidsPrioritet.txt";
      if(db->StartIndlaesning(s))
      {
        while(ok &&
              db->FindString(LaererID, "LaererID_Ti") &&
              db->FindInt(prio, "Prioritet_Ti") &&
              db->FindInt(col, "Kolonne_Ti") &&
              db->FindInt(row, "Raekke_Ti"))
        {
          SkemaKPtr->VurderOgLaegPLektion(LaererID, prio, col, row);
          ok = db->FindNaeste();
        }
        return true;
      }
    }
    return false;
}//
///Funktionen henter fra databasen alle lektioner ind, hvorefter disse placeres
///på de enkelte skemaer.!
bool Portal::HentLektioner()
{
    string s, HoldID, FagID, LaererID, LokaleID;
    int Blok, col, row;
    bool ok = true;
    if(PlanID != "tom")
    {
      if(Kilde == 'd')
        s  = ("select * from Lektion where PlanID_Le = '" + PlanID + "'");
      else if(Kilde == 'f')
        s = "LektionsListe.txt";

      if(db->StartIndlaesning(s))
      {
        while(ok &&
              db->FindString(HoldID, "HoldID_Le") &&
              db->FindString(FagID, "FagID_Le") &&
              db->FindString(LaererID, "LaererID_Le") &&
              db->FindString(LokaleID, "LokaleID_Le") &&
              db->FindInt(Blok, "Blokstoerrelse_Le") &&
              db->FindInt(col, "Kolonne_Le") &&
              db->FindInt(row,"Raekke_Le"))
        {
          SkemaKPtr->OpretOgLaegLektion(HoldID, FagID, LaererID, LokaleID, Blok, col, row);
          ok = db->FindNaeste();
          if(!ok)
          {
            return false;
          }
        }
        return true;
      }
    }
    return false;
}//
//----------------------------Opret funktion----------------------------------//
///Funktionen kontakter KontrolKlassen hvorefter navnene på de enkelte
///skemaer som skal oprettes returneres. Herefter oprettes skemaerne i planen.
bool Portal::OpretAlleSkemaerFor(char type)
{
    switch(type)
    {
      case 'h':
        while(!HoldListe->tom())
          SkemaKPtr->OpretSkema(HoldListe->pop(), type);
        return true;
      case 'l':
        while(!LaererListe->tom())
		  SkemaKPtr->OpretSkema(LaererListe->pop(), type);
        return true;
      case 'k':
        while(!LokaleListe->tom())
		  SkemaKPtr->OpretSkema(LokaleListe->pop(), type);
        return true;
    }
    return false;
}//
//-------------------------------Kontrol funktion-----------------------------//
///Funktionen konstrollere om alle hold lektionerne har tilsvarende lektioner
///ude på lokale og lærer skemaerne og omvendt. DVS at denne funktion
///kontrollere om der er gået noget galt med skemaerne så der er opstået
///fejl i skemaerne.
bool Portal::KontrollerSkemaer()
{
    int Gfejl(0);
    int fejl(0);
	SkemaKPtr->KontrollerSkemaer(fejl, 'h');
    Gfejl += fejl;
    cout << fejl << " ";
    fejl = 0;
    SkemaKPtr->KontrollerSkemaer(fejl, 'l');
    Gfejl += fejl;
    cout << fejl << " ";
    fejl = 0;
    SkemaKPtr->KontrollerSkemaer(fejl, 'k');
    Gfejl += fejl;
    cout << fejl << " ";
    fejl = 0;
    return Gfejl == 0;
}//
//----------------------------------------------------------------------------//
//----------------------------Skin funktioner---------------------------------//
//----------------------------------------------------------------------------//
bool Portal::HentSkema(const string& ID, stack<LektionsData*>*& Stack, char type)
{
    return SkemaKPtr->HentSkema(ID, Stack, type);
}
bool Portal::HentPSkema(stack<PLektionsData*>& Stack, const string& LaererID)
{
    return SkemaKPtr->HentPSkema(Stack, LaererID);
}
//----------------------------------------------------------------------------//
//Udskrivs funktioner
void Portal::UdskrivAlleSkemaer()
{	SkemaKPtr->UdskrivAlleSkemaer();
}
void Portal::UdskrivSkema(const string& ID, char type)
{	SkemaKPtr->UdskrivSkema(ID, type);
}
void Portal::UdskrivPSkema(const string& ID)
{
	SkemaKPtr->UdskrivPSkema(ID);
}
void Portal::SletAlt()
{	SkemaKPtr->SletAlt();
}
//----------------------------------------------------------------------------//
//Optællings funktioner
double Portal::BeregnVariansFor(const string& ID, char type)
{
	return SkemaKPtr->BeregnVariansFor(ID, type);
}
int Portal::BeregnTotaleLagteLektioner()
{
	return SkemaKPtr->BeregnTotaleLagteLektioner();
}

int Portal::AntalMellemLektioner()
{
    return SkemaKPtr->AntalMellemLektioner();
}
int Portal::LagteFagLektioner(string HoldID, string FagID)
{	return SkemaKPtr->LagteFagLektioner(HoldID, FagID);
}
int Portal::SkemalagteLektioner(string ID, char type)
{	return SkemaKPtr->SkemalagteLektioner(ID, type);
}
int Portal::LagtePLektioner(string LaererID)
{
    return SkemaKPtr->LagtePLektioner(LaererID);
}
//----------------------------------------------------------------------------//
//access funktioner
bool Portal::ErLektionTom(string ID, char type, int col, int row)
{	return SkemaKPtr->ErLektionTom(ID, type, col, row);
}
bool Portal::ErFagLektion(string HoldID, string FagID, int col, int row)
{	return SkemaKPtr->ErFagLektion(HoldID, FagID, col, row);
}
bool Portal::ErLektionDobbelt(string ID, char type,int col, int row)
{	return SkemaKPtr->ErLektionDobbelt(ID, type, col, row);
}
//----------------------------------------------------------------------------//
//Opret funktioner
bool Portal::VurderOgLaegPLektion(string LaererID, int prioritet, int col, int row)
{	return SkemaKPtr->VurderOgLaegPLektion(LaererID, prioritet, col, row);
}
void Portal::OpretOgLaegLektion(string HoldID, string FagID, string LaererID,
								string LokaleID, int blok, int col, int row)
{	SkemaKPtr->OpretOgLaegLektion(HoldID, FagID, LaererID, LokaleID, blok, col, row);
}
//----------------------------------------------------------------------------//
//Byt funktioner
void Portal::BytLektion(string ID, int blok, char type, int fra_col, int fra_row,
                             int til_col, int til_row)
{	SkemaKPtr->BytLektion(ID, type, fra_col, fra_row, til_col, til_row);
}
bool Portal::VurderBytningAfLektion(string ID, int blok,  char type, int fra_col,
                                         int fra_row, int til_col, int til_row)
{	return SkemaKPtr->VurderBytningAfLektion(ID, blok, type, fra_col, fra_row, til_col, til_row);
}

bool Portal::VurderOgBytLektion(string ID, int blok,  char type, int fra_col,
                                     int fra_row, int til_col, int til_row)
{	return SkemaKPtr->VurderOgBytLektion(ID, blok, type, fra_col, fra_row, til_col, til_row);
}
//----------------------------------------------------------------------------//
//Konstruktør
Portal::Portal(const string PlanID_, int col, int row, char Kilde_ )
{
    PlanID = PlanID_;
    SkemaKPtr = new SkemaKontrol(col, row);
    db = new SqlKlasse(Kilde_);
    Kilde = Kilde_;
    max_col = col;
    max_row = row;
}
//destructor
Portal::~Portal()
{
    delete SkemaKPtr;
    delete db;
}
//----------------------------------------------------------------------------//
