include "GenericPassengerStation.gs"
include "UBahnWagen.gs"
include "UBahnSignal.gs"
include "vehicle.gs"
include "GSTrackSearch.gs"

class UBahnStation isclass GenericPassengerStation
{

	public int whoAmI;	//Diesen Wert vergleicht die Funktion mit dem Zielfahrtschild; bei Übereinstimmung steigen alle Passagiere aus und die Dasy zeigt "Nicht einsteigen!"!
	public int MySpeaker;	//Wer ist der Abfertiger?
	bool isUBahn;		//Ist das da ein U-Bahnwagen???

	//the base of the following function was the same function in the "GenericPassengerStation.gs" which I have changed.

	int max(int a0, int a1)
	{
		if (a0 > a1)
			return a0;
		return a1;
	}

	public void Init(void)
	{
		inherited();
		MySpeaker = Math.Rand(0, 5 );
	}

	bool PerformMassStoppedLoad(Vehicle vehicle, string triggerName)
	{

		UBahnTriebwagen MyUBahn = null;
		Train train = vehicle.GetMyTrain();
		isUBahn = vehicle.isclass(UBahnTriebwagen);						// Ist der aktuelle Wagen definitionsgemäß ein U-Bahnwagen?

		if (isUBahn)
		{
			MyUBahn = cast<UBahnTriebwagen>(vehicle);
			//if (MyUBahn.Fahrtziel <= 1)							// Wenn ja und falls das Fahrtziel kein "offizielles" ist, wird abgebrochen (z.B. "Bitte nicht einsteigen")
			//	return false;
		}

		if (itcPassengerStation.IsAlreadyAdded(vehicle))
			return false;


		// Already loading everything.
			int i;
		
		TrackLoadInfo info = new TrackLoadInfo();
		GetTrackAndSide(vehicle, triggerName, info);
		if (!info.trackName)
			return false;

		Interface.Log("PerformMassStoppedLoad> trainLeftSide = " + info.trainLeftSide);

		if (info.trainLeftSide == vehicle.GetDirectionRelativeToTrain())
		{
			if (isUBahn)									// Falls es ein UBahn-W. ist, vordefinierte Funktion zum Türöffnen der linken Türen benutzen, sonst Standardanimation abspielen
			{
				while( (! MyUBahn.DoorFreeL) and (Math.Fabs(vehicle.GetVelocity()) < 3) and (train.GetAutopilotMode() == 1) and (train.GetPhysicsModel() != 1) )
					Sleep( 0.1 );
				if(Math.Fabs(vehicle.GetVelocity()) < 3)
				{
					Sleep( Math.Rand(0.0, 1.0) );
					MyUBahn.LDoor = true;
					MyUBahn.OpenDoorsL();
				}
				else
					return false;
			}
			else
				SetMeshAnimationState("left-passenger-door", true);
		}
		else
		{
			if (isUBahn)									// Analog für rechte Tür
			{
				while( (! MyUBahn.DoorFreeR) and (Math.Fabs(vehicle.GetVelocity()) < 3) and (train.GetAutopilotMode() == 1) and (train.GetPhysicsModel() != 1) )
					Sleep( 0.1 );
				if(Math.Fabs(vehicle.GetVelocity()) < 3)
				{
					MyUBahn.RDoor = true;
					MyUBahn.OpenDoorsR();
				}
				else
					return false;
			}
			else
				SetMeshAnimationState("right-passenger-door", true);
		}
		bool isFirstVehicleInThisTrain;

		isFirstVehicleInThisTrain = itcPassengerStation.AddVehicle(vehicle, false);


		if (isFirstVehicleInThisTrain)
		{
			Vehicle[] vehicles = train.GetVehicles();
			
			Sleep(3);

			//int doLoad = ACTION_LOADING;

			int doLoad = ACTION_NOTHING;
			if (itc.IsTrainCommand(train, Industry.LOAD_COMMAND))
				doLoad = ACTION_LOADING;
			else if (itc.IsTrainCommand(train, Industry.UNLOAD_COMMAND))
				doLoad = ACTION_UNLOADING;

			int wohin;
			bool darfeinsteigen = true;

			if (isUBahn)									// Falls U-Bahnwagen:
			{
				wohin = (cast<UBahnTriebwagen>(vehicle)).Fahrtziel;
				if ((wohin == whoAmI) or (wohin <= 1) or (wohin == 3) or (wohin == 50) or (wohin == 51))
					darfeinsteigen = false;						// Falls Fahrtziel = whoAmI oder Betriebsfahrt o.Ä., dann dürfen keine Leute einsteigen
				if (! darfeinsteigen)							// "Wir bitten alle Fahrgaeste, auszusteigen!" (falls Fahrtziel mit diesem Bhf übereinstimmt)
					if( (cast<UBahnTriebwagen>(vehicle)).selbstAbfert )
						Sleep(World.PlaySound( vehicle.GetAsset().FindAsset ("sound_ansage"), "sound/Aussteigen.wav", 1000.0, 100.0, 200.0, vehicle, "a.doors"));
					else
						Sleep(World.PlaySound( vehicle.GetAsset().FindAsset ("sound_ansage"), "sound/Abfert_Aussteigen" + cast<string>MySpeaker + ".wav", 1000.0, 100.0, 200.0, vehicle, "a.doors"));
				else if ( (wohin >= 5) and (wohin <= 14) and (cast<UBahnTriebwagen>(vehicle)).selbstAbfert )				// "Zug nach blablabla." (sonst)
				{
					string zugnachsound = "sound/ZT_" + cast<string>wohin + ".wav";
					Sleep(World.PlaySound( vehicle.GetAsset().FindAsset ("sound_ansage"), zugnachsound, 1000.0, 100.0, 200.0, vehicle, "a.doors"));
				}
			}

			// Immer erst aussteigen lassen, dann einsteigen!

			if (doLoad == ACTION_UNLOADING  or  doLoad == ACTION_LOADING)
			{
				ProductQueue unloadQueue = GetQueue("passengers_off_" + info.platformIndex);
        			PerformProductLoadAndUnload(unloadQueue, train, ACTION_UNLOADING, info);
			}

			if (darfeinsteigen)								// ..., wenn doch:
			{
													// "Einsteigen, bitte!!!"
				if( (cast<UBahnTriebwagen>(vehicle)).selbstAbfert )
					World.PlaySound( vehicle.GetAsset().FindAsset ("sound_ansage"), "sound/Einsteigen.wav", 1000.0, 100.0, 200.0, vehicle, "a.doors");
				else
					World.PlaySound( vehicle.GetAsset().FindAsset ("sound_ansage"), "sound/Abfert_Einsteigen" + cast<string>MySpeaker + ".wav", 1000.0, 100.0, 200.0, vehicle, "a.doors");

      				if (doLoad == ACTION_LOADING)						// ... und die Leute steigen ein
				{
					ProductQueue loadQueue = GetQueue("passengers_on_" + info.platformIndex);
        				PerformProductLoadAndUnload(loadQueue, train, ACTION_LOADING, info);
				}

			}
			else										// sonst steigt keiner ein, sondern...
			{
				int i,j;
													//Wer nicht freiwillig geht, wird von den Sicherheitsmenschen aus der U-Bahn rausgeschmissen... ;-)
				for( i = 0; i < vehicles.size(); i++)
				{
					ProductQueue[] vehicleQueues = vehicles[i].GetQueues();
					for (j = 0; j < vehicleQueues.size(); j++)
					{
						ProductQueue vehicleQueue = vehicleQueues[j];
						vehicleQueue.DestroyAllProducts();
					}
				}
			}

			Sleep(1);

													//"Zurückbleiben, bitte!!!"
			if (isUBahn)									// Falls U-Bahnwagen und Fahrtziel = whoAmI...
			{
				if( (cast<UBahnTriebwagen>(vehicle)).selbstAbfert )
					World.PlaySound( vehicle.GetAsset().FindAsset ("sound_ansage"), "sound/Zurueck.wav", 1000.0, 100.0, 200.0, vehicle, "a.doors");
				else
				{
					if ( darfeinsteigen and (
						(wohin == 5) or
						(wohin == 6) or
						(wohin == 10) or
						(wohin == 26) or
						(wohin == 27) or
						(wohin == 28) or
						(wohin == 31) or
						(wohin == 32)
						 ))
						World.PlaySound( vehicle.GetAsset().FindAsset ("sound_ansage"), "sound/Abfert_nach" + cast<string>wohin + "Zurueck" + cast<string>MySpeaker + ".wav", 1000.0, 100.0, 200.0, vehicle, "a.doors");
					else
						World.PlaySound( vehicle.GetAsset().FindAsset ("sound_ansage"), "sound/Abfert_Zurueck" + cast<string>MySpeaker + ".wav", 1000.0, 100.0, 200.0, vehicle, "a.doors");
				}
			}

			Sleep(2);

			//A2 betätigen falls Zug sich nicht selber abfertigt:

			if (isUBahn)
				if ( ! (cast<UBahnTriebwagen>(vehicle)).selbstAbfert )
				{
					GSTrackSearch thesearch = train.GetVehicles()[0].BeginTrackSearch(true);
					object nextObject = thesearch.SearchNext();
					while( (nextObject != null) and (! nextObject.isclass(Signal) ) )
					{
						nextObject = thesearch.SearchNext();
					}
	
					if( (nextObject != null) and ( nextObject.isclass(UBahnSignal) ) )
					{
						(cast<UBahnSignal>nextObject).A2 = true;
					}
				}

													// Alle Türen schließen...

			float wartezeit = 0.0;

			if( isUBahn and (train.GetAutopilotMode() == 1) and  (train.GetPhysicsModel() != 1) )
			{
				while( (MyUBahn.DoorFreeL) or (MyUBahn.DoorFreeR) and (Math.Fabs(vehicle.GetVelocity()) < 3) )
					Sleep( 0.1 );
			}
			else
				Sleep(2);

			for (i = 0; i < vehicles.size(); i++)
			{
				Vehicle iVehicle = vehicles[i];

				if (itcPassengerStation.IsAlreadyAdded(iVehicle))
				{

					if (iVehicle.isclass(UBahnTriebwagen))			// entweder vordefinierte Funktion:
					{
						(cast<UBahnTriebwagen>(iVehicle)).CloseDoors();
						wartezeit = Math.Fmax(wartezeit,(cast<UBahnTriebwagen>(iVehicle)).DoorCloseTime);
						(cast<UBahnTriebwagen>(iVehicle)).DoorFreeL = false;
						(cast<UBahnTriebwagen>(iVehicle)).DoorFreeR = false;
					}
					else							// oder Standardanimation.
					{
						SetMeshAnimationState("left-passenger-door", false);
						SetMeshAnimationState("right-passenger-door", false);
						wartezeit = Math.Fmax(wartezeit,7.0);
					}
			        }
			}
				
			Sleep(wartezeit);								// solange warten, bis die längste Türschließdauer verstrichen ist...

			for (i = 0; i < vehicles.size(); i++)						// Nun alle Wagen noch freigeben; das war's dann schon wieder!!
			{
				Vehicle iVehicle = vehicles[i];
				if (itcPassengerStation.IsAlreadyAdded(iVehicle))
				{
					itcPassengerStation.RemoveVehicle(iVehicle);
				}
			}

			return true;
		}
		return false;
	}







