using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Diagnostics;
using System.Collections;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Net;


namespace MasterProject
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
            DecisionTreeTxtBox.Enabled = false;
            button5.Enabled = false;
            checkBox1.Checked = true;
        }

        int LandmarksNumber = 0, index;
        MeasurementVector[] FinalDelayAndJitterArray;
        MeasurementVector[] FinalBandwidthArray;
        Time[] TimeArray;

        private void button1_Click(object sender, EventArgs e)
        {
            int[] series=new int[2];
            series[1] = 2;
            series[0] = 1;
    //        this.QoEChart.Series["QoE"].Points.AddXY("Landmark " + 1, 1);
  //          this.QoEChart.Series["QoE"].Points.AddXY("Landmark " + 1, 2);

//return;
           
            FinalDelayAndJitterArray = new MeasurementVector[1000];
            FinalBandwidthArray = new MeasurementVector[1000];
            TimeArray = new Time[1000];
            LandmarksNumber = 0;

            if (LandmarksDelayRchTxt.Text == "")
            {
                MessageBox.Show("Choose landmarks, please !", "Error");
                return;
            }
            if (BWFileTxtBox.Text == "")
            {
                MessageBox.Show("Enter file path you want to make your test with, please !", "Error");
                return;
            }
            if (DecisionTreeTxtBox.Text == "")
            {
                if (!checkBox1.Checked) { 
                MessageBox.Show("No decision tree is chosen, please choose one !", "Error");
                return;
                }
            }

            if (ProbesNumeric.Value == 1)
            {
                DialogResult dr = MessageBox.Show("Jitter cannot be calculated! Only one probe is sent. Do you want to continue?", "Alert", MessageBoxButtons.YesNo);
                if (dr == DialogResult.No)
                    return;
            }

            // Count the number of landmarks in the richTextBox
            foreach (string landmark in LandmarksDelayRchTxt.Lines)
                LandmarksNumber++;   

            Thread t = new Thread(new ThreadStart(Run));
            t.Start();
        }

        bool MeanResult = false;
        bool[] QoEPerLanmark;
        int[] skypeQoEPerLandmark;
        int skypeQoEMeanResult;
        void Run()
        {
            QoEPerLanmark = new bool[LandmarksNumber];
            skypeQoEPerLandmark=new int[LandmarksNumber];
            int LocalIndex = 0;
            while (true)
            {
                // Get Two-way Delay and Jitter Values 
                FinalDelayAndJitterArray[LocalIndex] = PingSetOfLandmarks();
                if (FinalDelayAndJitterArray[LocalIndex] == null)
                    return;

                // Get Bandwidth (Uploading + Downnloading) Values
                FinalBandwidthArray[LocalIndex] = SendFileToSetOfLandmarks();
                if (FinalBandwidthArray[LocalIndex] == null)
                    return;

                // Calculate Loss Rate LR = max(CR - AB, 0) / AB
                int[] LossRate=new int[2];
                LossRate = PingHostLossProb(AllLandmarks[LocalIndex], 100, LocalIndex);

                //// Make QoE Estimation
                //// For the Set of Landmarks First
                int[] LossRatePerLandmark = new int[2];
                for (int i = 0; i < LandmarksNumber; i++)
                {
                   LossRatePerLandmark = PingHostLossProb(AllLandmarks[i], 100,i);
                  /* if (!isSkypeChecked)
                   {
                        QoEPerLanmark[i] = CallerClass.Call(root,                             // Decision-tree Root
                                                           TwoWayDelayPerLandmarkArray[i],   // Delay
                                                           JitterPerLandmarkArray[i],        // Jitter
                                                           UploadBWPerLandmarkArray[i],      // UBandwidth
                                                           DownloadBWPerLandmarkArray[i],    // DBandwidth
                                                           LossRatePerLandmark[0]);             // LossRate 
                   }
                   else
                   {*/
                       skypeQoEPerLandmark[i] = estimatedSkypeQuality(DownloadBWPerLandmarkArray[i], UploadBWPerLandmarkArray[i], (int)TwoWayDelayPerLandmarkArray[i] / 2, (int)TwoWayDelayPerLandmarkArray[i] / 2, LossRatePerLandmark[0], LossRatePerLandmark[1]);
                   //}
                    

                }
                //// Then for the Mean Values of Measurements
               
                MeanResult = CallerClass.Call(root,                                            // Decision-tree Root
                                              FinalDelayAndJitterArray[LocalIndex].dimension1, // Delay
                                              FinalDelayAndJitterArray[LocalIndex].dimension2, // Jitter
                                              FinalBandwidthArray[LocalIndex].dimension1,      // UBandwidth
                                              FinalBandwidthArray[LocalIndex].dimension2,      // DBandwidth
                                              LossRate[0]);                                       // LossRate
                skypeQoEMeanResult = estimatedSkypeQuality(FinalBandwidthArray[LocalIndex].dimension2, FinalBandwidthArray[LocalIndex].dimension1, (int)FinalDelayAndJitterArray[LocalIndex].dimension1 / 2, (int)FinalDelayAndJitterArray[LocalIndex].dimension1 / 2, LossRate[0], LossRate[1]);
                // Get Full Time
                TimeArray[LocalIndex] = new Time();

                // Draw the Charts
                this.DelayChart.Series["Round-trip Delay"].Points.AddXY(TimeArray[LocalIndex].ToString(), FinalDelayAndJitterArray[LocalIndex].dimension1);
                this.JitterChart.Series["Jitter"].Points.AddXY(TimeArray[LocalIndex].ToString(), FinalDelayAndJitterArray[LocalIndex].dimension2);
                this.UploadBandwidthChart.Series["Upload Bandwidth"].Points.AddXY(TimeArray[LocalIndex].ToString(), FinalBandwidthArray[LocalIndex].dimension1);
                this.DownloadBandwidthChart.Series["Download Bandwidth"].Points.AddXY(TimeArray[LocalIndex].ToString(), FinalBandwidthArray[LocalIndex].dimension2);

            //    if (!isSkypeChecked) { 
                for (int i = 0; i < LandmarksNumber; i++)
                {
                   // switch (QoEPerLanmark[i])
                 //   {
                  //      case true:
                    this.QoEChart.Series["QoE"].Points.AddXY("Landmark " + i + 1, skypeQoEPerLandmark[i]);
                  //          break;
                 //       case false:
                  //          this.QoEChart.Series["QoE"].Points.AddXY("Landmark " + i + 1, 1);
                 //           break;
                 //   }
                }
             //   switch (MeanResult)
             //   {
              //      case true:
                this.MeanQoEChart.Series["Mean QoE"].Points.AddXY(TimeArray[LocalIndex].ToString(), skypeQoEMeanResult);
              //          break;
             //       case false:
              //          this.MeanQoEChart.Series["Mean QoE"].Points.AddXY(TimeArray[LocalIndex].ToString(), 1);
             //           break;
              //  }
             //   }
              //  else
               // {
                //    for (int i = 0; i < LandmarksNumber; i++)
                  //  {
                   //     this.QoEChart.Series["QoE"].Points.AddXY("Landmark " + i + 1, skypeQoEPerLandmark[i]);   
                    //}
                     //       this.MeanQoEChart.Series["Mean QoE"].Points.AddXY(TimeArray[LocalIndex].ToString(), skypeQoEMeanResult);
                    

//                }
              //  LocalIndex++;
                Console.WriteLine("finished with loss=" + LossRate[0] + "," + LossRate[0]+"\n bandwidth="+FinalBandwidthArray[0].dimension1+","+FinalBandwidthArray[0].dimension2+"\n delay"+TwoWayDelayArray[0]+","+TwoWayDelayArray[1]);
                Thread.Sleep((int)PeriodNumeric.Value * 60 * 1000);
                //Thread.Sleep(50000);
            }
        }

        // Delay and Jitter Measurement
        long elapsedMs = 0;
        double Total2WDPerLandmark = 0, Total2WD = 0, _2WD = 0;
        double TotalJitterPerLandmark = 0, TotalJitter = 0;
        int[] TwoWayDelayPerLandmarkArray;
        int[] JitterPerLandmarkArray;
        int MeanTwowayDelay = 0, MeanJitter = 0;
        double[] TwoWayDelayArray;
        bool MoreThanOneCampaign = true;
       
        public MeasurementVector PingSetOfLandmarks()
        {
            index = 0;
            Total2WD = 0;
            Total2WDPerLandmark = 0;
           
            if (ProbesNumeric.Value == 1)
                MoreThanOneCampaign = false;

          

            TwoWayDelayPerLandmarkArray = new int[LandmarksNumber];
            JitterPerLandmarkArray = new int[LandmarksNumber];

            // Ping each landmark
            foreach (string Landmark in LandmarksDelayRchTxt.Lines)
            {
                Total2WDPerLandmark = 0;
                TwoWayDelayArray = new double[(int)ProbesNumeric.Value];
                // Ping selected landmark n times (ProbesNumeric.Value)
                for (int i = 0; i < ProbesNumeric.Value; i++)
                {
                    int RTT = PingHostDelay(Landmark);

                    Total2WDPerLandmark += RTT;
                    TwoWayDelayArray[i] = RTT;
                }

                // Jitter Per Landmark
                if (MoreThanOneCampaign)
                {
                    TotalJitterPerLandmark = 0;
                    for (int i = 0; i < TwoWayDelayArray.Length - 1; i++)
                        TotalJitterPerLandmark += Math.Abs((TwoWayDelayArray[i + 1] - TwoWayDelayArray[i]));
                    JitterPerLandmarkArray[index] = (int)(TotalJitterPerLandmark / (double)ProbesNumeric.Value);
                }

                // 2WD value Per Landmark
                TwoWayDelayPerLandmarkArray[index] = (int)Total2WDPerLandmark / (int)ProbesNumeric.Value;

                index++;
            }

            // Average Jitter value over number of landmarks
            if (MoreThanOneCampaign)
            {
                for (int i = 0; i < LandmarksNumber; i++)
                    TotalJitter += JitterPerLandmarkArray[i];

                MeanJitter = (int)(TotalJitter / LandmarksNumber); // This is the final-average-value of Jitter
            }
            else
            {
                MeanJitter = 0;
                JitterChart.Visible = false;
            }

            // Average OWD value over number of landmarks
            for (int i = 0; i < LandmarksNumber; i++)
                Total2WD += TwoWayDelayPerLandmarkArray[i];

            MeanTwowayDelay = (int)(Total2WD / LandmarksNumber); // This is the final-average-value of One-way Delay

            return new MeasurementVector(MeanTwowayDelay, MeanJitter);
        }

        // Bandwidth Measurement
        int[] UploadBWPerLandmarkArray;
        int[] DownloadBWPerLandmarkArray;
        Socket ClientSocket;
        byte[] FileContent;
        byte[] FileRec;
        int BWindex = 0;
        static int kilo = 1024;
        FileStream fsNew;
        public MeasurementVector SendFileToSetOfLandmarks()
        {
            var watch = Stopwatch.StartNew();
            int offset = 0;
            int BytesRec;
            UploadBWPerLandmarkArray = new int[LandmarksNumber];
            DownloadBWPerLandmarkArray = new int[LandmarksNumber];
            BWindex = 0;
            // Measure Uploading and Downloading Bandwidth per each landmark
            foreach (string Landmark in LandmarksDelayRchTxt.Lines)
            {
                // Creating the socket and the target IPEndPoint object
                try
                {
                    ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                }
                catch
                {
                    MessageBox.Show("Some problem occured during building the socket !\nPlease, check your account administrative settings.", "Error");
                    return null;
                }
                IPEndPoint iep = new IPEndPoint(IPAddress.Parse(Landmark), 51254);
                // Connecting to the Landmark
                try
                {
                    ClientSocket.Connect((EndPoint)iep);
                }
                catch
                {
                    MessageBox.Show("Landmark: " + Landmark + " is not available! Please, try agian later.", "Error");
                    return null;
                }

                // Calculating Uploading Bandwidth
                // Sending the file
                try
                {
                    FileContent = File.ReadAllBytes(fsNew.Name);
                    watch = Stopwatch.StartNew(); // Start a timer before sending the file
                    ClientSocket.Send(BitConverter.GetBytes(FileContent.Length)); // Send file size
                    ClientSocket.Send(BitConverter.GetBytes(0)); // End of send : send(0)
                    int x = ClientSocket.Send(FileContent, 0, FileContent.Length, SocketFlags.None); // Send file
                  //  watch.Stop(); // Stop the timer after sending the file
                }
                catch
                {
                    MessageBox.Show("Problem in sending the file to the landmark: " + Landmark + " ! Please, try agian later.", "Error");
                    return null;
                }
                // Uploading Bandwidth is

                
                // Calculate Downloading Bandwidth
                FileStream FileEcho;
                try
                {
                    FileEcho = new FileStream("C:\\ClientFiles\\EchoedFile.txt", FileMode.Create);
                }
                catch
                {
                    MessageBox.Show("Problem in creating the echoed-back file from the server! Please check your administrative settings.", "Error");
                    return null;
                }
                // Receiving the file
                try
                {
                    offset = 0;
                    FileRec = new byte[FileContent.Length];
                    watch = Stopwatch.StartNew(); // Start a timer before recieving the file
                    int i = 0;
                    while (offset < FileContent.Length)
                    {
                        BytesRec = ClientSocket.Receive(FileRec);
                        FileEcho.Write(FileRec, offset, BytesRec);
                        offset += BytesRec;
                        if(i==0){
                        watch.Stop();
                        float firstpart = FileContent.Length * 8 / kilo;// / kilo;
                        float secondpart = (float)watch.ElapsedMilliseconds / 1000;
                        UploadBWPerLandmarkArray[BWindex] = Convert.ToInt32((firstpart) / (secondpart));
                        watch = Stopwatch.StartNew();    
                        }

                        i++;
                    }
                    watch.Stop(); // Stop the timer after receiving the file
                    
                }
                catch
                {
                   // MessageBox.Show("Problem in receiving the file from the landmark: " + Landmark + " ! Please, try agian later.", "Error");
                    //return null;
                    watch.Stop();
                }
                // Downloading Bandwidth is
                float firstpart2 = FileContent.Length * 8 / kilo;// / kilo;
                float secondpart2 = (float)watch.ElapsedMilliseconds / 1000;
                DownloadBWPerLandmarkArray[BWindex] = Convert.ToInt32(
                                                    firstpart2 / secondpart2
                                                    ); // Size of file in Mbits / Time in Sec = Mbps
                BWindex++;
                ClientSocket.Close();
                FileEcho.Close();
            }

            // Averaging over number of landmarks
            int TotalUploadBandwidth = 0;
            int TotalDownloadBandwidth = 0;
            for (int i = 0; i < LandmarksNumber; i++)
            {
                TotalDownloadBandwidth += DownloadBWPerLandmarkArray[i];
                TotalUploadBandwidth += UploadBWPerLandmarkArray[i];
            }
            // This vector represents the final-average-value of both upload and download bandwidth
            return new MeasurementVector((int)(TotalUploadBandwidth / LandmarksNumber), (int)(TotalDownloadBandwidth / LandmarksNumber));
        }

        // Browse File to Use for Bandwidth Measurement
        FileStream fs;
        int _MB = 2 * kilo * kilo;
        private void button4_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                fs = new FileStream(openFileDialog1.FileName, FileMode.Open);
                if (fs.Length > _MB) // File size needed to be greater then 10MB
                {
                    BWFileTxtBox.Text = fs.Name;
                    fsNew = fs;
                    fs.Close();
                }
                else
                {
                    MessageBox.Show("Plese choose a file with a size greater than 2MB !", "Error");
                    fs = null;
                    return;
                }
            }
            else
            {
                MessageBox.Show("Error in opening the requested file !", "Error");
                return;
            }
        }

        // Choose Decision Tree (Configuration File)
        Node root;
        FileStream DecisionTreeFile;
        private void button5_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                DecisionTreeFile = new FileStream(openFileDialog1.FileName, FileMode.Open);
                DecisionTreeTxtBox.Text = DecisionTreeFile.Name;
                DecisionTreeFile.Close();
                root = CallerClass.Load(DecisionTreeFile.Name);
                if (root == null)
                {
                    MessageBox.Show("Error in Decision Tree File Format ! Please choose a valid XML file format.", "Error");
                    DecisionTreeFile.Close();
                    return;
                }
            }
            else
            {
                MessageBox.Show("Error in opening the requested Decision Tree file !", "Error");
                return;
            }
        }

        private void SelectLandmarks_Click(object sender, EventArgs e)
        {
            try
            {
                LandNumber = Convert.ToInt32(LandmarksNo.Text);
            }
            catch
            {
                MessageBox.Show("Please enter the number of landmarks !", "Error");
                return;
            }
            if (LandNumber < 1 || LandNumber >100)
            {
                MessageBox.Show("Landmarks number shall be a value between 1 and 100 !","Error");
                return;
            }
            Thread t = new Thread(new ThreadStart(BeginLandmarksSelection));
            t.Start();
        }

        string[] AllLandmarks = new string[100];
        ArrayList ChosenLandmarks = new ArrayList();
        ArrayList LandmarksFirstSet = new ArrayList();
        ArrayList LandmarksSecondSet = new ArrayList();
        ArrayList LandmarksthirdSet = new ArrayList();
        int LandNumber;
        static Random r;
        private static byte[] data;
        public void BeginLandmarksSelection()
        {
            IPEndPoint iep;
            EndPoint ep;
            ICMP packet;
            Socket host;
            byte[] data = new byte[1024];
            int recv;
            var watch = Stopwatch.StartNew();
            long MS, RTD = 0;

            // initialize the AllLandmarks array
            InitializeLandmarksArray();

            string RandomLandmark = "";
            ChosenLandmarks.Clear();
            // Select landmarks randomly
            if (radioButtonRandom.Checked)
            {
                int i = 0;
                r = new Random();
                while (i < LandNumber)
                {
                    int size = getLandmarkNumber();
                    int randomNumber = r.Next(0, size-1);
                    RandomLandmark = AllLandmarks[randomNumber];
                    if (!ChosenLandmarks.Contains(RandomLandmark))
                    {
                        ChosenLandmarks.Add(RandomLandmark);
                        i++;
                    }
                }
            }
            else if (radioButtonIntelligent.Checked) // Select landmarks intelligently according to RTD order
            {
                try
                {
                    host = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
                }
                catch
                {
                    MessageBox.Show("Some problem occured during building the socket !\nPlease, check your account administrative settings.", "Error");
                    return;
                }

                for (int i = 0; i < AllLandmarks.Length; i++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        // Ping all landmarks and sort them in three lists according to RTD value (Each landmark 4 times)
                        try
                        {
                            iep = new IPEndPoint(IPAddress.Parse(AllLandmarks[i]), 0);
                            ep = (EndPoint)iep;
                            packet = new ICMP();
                            packet.Type = 0x08;
                            packet.Code = 0x00;
                            packet.Checksum = 0;
                            Buffer.BlockCopy(BitConverter.GetBytes((short)1), 0, packet.Message, 0, 2);
                            Buffer.BlockCopy(BitConverter.GetBytes((short)1), 0, packet.Message, 2, 2);
                            data = Encoding.ASCII.GetBytes("test packet");
                            Buffer.BlockCopy(data, 0, packet.Message, 4, data.Length);
                            packet.MessageSize = data.Length + 4;
                            int packetsize = packet.MessageSize + 4;

                            UInt16 chcksum = packet.getChecksum();
                            packet.Checksum = chcksum;

                            host.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 2000);
                            watch = Stopwatch.StartNew(); // Start a timer before ping
                            host.SendTo(packet.getBytes(), packetsize, SocketFlags.None, iep);
                            try
                            {
                                data = new byte[1024];
                                recv = host.ReceiveFrom(data, ref ep);
                                watch.Stop(); // Stop timer after ping
                            }
                            catch (SocketException)
                            {
                                //MessageBox.Show("No response from host: " + AllLandmarks[i] +
                                //                " Please check the availability of this host or your Internet connection!", "Error");
                                continue;
                            }
                            ICMP response = new ICMP(data, recv);
                        }
                        catch
                        {
                            MessageBox.Show("Problem in pinging host: " + AllLandmarks[i], "Error");
                            return;
                        }
                        MS = watch.ElapsedMilliseconds;
                        RTD += MS; // RTD : Two-way Delay
                    }

                    RTD = RTD / 4;

                    if (RTD < 80)
                        LandmarksFirstSet.Add(AllLandmarks[i]);
                    else if (RTD >= 80 && RTD < 200)
                        LandmarksSecondSet.Add(AllLandmarks[i]);
                    else if (RTD >= 200)
                        LandmarksthirdSet.Add(AllLandmarks[i]);
                }

                // Filling the chosen landmarks
                ChosenLandmarks.Clear();
                r = new Random();
                int k = 0;
                while (ChosenLandmarks.Count != LandNumber)
                {
                    k=0;
                    while (k < Convert.ToInt32(LandNumber * LandmarksFirstSet.Count / 100))
                    {
                        if (ChosenLandmarks.Count == LandNumber)
                            break;
                        else
                            try
                            {
                                RandomLandmark = LandmarksFirstSet[r.Next(0, LandmarksFirstSet.Count)] as string;
                                if (!ChosenLandmarks.Contains(RandomLandmark))
                                {
                                    ChosenLandmarks.Add(RandomLandmark);
                                    k++;
                                }
                            }
                            catch
                            { continue; }
                    }
                    k = 0;
                    while (k < Convert.ToInt32(LandNumber * LandmarksSecondSet.Count / 100))
                    {
                        if (ChosenLandmarks.Count == LandNumber)
                            break;
                        else
                            try
                            {
                                RandomLandmark = LandmarksSecondSet[r.Next(0, LandmarksSecondSet.Count)] as string;
                                if (!ChosenLandmarks.Contains(RandomLandmark))
                                {
                                    ChosenLandmarks.Add(RandomLandmark);
                                    k++;
                                }
                            }
                            catch
                            { continue; }
                    }
                    k = 0;
                    while (k < Convert.ToInt32(LandNumber * LandmarksthirdSet.Count / 100))
                    {
                        if (ChosenLandmarks.Count == LandNumber)
                            break;
                        else
                            try
                            {
                                RandomLandmark = LandmarksthirdSet[r.Next(0, LandmarksthirdSet.Count)] as string;
                                if (!ChosenLandmarks.Contains(RandomLandmark))
                                {
                                    ChosenLandmarks.Add(RandomLandmark);
                                    k++;
                                }
                            }
                            catch
                            { continue; }
                    }
                }
            }

            LandmarksDelayRchTxt.Clear();
            // Fill the Landmarks RichTextBox
            for (int i = 0; i < ChosenLandmarks.Count; i++)
            {
                if (i != ChosenLandmarks.Count - 1)
                {
                    LandmarksDelayRchTxt.Text += ChosenLandmarks[i] + "\n";
                }
                else
                {
                    LandmarksDelayRchTxt.Text += ChosenLandmarks[i];
                }
            }
        }

        private void InitializeLandmarksArray()
        {
           // AllLandmarks[0] = "141.11.0.165";
            AllLandmarks[0] = "157.92.44.101";
          //  AllLandmarks[0] = "159.217.144.112";
         //   AllLandmarks[0] = "188.44.50.106";
          //  AllLandmarks[0] = "192.16.125.12";
         //   AllLandmarks[0] = "130.194.252.8";
        //    AllLandmarks[0] = "219.243.208.60";
        //    AllLandmarks[0] = "129.110.125.51";
            
            /*AllLandmarks[0] = "134.76.249.230";
            AllLandmarks[1] = "161.106.240.18";
            AllLandmarks[2] = "193.10.64.35";
            AllLandmarks[3] = "130.192.157.138";
            AllLandmarks[4] = "156.17.10.52";
            AllLandmarks[5] = "192.33.210.16";
            AllLandmarks[6] = "131.188.44.100";
            AllLandmarks[7] = "194.167.254.18";
            AllLandmarks[8] = "158.110.27.116";
            AllLandmarks[9] = "195.148.124.73";
            AllLandmarks[10] = "150.244.58.161";
            AllLandmarks[11] = "193.55.112.41";
            AllLandmarks[12] = "193.136.124.228";
            AllLandmarks[13] = "193.136.166.56";
            AllLandmarks[14] = "212.235.189.115";
            AllLandmarks[15] = "192.42.43.22";
            AllLandmarks[16] = "130.149.49.136";
            AllLandmarks[17] = "194.42.17.121";
            AllLandmarks[18] = "193.138.2.12";
            AllLandmarks[19] = "169.229.50.4";
            AllLandmarks[20] = "193.190.168.49";
            AllLandmarks[21] = "138.246.99.250";
            AllLandmarks[22] = "145.99.179.147";
            AllLandmarks[23] = "212.51.218.237";
            AllLandmarks[24] = "132.65.240.101";
            AllLandmarks[25] = "193.144.21.130";
            AllLandmarks[26] = "138.48.3.201";
            AllLandmarks[27] = "147.102.3.113";
            AllLandmarks[28] = "195.148.124.74";
            AllLandmarks[29] = "157.181.175.248";
            AllLandmarks[30] = "155.185.54.249";
            AllLandmarks[31] = "130.237.50.124";
            AllLandmarks[32] = "132.227.62.121";
            AllLandmarks[33] = "131.254.208.11";
            AllLandmarks[34] = "130.192.157.131";
            AllLandmarks[35] = "130.92.70.254";
            AllLandmarks[36] = "212.199.61.205";
            AllLandmarks[37] = "158.110.27.127";
            AllLandmarks[38] = "128.232.103.202";
            AllLandmarks[39] = "193.167.187.186";
            AllLandmarks[40] = "212.235.189.114";
            AllLandmarks[41] = "131.130.69.164";
            AllLandmarks[42] = "194.42.17.123";
            AllLandmarks[43] = "83.230.127.122";
            AllLandmarks[44] = "145.99.179.146";
            AllLandmarks[45] = "139.91.90.239";
            AllLandmarks[46] = "130.37.193.143";
            AllLandmarks[47] = "130.73.142.87";
            AllLandmarks[48] = "149.156.5.116";
            AllLandmarks[49] = "193.1.170.135";
            AllLandmarks[50] = "143.215.131.206";
            AllLandmarks[51] = "138.48.3.203";
            AllLandmarks[52] = "130.237.50.125";
            AllLandmarks[53] = "147.83.29.234";
            AllLandmarks[54] = "193.136.166.54";
            AllLandmarks[55] = "85.23.168.77";
            AllLandmarks[56] = "195.130.121.204";
            AllLandmarks[57] = "130.104.72.201";
            AllLandmarks[58] = "141.76.45.18";
            AllLandmarks[59] = "195.113.161.13";
            AllLandmarks[60] = "221.199.217.144";
            AllLandmarks[61] = "213.73.40.105";
            AllLandmarks[62] = "193.167.187.185";
            AllLandmarks[63] = "134.151.255.181";
            AllLandmarks[64] = "157.181.175.249";
            AllLandmarks[65] = "130.206.158.140";
            AllLandmarks[66] = "130.83.166.243";
            AllLandmarks[67] = "130.79.48.57";
            AllLandmarks[68] = "193.145.46.242";
            AllLandmarks[69] = "195.130.124.1";
            AllLandmarks[70] = "85.23.168.76";
            AllLandmarks[71] = "194.167.254.19";
            AllLandmarks[72] = "192.41.135.219";
            AllLandmarks[73] = "129.88.70.227";
            AllLandmarks[74] = "194.47.148.170";
            AllLandmarks[75] = "192.38.109.143";
            AllLandmarks[76] = "193.205.215.74";
            AllLandmarks[77] = "147.83.30.164";
            AllLandmarks[78] = "193.166.160.98";
            AllLandmarks[79] = "148.81.140.194";
            AllLandmarks[80] = "139.165.12.212";
            AllLandmarks[81] = "152.66.245.162";
            AllLandmarks[82] = "129.242.19.196";
            AllLandmarks[83] = "80.65.237.10";
            AllLandmarks[84] = "193.1.170.136";
            AllLandmarks[85] = "193.226.19.30";
            AllLandmarks[86] = "128.232.103.203";
            AllLandmarks[87] = "193.138.2.13";
            AllLandmarks[88] = "222.99.146.83";
            AllLandmarks[89] = "222.99.146.81";
            AllLandmarks[90] = "128.36.233.153";
            AllLandmarks[91] = "156.62.231.244";
            AllLandmarks[92] = "133.9.81.164";
            AllLandmarks[93] = "157.92.44.103";
            AllLandmarks[94] = "169.229.50.14";
            AllLandmarks[95] = "128.112.139.42";
            AllLandmarks[96] = "200.129.132.18";
            AllLandmarks[97] = "133.1.74.162";
            AllLandmarks[98] = "142.150.238.13";
            AllLandmarks[99] = "140.109.17.181";*/
        }
        private int getLandmarkNumber()
        {
            int count = 0;
            foreach(String landmark in AllLandmarks){
                if (landmark != null)
                    count++;
            }
            return count;
        }
        //ME
        public static int[] PingHostLossProb(string host, int times,int index)
        {

            #region OldCodeUsingPing
            /*   IPAddress address = GetIpFromHost(ref host);
            PingOptions pingOptions = new PingOptions(128, true);
            Ping ping = new Ping();
            int successfull = 0;
            byte[] buffer = new byte[32];
            for (int i = 0; i < times; i++)
            {
                try
                {
                    PingReply pingReply = ping.Send(address, 1000, buffer, pingOptions);
                    if (!(pingReply == null))
                    {
                        switch (pingReply.Status)
                        {
                            case IPStatus.Success:
                                successfull++;
                                break;
                            default:
                                Console.WriteLine("Ping failed: {0}", pingReply.Status.ToString());
                                break;
                        }
                    }
                }
                catch (PingException ex)
                {
                    Console.WriteLine("Connection Error: {0}", ex.Message);
                }
                catch (SocketException ex)
                {
                    Console.WriteLine("Connection Error: {0}", ex.Message);
                }
            }
            int lost = times - successfull;
            Double perc = (lost * 100 / times);
            return (int)perc;*/
            
            #endregion

            int[] losses = new int[2];

            UdpClient udpClient = new UdpClient();
            udpClient.Connect(host, 9050);

            for (int i = 0; i < 100; i++)
            {
                Byte[] senddata = Encoding.ASCII.GetBytes(i.ToString());
                udpClient.Send(senddata, senddata.Length);
                Console.WriteLine("SEND: " + i);
                // if (i == 53)
                //   Thread.Sleep(15000);
            }
            Console.WriteLine("FINSISHED seding");

            IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
            Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);

            string received = Encoding.ASCII.GetString(receiveBytes);


            int uploadLoss = 100 - int.Parse(received);
            Console.WriteLine("Upload Loss= " + uploadLoss + "%");
            Thread.Sleep(5000);

            int downloadReceived = 0;
            //receive all packets for download
            while (true)
            {
                try
                {
                    Byte[] receiveBytes1 = udpClient.Receive(ref RemoteIpEndPoint);
                    string received1 = Encoding.ASCII.GetString(receiveBytes1);
                    udpClient.Client.ReceiveTimeout = 5000;
                    if (received1 == "secret")
                        downloadReceived++;
                    Console.WriteLine("RECEIVED packet " + downloadReceived);
                }
                catch
                {
                    break;
                }
            }
            int downloadLoss = 100 - downloadReceived++;
            Console.WriteLine("Upload Loss= " + uploadLoss + "%");
            Console.WriteLine("Download Loss= " + downloadLoss + "%");
            udpClient.Close();
            losses[1] = uploadLoss;
            losses[0] = downloadLoss;
            return losses;
        
        
        }
        public static int PingHostDelay(string host)
        {
            int RTT = 0;
            IPAddress address = GetIpFromHost(ref host);
            PingOptions pingOptions = new PingOptions(128, true);
            Ping ping = new Ping();
            byte[] buffer = new byte[32];

                try
                {
                    PingReply pingReply = ping.Send(address, 1000, buffer, pingOptions);
                    if (!(pingReply == null))
                    {
                        switch (pingReply.Status)
                        {
                            case IPStatus.Success:
                                RTT = (int)pingReply.RoundtripTime;
                                break;
                            default:
                                Console.WriteLine("Ping failed: {0}", pingReply.Status.ToString());
                                break;
                        }
                    }
                }
                catch (PingException ex)
                {
                    Console.WriteLine("Connection Error: {0}", ex.Message);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Connection Error: {0}", ex.Message);
                }

                return RTT;
        }
        private static IPAddress GetIpFromHost(ref string host)
        {
            //variable to hold our error message (if something fails)
            string errMessage = string.Empty;

            //IPAddress instance for holding the returned host
            IPAddress address = null;

            //wrap the attempt in a try..catch to capture
            //any exceptions that may occur
            try
            {
                //get the host IP from the name provided
                address = Dns.GetHostEntry(host).AddressList[0];
            }
            catch (SocketException ex)
            {
                //some DNS error happened, return the message
                errMessage = string.Format("DNS Error: {0}", ex.Message);
            }
            return address;
        }
        // Close Application Button
        private void button2_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
            {
                DecisionTreeTxtBox.Enabled = false;
                button5.Enabled = false;
             //   isSkypeChecked = true;
            }
            else{
                DecisionTreeTxtBox.Enabled = true;
                button5.Enabled = true;
            //    isSkypeChecked = false;
            }
        }

        private int estimatedSkypeQuality(int downloadBandwidth, int uploadBandwidth, int downloadDelay, int uploadDelay, int downloadLoss, int uploadLoss)
        {
            int estimation=2;

            if (downloadBandwidth > 1078 && downloadDelay <= 94) estimation = 3;

            if (uploadBandwidth > 1903 && downloadBandwidth > 1078) estimation = 3;

            if (downloadBandwidth <= 1078 && downloadDelay <= 665 && uploadLoss > 0 && uploadLoss <= 2 && downloadLoss > 0 && downloadLoss <= 2) estimation = 3;

            if (downloadBandwidth <= 12) estimation = 0;

            if (uploadBandwidth <= 14 && uploadDelay <= 854) estimation = 0;

            if (downloadBandwidth <= 723 && uploadDelay <= 400 && downloadDelay > 481 && uploadLoss > 36 && uploadLoss <= 46 && downloadLoss > 22 && downloadLoss <= 45) estimation = 0;

            if (uploadBandwidth <= 18 && downloadDelay > 417 && downloadDelay <= 665) estimation = 0;

            if (uploadDelay > 464 && uploadDelay <= 615 && uploadLoss <= 27 && downloadLoss > 43) estimation = 0;

            if (uploadLoss > 27 && uploadLoss <= 46 && downloadLoss > 45) estimation = 0;

            if (downloadBandwidth <= 848 && uploadDelay > 479 && uploadLoss > 47) estimation = 0;

            if (uploadLoss <= 27 && downloadLoss > 48) estimation = 0;

            if (uploadDelay <= 479 && uploadLoss > 46) estimation = 1;

            if (uploadBandwidth > 14 && uploadBandwidth <= 17) estimation = 1;

            if (downloadDelay > 992) estimation = 1;

            if (uploadBandwidth > 17 && downloadBandwidth > 12 && uploadDelay > 400 && uploadLoss > 27 && downloadLoss <= 44) estimation = 1;

            if (uploadBandwidth > 17 && uploadBandwidth <= 1903 && downloadBandwidth > 12 && downloadDelay > 94 && uploadLoss <= 27 && downloadLoss <= 9) estimation = 2;

            if (uploadDelay <= 400 && uploadLoss > 27 && uploadLoss <= 46 && downloadLoss <= 22) estimation = 2;

            if (uploadBandwidth > 30 && downloadBandwidth > 12 && uploadLoss <= 27 && downloadLoss > 9 && downloadLoss <= 43) estimation = 2;

            if (uploadBandwidth > 17 && downloadBandwidth > 12 && uploadDelay > 400 && uploadLoss <= 28 && downloadLoss <= 35) estimation = 2;

return estimation;
        }
    }
}