public void getCorrelatedFeature()      //get the correlated feature
        {
            CorrelatedFeature = "";
            Line reg = null;

            for (int i = 0; i < cf.Count; i++)
            {
                if (cf[i].Feature1 == DesiredFeature)
                {
                    CorrelatedFeature = cf[i].Feature2;
                    reg = cf[i].LineReg;
                    break;
                }
                if (cf[i].Feature2 == DesiredFeature)
                {
                    CorrelatedFeature = cf[i].Feature1;
                    reg = cf[i].LineReg;
                    break;
                }
            }
            // adding the point to the graphs
            if ((CorrelatedFeature.EndsWith("1") || CorrelatedFeature.EndsWith("2")) && CorrelatedFeature != "")
            {
                PointsTopLeftGraph.Add(new DataPoint(TimeInDeci, getDuplicatedFaetureVal(CorrelatedFeature)));
                PointsBottomGraph.Add(new DataPoint(PointsTopRightGraph.Last().Y, PointsTopLeftGraph.Last().Y));
                // if the bottom graph has more then 30 points inside it, the first point will move to the old bottom graph points
                if (PointsBottomGraph.Count > 30)
                {
                    OldPointsBottomGraph.Add(PointsBottomGraph.First());
                    PointsBottomGraph.Remove(PointsBottomGraph.First());
                }
                // for saving the minimum and maximum x values of the line regression.
                if (PointsBottomGraph.Last().X < lineMinX)
                {
                    lineMinX = (float)PointsBottomGraph.Last().X;
                }
                if (PointsBottomGraph.Last().X > lineMaxX)
                {
                    lineMaxX = (float)PointsBottomGraph.Last().X;
                }
                if (LineBottomGraph.Count == 0)
                {
                    LineBottomGraph.Add(new DataPoint(lineMinX, reg.f(lineMinX)));
                    LineBottomGraph.Add(new DataPoint(lineMaxX, reg.f(lineMaxX)));
                }
                else
                {
                    LineBottomGraph[0] = new DataPoint(lineMinX, reg.f(lineMinX));
                    LineBottomGraph[1] = new DataPoint(lineMaxX, reg.f(lineMaxX));
                }
            }
            // the same idea in case the desired feature doesnt have a duplicate value
            else if (CorrelatedFeature != "")
            {
                PointsTopLeftGraph.Add(new DataPoint(TimeInDeci, getFaetureVal(CorrelatedFeature)));
                PointsBottomGraph.Add(new DataPoint(PointsTopRightGraph.Last().Y, PointsTopLeftGraph.Last().Y));
                if (PointsBottomGraph.Count > 30)
                {
                    OldPointsBottomGraph.Add(PointsBottomGraph.First());
                    PointsBottomGraph.Remove(PointsBottomGraph.First());
                }
                if (PointsBottomGraph.Last().X < lineMinX)
                {
                    lineMinX = (float)PointsBottomGraph.Last().X;
                }
                if (PointsBottomGraph.Last().X > lineMaxX)
                {
                    lineMaxX = (float)PointsBottomGraph.Last().X;
                }
                if (LineBottomGraph.Count == 0)
                {
                    LineBottomGraph.Add(new DataPoint(lineMinX, reg.f(lineMinX)));
                    LineBottomGraph.Add(new DataPoint(lineMaxX, reg.f(lineMaxX)));
                }
                else
                {
                    LineBottomGraph[0] = new DataPoint(lineMinX, reg.f(lineMinX));
                    LineBottomGraph[1] = new DataPoint(lineMaxX, reg.f(lineMaxX));
                }
            }
            // else, the desired value is changed
            else
            {
                pointsTopLeftGraph.Clear();
                pointsBottomGraph.Clear();
                lineBottomGraph.Clear();
                OldPointsBottomGraph.Clear();
                CorrelatedFeature = "";
            }
        }
        // starting the application
        public void start()
        {
            this.connect(Constants.HOST_IP, Constants.HOST_PORT);       // connecting to the flight gear server.
            NetworkStream writer = new NetworkStream(fg);               // creating a stream for writing to the server.
            string        line;

            new Thread(delegate()
            {
                if (ts.FeaturesMap.Count == 0)                      // saving the values of the reg flight in timeseries
                {
                    ts.initFeaturesMap(regFlightFile, settingsFile);
                }
                SimpleAnomalyDetector simp = new SimpleAnomalyDetector();
                cf = simp.LearnNormal(ts);
                //dynamic c = loadDLL();
                //TimeSeries anomalyTs = new TimeSeries();
                //anomalyTs.initFeaturesMap(AnomalyFlight, settingsFile);
                //List<AnomalyReport> anomalies = c.Detect(anomalyTs);
                //int anomalyIndex = 0;
                while (timeInDeciSeconds <= ts.getNumOfTimesteps())          // while we are not at the end of the flight
                {
                    if (!Stop)                                               // if the video is not stopped.
                    {
                        UpdateTime();                                        // updating the time of the flight by 1 deciseconds.
                        if (timeInDeciSeconds == ts.getNumOfTimesteps() - 1) // if the time is the end of the flight we will pause the connection.
                        {
                            Stop = true;
                        }
                        if ((DesiredFeature.EndsWith("1") || DesiredFeature.EndsWith("2")) && DesiredFeature != "")      // check if the feature has 2 occurences.
                        {
                            PointsTopRightGraph.Add(new DataPoint(TimeInDeci, getDuplicatedFaetureVal(DesiredFeature))); // adding new point to the graph of the desired feature;
                            getCorrelatedFeature();                                                                      // if the feature has a correlated feature, it will handle the correlated feature's graph here.
                            InvalidateFlag++;                                                                            // indicating we made a chenge in points.
                        }
                        else if (DesiredFeature != "")
                        {
                            PointsTopRightGraph.Add(new DataPoint(TimeInDeci, getFaetureVal(DesiredFeature)));
                            getCorrelatedFeature();
                            InvalidateFlag++;
                        }

                        /*
                         * if((anomalyIndex > anomalies.Count) && anomalies[anomalyIndex++].TimeStep == TimeInDeci)
                         * {
                         *  UpdateAnomaly();
                         * }
                         */
                        line = ts.GetTimestepStr(timeInDeciSeconds);                                    // getting the next time series line.

                        // updating the flight members
                        Elevator    = (ts.getFeatureVal("elevator", timeInDeciSeconds)) * 130 + 125; // update the elevator.
                        Aileron     = (ts.getFeatureVal("aileron", timeInDeciSeconds)) * 130 + 125;  // update the aileron.
                        Throttle    = (getDuplicatedFaetureVal("throttle1")) * 46 + 46;              // update the throttle.
                        Rudder      = (ts.getFeatureVal("rudder", timeInDeciSeconds)) + 46;          // update the rudder.
                        Height      = ts.getFeatureVal("altitude-ft", timeInDeciSeconds);            // update the altitude-ft.
                        FlightSpeed = ts.getFeatureVal("airspeed-kt", timeInDeciSeconds);            // update the airspeed-kt.
                        Direction   = ts.getFeatureVal("heading-deg", timeInDeciSeconds);            // update the heading-deg.
                        Roll        = ts.getFeatureVal("roll-deg", timeInDeciSeconds);               // update the roll-deg.
                        Yaw         = ts.getFeatureVal("side-slip-deg", timeInDeciSeconds);          // update the side-slip-deg.
                        Pitch       = ts.getFeatureVal("pitch-deg", timeInDeciSeconds);              // update the pitch-deg.
                        if (writer.CanWrite)
                        {
                            byte[] writeBuffer = Encoding.ASCII.GetBytes(line + "\r\n"); // start writing the given features.
                            writer.Write(writeBuffer, 0, writeBuffer.Length);
                            writer.Flush();
                            // sending data in 10HZ
                            int converToIntSpeed = Convert.ToInt32(100 / Speed);        // this is how we use the speed of the video
                            Thread.Sleep(converToIntSpeed);                             // the sleep method decides the rate we produce the video.
                        }
                        else
                        {
                            Console.WriteLine("Sorry. You cannot send information to Flight Gear right now.");
                        }
                    }
                    else
                    {
                        while (Stop)
                        {
                        }
                        ;                 // so we wont return to the main loop while we are at pause or stop button.
                    }
                }
                writer.Close();
                fg.Close();
            }).Start();
        }