	// Überschreiben der alten PerformMassStopped-Funktion, damit der Zug nicht mehr "eingefangen" wird.

	thread void PerformMassStopped(Vehicle vehicle, string triggerName)
	{
		Train myTrain = vehicle.GetMyTrain();

		if (itc.IsLockedVehicle(vehicle))
		{
			// this vehicle is already involved in some other loading.
			// probably caused by having two overlapping triggers both calling PerformStopped.
			Interface.Log("BaseIndustry.PerformMassStopped> vehicle already locked");
			return;
		}


		Interface.Log("BaseIndustry.PerformMassStopped");

		bool isUnderScriptControl = itc.IsControllingVehicle(vehicle);

		myTrain.IncTrainBusy();

		// Stop the train

		if ( ( myTrain.GetAutopilotMode() != 1 ) or (myTrain.GetPhysicsModel() == 1) )
		{
			if (!isUnderScriptControl)
				itc.AddVehicle(vehicle, true);
			itc.AddVehicleLock(vehicle);
			itc.SetVehicleSpeed(vehicle, 0.0f);
		}

			ThreadPerformMassStoppedLoad(vehicle, triggerName);

		Interface.Log("BaseIndustry.PerformMassStopped- handing over to the threads");
	}

	// Überschreiben der ThreadPerformMassStoppedLoad-Funktion, damit der Zug nicht mehr "eingefangen" wird.

	thread void ThreadPerformMassStoppedLoad(Vehicle vehicle, string triggerName)
	{
		Interface.Log("* ThreadPerformMassStoppedLoad::vehicle = " + vehicle.GetLocalisedName());

		Train myTrain = vehicle.GetMyTrain();

		bool loadingAllDone = PerformMassStoppedLoad(vehicle, triggerName);

		if ( ( myTrain.GetAutopilotMode() != 1 ) or (myTrain.GetPhysicsModel() == 1) )
			itc.RemoveVehicleLock(vehicle);

		myTrain.DecTrainBusy();

		itc.RemoveVehicle(vehicle);
    
		if (loadingAllDone)
		{
			PostMessage(myTrain, "HandleTrain", "Release", 1.0);
			PostMessage(me, "GenericIndustry", "LoadComplete", 0.0f);
		}
	}


};