private Simulation Sim;                 //Only used to call emergency exit.

        public Tram(int number, Endstation place, int max, string datafolder, Simulation sim)
        {
            PassMax = max;
            PassCurr = 0;
            TramNo = number;
            indepot = true;
            busy = false;
            Position = place;
            hasloaded = false;
            TotIn = 0; TotOut = 0;
            cameFromDepot = false;
            Sim = sim;

            int i = 0;
            while (i < place.depot.Length) {
                if (place.depot[i] == null) {
                    place.depot[i] = this;
                    break;
                }
                i++;
            }
            logger = new StreamWriter(datafolder + "Tram" + TramNo.ToString() + ".csv");
            logger.WriteLine("time , place of departure , place of arrival");
            tramActivitylog = new StreamWriter(datafolder+"activityLogTram" + TramNo.ToString() + ".txt");
            logPassengers = new StreamWriter(datafolder + "Tram" +TramNo.ToString() + "PassLog.csv");
            logPassengers.WriteLine("time, location, passengers, passengers in, passengers out");
        }
 /*
     Creates the eventlist.
     Events added upon creation:
         EndSim event
         RecruitTram event (planned 30 seconds before each planned departure at the endstation containing the depot)
 */
 public static void buildEventList (int endtime, int[] timetable, Endstation place, Simulation sim) {
     Sim = sim;
     if (Simulation.EXPLICIT) {
         Console.WriteLine("Initialising event list");
         if (Simulation.WAIT) Console.ReadLine();
     }
     list.Add(new EndSim(endtime, sim));
     for (int i = 0; i < timetable.Length; i++) {
         int time = Math.Max(0, timetable[i] - 30);
         new RecruitTram(time, null, place);
     }
 }
 /*
     called when the EndSim event is called. Checks if the eventlist is empty. If it's not, it creates a new EndSim event and forces continuation of the main loop.
 */
 public static bool allowEnding(Simulation sim) {
     Console.WriteLine("Checking if allowing to end");
     if (list.Count() > 0) {
         Console.WriteLine("Simulation would've ended while not all events were done");
         if (Simulation.WAIT) Console.ReadLine();
         list.Add( new EndSim ( list[list.Count() -1].ETime + 600, sim) );
         return false;
     }
         
     else {
         Console.WriteLine("Ending Simulation Allowed at time." );
         return true;
     }
 }
 public EndSim(int time, Simulation sim) {
     Priority = -1;
     ETime = time;
     Name = "Endsim";
     Sim = sim;
     if (Simulation.EXPLICIT) Console.WriteLine("End of simulation planned for " + ETime.ToString());
 }
        static void Main(string[] args) {
            Console.WriteLine("give folder name \n");
            string folder = Console.ReadLine();
            Simulation sim = new Simulation(folder); 

        }
 public InTransit (int maxTrams, Simulation sim, string name) {
     Spaces = new Tram[maxTrams];
     Name = "intransitafter" + name;
     Sim = sim;
 }
        public Endstation (string name, bool depot, int maxtrams, TimeDistr inrate, TimeDistr outrate, 
                           TimeDistr indens, int pass, double driveavg, double drivevar, TimeDistr schedule,
                           int timefromstrt, string datafolder, Simulation sim ) 
                           : base(name,inrate,outrate,indens, pass, driveavg, drivevar, datafolder, sim) {
            if (Simulation.EXPLICIT) {
                Console.WriteLine("Initialising Endstation " + name);
                if (Simulation.WAIT) Console.ReadLine();
            } 
            Spaces = new Tram[2];
            raillock = new bool[2];
            if (depot) this.depot = new Tram[maxtrams];
            Name = name;
            Dweltime = 4* 60;  //Parameterize this.
            //counter = 0;

            logPunctuality = new StreamWriter(datafolder + Name + "Punctuality.csv");
            logPunctuality.WriteLine("Time , Deviation from schedule");

            //create schedule
            int[] periods = schedule.getTimes();
            double[] intensity = schedule.getRates();

            if (Simulation.EXPLICIT) {
                Console.WriteLine("Creating timetable at Endstation " + name);
                if (Simulation.WAIT) Console.ReadLine();
            } 
            Queue<int> temptable = new Queue<int>();

            for (int i = 0; i < periods.Length ; i++) {
                if ( (i+1 == periods.Length + timefromstrt) || (intensity[i] == 0.0) ){
                    if (Simulation.EXPLICIT) Console.WriteLine("Scheduled leaving of tram at " + (periods[i]+ timefromstrt).ToString() );
                    temptable.Enqueue(periods[i] + timefromstrt);
                    continue;
                }
                int next = periods[i] + timefromstrt;
                
                int intdeptime = Convert.ToInt32( 3600.0/intensity[i]);
                while (next < periods[i+1] + timefromstrt) {
                    if (Simulation.EXPLICIT) Console.WriteLine("Scheduled event leaving at " + next.ToString() );

                    temptable.Enqueue(next);
                    next += intdeptime;
                }
            }

            timetable = temptable.ToArray();
            StreamWriter logTimeSchedule = new StreamWriter(datafolder + Name + "schedule.txt");
            
            foreach (int i in timetable) {
                logTimeSchedule.WriteLine(i.ToString());
            }

            usedtimes = new bool[timetable.Length];
            for (int i = 0; i < usedtimes.Length; i++) {
                usedtimes[i] = false;
            }
            logTimeSchedule.Close();

        }
        public Station (string name, TimeDistr inrate, TimeDistr outrate, TimeDistr indens, int pass, 
                        double driveavg, double drivevar, string datafolder, Simulation sim) { 
            if (Simulation.EXPLICIT) {
                Console.WriteLine("Initialising station " + name);
                if (Simulation.WAIT) Console.ReadLine();
            } 
            Name = name;
            Spaces = new Tram[1];
            lastpassupdate = 0;
            PassWaiting = 0;
            lastDeparture = 0;
            TotalIn = 0;
            TotalOut = 0;
            DriveAvg = driveavg;
            DriveVar = drivevar;
            Sim = sim;


            //reformulate distributions for incoming passengers to something sensible
            int[] times = indens.getTimes();
            double[] passengers = new double[times.Length];
            for (int i = 0; i < passengers.Length; i++) {
//                if (Simulation.EXPLICIT) Console.WriteLine("Calculating passengers at time " + times[i].ToString());
                passengers[i] = Convert.ToDouble(pass) * inrate.getRate(times[i]) * indens.getRate(times[i]);
//                if (Simulation.EXPLICIT) Console.WriteLine("Passengers from time " + times[i].ToString() + " : " + passengers[i].ToString());
            }
            PassArrival = new TimeDistr(times, passengers);

            PassArrival.WriteToFile(datafolder+Name+"PassDistr.csv");

            PassOut = outrate;
    
            logPassengersWaiting = new StreamWriter(datafolder + Name + "PassWaiting.csv");
            logPassengersWaiting.WriteLine("Time , Passengers waiting, passengers in tram");
            logInterDepartureTime = new StreamWriter(datafolder + Name + "IntDepTime.csv");
            logInterDepartureTime.WriteLine("Time , time since last Departure");
            logTramsWaiting = new StreamWriter(datafolder + Name + "TramsWaiting.csv");
            logTramsWaiting.WriteLine("Time , trams waiting , trams at station");
            logWaitingtime = new StreamWriter(datafolder + Name + "WaitingTime.csv");
            logWaitingtime.WriteLine("Time , passengers already waiting , time last departure , new passengers , time since last passenger update , passengers waiting after loading");
            logDwelltime = new StreamWriter(datafolder + name + "Dwelltime.csv");
            logDwelltime.WriteLine("Time , dwelltime of departing tram");

        }