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

#include <string.h>
#include <iostream.h>

#include "MathDefs.h"
#include "Kalender.h"
#include "Zufall.h"
#include "Messung.h"
#include "Messager.h"

#include "Token.h"

#define _BAUSTEIN_CPP
#include "modell.h"
#include "baustein.h"

#include "transp.h"
#include "arbplan.h"
#include "sfxprg.h"
#include "ereignis.h"
#include "drehpuff.h"
#include "regalver.h"
#include "realzeit.h"

// LCE
//typedef void* (*newObject) ();
//HINSTANCE lceLibrary;
//LCE
//---------------------------------------------------------
// Klasse typBaustein
//---------------------------------------------------------

double typBaustein::ClassNehmSchritt	= 0.1; // Meter
double typBaustein::ClassDrehSchritt	= 1.0; // Grad
double typBaustein::ClassFahrSchritt	= 0.1;  // Meter //sollte in der ini des Modells eingelesen werden Mark 22.01.03
double typBaustein::ClassTaktFaktor		= 5.0;  // ist meiner Meinung nach besser als irgenwelche "wilden"
//Zahlen von denen keiner weiss wozu sie da sind :-) siehe Verteil- und FTS-Wagen.
//Dient der Verfeinerung des Taktschrittes.  Norman 26.09.01 
//dieser classtaktfaktor ist der letzte Schund, sollte nicht mehr verwendet werden. Mark 22.01.03

typBaustein::typBaustein (unsigned n, unsigned b)
 : ObjNummer    (n),
   ObjBasistyp  (b),
   ObjVariante  (0),
   ObjZaehler   (0),

   ObjBelegung       (0),
   ObjBuchung        (0),
   ObjKapazitaet     (1),
   ObjPhysKapazitaet (1),

   ObjPrioritaet     (0),
   ObjStrategie      (0),
   ObjZustandWZ      (),
   ObjAufnahmezeit   (),
   ObjWartezeitSchwelle (0.0),

   ObjTaktSchritte   (0),
   ObjTaktZeit       (),
   ObjTaktZiel       (),

   ObjZustand        (RUHE),
   ObjAlterZustand   (RUHE),

   ObjWinkel         (0),
   ObjKorrekturWinkel(0),
   ObjGeometry       (),
   ObjDrehGeometry   (&ObjGeometry),
   ObjPalPlaetze     (1),
   ObjEingaenge      (2),
   ObjAusgaenge      (2),

   ObjTransportEinheit     (NULL),
   ObjZielBaustein   (NULL),
   ObjEvent          (NULL),
   ObjUData          (NULL),
   ObjAvis           (NULL),

   ObjSyncPartner    (0),
   
   ObjMeldungen      (),
   
   ObjTransportBestellungen (), //Transportbestellsystem

   ObjBelGeschichte  (NULL),
   ObjAuslGeschichte (NULL),
   ObjStoerGeschichte(NULL),

   ObjStoerDauer     (),
   ObjStoerEnde      (NULL),

   ObjSperrung       (false)
 { 
   Msg.Status("Erzeuge %s Bausteinnr: %i",BstTypTxt(),ObjNummer); 

/*
   zLCE_InterfaceBstDaten = NULL;
   newObject lceObj;
   lceLibrary = LoadLibrary("LCE.dll");
   if (lceLibrary != NULL) {
      if (Basistyp () == tMaschine) {
         lceObj = (newObject) (GetProcAddress(lceLibrary, "@LCE_MaschinenDaten@createLCE_MaschinenDaten$qv"));
         if (lceObj != NULL) {
            zLCE_InterfaceBstDaten = (LCE_InterfaceBstDaten*) (lceObj());
            zLCE_InterfaceBstDaten->setBaustein(this);
         }
         this->setAuslGeschichte (new Geschichte());
      }
      if ((Basistyp () == tVerteilwagen) || (Basistyp () == tMehrfachLader) || (Basistyp () == tLaufkran)) {
         lceObj = (newObject) (GetProcAddress(lceLibrary, "@LCE_FahrzeugDaten@createLCE_FahrzeugDaten$qv"));
         if (lceObj != NULL) {
            zLCE_InterfaceBstDaten = (LCE_InterfaceBstDaten*) (lceObj());
            zLCE_InterfaceBstDaten->setBaustein(this);
         }         
         this->setAuslGeschichte (new Geschichte());
      }      
   }
   */
  
   }

/*virtual*/ typBaustein::~typBaustein () {
  
  if (ObjAvis)           delete ObjAvis;
  if (ObjUData)          delete ObjUData;
  if (ObjAuslGeschichte) delete ObjAuslGeschichte;
  if (ObjBelGeschichte)  delete ObjBelGeschichte;
  if (ObjStoerGeschichte)delete ObjStoerGeschichte;
  for (unsigned i = 0; i < ObjPalPlaetze.Count (); i++)
    if (ObjPalPlaetze [i]) delete ObjPalPlaetze[i];
  MySFXModel->removePermanent (*this);
}

void typBaustein::bewegen (const Vec3D& moveVec) {
  Vec3D v (moveVec);
  ObjGeometry.move (ObjGeometry.DirToLocal (v), 0);
}

void typBaustein::positionieren (const Vec3D& newPos) {
  ObjGeometry.setPos (newPos, 0);
}

void typBaustein::drehen (const Angle& ang) {
  ObjDrehGeometry->rotate (EZ, ang, 0);
  ObjWinkel += ang;
  if (ObjWinkel < 0.0)  ObjWinkel += 360;
  else if (ObjWinkel == 360.0) ObjWinkel = Angle (0.0);
}

void typBaustein::ausrichten (const Angle& angToX) {
  ObjWinkel = angToX;
  if (ObjWinkel < 0.0)  ObjWinkel += 360;
  else if (ObjWinkel == 360.0) ObjWinkel = Angle (0.0);
  Angle a (ObjWinkel - ObjKorrekturWinkel);
  ObjDrehGeometry->setXTo (Vec3D (a.cos (), a.sin (), 0.0), 0);
}

ostream& typBaustein::Id_Schreiben (ostream& ostrm) const {
  ostrm << " ";
  ostrm.width (3);
  ostrm << ObjNummer << " ";
  ostrm.width (3);
  ostrm << ObjBasistyp << " ";
  ostrm.width (3);
  ostrm << ObjVariante;
  return ostrm;
}

