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

namespace WLANBasic1009
{
    public partial class Graph : Form
    {
        public static EventHandler graphEventHandler;
        AccessPointCollection accessPointsList;
        public delegate void graphDelegate(List<int> list);
        graphDelegate myGraphDelegate;
        List<int> selectedRSSI;
        List<string> selectedMACs;

        private Bitmap toBeDisplayed, olPart, newPart;
        private Graphics g1;
        private PictureBox display;

        int width = 0;
        int height = 0;
        int graphAreaWidth = 0;
        int graphAreaHeight = 0;
        int graphX0 = 0;
        int graphY0 = 0;

        public Graph(AccessPointCollection _accessPointsList, List<string> _selectedMacs)
        {

            accessPointsList = _accessPointsList;
            selectedMACs = _selectedMacs;
            graphEventHandler = new EventHandler(graphTimerHandler);

            myGraphDelegate = this.addNewGraphElement;

            display = new PictureBox();
            display.Width = this.Width - 20;
            display.Height = this.Height - 30;
            this.Controls.Add(display);
            
            width = display.Width;
            height = display.Height;

            graphAreaWidth = width - 90;
            graphAreaHeight = height - 41;
            graphX0 = 60;
            graphY0 = 21;

            selectedRSSI = new List<int>();

            InitializeComponent();
            drawPart1();
        }

        public void drawPart1()
        {

            toBeDisplayed = new Bitmap(width, height);
            #region Draw White BackGround , Axis and scale
            g1 = Graphics.FromImage(toBeDisplayed);
            g1.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, width, height));
            //draw upper line
            g1.DrawLine(new Pen(Color.Black, 1), 60, 20, width - 30, 20);
            g1.DrawString(" 0 dBm", new Font("Calibri", 9, FontStyle.Regular), new SolidBrush(Color.Black), 4, 12);
            //draw buttom line
            g1.DrawLine(new Pen(Color.Black, 1), 60, height - 20, width - 30, height - 20);
            g1.DrawString("-90 dBm", new Font("Calibri", 9, FontStyle.Regular), new SolidBrush(Color.Black), 4, this.Height - 28);
            //draw middle line
            g1.DrawLine(new Pen(Color.Black, 1), 60, height / 2, width - 30, height / 2);
            g1.DrawString("-45 dBm", new Font("Calibri", 9, FontStyle.Regular), new SolidBrush(Color.Black), 4, 12 + (this.Height - 40) / 2);

