// $Source: /usr/local/SimSoft/Sfx3D/src/gts/gtstbv.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: gtstbv.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 "gtsglob.h"
#include "gtsbst.h"
#include "gtstbv.h"
#include "gtstfk.h"

typVerkettung::typVerkettung () :
   EingangsListe(),
   AusgangsListe(),
   imFahrkurs(false)
{ };

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typVerkettung::LoeseEingangsVerkettung (typBaustein* zbst)
{
  typBstVerkettung* zhilfe = SucheBstInEingangsListe (zbst);
  if (zhilfe) delete EingangsListe.remove (*zhilfe);
}  // ENDE LoeseEingangsVerkettung

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typVerkettung::LoeseAusgangsVerkettung (typBaustein* zbst)
{
  typBstVerkettung* zhilfe = SucheBstInAusgangsListe (zbst);
  if (zhilfe) delete AusgangsListe.remove (*zhilfe);
}  // ENDE LoeseEingangsVerkettung

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typVerkettung::BstLoeseVerkettung (typBaustein* zvonbst)
{
  LoeseAusgangsVerkettung (zvonbst);
  zvonbst->LoeseEingangsVerkettung ((typBaustein*)this);
  FahrkursListe->TFKmitBausteinLoeschen ((typBaustein*)this, zvonbst);  
}  // ENDE BstLoeseVerkettung

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typVerkettung::BstVerketten (int vonplatz, typBaustein* zmitbst, 
                                 int mitplatz, int unterwinkel)
{
  cout<<"1"<<endl;
  if (!pruefeTBVEingabe (((typBaustein*)this)->i_BstTyp(), zmitbst->i_BstTyp()))
      return;
  
  if (SucheBstInAusgangsListe (zmitbst))
  {
    cout<<"2"<<endl;
    Meld.Ausgabe(49, ((typBaustein*)this)->i_BstNr(), zmitbst->i_BstNr());
    return;
  }  
  cout<<"3"<<endl;
  AusgangVerketten (zmitbst, vonplatz, mitplatz, unterwinkel);
  zmitbst->EingangVerketten (((typBaustein*)this), vonplatz, mitplatz, unterwinkel);    

//  io_w_string ("Pruefe_und_verkette_ftsknoten", "%s\n");
/*    
    GES.CON:  ftsnetztypset = [tftseinbahnstrecke..tftsendstrecke];
          if verketten then pruefe_und_verkette_ftsknoten
                                                (zbaustein, zobjekt, vonplatz,
                                                 mitplatz, unterwinkel);
*/
}  // ENDE BstVerketten                             

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typVerkettung::EingangVerketten (typBaustein* zvonbst, 
                               int vonplatz, int mitplatz, int unterwinkel)
{
  typBstVerkettung* zhilfe;
  zhilfe = new typBstVerkettung(zvonbst, vonplatz, mitplatz, unterwinkel); 
  EingangsListe.append(*zhilfe);
}  // ENDE EingangVerketten

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typVerkettung::AusgangVerketten (typBaustein* zmitbst, 
                               int vonplatz, int mitplatz, int unterwinkel)
{
  typBstVerkettung* zhilfe;
  zhilfe = new typBstVerkettung(zmitbst, vonplatz, mitplatz, unterwinkel); 
  AusgangsListe.append(*zhilfe);
}  // ENDE AusgangVerketten

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
typBstVerkettung* typVerkettung::SucheBstInEingangsListe (typBaustein* zbstein)
{
  LCursor<typBstVerkettung> zhilfe;
  for (zhilfe = EingangsListe; zhilfe; zhilfe++)
     if (zhilfe()->zBst == zbstein) return zhilfe();
  return NULL;
}  // ENDE SucheBstInEingangsListe 

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
typBstVerkettung* typVerkettung::SucheBstInAusgangsListe (typBaustein* zbstein)
{
  LCursor<typBstVerkettung> zhilfe;
  for (zhilfe = AusgangsListe; zhilfe; zhilfe++)
     if (zhilfe()->zBst == zbstein) return zhilfe();
  return NULL;
}  // ENDE SucheBstInAusgangsListe 

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typVerkettung::TBVSchreiben (ostream& ostrm,
                                  typBaustein* zbstein, int& satznr)
{
  LCursor<typBstVerkettung> zhilfe;
  for (zhilfe = AusgangsListe; zhilfe; zhilfe++)
  {
    satznr++;
    Write (ostrm, "%4d  ", satznr);
    Write (ostrm, "%4d  ", zbstein->i_BstNr());
    Write (ostrm, "%4d  ", zhilfe()->i_vonPlatz());
    Write (ostrm, "%4d  ", zhilfe()->zBst->i_BstNr());
    Write (ostrm, "%4d  ", zhilfe()->i_mitPlatz());
    Write (ostrm, "%4d    ", zhilfe()->i_unterWinkel());
    Write (ostrm, "%s;\n", zbstein->getName().str());
  }
}  // ENDE TBVSchreiben

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool typVerkettung::EndeFahrkurs (const typBaustein* zende)
{
  LCursor<typBstVerkettung> zhilfe;
  for (zhilfe = AusgangsListe; zhilfe; zhilfe++)
      if (zhilfe()->zBst == zende) break;
      
  if (zhilfe == NULL) return false;
  
  FahrkursListe->TMP_Fahrkurs->erzeugeStation (zhilfe()->zBst);
  zhilfe()->zBst->s_imFahrkurs(true);
  return true;
}  // ENDE EndeFahrkurs