/*virtual*/ void typBaustein::typTGSlesen (InputFile& file) {

	double x, y, z;
  	//double TempWinkelY;
  	Vec3D pos;

	if (!strcmp (MySFXModel->ModelExtension().str(), ".xml")) {
		/*
		Ustring identValue;
      Ustring tagName;

      if (ObjBasistyp == 1) {
   		identValue = Ustring("Q") + Ustring (ObjNummer);
         tagName = Ustring ("Quelle");
      } else if (ObjBasistyp == 7) {
      	identValue = Ustring("M") + Ustring (ObjNummer);
         tagName = Ustring ("Maschine");
      } else {
      	Msg.Error ("typBaustein::typTGSlesen (...)", "Can't find basistype: \"%i\"!!!", ObjBasistyp);
      }

   	
   	XMLHandler *MyXMLHandler = MySFXModel->ModelXMLHandler();
      const char* xVal = MyXMLHandler->GetChildElementValue(3, "Pos-X", tagName.str(), 2, "Inv-Nr", identValue.str());
      const char* yVal = MyXMLHandler->GetChildElementValue(3, "Pos-Y", tagName.str(), 2, "Inv-Nr", identValue.str());
      const char* zVal = MyXMLHandler->GetChildElementValue(3, "Pos-Z", tagName.str(), 2, "Inv-Nr", identValue.str());
		
		if ((xVal == NULL) || (yVal == NULL) || (zVal == NULL))
    		Msg.Error ("typBaustein::typTGSlesen (...)", "Can't find Pos-X\"%s\", Pos-Y\"%s\" or Pos-Z\"%s\"!!!", xVal, yVal, zVal);

  		x = atof (xVal);
  		y = atof (yVal);
  		z = atof (zVal);

      const char* var = MyXMLHandler->GetChildElementValue(2, "Sfx-Variante", tagName.str(), 2, "Inv-Nr", identValue.str());
      if (var != NULL)
      	ObjVariante = atoi(var);
      else
      	ObjVariante = 3;

		pos = Vec3D (x, y, z);
  		ObjGeometry.move (pos);


      const char* orientation = MyXMLHandler->GetChildElementValue(3, "Ausrichtung", tagName.str(), 2, "Inv-Nr", identValue.str());
      if (!strcmp(orientation, "N"))
      	ObjWinkel = Angle (atof ("90.0"));
      else if (!strcmp(orientation, "W"))
      	ObjWinkel = Angle (atof ("180.0"));
      else if (!strcmp(orientation, "S"))
      	ObjWinkel = Angle (atof ("270.0"));
      else if (!strcmp(orientation, "O"))
      	ObjWinkel = Angle (atof ("0.0"));

     	ObjGeometry.rotate (EZ, ObjWinkel);
		*/

   } else {

   	SFXToken tok;

	  	tok.nextToken (file);
     	ObjVariante = atoi (tok ());

  		tok.nextToken (file);
  		x = atof (tok ());
  		tok.nextToken (file);
  		y = atof (tok ());
  		tok.nextToken (file);
  		z = atof (tok ());


		pos = Vec3D (x, y, z);
  		ObjGeometry.move (pos);



		if (MySFXModel->Release () >= 15.00) {

      	tok.nextToken (file);
      	ObjWinkelX = Angle (atof (tok ()));
      	ObjGeometry.rotate (EX, ObjWinkelX);
      	tok.nextToken (file);
      	ObjWinkelY = Angle (atof (tok ()));
      	ObjGeometry.rotate (EY, ObjWinkelY);
      	tok.nextToken (file);
      	ObjWinkel = Angle (atof (tok ()));
      	ObjGeometry.rotate (EZ, ObjWinkel);
   	// Versionen vor Release 15 besitzen nur einen Drehwinkel um die z-Achse
   	} else {

   		tok.nextToken (file);
   		ObjWinkel = Angle (atof (tok ()));
   		ObjGeometry.rotate (EZ, ObjWinkel);

  		}

   	tok.nextToken (file); // Anzahl Infos
   	ObjZaehler = atoi (tok ());
   	tok.nextToken (file);  // Name

  		file.jump (100); //EOL

  		for (unsigned zeile = 1; zeile <= ObjZaehler; zeile++) {
    		tok.nextToken (file);
    		file.jump (200); //EOL
  		}

   }

  TGBPermPattern* myTGBPattern = MySFXModel->TGBLibrary ()->findPerm (ObjBasistyp, ObjVariante);

  const DynArray<Vec3D>& d (myTGBPattern->PalPositions ());
  d.First ();
  for (unsigned i = 0; d (); i++, d++)
    ObjPalPlaetze[i] = new typPlatz (i, *(d ()), this);

  GeoObject* geo = new GeoObject ();
  geo->copyContents (*(myTGBPattern->MyGeometry ()));
  geo->setParent (ObjGeometry);
  geo->setSelectionToMum ();

  if (MySFXModel->TGBLibrary ()->hasToBuildNumbers () && (ObjBasistyp != tRegaleinheit))
    ObjGeometry.insert (*(TGBPattern::buildText (Ustring (ObjNummer), myTGBPattern->NumberHeight (),
                                               3.0, myTGBPattern->NumberPos ())));

  ObjGeometry.setParent (*(MySFXModel->ModelSpace ()));
  MySFXModel->insertPermanent (*this, ObjGeometry);
}

/*virtual*/ ostream& typBaustein::typTGSschreiben (ostream& ostrm) const {
  ostrm.precision (2);
  ostrm << "TGS: ";
  Id_Schreiben (ostrm);
  ostrm << " ";
  ostrm.width (6);
  ostrm << ObjGeometry.Pos () << " ";
  ostrm.width (6);
  ostrm << ObjWinkel.deg () << " ";
  ostrm.width (6);
  ostrm << ObjWinkelY.deg () << " ";
  ostrm.width (6);
  ostrm << ObjWinkelX.deg () << " ";
  ostrm.width (2);
  ostrm << ObjZaehler << endl;
  return ostrm;
}

/*virtual*/ void typBaustein::typTBVlesen (InputFile& file) {
  SFXToken tok;
  tok.nextToken (file);
  tok.nextToken (file);
  typBaustein* bst = baustein [atoi (tok ())];

  bst->addEingang (this);
  addAusgang (bst);
  file.jump (100); //EOL

  if ((bst->Basistyp ()) != tFtsVerwalter)
    ObjZielBaustein = bst;
}

/*virtual*/ ostream& typBaustein::typTBVschreiben (ostream& ostrm) const {
  ostrm << "TBV: ";
  Id_Schreiben (ostrm);
  ostrm << "Eingaenge: ";
  for (ObjEingaenge.First (); ObjEingaenge (); ObjEingaenge++) {
    ostrm.width (6);
    ostrm << " " << ObjEingaenge ()->Nummer () << " ";
  }
  ostrm << endl << "Ausgaenge: ";
  for (ObjAusgaenge.First (); ObjAusgaenge (); ObjAusgaenge++) {
    ostrm.width (6);
    ostrm << " " << ObjAusgaenge ()->Nummer () << " ";
  }
  ostrm << endl;
  return ostrm;
}

/*virtual*/ void typBaustein::typTTPlesen (InputFile& file) {
  SFXToken tok;
  tok.nextToken (file);
  ObjAufnahmezeit = SimTime (atof (tok ()) * SimTime::SecondsPerMinute ());
  ObjPhysKapazitaet = ObjKapazitaet = 1;
  file.jump (100); //EOL
}

/*virtual*/ ostream& typBaustein::typTTPschreiben (ostream& ostrm) const {
  ostrm.precision (2);
  ostrm << "TTP: ";
  Id_Schreiben (ostrm);
  ostrm << " ";
  ostrm.width (6);
  ostrm << ObjAufnahmezeit.inMinutes () << endl;
  return ostrm;
}

