//
// UBahnSignal.gs
//

include "signal.gs"
include "train.gs"
include "trackside.gs"
include "GSTrackSearch.gs"
include "trackmark.gs"


class UBahnPreSignal isclass Signal
{
	public bool isDistant = false;
};

class UBahnDirMarker isclass Trackside
{

/* Gleis-Marker: (alt, neues System: (Max)(Min)(Gleis) )
	0: Stop
	1: (linkes) Kehrgleis
	2: rechtes Kehrgleis
	3: mittleres / drittes Kehrgleis
*/

	/* Neues Bezeichnungssystem:
	drei Ziffern, die zusammen eine Zahl zwischen
	0 und 999 ergeben: xyz,
	wobei x der höchste und y der niedrigste zuzulassende Hp-Zustand sind.
	Hierbei gilt folgende Reihenfolge: [niedrig] Hp0 Hp4 Hp3 Hp2 Hp1 [hoch]
	Ein Signal, welches vor einem Marker steht mit 230 als "gleis"-Zahl darf
	also höchstens Hp2 zeigen (niemals Hp1) und muss mindestens Hp3 zeigen;
	eine Hp4-Situation würde also Hp0 bedeuten.

	Die Gleisnummer ist für's Zs2-Signal */

	public int gleis = 0;
};

class UBahnSignal isclass UBahnPreSignal
{

	public void StateHandler(void);

	public Signal nextSignal;			// Nächstes Signal
	public float nextSignalDist;			// Entfernung zum nächsten Signal
	public Signal overnextSignal;			// Übernächstes Signal
	public float overnextSignalDist;		// Entfernung zum übernächsten Signal
	public object nextObject;
	public float nextVehicleDist;			// Entfernung vom Signal bis zum nächstfolgendem Fahrzeug
	public bool comingVehicle;			// Kommt ein Wagen an?
	public object VehicleComing;			// Welcher Wagen?
	public int nextGleisMark;			// Wert der nächsten Signal-Gleismarkierung
	public int hp;					// Hauptsignal-Zustand
	public bool nextSwitchFalse;			// Nächste Weiche ist falsch gestellt!
	public bool A2;					// Abfahrtssignal ist aktiviert (wird bei Hp0 automatisch deaktiviert)

	Train comingTrain;				// Der Zug, der kommt

	thread void Check(void)
	{
		while (1)
		{

			//Halbsekündliche Überwachung:

			Sleep(2.5);

			//Tracksearch in Signalrichtung:

			GSTrackSearch thesearch = BeginTrackSearch(true);
			nextObject = thesearch.SearchNext();
			nextSignal = null;
			nextVehicleDist = -1;
			overnextSignal = null;
			nextGleisMark = -1;
			while( (nextObject != null) )
			{
				if (nextObject.isclass(Signal) and thesearch.GetFacingRelativeToSearchDirection() )
				{
					bool ObjectisDistant = false;
					if ( nextObject.isclass(UBahnPreSignal) )
					{
						UBahnPreSignal temp = nextObject;
						ObjectisDistant = temp.isDistant;
					}
					else
						ObjectisDistant = false;

					if ( nextSignal == null )
					{
						if (! ObjectisDistant )
						{
							nextSignal = nextObject;
							nextSignalDist = thesearch.GetDistance();
						}
					}
					else if ( overnextSignal == null )
					{
						if (! ObjectisDistant )
						{
							overnextSignal = nextObject;
							overnextSignalDist = thesearch.GetDistance();
						}
					}
					else
					{
						if (! ObjectisDistant )
						{
							break;
						}
					}
				}
				if (nextObject.isclass(Vehicle) and ( nextVehicleDist == -1 ))
					nextVehicleDist = thesearch.GetDistance();
				if (nextObject.isclass(UBahnDirMarker) and thesearch.GetFacingRelativeToSearchDirection() and (nextGleisMark == -1))
				{
					UBahnDirMarker temp = nextObject;
					nextGleisMark = temp.gleis;
				}
				nextObject = thesearch.SearchNext();
			}

			thesearch = BeginTrackSearch(false);
			nextObject = thesearch.SearchNext();
			bool foundPrevSignal = false;
			comingVehicle = false;
			VehicleComing = null;
			while( (nextObject != null) )
			{
				if (nextObject.isclass(Signal) and ! thesearch.GetFacingRelativeToSearchDirection() )
				{
					bool ObjectisDistant = false;
					if ( nextObject.isclass(UBahnPreSignal) )
					{
						UBahnPreSignal temp = nextObject;
						ObjectisDistant = temp.isDistant;
					}
					else
						ObjectisDistant = false;

					if ( (! foundPrevSignal) and (! ObjectisDistant) )
					{
						foundPrevSignal = true;
					}
					else if (! ObjectisDistant)
					{
						break;
					}
				}
				if ((nextObject.isclass(Vehicle)) and ! comingVehicle)
				{
					comingVehicle = true;
					VehicleComing = nextObject;
				}
				nextObject = thesearch.SearchNext();
			}

			StateHandler();

			if( GetSignalState() == 0)
				A2 = false;
		}
	}

	public void Init ()
	{
		inherited();
		Check();
	}

	public void StateHandler(){}

};

