//Collision Detection
 //True = collision, false = geen collision
 public bool collisionDetection(Airplane airplane, Way way, Node targetNode)
 {
     foreach (Airplane collisionAirplane in airplanes)
     {
         collisionAirplane.hasCollision = false;
         if (!collisionAirplane.Equals(airplane) && collisionAirplane.isOnAirport()) // Eigen vliegtuig niet meerekenen & vliegtuig moet in bereik van Airport zijn.
         {
             if (collisionAirplane.navigator.currentWay.Equals(way))   // Een ander vliegtuig rijdt op dit moment op de weg
             {
                 if (collisionAirplane.navigator.currentWay.direction == 0)
                 {
                     if (targetNode == collisionAirplane.navigator.getTargetNode())
                     {
                         if (airplane.navigator.getDistanceToTargetNode(airplane.location) > collisionAirplane.navigator.getDistanceToTargetNode(collisionAirplane.location) && airplane.navigator.getDistanceToTargetNode(airplane.location) - collisionAirplane.navigator.getDistanceToTargetNode(collisionAirplane.location) < 150)
                         {
                             airplane.hasCollision = true;
                             return true;
                         }
                     }
                 }
                 if (collisionAirplane.navigator.currentWay.direction != 0)
                 {
                     if (airplane.navigator.getDistanceToTargetNode(airplane.location) > collisionAirplane.navigator.getDistanceToTargetNode(collisionAirplane.location) && airplane.navigator.getDistanceToTargetNode(airplane.location) - collisionAirplane.navigator.getDistanceToTargetNode(collisionAirplane.location) < 150)
                     {
                         airplane.hasCollision = true;
                         return true;
                     }
                 }
             }
         }
     }
     return false;
 }
 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;
        }
        public List<Airplane> planesOnWayInDirection(Way targetway, Node startnode, Airplane source)
        {
            //Maakt een lijst aan met alle vliegtuigen die op een bepaalde weg gaan rijden, en waarbij ze in de richting rijden van startnode > andere node
            List<Airplane> returnlist = new List<Airplane>();

            foreach (Airplane airplane in airplanes)
            {
                if (source != airplane && airplane.navigator != null)
                {
                    if (airplane.navigator.hasWay(targetway))
                    {
                        Node othernode;
                        if (targetway.nodeConnections[0] == startnode)
                            othernode = targetway.nodeConnections[1];
                        else othernode = targetway.nodeConnections[0];
                        if (airplane.navigator.nodes.IndexOf(startnode) < airplane.navigator.nodes.IndexOf(othernode))
                            returnlist.Add(airplane);
                    }
                }
            }

            return returnlist;
        }
        private static void showAsyncPopup(Airplane airplane)
        {
            DialogResult res = MessageBox.Show("Vliegtuig met registratie " + airplane.registration + " komt eerder aan bij een gate dan dat deze vrij is, wilt u de gate veranderen?", "Gate bezet", MessageBoxButtons.YesNo);
            if (res == DialogResult.Yes)
            {
                ScheduleForm scheduleForm = new ScheduleForm(airport);
                scheduleForm.selectedAirplane = airplane;
                scheduleForm.loadPLanes();
                Program.mainForm.Invoke((Action)(() => scheduleForm.ShowDialog()));
                scheduleForm.Focus();
            }
            if (res == DialogResult.No)
            {
                airplane.askAgain = false;
            }

            popup = false;
        }
        /*
         * Permission requesters
         */
        public bool requestWayAccess(Airplane airplane, Way way, Node targetNode)
        {
            if (way != null)
            {
                List<Airplane> currentAirplaneList = new List<Airplane>();
                foreach (Airplane currentAirplane in airplanes)                 // Alle vliegtuigen bekijken
                {
                    if (!currentAirplane.Equals(airplane) && currentAirplane.isOnAirport()) // Eigen vliegtuig niet meerekenen & vliegtuig moet in bereik van Airport zijn.
                    {
                        if (currentAirplane.navigator.currentWay.Equals(way))   // Een ander vliegtuig rijdt op dit moment op de weg
                        {
                            currentAirplaneList.Add(currentAirplane);
                        }
                    }
                }

                if (way.direction != 0)
                {
                    if (currentAirplaneList.Count == 0)
                    {
                        return true;
                    }
                    if (currentAirplaneList.Count == 1)
                        if (currentAirplaneList[0].navigator.getDistanceToTargetNode(currentAirplaneList[0].location) < 700)
                            return true;                                    // Ruw, maar het werkt net zoals hiervoor
                    if (currentAirplaneList.Count == 2)
                        if (Math.Max(currentAirplaneList[0].navigator.getDistanceToTargetNode(currentAirplaneList[0].location), currentAirplaneList[0].navigator.getDistanceToTargetNode(currentAirplaneList[0].location)) < 700)
                            return true;
                    return false;
                }
                else if (!(way is Gate))
                {
                    if (!(way is Runway))
                    {
                    List<Airplane> sameNodeList = new List<Airplane>();
                    foreach (Airplane currentAirplaneListAirplane in currentAirplaneList)
                    {
                        if (currentAirplaneListAirplane.navigator.getTargetNode() != targetNode)
                            sameNodeList.Add(currentAirplaneListAirplane);
                    }

                    if (sameNodeList.Count == 0)
                        return true;
                    if (sameNodeList.Count == 1)
                        if (sameNodeList[0].navigator.getDistanceToTargetNode(sameNodeList[0].location) < 700)
                            return true;
                    if (sameNodeList.Count == 2)
                        if (Math.Max(sameNodeList[0].navigator.getDistanceToTargetNode(sameNodeList[0].location), sameNodeList[1].navigator.getDistanceToTargetNode(sameNodeList[1].location)) < 700)
                            return true;
                    }
                    else if (way is Runway)
                    {
                        if (currentAirplaneList.Count == 0)
                            return true;
                        return false;
                    }
                }

                else if (way is Gate)
                {
                    if (currentAirplaneList.Count == 0)
                        return true;
                }

                return false;
            }
            return false;
        }
 public bool requestTakeOff(Airplane airplane)
 {
     return true;
 }
 // True als vliegtuig een navigator krijgt
 /*
  * Resource requesters
  */
 public bool requestNavigator(Airplane airplane)
 {
     airplane.navigator = new Navigator(airplane, this.ways, this); // En krijgt hij een nieuwe Navigator, die als het goed is een route uitrekent naar de Runway
     return true;
 }
 public void writePLane(Airplane airplane)
 {
     XmlElement plane = PlaneDocument.CreateElement("plane");
     plane.SetAttribute("registration", airplane.registration);
     plane.SetAttribute("carrier", airplane.carrier);
     plane.SetAttribute("type", airplane.typeName);
     plane.SetAttribute("origin", airplane.origin);
     plane.SetAttribute("destination", airplane.destination);
     plane.SetAttribute("departureDate", airplane.departureDate.ToString());
     plane.SetAttribute("arrivalDate", airplane.arrivalDate.ToString());
     plane.SetAttribute("flight", airplane.flight);
     plane.SetAttribute("landingDate", airplane.landingDate.ToString());
     string location = (airplane.location[0] + "," + airplane.location[1]);
     plane.SetAttribute("location", location);
     plane.SetAttribute("gate", airplane.gate);
     XmlNode schedule = PlaneDocument.SelectSingleNode("/schedule");
     schedule.AppendChild(plane);
     PlaneDocument.Save(@"Simulation\schedule.xml");
 }
 private void selectionChange(object sender, ListViewItemSelectionChangedEventArgs e)
 {
     string registration = e.Item.Text;
     foreach (Airplane ap in airport.airplanes)
     {
         if (ap.Registration == registration)
         {
             selectedAirplane = ap;
         }
     }
 }
 private Node findStartNode(Way w, Airplane a)
 {
     if (w.direction == 1) return w.nodeConnections[1]; //Als richting 1, dan de Node waar de baan eindigt is beginpunt
     if (w.direction == -1) return w.nodeConnections[0]; //Andersom voor richting -1
     if (w.direction == 0)                               //Dichtstbijzijnde op dubbelbaansweg
     {
         double d = 1000000; double temp;
         foreach (Node n in w.nodeConnections)
         {
             temp = Utils.getDistanceBetweenPoints(a.location, n.location);
             if (temp < d) d = temp;
         }
         foreach (Node n in w.nodeConnections) if (Utils.getDistanceBetweenPoints(a.location, n.location) == d) return n;
     }
     return null;
 }
        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 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();
            }
        }