/*virtual*/ void typBaustein::typTSTlesen (InputFile& file) {
  SFXToken tok;

  tok.nextToken (file);
  ObjStrategie = atoi (tok ());
  tok.nextToken (file);
  ObjPrioritaet = atoi (tok ());
  tok.nextToken (file);
  ObjWartezeitSchwelle = atof (tok ());

  if (ObjAvis) {
    tok.nextToken (file);
    ObjAvis->setDirSollAnzahl (atoi (tok ()));
    tok.nextToken (file);
    ObjAvis->setIndSollAnzahl (atoi (tok ()));
  }
  file.jump (100); //EOL
}

/*virtual*/ ostream& typBaustein::typTSTschreiben (ostream& ostrm) const {
  ostrm << "TST: ";
  Id_Schreiben (ostrm);
  ostrm << " ";
  ostrm.width (2);
  ostrm << ObjStrategie << " ";
  ostrm.width (2);
  ostrm << ObjPrioritaet << endl;
  return ostrm;
}

/*virtual*/ void typBaustein::typTPVlesen (InputFile&) {
  sim_error ("BAUSTEIN", "typBaustein::typTPVlesen",
             "falscher Bausteintyp fuer TPVlesen", ObjNummer, FATAL);
}

/*virtual*/ ostream& typBaustein::typTPVschreiben (ostream& ostrm) const {
  ostrm << "Irgend_ein_Verwalter ";
  ostrm.width (3);
  ostrm << ObjNummer << endl;
  return ostrm;
}

ostream& typBaustein::schreibeZustand (ostream& ostrm) const {
  ostrm << "<";
  ostrm.width (2);
  ostrm << ObjNummer << " ";
  ostrm.width (2);
  ostrm << ObjZustand << " ";
  ostrm.width (2);
  ostrm << ObjBelegung << " ";
  ostrm.width (2);
  ostrm << AnzahlMeldungen () << " >";
  return ostrm;
}

ostream& typBaustein::schreibeProtokoll (ostream& ostrm) const {
  ostrm << " ";
  ostrm.width (2);
  ostrm << ObjNummer << " ";
  ostrm.width (2);
  ostrm << AnzahlMeldungen ();
  if (ObjBelGeschichte)  ostrm << (*ObjBelGeschichte);
  else ostrm << "    <------ not initialized ------>";
  if (ObjAuslGeschichte) ostrm << (*ObjAuslGeschichte);
  else ostrm << "    <------ not initialized ------>";
  if (ObjStoerGeschichte) ostrm << (*ObjStoerGeschichte);
  else ostrm << "    <------ not initialized ------>";
  ostrm << endl;
  return ostrm;
}

unsigned typBaustein::Nummer () const {
  return ObjNummer;
}

Ustring typBaustein::Name () const {
   return ObjName;   
}

unsigned typBaustein::Basistyp () const {
  return ObjBasistyp;
}

const Vec3D& typBaustein::Position () const {
  return ObjGeometry.Pos ();
}

const Angle& typBaustein::Winkel () const {
  return ObjWinkel;
}

/*virtual*/ Vec3D typBaustein::UebernahmePos (const typBaustein&) const {
  sim_error ("BAUSTEIN", "typBaustein::UebernahmePos",
             "falscher Bausteintyp fuer UebernahmePos", ObjBasistyp, FATAL);
  return Vec3D ();
}

/*virtual*/ Vec3D typBaustein::UebergabePos (const typBaustein&) const {
  sim_error ("BAUSTEIN", "typBaustein::UebergabePos",
             "falscher Bausteintyp fuer UebergabePos", ObjBasistyp, FATAL);
  return Vec3D ();
}

unsigned typBaustein::AnzahlEingaenge () const {
  return ObjEingaenge.Count ();
}

unsigned typBaustein::AnzahlAusgaenge () const {
  return ObjAusgaenge.Count ();
}

/*virtual*/ unsigned typBaustein::Kapazitaet () const {
  return ObjKapazitaet;
}

/*virtual*/ unsigned typBaustein::setKapazitaet (unsigned wert) {
  return (wert <= ObjPhysKapazitaet) ? 
         (ObjKapazitaet = wert) : (ObjKapazitaet = ObjPhysKapazitaet);
}

unsigned typBaustein::Strategie () const {
  return ObjStrategie;
}

/*virtual*/ unsigned typBaustein::setStrategie (unsigned stratNr) {
  return (ObjStrategie = stratNr);
}

//Transportbestellsystem