            //draw scale
            g1.DrawLine(new Pen(Color.Black, 1), 50, 36, 60, 36);
            g1.DrawString("-10", new Font("Calibri", 7, FontStyle.Regular), new SolidBrush(Color.Black), 30, 32);
            g1.DrawLine(new Pen(Color.Black, 1), 50, 52, 60, 52);
            g1.DrawString("-20", new Font("Calibri", 7, FontStyle.Regular), new SolidBrush(Color.Black), 30, 48);
            g1.DrawLine(new Pen(Color.Black, 1), 50, 68, 60, 68);
            g1.DrawString("-30", new Font("Calibri", 7, FontStyle.Regular), new SolidBrush(Color.Black), 30, 64);
            g1.DrawLine(new Pen(Color.Black, 1), 50, 116, 60, 116);
            g1.DrawString("-60", new Font("Calibri", 7, FontStyle.Regular), new SolidBrush(Color.Black), 30, 112);
            g1.DrawLine(new Pen(Color.Black, 1), 50, 132, 60, 132);
            g1.DrawString("-70", new Font("Calibri", 7, FontStyle.Regular), new SolidBrush(Color.Black), 30, 128);
            g1.DrawLine(new Pen(Color.Black, 1), 50, 148, 60, 148);
            g1.DrawString("-80", new Font("Calibri", 7, FontStyle.Regular), new SolidBrush(Color.Black), 30, 144);
            #endregion
            display.Image = toBeDisplayed;
        }

        public void addNewGraphElement(List<int> values)
        {
            olPart = new Bitmap(graphAreaWidth - 10, graphAreaHeight);
            g1 = Graphics.FromImage(olPart);
            g1.DrawImage(toBeDisplayed, 0, 0, new Rectangle
                (graphX0 + 10, graphY0, graphAreaWidth - 10, graphAreaHeight), GraphicsUnit.Pixel);
            newPart = new Bitmap(10, graphAreaHeight);
            g1 = Graphics.FromImage(newPart);
            g1.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, 10, graphAreaHeight));
            g1.DrawLine(new Pen(Color.Black, 1), 0, graphAreaHeight / 2, 10, graphAreaHeight / 2);
            #region draw Points on a graph
            int i = 0;
            foreach (int RSSI in values)
            {
                if (RSSI > -90 && RSSI < 0)
                {
                    if (i == 0)
                    {
                        drawPointBlue(RSSI, g1);
                    }
                    else if (i == 1)
                    {
                        drawPointGreen(RSSI, g1);
                    }
                    else if (i == 2)
                    {
                        drawPointRed(RSSI, g1);
                    }
                    else
                    {
                        drawPointViolet(RSSI, g1);
                    }
                }
                i++;
            }
            #endregion
            g1 = Graphics.FromImage(toBeDisplayed);
            g1.DrawImage(olPart, graphX0, graphY0, new Rectangle(0, 0, graphAreaWidth - 10, graphAreaHeight), GraphicsUnit.Pixel);
            g1.DrawImage(newPart, graphX0 + graphAreaWidth - 10, graphY0, new Rectangle(0, 0, 10, graphAreaHeight), GraphicsUnit.Pixel);
            display.Image = toBeDisplayed;
        }

        public void drawPointRed(int RSSI, Graphics g)
        {
            g.DrawEllipse(new Pen(Color.Red, 2), 7, ((graphAreaHeight * RSSI / 90) * (-1)), 1, 1);
        }
        public void drawPointBlue(int RSSI, Graphics g)
        {
            g.DrawEllipse(new Pen(Color.Blue, 2), 5, ((-1) * (graphAreaHeight * RSSI / 90)), 1, 1);
        }
        public void drawPointGreen(int RSSI, Graphics g)
        {
            g.DrawEllipse(new Pen(Color.Green, 2), 3, ((-1) * (graphAreaHeight * RSSI / 90)), 1, 1);
        }
        public void drawPointViolet(int RSSI, Graphics g)
        {
            g.DrawEllipse(new Pen(Color.Violet, 2), 1, ((-1) * (graphAreaHeight * RSSI / 90)), 1, 1);
        }

        private void Graph_Deactivate(object sender, EventArgs e)
        {
            MyTimer.isTime -= Graph.graphEventHandler;
            MyTimer.isTime += Form1.mainFormEventHandler;
            Form1.refreshMainFrom = true;
            //MessageBox.Show("Graph_Deactivate");
        }

        private void Graph_Closing(object sender, CancelEventArgs e)
        {
            //MyTimer.isTime -= Graph.graphEventHandler;
            //MyTimer.isTime += Form1.mainFormEventHandler;
            //MessageBox.Show("Graph_Closing");
        }

        private void Graph_Closed(object sender, EventArgs e)
        {
            //MyTimer.isTime -= Graph.graphEventHandler;
            //MyTimer.isTime += Form1.mainFormEventHandler;
            //MessageBox.Show("Graph_Closed");
        }

        public void graphTimerHandler(object sender, EventArgs args)
        {
            accessPointsList.Refresh();
            selectedRSSI.Clear();
            selectedRSSI.Add(1);
            selectedRSSI.Add(1);
            selectedRSSI.Add(1);
            selectedRSSI.Add(1);
            foreach (AccessPoint ap in accessPointsList)
            {
                if (selectedMACs.Contains(ap.PhysicalAddress.ToString()))
                {
                    int index = selectedMACs.IndexOf(ap.PhysicalAddress.ToString());
                    switch (index)
                    {
                        case 0:
                            selectedRSSI[0] = ap.SignalStrength.Decibels;
                            //selectedRSSI.Insert(0, ap.SignalStrength.Decibels);
                            break;
                        case 1:
                            selectedRSSI[1] = ap.SignalStrength.Decibels;
                            //selectedRSSI.Insert(1, ap.SignalStrength.Decibels);
                            break;
                        case 2:
                            selectedRSSI[2] = ap.SignalStrength.Decibels;
                            //selectedRSSI.Insert(2, ap.SignalStrength.Decibels);
                            break;
                        case 3:
                            selectedRSSI[3] = ap.SignalStrength.Decibels;
                            //selectedRSSI.Insert(3, ap.SignalStrength.Decibels);
                            break;
                        default:

                            break;
                    }

                }

            }

            this.Invoke(myGraphDelegate, new object[] { selectedRSSI });
            LogSaver.saveToLog(accessPointsList, selectedMACs);
        }

    }
}