override public void TramArrive(Tram tram)
        {
            if (firstOpenPos() == -1)
            {
                Console.WriteLine("Attempted to TramArrive at full endpoint. Crashing");
                Console.ReadLine(); Sim.EmergencyExit();;
            }
            else
            {
                tram.moveToNext();
                tram.busy      = false;
                tram.hasloaded = false;
                Previous.bumpTrams();
                tram.arrivaltime = Time.Now();
                tram.tramActivitylog.WriteLine(Time.Now() + " , Arrival , " + Name);

                logInterDepartureTime.WriteLine((Time.Now()).ToString() + " , " + (Time.Now() - lastDeparture).ToString());

                if (!TramRetire(tram))
                {
                    if (!tramloading)
                    {
                        new StartPassTransfer(Time.Now(), tram, this);
                        tramloading = true;
                    }
                }
            }
        }
        override public void handleDepart(Tram tram, int slot)
        {
            int pos = findTram(tram);

            if (pos == 0)       // tram in line with departing rail
            {
                if (!raillock[0])
                {
                    tram.busy = true;
                    int time = TimeLocked();
                    new TrackLock(Time.Now() + time, tram, this, 0, false);
                    logPunctuality.WriteLine(Time.Now().ToString() + " , " + (Time.Now() - timetable[slot]).ToString());
                    counter++;
                    //Console.WriteLine(counter.ToString());

                    base.handleDepart(tram, 0);
                }
                else
                {
                    usedtimes[slot] = false;
                    tram.busy       = false;
                }
            }
            else if (pos == 1)       // tram not in line with departing rail
            {
                if ((!raillock[0]) && (!raillock[1]))
                {
                    tram.busy = true;
                    int time = TimeLocked();
                    logPunctuality.WriteLine(Time.Now().ToString() + " , " + (Time.Now() - timetable[slot]).ToString());
                    counter++;
                    //Console.WriteLine(counter.ToString());
                    new TrackLock(Time.Now() + time, tram, this, 2, false);

                    base.handleDepart(tram, 0);
                }
                else
                {
                    usedtimes[slot] = false;
                    tram.busy       = false;
                }
            }
            else
            {
                Console.WriteLine("Event handleDepart at station " + Name + " at time " + Time.Now().ToString() + " attempted on tram not at the station.");
                Console.ReadLine(); Sim.EmergencyExit();
            }
        }
/*
 *          TramLock methods
 *
 */
        override public void LockTrack(int track)
        {
            if (track == 2)
            {
                LockTrack(0);
                LockTrack(1);
            }
            else
            {
                if (raillock[track])
                {
                    Console.WriteLine("Attempt to lock locked track. Crashing");
                    Console.ReadLine(); Sim.EmergencyExit();;
                }
                raillock[track] = true;
            }
        }
        /*
         *  used to reserve a slot when planning a departure
         *  necessary so that other trams cannot use this scheduled departure for their decisions, but allows for the tram to release the slot in case it cannot leave at the scheduled time.
         */
        private int ReserveSlot()
        {
            int first = -1;

            for (int i = 0; i < usedtimes.Length; i++)
            {
                if (!usedtimes[i])
                {
                    first = i; break;
                }
            }
            if (first == -1)
            {
                Console.WriteLine("Tried to reserve from an empty timetable at station " + Name);
                Console.ReadLine(); Sim.EmergencyExit();
            }
            usedtimes[first] = true;
            return(first);
        }
        //Handles actual arrival.
        override public void TramArrive(Tram tram)
        {
            if (this.firstOpenPos() == -1)
            {
                Console.WriteLine("Tried to move tram to station" + Name + " while there were no free spaces. Crashing");
                Console.ReadLine(); Sim.EmergencyExit();;
            }
            else
            {
                tram.moveToNext();
                tram.busy = false;
                Previous.bumpTrams();
                tram.arrivaltime = Time.Now();
                tram.tramActivitylog.WriteLine(Time.Now() + " , Arrival , " + Name);

                new StartPassTransfer(Time.Now(), tram, this);
                logInterDepartureTime.WriteLine((Time.Now()).ToString() + " , " + (Time.Now() - lastDeparture).ToString());
            }
        }
        override public void UnlockTrack(int track)
        {
            if (Simulation.EXPLICIT)
            {
                Console.WriteLine("Releasing tracklocks at station " + Name);
            }
            if (track == 2)
            {
                raillock[0] = false;
                raillock[1] = false;
            }
            else
            {
                if (!raillock[track])
                {
                    Console.WriteLine("Attempt to unlock unlocked track. Crashing");
                    Console.ReadLine(); Sim.EmergencyExit();;
                }
                raillock[track] = false;
            }

            //Check if tram can enter/leave station.

            if (ReadyTram() != null && !raillock[0])
            {
                if (Simulation.EXPLICIT)
                {
                    Console.WriteLine("Planning departure of tram" + ReadyTram().TramNo.ToString() + " from station " + Name + " after lock has been released");
                }
                //Console.ReadLine();
                planDeparture(ReadyTram());
            }
            if (Previous.ReadyTram() != null && !raillock[1])
            {
                if (Simulation.EXPLICIT)
                {
                    Console.WriteLine("Planning arrival of tram after lock has been released");
                }
                //Console.ReadLine();
                new EndTransit(Time.Now(), Previous.ReadyTram(), this);
            }
        }
/*
 *          Departure methods
 */


        //due to the scheduling at Termini which doesn't exist at regular stations, it's require to plan departures in advance.
        public void planDeparture(Tram tram)
        {
            int next = NextDeparture();

            if (next == -1)
            {
                TramRetire(tram);
                return;
            }

            int slot = ReserveSlot();



            if (next < Time.Now())
            {
                tram.busy = true;
                new StartTransit(Time.Now(), tram, this, slot);
            }
            else
            {
                tram.busy = true;
                new StartTransit(next, tram, this, slot);
            }

            if (tramloading && ReadyToLoad() != null)
            {
                Console.WriteLine("At planDeparture: tramloading == true, but also tram ready to load.");
                Console.ReadLine(); Sim.EmergencyExit();
            }
            if (ReadyToLoad() != null)
            {
                if (ReadyToLoad().TramNo == tram.TramNo)
                {
                    Console.WriteLine("Trying to start passenger loading departing tram");
                    Console.ReadLine(); Sim.EmergencyExit();
                }
                tramloading = true;
                new StartPassTransfer(Time.Now(), ReadyToLoad(), this);
            }
        }