/*virtual*/ void typBaustein::bestelleBstHolenAnfangGliedern (const unsigned /*zielBstNr*/, const unsigned /*palPlatz*/) {
	  sim_error ("BAUSTEIN", "typBaustein::bestelleBstHolenAnfangGliedern",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ void typBaustein::bestelleBstHolen (const unsigned /*zielBstNr*/, const unsigned /*palPlatz*/) {
	  sim_error ("BAUSTEIN", "typBaustein::bestelleBstHolen",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ void typBaustein::bestelleBstBringenAnfangGliedern (const unsigned /*zielBstNr*/, const unsigned /*palPlatz*/) {
	sim_error ("BAUSTEIN", "typBaustein::bestelleBstBringenAnfangGliedern",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ void typBaustein::bestelleBstBringen (const unsigned /*zielBstNr*/, const unsigned /*palPlatz*/) {
	sim_error ("BAUSTEIN", "typBaustein::bestelleBstBringen",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ void typBaustein::BestellungVorGliedern (typTransportBestellung* /*neu*/, const typTransportBestellung* /*alt*/) {
	sim_error ("BAUSTEIN", "typBaustein::BestellungVorGliedern",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ void typBaustein::loescheBestellungHolen (const unsigned /*zielBstNr*/, const unsigned /*palPlatz*/) {
	sim_error ("BAUSTEIN", "typBaustein::loescheBestellungHolen",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ void typBaustein::loescheBestellungBringen (const unsigned /*zielBstNr*/, const unsigned /*palPlatz*/) {
	sim_error ("BAUSTEIN", "typBaustein::loescheBestellungBringen",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ void typBaustein::loescheBestellung (const typTransportBestellung* /*welche*/) {
	sim_error ("BAUSTEIN", "typBaustein::loescheBestellung",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ void typBaustein::loescheAlleBestellungen () {
	sim_error ("BAUSTEIN", "typBaustein::loescheAlleBestellungen",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ bool typBaustein::hasTransportBestellung () const {
   return sim_error ("BAUSTEIN", "typBaustein::hasTransportBestellung",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ typTransportBestellung* typBaustein::GibTranspBestZuBaustein (const unsigned /*Bst*/, const unsigned /*Typ*/) const {
	return (typTransportBestellung*) sim_error ("BAUSTEIN", "typBaustein::GibTranspBestZuBaustein",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ typTransportBestellung* typBaustein::GibTransportBestellung (const unsigned /*welche*/) const {
	return (typTransportBestellung*) sim_error ("BAUSTEIN", "typBaustein::GibTransportBestellung",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
	/*LCursor<typTransportBestellung> c (ObjTransportBestellungen);
	c.First ();
	for (unsigned i = 1; i < welche; i++) {
		c++;
	}
	return c ();*/ //von Mark uebernommen (rudi: 04-09-03)
}

/*virtual*/ void typBaustein::DruckeTransportBestellungen () const {
   sim_error ("BAUSTEIN", "typBaustein::DruckeTransportBestellungen",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}
   
//Transportbestellsystem Ende

int typBaustein::Prioritaet () const {
  return ObjPrioritaet;
}

int typBaustein::setPrioritaet (int prionr) {
  return (ObjPrioritaet = prionr);
}

zustandstypen typBaustein::Zustand () const {
  return ObjZustand;
}

typAvis* typBaustein::Avis () const {
  return ObjAvis;
}

bool typBaustein::hasMeldungen () const {
  return !ObjMeldungen.isEmpty ();
}

unsigned typBaustein::AnzahlMeldungen () const {
  return ObjMeldungen.Count ();
}

// Funktion ist nur fuer Fehlersuche 
void typBaustein::printMeldeliste () {
  cout << endl << endl <<"Meldeliste von Baustein " << ObjNummer 
       << " :" << endl;
  int zaehler = 1;
  for (LCursor<typMeldung> c (ObjMeldungen); c; c++) {
    typTransportEinheit* zTE = c ()->TransportEinheit ();
    cout << "Meld " << zaehler++ << " : von Bst " 
         << c ()->VonBaustein ()->Nummer () << " nach Bst "
         << c ()->NachBaustein ()->Nummer () << " nextB = "
         << zTE->nextBaustein ()->Nummer () << endl;
  }
}

/*virtual*/ unsigned typBaustein::Belegung () const {
  return ObjBelegung;
}

unsigned typBaustein::Buchung () const {
  return ObjBuchung;
}

double typBaustein::ZustandZeit () const {
  return (Modellzeit() - ObjZustandWZ).inMinutes ();
}

Ustring typBaustein::ZustandTxt() const {
  static Ustring strZustand;
  switch (ObjZustand)  {
    case RUHE           :  return strZustand = "RUHE      ";
    case AKTIVIERT      :  return strZustand = "AKTIVIERT ";
    case AUFNEHMEN      :  return strZustand = "AUFNEHMEN ";
    case ARBEITEN       :  return strZustand = "ARBEITEN  ";
    case ABGEBEN        :  return strZustand = "ABGEBEN   ";
    case FOERDERN       :  return strZustand = "FOERDERN  ";
    case DREHEN         :  return strZustand = "DREHEN    ";
    case FAHREN         :  return strZustand = "FAHREN    ";
    case WARTEN         :  return strZustand = "WARTEN    ";
    case POLLING        :  return strZustand = "POLLING   ";
    case WARTEDP        :  return strZustand = "WARTEDP   ";
    case SCHLAFEN       :  return strZustand = "SCHLAFEN  ";
    case PRGWARTEN      :  return strZustand = "PRGWARTEN ";
    case SFOERDERN      :  return strZustand = "SFOERDERN ";
    case GESTOERT       :  return strZustand = "GESTOERT  ";
    case GESPERRT       :  return strZustand = "GESPERRT  ";
    case SYNCWARTEN     :  return strZustand = "SYNCWARTEN";
    case LADEN          :  return strZustand = "LADEN     ";
    default             :  return strZustand = "Unbekannt ";
  };
}

Ustring typBaustein::BstTypTxt () const {
  static Ustring strTyp;
  switch (ObjBasistyp)  {
    case tLayout                  : return strTyp = "Layout              ";
    case tQuelle                  : return strTyp = "Quelle              ";
    case tSenke                   : return strTyp = "Senke               ";
    case tStaufoerderer           : return strTyp = "Staufoerderer       ";
    case tRechtsKurvenStaufoerderer: return strTyp = "StaufoerdererRechts ";
    case tLinksKurvenStaufoerderer : return strTyp = "StaufoerdererLinks  ";
    case tWeiche                  : return strTyp = "Weiche              ";
    case tVerteilwagen            : return strTyp = "Verteilwagen        "; 
    case tMaschine                : return strTyp = "Maschine            ";
    case tDrehpuffer              : return strTyp = "Drehpuffer          ";
    case tMehrfachLader           : return strTyp = "MehrfachLader       ";
    case tLaufkran                : return strTyp = "Laufkran            ";
    case tAbstrakteRegaleinheit   : return strTyp = "AbstrRegaleinheit   ";
    case tSammler                 : return strTyp = "Sammler             ";
    case tRegaleinheit            : return strTyp = "Regaleinheit        ";
    case tRegalverwalter          : return strTyp = "Regalverwalter      ";
    case tNcPoolverwalter         : return strTyp = "NcPoolverwalter     ";
    case tKettenfoerderer         : return strTyp = "Kettenfoerderer     ";
    case tQuerfoerderer           : return strTyp = "Querfoerderer       ";
    case tKommissionierer         : return strTyp = "Kommissionierer     ";
    case tKomVerwalter            : return strTyp = "KomVerwalter        ";
    case tFtsLadepool             : return strTyp = "FtsLadepool         ";
    case tFtsLadeplatz            : return strTyp = "FtsLadeplatz        ";
    case tFtsVerwalter            : return strTyp = "FtsVerwalter        ";
    case tFtsWagen                : return strTyp = "FtsWagen            ";
    case tFtsEinbahnstrecke       : return strTyp = "FtsEinbahnstrecke   ";
    case tFtsZweibahnstrecke      : return strTyp = "FtsZweibahnstrecke  ";
    case tFtsKurve                : return strTyp = "FtsKurve            ";
    case tFtsAbzweigung           : return strTyp = "FtsAbzweigung       ";
    case tFtsKreuzung             : return strTyp = "FtsKreuzung         ";
    case tFtsEinbahnMitInhalt     : return strTyp = "FtsEinbahnMitInhalt ";
    case tFtsZweibahnMitInhalt    : return strTyp = "FtsZweibahnMitInhalt";
    case tFtsEndstrecke           : return strTyp = "FtsEndstrecke       ";
    default                       : return strTyp = "Unbekannt           ";
  };
}

const SimTime& typBaustein::Aufnahmezeit () const {
  return ObjAufnahmezeit;
}

const SimTime& typBaustein::setAufnahmezeit (const SimTime& time) {
  return ((time > 0) ? (ObjAufnahmezeit = time) : ObjAufnahmezeit);
}

unsigned typBaustein::SyncPartner () const { 
  return ObjSyncPartner; 
}

void typBaustein::setSyncPartner (unsigned spartner) { 
  ObjSyncPartner = spartner;
}

/*virtual*/ const double& typBaustein::setGeschwindigkeit (const double& /*wert*/) {
  sim_error ("BAUSTEIN", "typBaustein::setGeschwindigkeit",
             "Bausteintyp hat keine Geschwindigkeit", ObjNummer, FATAL);
  return ClassNehmSchritt; // damit Compiler a Ruh' gibt!!!! (wird eh abgebrochen)
}

/*virtual*/ unsigned typBaustein::AnzahlArbeitsliste () const {
  return 0;
}

/*virtual*/ bool typBaustein::isUebergabeBereit (typTransportEinheit*, typBaustein*) const {
  return true;
}

/*virtual*/ void typBaustein::UebergabeVorbereiten (typTransportEinheit*)
 { }

/*virtual*/typBaustein* typBaustein::setZielBaustein (typTransportEinheit *zTE) {
  ObjAvis->decIndIstAnzahl ();
  ObjAvis->incDirIstAnzahl ();
  (zTE->Baustein ())->Avis ()->decDirIstAnzahl ();
  return this;
}

UserData* typBaustein::getUserData () const {
  return ObjUData;
}

void typBaustein::setUserData (UserData* data) {
  if (ObjUData && data != NULL)
    sim_error ("BAUSTEIN", "typBaustein::setUserData",
             "Bausteintyp hat bereits UserData", ObjNummer, FATAL);
  else ObjUData = data;
}

/*virtual*/ typBaustein* typBaustein::setVerwalter (typBaustein*) {
  sim_error ("BAUSTEIN", "typBaustein::setVerwalter",
             "Bausteintyp kann nicht verwaltet werden", ObjBasistyp, FATAL);

  return NULL;
}

/*virtual*/ typRegalverwalter* typBaustein::setBetreuer (typRegalverwalter*) {
  sim_error ("BAUSTEIN", "typBaustein::setBetreuer",
             "Bausteintyp kann nicht betreut werden", ObjBasistyp, FATAL);
  return NULL;
}

Geschichte *typBaustein::BelGeschichte () const {
  return ObjBelGeschichte;
}

void typBaustein::setBelGeschichte (Geschichte *bGeschichte) {
  ObjBelGeschichte = bGeschichte;
}

Geschichte *typBaustein::AuslGeschichte () const {
  return ObjAuslGeschichte;
}

void typBaustein::setAuslGeschichte (Geschichte *aGeschichte) {
  ObjAuslGeschichte = aGeschichte;
}

Geschichte *typBaustein::StoerGeschichte () const {
  return ObjStoerGeschichte;
}

void typBaustein::setStoerGeschichte (Geschichte *sGeschichte) {
  ObjStoerGeschichte = sGeschichte;
}

void typBaustein::empfangeMeldung (typMeldung *zM) {
//  zM->VonBaustein ()->ObjMeldungen.remove (*zM);  04.02.03 rei
//  if (!(zM->unverkettet ())) zM->ausgliedern (); /*FTS*/
//  if ((zM->zTransportEinheit ())->zi_NachRBaustein () == this) zM->incPrio (10);
// ?????  if ((zM->zTransportEinheit ())->ZielPlatz ()->Baustein () == this) zM->incPrio (10);
   zM->PrioEingliedern (ObjMeldungen);
   //if ((ObjZustand == RUHE) || (ObjZustand == POLLING) || (ObjZustand == WARTEN) || 
   //      (ObjZustand == WARTEDP) || (ObjZustand == PRGWARTEN)) {


      planesofort (ETaktivieren, ObjNummer, zM->VonBaustein ()->Nummer ());
   //}
}

/*virtual*/ typPlatz* typBaustein::waehlePlatz (typTransportEinheit*) {
  sim_error ("BAUSTEIN", "typBaustein::waehlePlatz",
             "Bausteintyp hat keine Plaetze", ObjBasistyp, FATAL);
  return NULL;
}

typTransportEinheit *typBaustein::TransportEinheit () const {
  return ObjTransportEinheit;
}

typTransportEinheit *typBaustein::gibTransportEinheit (typMeldung* zM) {
  if (zM->TransportEinheit () != ObjTransportEinheit)
    sim_error ("BAUSTEIN", "typBaustein::gibTransportEinheit",
               "falsche TransportEinheit angefordert", ObjNummer, FATAL);
  decBelegung ();
  ObjTransportEinheit->AktPlatz ()->setTransportEinheit (NULL);
  ObjTransportEinheit = NULL;
  setZustand (AKTIVIERT);
  planesofort (ETaabgeben, ObjNummer, zM->NachBaustein ()->Nummer ());
  return ObjTransportEinheit;
}

/*virtual*/ void typBaustein::a_aufnehmen () {
  typMeldung *zM = holeMeldung ();
  ObjZielBaustein->gibTransportEinheit (zM);
  aufnehmenEinleiten (ObjTransportEinheit->ZielPlatz ()->Position (), ObjAufnahmezeit);

}

/*virtual*/ void typBaustein::e_aufnehmen () {
  typPlatz *p (ObjTransportEinheit->AktPlatz ());
  if (p->Buchung () != ObjTransportEinheit)
    sim_error ("BAUSTEIN", "typBaustein::e_aufnehmen",
               "TransportEinheit ist nicht auf Platz gebucht", ObjNummer, FATAL);
  p->setBuchung (NULL);
  ObjBuchung--;

  ObjTransportEinheit->positionieren (p->Position ());
  if (ObjStoerDauer > SimTime (0.0))
    planesofort (ETastoerung, ObjNummer);
  else {
    setZustand (AKTIVIERT);
    planesofort (ETaarbeiten, ObjNummer, 0);
  }
  planesofort (ETeabgeben, ObjZielBaustein->Nummer (), ObjNummer);
}

/*virtual*/ void typBaustein::a_arbeiten () {
  setZustand (ARBEITEN);
  planedelta (ObjTransportEinheit->Vorgang ()->Dauer (), ETearbeiten, ObjNummer, 0);
  if (MySFXModel->RealTime ())
    RzsSenden (ObjNummer, ETaarbeiten, 0);
}

/*virtual*/ void typBaustein::e_arbeiten () {
  ObjTransportEinheit->schalteVorgang ();
  if (ObjStoerDauer > SimTime (0.0))
    planesofort (ETastoerung, ObjNummer);
  else {
    setZustand (AKTIVIERT);
    planesofort (ETameldewarten, ObjNummer, 0);
  }
}

/*virtual*/ void typBaustein::a_meldewarten () {
  setZustand (WARTEN);
  ObjTransportEinheit->Anmelden ();
}

/*virtual*/ void typBaustein::a_abgeben () {
  setZustand (ABGEBEN);
}

/*virtual*/ void typBaustein::e_abgeben () {
  setZustand (RUHE);
  planesofort (ETaktivieren, ObjNummer, ObjNummer);
  aktiviereEingaenge ();
}

/*virtual*/void typBaustein::e_drehen () {
  sim_error ("BAUSTEIN", "typBaustein::a_drehen",
             "falscher Bausteintyp fuer Drehen", ObjBasistyp, FATAL);
}

/*virtual*/ void typBaustein::a_drehen () {
  sim_error ("BAUSTEIN", "typBaustein::e_drehen",
             "falscher Bausteintyp fuer Drehen", ObjBasistyp, FATAL);
}

/*virtual*/ void typBaustein::a_foerdern () {
  sim_error ("BAUSTEIN", "typBaustein::a_foerdern",
             "falscher Bausteintyp fuer Foerdern", ObjBasistyp, FATAL);
}

/*virtual*/ void typBaustein::e_foerdern () {
  sim_error ("BAUSTEIN", "typBaustein::e_foerdern",
             "falscher Bausteintyp fuer Foerdern", ObjBasistyp, FATAL);
}

/*virtual*/ void typBaustein::a_heben () {
  sim_error ("BAUSTEIN", "typBaustein::a_heben",
             "falscher Bausteintyp fuer Heben", ObjBasistyp, FATAL);
}

/*virtual*/ void typBaustein::e_heben () {
  sim_error ("BAUSTEIN", "typBaustein::e_heben",
             "falscher Bausteintyp fuer Heben", ObjBasistyp, FATAL);
}

/*virtual*/ void typBaustein::a_senken () {
  sim_error ("BAUSTEIN", "typBaustein::a_senken",
             "falscher Bausteintyp fuer Senken", ObjBasistyp, FATAL);
}

/*virtual*/ void typBaustein::e_senken () {
  sim_error ("BAUSTEIN", "typBaustein::a_senken",
             "falscher Bausteintyp fuer Senken", ObjBasistyp, FATAL);
}

/*virtual*/ void typBaustein::aSperren () {
  ObjSperrung = true;
  ObjAlterZustand = ObjZustand;
  setZustand (GESPERRT);
}

/*virtual*/ void typBaustein::eSperren () {
  ObjSperrung = false;
  setZustand (ObjAlterZustand);
  planesofort (ETaktivieren, ObjNummer, ObjNummer);
  aktiviereEingaenge ();
  aktiviereAusgaenge ();
}

/*virtual*/ void typBaustein::a_kommissionieren () {
  sim_error ("BAUSTEIN", "typBaustein::a_kommissionieren",
             "falscher Bausteintyp fuer Kommissionierer", ObjNummer, FATAL);
}

/*virtual*/ void typBaustein::e_kommissionieren () {
  sim_error ("BAUSTEIN", "typBaustein::e_kommissionieren",
             "falscher Bausteintyp fuer Kommissionierer", ObjNummer, FATAL);
}

/*virtual*/ void typBaustein::a_laden () {
  sim_error ("BAUSTEIN", "typBaustein::a_laden",
             "falscher Bausteintyp fuer Laden", ObjBasistyp, FATAL);
}

/*virtual*/ void typBaustein::e_laden () {
  sim_error ("BAUSTEIN", "typBaustein::e_laden",
             "falscher Bausteintyp fuer Laden", ObjBasistyp, FATAL);
}

void typBaustein::aStoeren () {
  ObjAlterZustand = ObjZustand;
  setZustand (GESTOERT);
  if (ObjStoerGeschichte) ObjStoerGeschichte->erfassen (100.0);
  ObjStoerEnde = new notiz (Modellzeit () + ObjStoerDauer, ETestoerung, ObjNummer);
  ObjStoerEnde->planeein ();
  ObjStoerDauer = SimTime (0.0);
}

/*virtual*/ void typBaustein::eStoeren () {
  ObjStoerEnde = NULL;
  if (ObjStoerGeschichte) ObjStoerGeschichte->erfassen (0.0);
  switch (ObjAlterZustand) {
    case AUFNEHMEN :  setZustand (AKTIVIERT);
                      planesofort (ETaarbeiten, ObjNummer, 0);
                      break;

    case ARBEITEN  :  setZustand (AKTIVIERT);
                      planesofort (ETameldewarten, ObjNummer, 0);
                      break;

    case PRGWARTEN :  setZustand (PRGWARTEN);
                      planesofort (ETaktivieren, ObjNummer, ObjNummer);
                      break;

    default        :  setZustand (ObjAlterZustand); // RUHE or POLLING!!!
                      planesofort (ETaktivieren, ObjNummer, ObjNummer);
                      aktiviereEingaenge ();
                      aktiviereAusgaenge ();
                      break;
  }
}

/*virtual*/ bool typBaustein::ausrichtenAufBaustein (typBaustein*) {
  return sim_error ("BAUSTEIN", "typBaustein::ausrichtenAufBaustein",
                    "falscher Bausteintyp fuer Ausrichten", ObjBasistyp, FATAL);
}

/*virtual*/ bool typBaustein::immerausrichtenAufBaustein(typBaustein*, bool /*= true*/) {
  return sim_error ("BAUSTEIN", "typBaustein::immerausrichtenAufBaustein",
                    "falscher Bausteintyp fuer Ausrichten", ObjBasistyp, FATAL);
}

/*virtual*/ void typBaustein::aufn_takt () {
  if (ObjZustand != AUFNEHMEN) return;
  if (ObjTaktSchritte) {
    ObjTaktSchritte--;
    Vec3D v (ObjTaktZiel - ObjTransportEinheit->Position ());
    if (v) {
      v = v.unit () * ClassNehmSchritt;
      ObjTransportEinheit->bewegen (v);
    }
    if (MySFXModel->Debug ())
      dprintf ("Aufn_takt %1d -> %1d: dx=%5.2f dy=%5.2f dz=%5.2f\n",
         ObjZielBaustein->Nummer (), ObjNummer, v.X (), v.Y (), v.Z ());
    planedelta (ObjTaktZeit, ETaufnTakt, ObjNummer, ObjZielBaustein->Nummer (), ObjTaktSchritte);
  }
  else {
    ObjTransportEinheit->positionieren (ObjTaktZiel);
    if (MySFXModel->Debug ())
      dprintf ("Aufn_takt %1d -> %1d: x=%5.2f y=%5.2f z=%5.2f\n",
               ObjZielBaustein->Nummer (), ObjNummer, ObjTaktZiel.X (), ObjTaktZiel.Y (), ObjTaktZiel.Z ());
  }
}

/*virtual*/ void typBaustein::fahr_takt () {
  sim_error ("BAUSTEIN", "typBaustein::fahr_takt",
             "falscher Bausteintyp fuer Fahren", ObjBasistyp, FATAL);
}

/*virtual*/ void typBaustein::dreh_takt () {
  sim_error ("BAUSTEIN", "typBaustein::dreh_takt",
             "falscher Bausteintyp fuer Drehen", ObjBasistyp, FATAL);
}

void typBaustein::aktivieren (unsigned vonWem) {
  if ((ObjStoerDauer > SimTime (0.0))
       && ((ObjZustand == RUHE) || (ObjZustand == POLLING)))
    planesofort (ETastoerung, ObjNummer);
  else
    if (((ObjZustand == RUHE) || (ObjZustand == POLLING)) && ObjSperrung)
      planesofort (ETasperrung, ObjNummer);
  else 
    if (!isGesperrtOrGestoert ())
      individuellAktivieren (baustein [vonWem]);
}

/*virtual*/ void typBaustein::ArbBestellung (unsigned /*was*/,      unsigned /*istvorg*/,
                                             unsigned /*sollvorg*/, unsigned /*wieoft*/) {
  sim_error ("BAUSTEIN", "typBaustein::ArbBestellung",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ void typBaustein::TEBestellung (typTransportEinheit* /*te*/, unsigned /*sollvorg*/) {
   sim_error ("BAUSTEIN", "typBaustein::TEBestellung",
              "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ void typBaustein::ArtBestellung (unsigned /*was*/,      unsigned /*istvorg*/,
                                             unsigned /*sollvorg*/, unsigned /*wieoft*/) {
   sim_error ("BAUSTEIN", "typBaustein::ArtBestellung",
              "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ void typBaustein::ArbZuweisen  (unsigned /*was*/, unsigned /*wohin*/,
                                            unsigned /*istVorg*/, unsigned /*sollVorg*/,
                                            unsigned /*wieoft*/) {
   sim_error ("BAUSTEIN", "typBaustein::ArbZuweisung",
              "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ void typBaustein::ArtZuweisen  (unsigned /*was*/, unsigned /*wohin*/,
                                            unsigned /*istVorg*/, unsigned /*sollVorg*/,
                                            unsigned /*wieoft*/) {
   sim_error ("BAUSTEIN", "typBaustein::ArtZuweisung",
              "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
}

/*virtual*/ bool typBaustein::loescheArbBestellung (unsigned /*was*/, unsigned /*istvorg*/) {
  sim_error ("BAUSTEIN", "typBaustein::loescheArbBestellung",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
  return false;
}

/*virtual*/ bool typBaustein::loescheTEBestellung (typTransportEinheit* /*te*/) {
  sim_error ("BAUSTEIN", "typBaustein::loescheTEBestellung",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
  return false;
}

/*virtual*/ bool typBaustein::loescheArtBestellung (unsigned /*was*/, unsigned /*istvorg*/) {
  sim_error ("BAUSTEIN", "typBaustein::loescheArtBestellung",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
  return false;
}

/*virtual*/ typTransportEinheit* typBaustein::GibProjektIDTE
                     (unsigned /*idnr = 0*/, unsigned /*projektID = 0*/, unsigned /*suchID = 0*/) {
  sim_error ("BAUSTEIN", "typBaustein::GibProjektIDTE",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
  return NULL;
}

/*virtual*/ unsigned typBaustein::AnzahlArbeitsplanVorhanden
                     (unsigned arbNr, unsigned istv /*= 0*/) const {
  return (ObjTransportEinheit && (ObjTransportEinheit->Baustein () == this)
          && ObjTransportEinheit->hatArbeitsplan (arbNr, istv)) ? 1 : 0;
}

/*virtual*/ unsigned typBaustein::AnzahlArtikelVorhanden
                     (unsigned artNr, unsigned istv /*= 0*/) const {
  return (ObjTransportEinheit && (ObjTransportEinheit->Baustein () == this)
          && ObjTransportEinheit->hatArtikel (artNr, istv)) ? 1 : 0;
}

/*virtual*/ double typBaustein::MengeArbeitsplanVorhanden
                   (unsigned arbNr, unsigned istv /*= 0*/) const {
  return (ObjTransportEinheit && (ObjTransportEinheit->Baustein () == this)
          && ObjTransportEinheit->hatArbeitsplan (arbNr, istv)) ? ObjTransportEinheit->Menge () : 0.0;
}

/*virtual*/ double typBaustein::MengeArtikelVorhanden
                   (unsigned artNr, unsigned istv /*= 0*/) const {
  return (ObjTransportEinheit && (ObjTransportEinheit->Baustein () == this)
          && ObjTransportEinheit->hatArtikel (artNr, istv)) ? ObjTransportEinheit->Menge () : 0.0;
}

/*virtual*/ unsigned typBaustein::AnzahlArbeitsplanBestellbar
                     (unsigned /*arbNr*/, unsigned /*istv = 0*/) const {
  sim_error ("BAUSTEIN", "typBaustein::AnzahlArbeitsplanBestellbar",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
  return 0;
}

/*virtual*/ unsigned typBaustein::AnzahlArtikelBestellbar
                     (unsigned /*artNr*/, unsigned /*istv = 0*/) const {
  sim_error ("BAUSTEIN", "typBaustein::AnzahlArtikelBestellbar",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
  return 0;
}

/*virtual*/ unsigned typBaustein::AnzahlProjektIDBestellbar
                     (unsigned /*artNr*/, unsigned /*suchID*/) const {
  sim_error ("BAUSTEIN", "typBaustein::AnzahlArtikelBestellbar",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
  return 0;
}

/*virtual*/ double typBaustein::MengeArbeitsplanBestellbar
                   (unsigned /*arbNr*/, unsigned /*istv = 0*/) const {
  sim_error ("BAUSTEIN", "typBaustein::MengeArbeitsplanBestellbar",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
  return 0;
}

/*virtual*/ double typBaustein::MengeArtikelBestellbar
                   (unsigned /*artNr*/, unsigned /*istv = 0*/) const {
  sim_error ("BAUSTEIN", "typBaustein::MengeArtikelBestellbar",
             "falscher Bausteintyp fuer Funktion", ObjNummer, FATAL);
  return 0;
}

void typBaustein::stoerungEinleiten (const SimTime& dauer) {
  if (ObjStoerEnde) {
    SimTime t = Modellzeit () + dauer;
    if (t > ObjStoerEnde->Zeit ()) {
      ObjStoerEnde->cancel ();
      ObjStoerEnde->setZeit (t);
      ObjStoerEnde->planeein ();
    }
  }
  else
    if (ObjStoerDauer > 0.0)
      ObjStoerDauer = Max (ObjStoerDauer.inMinutes (), dauer.inMinutes ()) *
                           SimTime::SecondsPerMinute ();
    else {
      ObjStoerDauer = dauer;
      planesofort (ETaktivieren, ObjNummer, 0);
    }
}

void typBaustein::sperrungEinleiten () {
  if ((ObjBasistyp == tRegalverwalter) || (ObjBasistyp == tNcPoolverwalter) ||
      (ObjBasistyp == tKomVerwalter)   || (ObjBasistyp == tFtsVerwalter)    ||
      (ObjBasistyp == tDrehpuffer)     || (ObjBasistyp == tFtsLadepool)     ||
      (ObjBasistyp == tFtsWagen))
    sim_error ("BAUSTEIN", "typBaustein::sperrungEinleiten",
             "falscher Bausteintyp fuer Sperrung", ObjNummer, WARNING);
  else {
    if (!ObjSperrung) {
      ObjSperrung = true;
      planesofort (ETaktivieren, ObjNummer, ObjNummer);
    }
    else {
      ObjSperrung = false;
      planesofort (ETesperrung, ObjNummer);
    }
  }
}

bool typBaustein::isGesperrtOrGestoert () const {
  return (ObjZustand == GESPERRT) || (ObjZustand == GESTOERT);
}

typMeldung *typBaustein::holeMeldung () /*const*/ {
  return ObjMeldungen.removeFirst ();
}

void typBaustein::aufnehmenEinleiten (const Vec3D& posZiel, const SimTime& zeit) {
  ObjTransportEinheit->schaltePlatz ();
  ObjTransportEinheit->AktPlatz ()->setTransportEinheit (ObjTransportEinheit);
  incBelegung ();
  setZustand (AUFNEHMEN);
  planedelta (zeit, ETeaufnehmen, ObjNummer, ObjZielBaustein->Nummer ());

  ObjTaktZiel = posZiel;
  double dz = ObjTaktZiel.Z () - ObjTransportEinheit->Position ().Z ();
  if (dz > 0)	ObjTransportEinheit->bewegen (Vec3D (0.0, 0.0, dz));

  Vec2D posWerk (ObjTransportEinheit->Position ().X (), ObjTransportEinheit->Position ().Y ());
  Vec2D ziel (ObjTaktZiel.X (), ObjTaktZiel.Y ());
  double weg = (ziel - posWerk).len ();

  if (MySFXModel->RealTime ()) {
    Angle ang = ((weg > 0.0) ? RZSNehmWinkel (posWerk, ziel) : Angle (0.0));
    if (ObjBasistyp != tDrehpuffer) // sorry, geht im Moment nicht besser; Matthias 23-02-99
      RzsSenden (ObjNummer, ETaaufnehmen, ((ang - ObjWinkel).deg () < 180.0) ? 1 : -1);
    if (ObjZielBaustein->ObjBasistyp != tDrehpuffer) // sorry, geht im Moment nicht besser; Matthias 23-02-99
      RzsSenden (ObjZielBaustein->Nummer (), ETaabgeben,
                 ((ang - ObjZielBaustein->Winkel ()).deg () < 180.0) ? 1 : -1);
  }

  if (MySFXModel->Cycle ()) {
    ObjTaktSchritte = (unsigned) ((weg - (ClassNehmSchritt / ClassTaktFaktor)) / ClassNehmSchritt);
    ziel -= posWerk;
    if (MySFXModel->Debug ())
      dprintf ("Aufnehmen %1d -> %1d: dx=%5.2f dy=%5.2f weg=%5.2f Schritte=%1d\n",
      ObjZielBaustein->Nummer (), ObjNummer, ziel.X (), ziel.Y (), weg, ObjTaktSchritte);
    if (ObjTaktSchritte > 0) {
      ObjTaktZeit = (zeit.inSeconds () / weg) * ClassNehmSchritt;
      if (MySFXModel->Debug ())
        dprintf ("     Zeit=%8.5f TaktZeit=%8.5f\n", zeit.inMinutes (), ObjTaktZeit.inMinutes ());
      aufn_takt ();
    }
    else ObjTransportEinheit->positionieren (ObjTaktZiel);
  }
  else ObjTransportEinheit->positionieren (ObjTaktZiel);
}

// fuer RZS zur Berechnung der Uebergaberichtung (Laufrichtung) der Paletten.
Angle typBaustein::RZSNehmWinkel (const Vec2D& posWerk, const Vec2D& posZiel) const {
  Vec2D delta (posZiel - posWerk);
  Angle ang (E2X.angle (delta));
  return (delta.Y () < 0.0) ? (Angle (360) - ang) : ang;
}

/*virtual*/ void typBaustein::addEingang (typBaustein* eingang) {
  ObjEingaenge.append (*eingang);
}

/*virtual*/ void typBaustein::addAusgang (typBaustein* ausgang) {
  ObjAusgaenge.append (*ausgang);
}

void typBaustein::aktiviereEingaenge () const {
  for (ObjEingaenge.First (); ObjEingaenge (); ObjEingaenge++)
    if (ObjEingaenge ()->Zustand () == POLLING)
      planesofort (ETaktivieren, ObjEingaenge ()->Nummer (), ObjNummer);
}

void typBaustein::aktiviereAusgaenge () const {
  for (ObjAusgaenge.First (); ObjAusgaenge (); ObjAusgaenge++)
    planesofort (ETaktivieren, ObjAusgaenge ()->Nummer (), ObjNummer);
}

zustandstypen typBaustein::setZustand (zustandstypen z) {
  ObjZustand = z;
  ObjZustandWZ = Modellzeit ();
  if (ObjAuslGeschichte) {
    switch (ObjZustand) {
      case AUFNEHMEN:
      case ARBEITEN:
      case ABGEBEN:
      case FOERDERN:
      case FAHREN:
      case DREHEN:     ObjAuslGeschichte->erfassen (100.0); break;
      /*
      								 if (zLCE_InterfaceBstDaten) {
      								 		int arbPlanNr = 0;
													if (TransportEinheit ()) {														
														arbPlanNr = TransportEinheit ()->Arbeitsplan ()->Nummer ();
													}			      								 	
      								 		zLCE_InterfaceBstDaten->erfassen(ObjZustand, arbPlanNr);  // LCE erfassen
      								 } break;  
      								 */
      default:         ObjAuslGeschichte->erfassen (0.0); break;
      /*
      								 if (zLCE_InterfaceBstDaten) {
      								 		int arbPlanNr = 0;
													if (TransportEinheit ()) {														
														arbPlanNr = TransportEinheit ()->Arbeitsplan ()->Nummer ();
													}			      								 	
      								 		zLCE_InterfaceBstDaten->erfassen(ObjZustand, arbPlanNr);  // LCE erfassen
      								 } break;  
      								 */
    }
  }
  return ObjZustand;
}

void typBaustein::incBelegung () {
  ObjBelegung++;
  if (ObjBelGeschichte) ObjBelGeschichte->erfassen (ObjBelegung);
}

void typBaustein::decBelegung () {
  ObjBelegung--;
  if (ObjBelGeschichte) ObjBelGeschichte->erfassen (ObjBelegung);
}

/*virtual*/ void typBaustein::wartenaufnehmen (typTransportEinheit* zTE, typBaustein* vonWem) {
  if (vonWem->isUebergabeBereit (zTE, this)) {
    setZustand (AKTIVIERT);
    planesofort (ETaaufnehmen, ObjNummer, vonWem->Nummer ());
  }
  else {
    setZustand (WARTEDP);
    vonWem->UebergabeVorbereiten (zTE);
  }
}

/*static*/ void typBaustein::setClassNehmSchritt (double wert){
   typBaustein::ClassNehmSchritt = wert;
}
   
/*static*/ void typBaustein::setClassDrehSchritt (double wert){
   typBaustein::ClassDrehSchritt = wert;
}
 
/*static*/ void typBaustein::setClassFahrSchritt (double wert){
   typBaustein::ClassFahrSchritt = wert;
}
 


//**********************************************   

GeoObject* typBaustein::ErzeugeGeoObject(Vec3D v) {
GeoObject* geo = new GeoObject ();

  geo->copyContents (*ObjTransportEinheit->Geometry ());
  geo->setPos (v);
  geo->setParent (ObjGeometry);
  //geo->setParent(*(MySFXModel->ModelSpace ()));
  geo->setSelectionToMum ();
 // cout << "Pos Baustein: "<< ObjGeometry.Pos() << "   Geo: " << geo->Pos() << endl;
  
  //geo->move(geo->PtToChild(ObjGeometry.Pos()));


  //ObjGeometry.setParent (*(MySFXModel->ModelSpace ()));
  //MySFXModel->insertPermanent (*this, ObjGeometry);
 return geo;
}

typBaustein* typBaustein::ZielBst() const{
	return ObjZielBaustein;
}

GeoObject* typBaustein::GibGeoObject() {
	return &ObjGeometry;
}

typPlatz* typBaustein::gibPlatz(int platz) {
   if (!ObjPalPlaetze[platz]) {
      sim_error ("BAUSTEIN", "typBaustein::gibPlatz",
             "Angeforderter Palettenplatz nicht vorhanden!", ObjNummer, FATAL);
   }
   return ObjPalPlaetze[platz];
}

int typBaustein::aktPalPlatz (){
   return sim_error ("BAUSTEIN", "typBaustein::aktPalPlatz",
            "Palettenplatz noch nicht definiert!", ObjNummer, FATAL);

}

void typBaustein::incBuchung(){
		ObjBuchung++;
}

void typBaustein::decBuchung(){
		ObjBuchung--;
}

// typBaustein
