// $Source: /usr/local/SimSoft/Sfx3D/src/gts/gtstfk.cpp,v $
// $Revision: 1.2 $
// $Author: baum $
// $Date: 2001/11/29 15:18:10 $
//
// Login name of the user who locked the revision
// $Locker:  $
// Tag name used to checkout the file
// $Name: Release-14 $
// State assigned to revision
// $State: Exp $
//
//
// $Log: gtstfk.cpp,v $
// Revision 1.2  2001/11/29 15:18:10  baum
// -Realzeitsteuerung eingebaut
// -Handsteuerung eingebaut
//

/*** Windows headers ***/
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
//#include <winnt.h>
#endif /*WIN32*/

//#include <dos.h>
#include <stdio.h>

#include <time.h>
#include "math.h"
#include "gtsglob.h"
#include "gtsbst.h"
#include "gtstfk.h"


bool WarteZeit = false;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TimerGoOn (ClientData /*cl*/)
{
  WarteZeit = false;
}

unsigned typFahrkursListe::TFKArt (unsigned ATyp, unsigned ETyp)
{
  if (TFKLogischeBausteinePruefen (ATyp) && TFKLogischeBausteinePruefen (ETyp))
  return 3;

  if (TFKLogischeBausteinePruefen (ATyp))
  return 1;

  if (TFKLogischeBausteinePruefen (ETyp))
  return 2;

  return 0;
}  // Ende TFKArt

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typFahrkursListe::TFKEingliedern (typFahrkurs* zFahrkurs)
{
  FkursListe.append(*zFahrkurs);
  zFahrkurs->s_Nummer(FkursListe.Count());
}  //  TFKEingliedern

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool typFahrkursListe::TFKAnfangPruefen (unsigned ATyp, bool mitLogik)
{
  if ( (ATyp == tQuelle)         || (ATyp == tGasse)           ||
       (ATyp == tMaschine)       || (ATyp == tSammler)         ||
       (ATyp == tRegaleinheit)   || (ATyp == tKommissionierer) ||
       (ATyp == tAbstrakteRegaleinheit))
  return true;

  if (mitLogik)
    if ((ATyp == tRegalverwalter) || (ATyp == tNcPoolverwalter) ||
        (ATyp == tKomVerwalter)   || (ATyp == tFtsVerwalter))
    return true;

  return false;
}  // Ende TFKAnfangPruefen
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool typFahrkursListe::TFKEndePruefen (unsigned ETyp, bool mitLogik)
{
  if ( (ETyp == tSenke)          || (ETyp == tGasse)           ||
       (ETyp == tMaschine)       || (ETyp == tSammler)         ||
       (ETyp == tRegaleinheit)   || (ETyp == tKommissionierer) ||
       (ETyp == tAbstrakteRegaleinheit))
  return true;
 
  if (mitLogik)
    if ((ETyp == tRegalverwalter)|| (ETyp == tNcPoolverwalter) ||
        (ETyp == tKomVerwalter)  || (ETyp == tFtsVerwalter) )
    return true;

  return false;
}  // Ende TFKEndePruefen

