public EditPlane(Introductieproject.Objects.Airplane airplane, Introductieproject.Airport.Airport airport, ScheduleForm sch)
 {
     InitializeComponent();
     this.airplane = airplane;
     this.airport = airport;
     this.sch = sch;
     loadGates();
     loadAirplane();
 }
 public NewPlane(Introductieproject.Objects.Airplane airplane, Introductieproject.Airport.Airport airport, ScheduleForm sch)
 {
     InitializeComponent();
     this.airplane = airplane;
     this.airport = airport;
     this.sch = sch;
     loadRunways();
     loadGates();
     loadTypes();
     arrivaldate.CustomFormat = "dd/MM/yyyy HH:mm";
     departuredate.CustomFormat = "dd/MM/yyyy HH:mm";
 }
        public Route findRoute(Node startNode, Node endNode, Airplane airplane, Airport.Airport airport)
        {
            /*
             * Deze methode maakt een stapel aan met routes. Het pakt de bovenste route van deze stapel. Route heeft Node, vorige Route en lengte.
             * Zolang routes op stapel, blijf draaien. Voor iedere route check Node. Is Node endNode? Ja + lengte < kortste Route dan nieuwe kortste Route.
             * Anders kijk Ways bij Node. Als Node = Endnote of lengte Route > lengte beste Route niet opnieuw pushen.
             * Anders nieuwe Route maken met Node andere kant van Way. Resultaat is kortste Route van beginNode naar endNode.
            */

            foreach (Way w in airport.ways)
                w.weightedLength = w.length;

            Stack<Route> routes = new Stack<Route>();
            Route bestRoute = null;
            routes.Push(new Route(startNode, null, 0));
            while (routes.Count > 0)
            {
                Route route = routes.Pop();
                if (route.hasNode(endNode))
                {
                    if (bestRoute == null || route.length < bestRoute.length)
                    {
                        bestRoute = route;
                    }
                }
                IList<Way> connections = route.local.connections;
                foreach (Way connection in connections)
                {
                    if (!route.hasNode(endNode))
                    {
                        if (route.local.isDirectionAllowed(connection))
                        {
                            if (bestRoute == null || route.length <= bestRoute.length)
                            {
                                Node connectedNode = route.local.getConnectedNode(connection);

                                if (!route.hasNode(connectedNode))
                                {
                                    Route newRoute = new Route(connectedNode, route, connection.weightedLength);
                                    routes.Push(newRoute);      //Zet nieuwe Route op stack met Node andere kant connection
                                }
                            }
                            connection.weightedLength = connection.length;
                        }
                    }
                }
            }

            return bestRoute;
        }
        static void Main(string[] args)
        {
            airport = createAirport();

            TimeKeeper.targetScale = 10;                    // Verhouding tussen real en simtime is 1, dus gelijk.
            DateTime simStartTime = new DateTime(2013, 1, 1, 22, 00, 00);
            TimeKeeper.init(simStartTime, true);            // TimeKeeper instellen op vaste starttijd

            mainForm = new MainForm(airport);
            mainForm.Show();

            Simulation.Simulation.initSimulation(airport, true);
            Simulation.Simulation.startSimulation();

            Application.Run(mainForm);
        }
        static Airport.Airport createAirport()
        {
            Airport.Airport airport = new Airport.Airport();

            Parser parser = new Parser();
            List<Taxiway> taxiWayList = new List<Taxiway>();
            List<Runway> runWayList = new List<Runway>();
            List<Gateway> gateWayList = new List<Gateway>();
            List<Gate> gateList = new List<Gate>();
            List<Node> nodeList= new List<Node>();
            parser.getWays(nodeList, runWayList, taxiWayList, gateWayList, gateList);

            airport.ways.AddRange(runWayList);
            airport.ways.AddRange(gateList);
            airport.ways.AddRange(gateWayList);
            airport.ways.AddRange(taxiWayList);
            airport.nodes.AddRange(nodeList);

            return airport;
        }
        /*
         * Berekent op welke schaal het vliegveld getekend zal worden
         */
        public void calculateScaling(Airport.Airport airport)
        {
            foreach (Airport.Node currentNode in airport.nodes)
            {
                if (currentNode.location[0] > maxXCoord)
                {
                    maxXCoord = currentNode.location[0];
                }
                if (currentNode.location[1] > maxYCoord)
                {
                    maxYCoord = currentNode.location[0];
                }
            }

            double xScale = (this.Width - zoomControl1.Width) / (maxXCoord * 2);
            double yScale = this.Height / (maxYCoord * 2);

            maxScreenPixels = Math.Min(this.Width - zoomControl1.Width, this.Height) + 100;

            drawingScale = Math.Min(xScale, yScale) * 2;
        }
        private void drawAirportToBitmap(Airport.Airport airport)
        {
            calculateScaling(airport);

            Graphics graphics = null;
            if (bmpAirport == null || bmpAirport.Size.Width != maxScreenPixels)
            {
                bmpAirport = new Bitmap(maxScreenPixels, maxScreenPixels);
                graphics = Graphics.FromImage(bmpAirport);
            }
            else
            {
                graphics = Graphics.FromImage(bmpAirport);
            }
            graphics.Clear(Color.DarkGray);
            graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            foreach (Way way in airport.ways)
            {
                if (way is Runway && showRunways)
                {
                    drawWay(graphics, Color.Red, way);
                }
                else if(way is Taxiway && showTaxiways)
                {
                    drawWay(graphics, Color.Black, way);
                }
                else if (way is Gateway && showGateways)
                {
                    drawWay(graphics, Color.Green, way);
                }
                else if (way is Gate && showGates)
                {
                    drawGate(graphics, Color.Gray, (Gate) way, way.name);
                }
            }
            if (firstPaint)
            {
               zoomlevelX = bmpAirport.Width -25;
               zoomlevelY = bmpAirport.Height -25;
               mapLocation = new Point(0, this.Height / 4);
               lastPanLocation = new Point(0, this.Height / 4) ;
               firstPaint = false;
            }
            airportDirty = false;
        }
        private void drawAirplanesToBitmap(Airport.Airport airport)
        {
            calculateScaling(airport);
            Graphics graphics = null;
            if (bmpAirplanes == null || bmpAirplanes.Size.Width != maxScreenPixels)
            {
                bmpAirplanes = new Bitmap(maxScreenPixels, maxScreenPixels);
                graphics = Graphics.FromImage(bmpAirplanes);
            }
            else
            {
                graphics = Graphics.FromImage(bmpAirplanes);
                graphics.Clear(Color.Transparent);
            }

            for (int i = 0; i < airport.airplanes.Count; i++ )
            {
                Airplane currentAirplane = airport.airplanes[i];
                if (currentAirplane.isOnAirport())
                {
                    int drawingLocationX = (int)(currentAirplane.location[0] * drawingScale + 10);
                    int drawingLocationY = (int)(currentAirplane.location[1] * drawingScale + 10);

                    if (i == AirplaneStatsControl.currentSelectedRow)
                    {
                        graphics.FillEllipse(Brushes.LightBlue, drawingLocationX - 3, drawingLocationY - 3, 6, 6);
                        graphics.DrawString(currentAirplane.flight, SystemFonts.DefaultFont, Brushes.Black, drawingLocationX + 2, drawingLocationY - 14);
                    }
                    else
                    {
                        graphics.FillEllipse(Brushes.White, drawingLocationX - 3, drawingLocationY - 3, 6, 6);
                        if (alwaysShowFlight)
                        {
                            graphics.DrawString(currentAirplane.flight, SystemFonts.DefaultFont, Brushes.Black, drawingLocationX + 2, drawingLocationY - 14);
                        }
                    }
                }
            }
            airplanesDirty = false;
        }
        public void init(Airport.Airport airport)
        {
            this.airport = airport;

            airportDirty = true;
            airplanesDirty = true;
        }
        public void simulate(Airport.Airport airport)
        {
            if (isSimulating)
            {
                return;
            }
            isSimulating = true;

            if (status == Status.CANCELLED)
            {
                //Hij doet niets meer als hij gecancelled is
            }
            else if (status == Status.APPROACHING)       // Vliegtuig is nog niet aangekomen
            {
                if (TimeKeeper.currentSimTime >= this.landingDate)
                {
                    if (this.navigator == null)
                    {
                        requestNavigator(airport);
                    }
                    if (requestWayAccess(airport, this.navigator.currentWay, this.navigator.getTargetNode()))
                    {
                        this.land();
                    }
                }
            }
            else if (status == Status.DEPARTED)
            {
            }
            else if (status == Status.DOCKING)      // Vliegtuig staat bij gate
            {
                if (cancelled)
                    status = Status.CANCELLED;
                if (TimeKeeper.currentSimTime >= actualDepartureDate)
                {
                    leaveDock();
                    requestNavigator(airport);
                }
            }
            else if (status == Status.WAITING_TAKEOFF)    // Vliegtuig wacht voordat hij mag opstijgen
            {
                speed = 0;
                requestTakeOff(airport);
            }
            else if (status == Status.TAKINGOFF)
            {
                double targetAngle = navigator.getAngleToTarget(location);
                if (angle != targetAngle)
                    rotate(targetAngle);
                else if (angle == targetAngle)
                {
                    this.accelerate(takeofSpeed);
                    if (this.speed == takeofSpeed)
                    {
                        takeOff();
                    }
                }
            }
            else if (navigator == null)
            {
                requestNavigator(airport);
            }
            else if (status == Status.TAXIING)
            {
                //status = Status.IDLE;

                Node targetNode = navigator.getTargetNode();

                if (targetNode == null)
                {
                    //wanneer de targetnode null is, betekent het dat de navigator bij zijn eindpunt is aangekomen
                    if (!hasDocked)
                    {
                        dock();
                    }
                }
                else
                {
                    double distanceToTarget = navigator.getDistanceToTargetNode(location);
                    double targetAngle = navigator.getAngleToTarget(location);

                    //maximumsnelheid staat nu vast op 10m/s, dat moet per baan verschillend worden. Snelheid in bochten staat vast op 3m/s
                    taxiSpeed = 20;
                    //if (navigator.getCurrentWay() is Gateway)

                    double cornerSpeed = 3;
                    navigator.location = this.location;

                    //TODO collision test
                    if (distanceToTarget < 20)
                    {
                        if (this.hasDocked && navigator.targetWay is Runway)
                        {
                            requestWayAccess(airport, navigator.targetWay, navigator.getTargetNode());
                            prepareTakeOff();
                        }

                        else if (navigator.hasNextTarget())
                        {

                            if (requestWayAccess(airport, navigator.targetWay, targetNode)) // Toestemming verzoeken voor volgende way
                            {
                                navigator.setNextTarget();
                            }
                            else if (!requestWayAccess(airport, navigator.targetWay, navigator.getTargetNode()) && navigator.getTargetWay() is Gate)
                            {
                                foreach (Airplane dockedPlane in airport.airplanes)
                                {
                                    // Als er al een vliegtuig staat bij de gate waar dit vliegtuig naartoe wilt, en de vertrektijd ligt na de verwachtte aankomst tijd: Open edit scherm voor nieuwe gate.
                                    if (dockedPlane.gate == this.gate && dockedPlane.isOnAirport() && (dockedPlane.status == Status.DOCKING || dockedPlane.status == Status.CANCELLED))
                                    {
                                        if (this.arrivalDate < dockedPlane.actualDepartureDate)
                                        {
                                            this.isWaiting = true;
                                            break;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                this.accelerate(cornerSpeed);
                                //speed = 0;
                            }
                        }
                    }

                    if (distanceToTarget <= 0.5)
                    {
                        if (this.hasDocked && navigator.targetWay is Runway)
                        {
                            requestWayAccess(airport, navigator.targetWay, navigator.getTargetNode());
                            prepareTakeOff();
                        }

                        if (requestWayAccess(airport, navigator.targetWay, navigator.getTargetNode()) && navigator.currentWay is Gate) // Toestemming verzoeken voor volgende way
                        {
                            if (!hasDocked)
                            {
                                if (Utils.getDistanceBetweenPoints(location,navigator.getFinalNode().location) < 0.5)
                                    dock();
                            }
                        }
                    }

                    if (distanceToTarget <= speed * TimeKeeper.elapsedSimTime.TotalSeconds)
                    {
                        moveBy(distanceToTarget);
                        speed = 0;
                    }

                    if (speed > taxiSpeed)
                    {
                        accelerate(taxiSpeed);
                    }

                    if (angle != targetAngle)  // Vliegtuig staat niet in de goede richting, roteren
                    {
                        rotate(targetAngle);
                    }

                    if (speed < taxiSpeed && distanceToTarget > 50 && angle == targetAngle)
                    {
                        accelerate(taxiSpeed);
                    }
                    else if ((speed > cornerSpeed) || speed < cornerSpeed && distanceToTarget <= 50 && angle == targetAngle && !standingStill && distanceToTarget > 0)
                    {
                        accelerate(cornerSpeed);
                    }
                    else if (navigator.currentWay is Taxiway && airport.collisionDetection(this, navigator.currentWay, navigator.getTargetNode()))
                    {
                        accelerate(0);
                    }

                    else if (angle == targetAngle)  //alleen move als hij in de goede richting staat
                    {
                        move();
                    }
                }
            }
            isSimulating = false;
        }
        public IList<Way> wayPoints; // De lijst met toekomstige waypoints voor het vliegtuig

        #endregion Fields

        #region Constructors

        public Navigator(Airplane airplane, List<Way> ways, Airport.Airport airport)
        {
            newRoute(airplane, ways, airport);
        }
 public void requestTakeOff(Airport.Airport airport)
 {
     if (airport.requestTakeOff(this))
     {
         status = Status.TAKINGOFF;
         navigator.setNextTarget();
     }
 }
 public void requestNavigator(Airport.Airport airport)
 {
     airport.requestNavigator(this);
 }
        public void update(Airport.Airport airport)
        {
            if (airport.airplanes.Count != dgvAirplanes.Rows.Count)
            {
                dgvAirplanes.Rows.Clear();
                dgvAirplanes.Rows.Add(airport.airplanes.Count);
            }
            for(int i = 0; i < airport.airplanes.Count; i++)
            {
                if (i == currentSelectedRow)
                {
                    dgvAirplanes.Rows[i].Selected = true;
                }
                Airplane currentAirplane = airport.airplanes[i];
                string[] columnValues = new string[]{currentAirplane.statusString, currentAirplane.Registration,
                                                     currentAirplane.PlannedArrival, currentAirplane.PlannedDeparture, currentAirplane.CurrentDelay};
                dgvAirplanes.Rows[i].SetValues(columnValues);
                dgvAirplanes.Rows[i].HeaderCell.Value = currentAirplane.flight;
                TimeSpan totalDelay = new TimeSpan();
                totalDelay = currentAirplane.delay + currentAirplane.arrivalDifference + currentAirplane.landingDifference;
                if (totalDelay.Ticks != 0)
                {
                    dgvAirplanes.Rows[i].Cells[4].Style.ForeColor = Color.Red;
                }
            }

            try
            {
                Airplane currentAirplane = airport.airplanes[currentSelectedRow];
                Navigator navi = currentAirplane.navigator;

                if (navi != null && navi.nodes != null)
                {

                    if (navi.wayList.Count != dgvNodes.Rows.Count)
                    {
                        dgvNodes.Rows.Clear();
                        dgvNodes.Rows.Add(navi.wayList.Count);
                    }

                    string completion;
                    Boolean hadCurrentWay = false;
                    for (int i = 0; i < navi.wayPoints.Count; i++)
                    {
                        Airport.Way currentWay = navi.wayPoints[i];

                        if (navi.currentWay is Runway)
                        {
                            completion = "0";
                        }
                        else
                        {
                            completion = "100";
                        }

                        if (currentWay.Equals(navi.currentWay))
                        {
                            dgvNodes.Rows[i].Selected = true;
                            double distanceLeft = Utils.getDistanceBetweenPoints(currentAirplane.location, navi.nodes[navi.targetNodeNumber - 1].location);
                            double totalDistance = (int)Utils.getDistanceBetweenPoints(navi.nodes[navi.targetNodeNumber - 1].location, navi.nodes[navi.targetNodeNumber].location);
                            completion = ((int)((distanceLeft / totalDistance) * 100)).ToString();
                            hadCurrentWay = true;
                        }
                        else if (hadCurrentWay)
                        {
                            completion = "0";
                        }

                        string loc1 = currentWay.nodeConnections[0].location[0] + "," + currentWay.nodeConnections[0].location[1];
                        string loc2 = currentWay.nodeConnections[1].location[0] + "," + currentWay.nodeConnections[1].location[1];

                        string permissionString = null;
                        if (navi.permissions[i] == Navigator.PermissionStatus.GRANTED)
                        {
                            permissionString = "Granted";
                        }
                        else if (navi.permissions[i] == Navigator.PermissionStatus.REQUESTED)
                        {
                            permissionString = "Requested";
                        }
                        else
                        {
                            permissionString = "Denied";
                        }

                        string[] columnValues = new string[]{currentWay.name, permissionString,
                                                         completion, loc1, loc2};

                        dgvNodes.Rows[i].SetValues(columnValues);
                    }
                }
                else
                {
                    dgvNodes.Rows.Clear();
                }

                lbSpeed.Text = currentAirplane.speed.ToString();
                lbLocX.Text = Math.Round(currentAirplane.location[0]).ToString();
                lbLocY.Text = Math.Round(currentAirplane.location[1]).ToString();
                lbStatus.Text = currentAirplane.statusString;
                lbGate.Text = "Gate " + currentAirplane.gate;
                lbFlight.Text = currentAirplane.Flight;

                pnAirplane.Invalidate();
            }
            catch (ArgumentOutOfRangeException) { }
        }
 public void init(Airport.Airport airport)
 {
     this.airport = airport;
 }
 public bool requestWayAccess(Airport.Airport airport, Way targetWay, Node targetNode)
 {
     if (airport.requestWayAccess(this, targetWay, targetNode))
     {
         navigator.permissions[navigator.targetNodeNumber] = Navigator.PermissionStatus.GRANTED;
         navigator.permissionCounter++;
         return true;
     }
     else
     {
         navigator.permissions[navigator.targetNodeNumber] = Navigator.PermissionStatus.REQUESTED;
         navigator.permissionCounter++;
         return false;
     }
 }
        public void draw(Airport.Airport airport)
        {
            if (airportDirty)
            {
                Thread airplanesDrawThread = new Thread(() => drawAirplanesToBitmap(airport));
                airplanesDrawThread.Start();

                drawAirportToBitmap(airport);

                airplanesDrawThread.Join();
            }
            else if(airplanesDirty)
            {
                drawAirplanesToBitmap(airport);
            }
        }
        public void newRoute(Airplane airplane, List<Way> ways, Airport.Airport airport)
        {
            /*
            Routeplanner zelf
            Om aan te roepen, geef een vliegtuig mee. Vliegtuig weet huidige coordinaten
            Stap 1, waar is het vliegtuig nu?
            */
            Way startWay = null;
            foreach (Way w in ways)
            {
                if (Utils.isPointInWay(airplane.location, w))
                {
                    //Kijkt of het vliegtuig zich op een weg bevindt en als dat zo is zet de startWay als die weg
                    startWay = w;
                    break;
                }
            }
            if (startWay == null)
                startWay = Utils.getClosestWay(airplane.location, ways);

            if (startWay != null) //Om zeker te weten dat een beginlocatie bepaald is
            {
                Way endWay = null;
                //Stap 2, waar moet het vliegtuig heen? Zoek een vrije gate als start een runway is, en vice versa

                if (!airplane.hasDocked)
                {

                    //Utils.getClosestWay(airplane.location, airplane.gate);

                       /*Check de gates - open gate. Als geen gates open, zoek 1: dichtstbijzijnde gate of 2: langst bezette gate.
                       * Optie 1 heeft waarschijnlijk iets kleinere kans op file voor 1 gate, vanwege meerdere Runways en vertraging tussen vliegtuigen landen op zelfde Runway.
                       * Optie 2 leidt vrijwel altijd tot alle nieuwe vliegtuigen naar dezelfde gate -> file.
                       * IList<Gate> availableGates = new List<Gate>();
                       * IList<Gate> occupiedGates = new List<Gate>();
                       * IList<Gate> reservedGates = new List<Gate>();
                       * occupiedGates = airport.occupiedGates();
                        */
                       foreach (Way w in ways)
                       {
                           if (w is Gate)
                           {
                               if (w.name == airplane.gate)
                               {
                                   endWay = (Gate)w;
                                   break;
                               }
                           }
                       }
                }
                else if (airplane.hasDocked)
                {
                    IList<Way> runways = new List<Way>();
                    foreach(Way w in ways)
                    {
                        if(w is Runway)
                            runways.Add(w);
                    }
                    endWay = Utils.getClosestWay(airplane.location, runways);
                }
                Node startNode = findStartNode(startWay, airplane);
                Node endNode = endWay.nodeConnections[1]; //De endNode is de beginNode van een Way want: vliegtuig moet naar begin runway of gate
                Route bestRoute = findRoute(startNode, endNode, airplane, airport);
                this.nodes = bestRoute.RouteList();
                wayPoints = convertNodesToWaypoints(bestRoute.RouteList()); // Geef de lijst met Ways door aan het vliegtuig. (Hier gekozen voor lijst van Ways, lijkt handiger ivm toestemming)
                for (int i = 0; i <= wayPoints.Count; i++)
                {
                    permissions.Add(PermissionStatus.NONE);
                }
                // Ways initten
                currentWay = startWay;
                getTargetWay();
            }
        }