bool typVerkettung::PruefeEndeFahrkurs (int btyp)
{
   if ((btyp == tGasse)               || (btyp == tMaschine)             ||
       (btyp == tSammler)             || (btyp == tRegaleinheit)         ||
       (btyp == tKommissionierer)     || (btyp == tFtsEinbahnstrecke)    ||
       (btyp == tFtsZweibahnstrecke)  || (btyp == tFtsKurve)             ||
       (btyp == tFtsAbzweigung)       || (btyp == tFtsKreuzung)          ||
       (btyp == tFtsEinbahnMitInhalt) || (btyp == tFtsZweibahnMitInhalt) ||
       (btyp == tFtsEndstrecke)       || (btyp == tFtsLadepool)          ||
       (btyp == tFtsLadeplatz)        || (btyp == tFtsWagen)             ||
       (btyp == tAbstrakteRegaleinheit)
      )
      return true;

   return false;        
}  // PruefeEndeFahrkurs

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool typVerkettung::BildeFahrkurs (typBaustein* zfkende)
{
  typBstZeiger* zStation;
  bool FKEnde = EndeFahrkurs (zfkende);
  if (FKEnde) return true;
  LCursor<typBstVerkettung> zhilfe;
  for (zhilfe = AusgangsListe; zhilfe; zhilfe++)
  {
    if (!zhilfe()->zBst->i_imFahrkurs()) 
    {
      FahrkursListe->TMP_Fahrkurs->erzeugeStation (zhilfe()->zBst);
      zhilfe()->zBst->s_imFahrkurs(true);
      if (!PruefeEndeFahrkurs (zhilfe()->zBst->i_BstTyp()))
         FKEnde = zhilfe()->zBst->BildeFahrkurs (zfkende);

      if (!FKEnde)
      {
        zStation = FahrkursListe->TMP_Fahrkurs->LetzteStationAusgliedern (); 
        zStation->zBst->s_imFahrkurs(false);
        delete zStation;
      }
      else break;
    }
  }
  return FKEnde;
}  // BildeFahrkurs
                              
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void typVerkettung::InfoVerkettung ()
{
  GTSView->MySpace()->MySelection()->removeAll();
  GeoObject* zgeo;
  if (AusgangsListe.isEmpty())
  {
    Meld.Ausgabe (43, ((typBaustein*)this)->i_BstNr());
    return;
  }
  GTSView->MySpace()->MySelection()->insert
                   (*(GTSMAP.find (*((typBaustein*)this))), Selection::SelRed);

  LCursor<typBstVerkettung> zhilfe;
  Ustring txt ("Bstnr.: ");
  txt += Ustring(((typBaustein*)this)->i_BstNr());
  txt += " verknüpft mit (";
  txt += Ustring(AusgangsListe.Count());
  txt += "):";
  for (zhilfe = AusgangsListe; zhilfe; zhilfe++)
  {
    zgeo = (GTSMAP.find (*(zhilfe()->zBst)));
    if (zgeo) GTSView->MySpace()->MySelection()->insert 
                                  (*zgeo, Selection::SelBlue);
    txt += " ";
    txt += Ustring(zhilfe()->zBst->i_BstNr());
    txt += ",";
  }
  txt.overwrite ("\n", txt.findRightPos(','));
  GTS_Meldungen (txt.str());
}  // InfoVerkettung// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
typVerkettung::~typVerkettung ()
{
  typBstVerkettung* zhilfe;
  typBaustein* zbstein = (typBaustein*) this;
  while (!AusgangsListe.isEmpty())
  {
   zhilfe = AusgangsListe.removeFirst();
   zhilfe->zBst->LoeseEingangsVerkettung (zbstein);
   delete zhilfe;
  }         
  while (!EingangsListe.isEmpty())
  {
   zhilfe = EingangsListe.removeFirst();
   zhilfe->zBst->LoeseAusgangsVerkettung (zbstein);
   delete zhilfe;
  }         
}  // ENDE ~typVerkettung