bool typFahrkursListe::TFKLogischeBausteinePruefen (unsigned ETyp)
{
  if ( (ETyp == tKomVerwalter)   || (ETyp == tNcPoolverwalter) ||
       (ETyp == tRegalverwalter) || (ETyp == tFtsVerwalter) )
  return true;

  return false;
}  // Ende TFKLogischeBausteinePruefen

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool typFahrkursListe::TFKPruefen (typBaustein* zanfang, typBaustein* zende)
{
  bool found = false;
  if (!TFKAnfangPruefen(zanfang->i_BstTyp()))
  {
    Meld.Ausgabe (101, zanfang->i_BstNr());
    return found;
  }
  if (!TFKEndePruefen(zende->i_BstTyp()))
  {
    Meld.Ausgabe (102, zende->i_BstNr());
    return found;
  }

  switch (TFKArt(zanfang->i_BstTyp(), zende->i_BstTyp()))
  {
    case 0  : found = TFKSuchen (zanfang, zende) ? true : false;
              if (!found) Meld.Ausgabe (11, zanfang->i_BstNr(), zende->i_BstNr());
              break;
    case 1  : found = zanfang->TFKSuchenVonPoolZuBaustein (zanfang, zende); break;
    case 2  : found = zende->TFKSuchenVonBausteinZuPool   (zanfang, zende); break;
    case 3  : found = zanfang->TFKSuchenVonPoolZuPool     (zanfang, zende); break;
    default : break;
  } // ENDE switch
  return found;
}  //  TFKPruefen

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
typFahrkurs* typFahrkursListe::FahrkursErzeugen (typBaustein* zanfang, typBaustein* zende)
{
  typFahrkurs* ZFK = TFKSuchen (zanfang, zende);
  if (ZFK != NULL) TFKLoeschen (ZFK);

  TMP_Fahrkurs = NULL;
  TMP_Fahrkurs = new typFahrkurs();
  TMP_Fahrkurs->erzeugeStation (zanfang);
  zanfang->s_imFahrkurs(true);
  bool fkgefunden = zanfang->BildeFahrkurs(zende);
  zanfang->s_imFahrkurs(false);
  if (!fkgefunden)
  {
    delete TMP_Fahrkurs;
    return (typFahrkurs*) NULL;
  }
  return TMP_Fahrkurs;
}  // FahrkursErzeugen

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typFahrkursListe::TFKErzeugen (typBaustein* zanfang, typBaustein* zende)
{
  if (!TFKAnfangPruefen(zanfang->i_BstTyp()))
  {
    Meld.Ausgabe (101, zanfang->i_BstNr());
    return;
  }
  if (!TFKEndePruefen(zende->i_BstTyp()))
  {
    Meld.Ausgabe (102, zende->i_BstNr());
    return;
  }

  typFahrkurs *fkurs;
  switch (TFKArt(zanfang->i_BstTyp(), zende->i_BstTyp()))
  {
    case 0  : fkurs = FahrkursErzeugen (zanfang, zende);
              if (fkurs)
              {
                fkurs->ZeigeFahrkurs ();
                TFKEingliedern (fkurs);
              }
              else
              Meld.Ausgabe (104, zanfang->i_BstNr(), zende->i_BstNr());
              break;
    case 1  : zanfang->TFKErzeugenVonPoolZuBaustein (zanfang, zende); break;
    case 2  : zende->TFKErzeugenVonBausteinZuPool   (zanfang, zende); break;
    case 3  : zanfang->TFKErzeugenVonPoolZuPool     (zanfang, zende); break;
    default : break;
  } // ENDE switch
}  //  TFKErzeugen

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typFahrkursListe::TFKLoeschen (typFahrkurs* zFahrkurs)
{
  FkursListe.remove (*zFahrkurs);
  delete zFahrkurs;
}  //  TFKLoeschen

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typFahrkursListe::TFKmitBausteinLoeschen 
                       (typBaustein* zbstein, 
                        typBaustein* zfolgebstein)
{
  LCursor<typFahrkurs> zfkurs;
  for (zfkurs = FkursListe; zfkurs; zfkurs++)
  {
    if (zfkurs()->IstFahrkursmitBaustein (zbstein, zfolgebstein))
        TFKLoeschen (zfkurs());
  }
}  // ENDE TFKmitBausteinLoeschen                        

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
typFahrkurs* typFahrkursListe::TFKSuchen (typBaustein* zanfang, typBaustein* zende)
{
  LCursor<typFahrkurs> zfkurs;
  for (zfkurs = FkursListe; zfkurs; zfkurs++)
      if (zfkurs()->IstFahrkurs (zanfang, zende)) return zfkurs();
  return NULL;
}  // ENDE TFKSuchen

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typFahrkursListe::TFKZeigen (typBaustein* zanfang, typBaustein* zende)
{
  if (!TFKAnfangPruefen(zanfang->i_BstTyp()))
  {
    Meld.Ausgabe (101, zanfang->i_BstNr());
    return;
  }
  if (!TFKEndePruefen(zende->i_BstTyp()))
  {
    Meld.Ausgabe (102, zende->i_BstNr());
    return;
  }

  typFahrkurs *fkurs;
  switch (TFKArt(zanfang->i_BstTyp(), zende->i_BstTyp()))
  {
    case 0  : fkurs = TFKSuchen (zanfang, zende);
              if (fkurs) fkurs->ZeigeFahrkurs ();
              else
              Meld.Ausgabe(11, zanfang->i_BstNr(), zende->i_BstNr());
              break;
    case 1  : zanfang->TFKZeigenVonPoolZuBaustein (zanfang, zende); break;
    case 2  : zende->TFKZeigenVonBausteinZuPool   (zanfang, zende); break;
    case 3  : zanfang->TFKZeigenVonPoolZuPool     (zanfang, zende); break;
    default : break;
  } // ENDE switch
}  //  TFKZeigen

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool typFahrkursListe::TFKLesen (Ustring datname)
{
  int satznr = 2;
  unsigned fknr, bstnr, anzstation;
  bool OK = true;
  typFahrkurs* zFahrkurs;
  typBaustein* zStation;

  SFXToken tok;
  InputFile *fin;
  fin = new InputFile (datname.str());
  if (!tok.findSentence (satznr, *fin))
     Msg.Error ("typFahrkursListe::TFKLesen()",
                "Satznr. in TFK-Datei nicht vorhanden", satznr);
  tok.EndOfLine (*fin);

  while((OK) && (satznr != -999))
  {
    tok.nextToken (*fin);   satznr = atoi (tok());
    if (satznr > 0)
    {
      tok.nextToken (*fin);   fknr       = atoi (tok());
      tok.nextToken (*fin);   anzstation = atoi (tok());
      zFahrkurs = new typFahrkurs();
      for (unsigned zaehler = 1; (zaehler <= anzstation) && OK ; zaehler++)
      {
        tok.nextToken (*fin);   bstnr = atoi (tok());
        if (((zaehler % 10)== 0) && (zaehler < anzstation))
           tok.EndOfLine (*fin);
        zStation = BausteinListe->Suche(bstnr+LASTBSTNR);
        if (zStation)
        {
          if ((zaehler == 1) && (zStation->i_BstTyp() == tFtsVerwalter))
              zFahrkurs->s_FTSVerwalter(zStation);
          else
          zFahrkurs->erzeugeStation(zStation);
        }
        else
        {
          Meld.Ausgabe(12, bstnr+LASTBSTNR, fknr);
          OK = false;
        }
      }
      tok.EndOfLine (*fin);
      TFKEingliedern (zFahrkurs);

      if (!OK) TFKLoeschen (zFahrkurs);
    }
    else
    tok.EndOfLine (*fin);
  }
  fin->close();
  delete fin;
  return OK;
}  // TFKLesen

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typFahrkursListe::TFKSchreiben (Ustring datname)
{
  int satznr = 2;
  LCursor<typFahrkurs> zfkurs;
  ofstream fout (datname.str ());
  DateiKopfSchreiben (fout, "TFK");
  Write (fout, "%4d  %4d\n", 2, 0);
  Write (fout, "%d\n", -1);
  Write (fout, "%s\n", "-1 SatzNr");
  Write (fout, "%s\n", "-1    RoutenNr  Anzahl    Stationen der Transportroute:");
  Write (fout, "%d\n",  -1);

  for (zfkurs = FkursListe; zfkurs; zfkurs++)
  {
    satznr++;
    Write (fout, "%4d   ", satznr);
    zfkurs()->TFKSchreiben (fout);
  }
  DateiFussSchreiben (fout, "TFK");
  fout.close ();
}  // TFKSchreiben

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
typFahrkursListe::~typFahrkursListe ()
{
  while (!FkursListe.isEmpty())
         delete FkursListe.removeFirst();
}  // ENDE ~typFahrkursListe

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typFahrkurs::append (typFahrkurs& flist) 
{
  typBstZeiger* zhilfe;
  typBstZeiger* zbst1;
  typBstZeiger* zbst2;
    
  zbst1 = StationsListe.Last();
  zbst2 = flist.StationsListe.First();
  if (zbst1)
     if (zbst1->zBst == zbst2->zBst) delete flist.StationsListe.removeFirst();
  while (!flist.StationsListe.isEmpty())
  {
     zhilfe = flist.StationsListe.removeFirst();
     StationsListe.append(*zhilfe);
  }      
}  // ENDE append

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typFahrkurs::ZeigeFahrkurs ()
{
  LCursor<typBstZeiger> zhilfe;
  Ustring tmp ("put_win {Transportroute: ");
  GTSView->MySpace()->MySelection()->removeAll();
  GeoObject* zgeo;
  for (zhilfe = StationsListe; zhilfe(); zhilfe++)
  {
    zgeo = (GTSMAP.find (*(zhilfe()->zBst)));
    if (zgeo) GTSView->MySpace()->MySelection()->insert
                                  (*zgeo, Selection::SelBlue);
    zhilfe()->zBst->s_imFahrkurs (false);
    tmp += Ustring(zhilfe()->zBst->i_BstNr()) + ",";
  }
  GTSView->MySpace()->flushAllViews();
  tmp.delPart (tmp.len()-1, 1);
  tmp += Ustring("\n}");
  Tcl_Eval (GTSInterpreter, (char*)tmp.str());
  WarteZeit = true;
  Tk_CreateTimerHandler(1000, TimerGoOn, NULL);
  while (WarteZeit) Tcl_DoOneEvent (0);
}  // ENDE ZeigeFahrkurs

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typFahrkurs::erzeugeStation (typBaustein* zbst) 
{
  typBstZeiger* zhilfe;
  zhilfe = new typBstZeiger(zbst); 
  StationsListe.append(*zhilfe);
}  // ENDE erzeugeStation

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool typFahrkurs::IstFahrkurs (typBaustein* zanfang, typBaustein* zende)
{
  typBstZeiger* z1hilfe = StationsListe.First();
  typBstZeiger* z2hilfe = StationsListe.Last();
  return ((z1hilfe->zBst == zanfang) && (z2hilfe->zBst == zende));
}  // ENDE IstFahrkurs

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool typFahrkurs::IstFahrkursmitBaustein 
                  (typBaustein* zbstein, typBaustein* zfolgebstein)
{
  LCursor<typBstZeiger> zhilfe;
  for (zhilfe = StationsListe; zhilfe(); zhilfe++)
    if (zhilfe()->zBst == zbstein) break;
    
  if (zhilfe == NULL) return false;
  if (zfolgebstein == NULL) return true;
  zhilfe++;
  if (zhilfe)
     if (zhilfe()->zBst == zfolgebstein) return true;
  return false;
}  // ENDE IstFahrkursmitBaustein
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typFahrkurs::TFKSchreiben (ostream& ostrm)
{
  LCursor<typBstZeiger> zhilfe;
  typBstZeiger* zletztes;
  Write (ostrm, "%4d ", Nr);
  int anzstationen = StationsListe.Count();
  if (zaufFTSVerwalter) anzstationen++;
  Write (ostrm, "    %4d   ", anzstationen);
  if (zaufFTSVerwalter)
     Write (ostrm, "%4d ", zaufFTSVerwalter->i_BstNr());

  int zaehler = 1;
  zletztes = StationsListe.Last();
  for (zhilfe = StationsListe; zhilfe; zhilfe++, zaehler++)
  {
    Write (ostrm, "%4d ", zhilfe()->zBst->i_BstNr());
    if ((zhilfe() != zletztes) && ((zaehler % 10) == 0))
         Write (ostrm, "\n%s", "                 ");
  }
  Write (ostrm, "%s\n", "");
}  // TFKSchreiben

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
typFahrkurs::~typFahrkurs ()
{
  while (!StationsListe.isEmpty())
         delete StationsListe.removeFirst();
}  // ENDE ~typFahrkurs

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

