using System;
using Microsoft.SPOT;
using System.Threading;
using System.Collections;
//using System.Net.Sockets;
using System.Runtime.CompilerServices;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Presentation.Media;
using System.Text;
using Microsoft.SPOT.Hardware.FreescaleMXSDemo;



namespace MXS_Sample_Project
{
    public class MXS
    {

        // Constant definitions used by the serial port class
        private const int COM1 = 0;
        private const int COM2 = 1;
        private const int Baud115200 = 115200;
        private const int PullDown = 1;
        private const int PullUp = 2;

        private static bool ipButton0Pressed = false;
        private static bool ipButton1Pressed = false;
        private static bool ipButton2Pressed = false;
        private static bool ipButton3Pressed = false;
        private static bool ipButton4Pressed = false;
        private static bool ipButton5Pressed = false;
        private static bool ipButton6Pressed = false;
        private static bool ipButton7Pressed = false;
        private static bool ipButton8Pressed = false;
        private static bool ipButton9Pressed = false;



        public static void Main()
        {
            MXS demo = new MXS();
            demo.Run();
        }

        public void Run()
        {
            UInt64 loopCount = 0;                 // Number of loop done of the infinite loop
            InterruptPort ipButton0;
            InterruptPort ipButton1;
            InterruptPort ipButton2;
            InterruptPort ipButton3;
            InterruptPort ipButton4;
            InterruptPort ipButton5;
            InterruptPort ipButton6;
            InterruptPort ipButton7;
            InterruptPort ipButton8;
            InterruptPort ipButton9;

            //LCD variables
            ScreenMetrics screen = ScreenMetrics.GetMetrics();          // Structure describing the LCD
            Bitmap bmp = new Bitmap(screen.Width, screen.Height);       // Bitmap holding the picture

            Font font = Resources.GetFont(Resources.FontResources.NinaB);
            bmp.DrawText("Press any button below!", font, Color.White, 20, 20);
            bmp.Flush();
            //COM variables
            SerialPort serialPort = null;                  // Handles the serial communication 

            Debug.Print("Setting the bitmap of the LCD to Width=" + screen.Width + " Height=" + screen.Height);

            /*********************************************************************************
             * 
             *      Initialization section
             * 
             *********************************************************************************/
            //Initialize COM
            try
            {
                Debug.Print("Setting up serial port");

                // Setting up the configuration of the serial port
                SerialPort.Configuration serialConfig = new SerialPort.Configuration((SerialPort.Serial)COM1, (SerialPort.BaudRate)Baud115200, false);

                // Instantiating the new serial comm.
                serialPort = new SerialPort(serialConfig);
            }
            catch (Exception _except)
            {
                Debug.Print(_except.Message);
                Debug.Print(_except.StackTrace);
            }

            Debug.Print("Serial port is writing/listening to " + serialPort.Config.Com + " at " + serialPort.Config.Speed);


            //Initialize GPIO
            Debug.Print("Setting up input buttons");

            ipButton0 = new InterruptPort(Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_9, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            ipButton0.OnInterrupt += new GPIOInterruptEventHandler(ipButton0_OnInterrupt);

            ipButton1 = new InterruptPort(Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_17, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            ipButton1.OnInterrupt += new GPIOInterruptEventHandler(ipButton1_OnInterrupt);

            ipButton2 = new InterruptPort(Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_16, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            ipButton2.OnInterrupt += new GPIOInterruptEventHandler(ipButton2_OnInterrupt);

            ipButton3 = new InterruptPort(Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_11, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            ipButton3.OnInterrupt += new GPIOInterruptEventHandler(ipButton3_OnInterrupt);

            ipButton4 = new InterruptPort(Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_8, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            ipButton4.OnInterrupt += new GPIOInterruptEventHandler(ipButton4_OnInterrupt);

            ipButton5 = new InterruptPort(Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_10, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            ipButton5.OnInterrupt += new GPIOInterruptEventHandler(ipButton5_OnInterrupt);

            ipButton6 = new InterruptPort(Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_12, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            ipButton6.OnInterrupt += new GPIOInterruptEventHandler(ipButton6_OnInterrupt);

            ipButton7 = new InterruptPort(Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_13, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            ipButton7.OnInterrupt += new GPIOInterruptEventHandler(ipButton7_OnInterrupt);

            ipButton8 = new InterruptPort(Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_14, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            ipButton8.OnInterrupt += new GPIOInterruptEventHandler(ipButton8_OnInterrupt);

            ipButton9 = new InterruptPort(Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_15, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            ipButton9.OnInterrupt += new GPIOInterruptEventHandler(ipButton9_OnInterrupt);


            /*********************************************************************************
             * 
             *      Running tests
             * 
             *********************************************************************************/
            Debug.Print("Launching loop");


            // Socket sample
            // Sending data to the socket if it's connected.
            // if(socketBeacon != null)
            //   socketBeacon.BeginSending();

            while (true)
            {
                if (ipButton0Pressed)
                {
                    ipButton0Pressed = false;
                    RunLcdTest(bmp, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_9);
                    if (serialPort != null)
                        RunComTest(serialPort, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_9);
                }

                if (ipButton1Pressed)
                {
                    ipButton1Pressed = false;
                    RunLcdTest(bmp, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_17);
                    if (serialPort != null)
                        RunComTest(serialPort, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_17);
                }


                if (ipButton2Pressed)
                {
                    ipButton2Pressed = false;
                    RunLcdTest(bmp, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_16);
                    if (serialPort != null)
                        RunComTest(serialPort, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_16);
                }

                if (ipButton3Pressed)
                {
                    ipButton3Pressed = false;
                    RunLcdTest(bmp, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_11);
                    if (serialPort != null)
                        RunComTest(serialPort, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_11);
                }

                if (ipButton4Pressed)
                {
                    ipButton4Pressed = false;
                    RunLcdTest(bmp, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_8);
                    if (serialPort != null)
                        RunComTest(serialPort, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_8);
                }

                if (ipButton5Pressed)
                {
                    ipButton5Pressed = false;
                    RunLcdTest(bmp, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_10);
                    if (serialPort != null)
                        RunComTest(serialPort, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_10);
                }

                if (ipButton6Pressed)
                {
                    ipButton6Pressed = false;
                    RunLcdTest(bmp, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_12);
                    if (serialPort != null)
                        RunComTest(serialPort, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_12);
                }

                if (ipButton7Pressed)
                {
                    ipButton7Pressed = false;
                    RunLcdTest(bmp, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_13);
                    if (serialPort != null)
                        RunComTest(serialPort, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_13);
                }

                if (ipButton8Pressed)
                {
                    ipButton8Pressed = false;
                    RunLcdTest(bmp, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_14);
                    if (serialPort != null)
                        RunComTest(serialPort, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_14);
                }

                if (ipButton9Pressed)
                {
                    ipButton9Pressed = false;
                    RunLcdTest(bmp, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_15);
                    if (serialPort != null)
                        RunComTest(serialPort, (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_15);
                }

                Thread.Sleep(1000);
                loopCount++;
            }
        }

        /// <summary>
        /// Running Serial port tests.  Incoming arrays will be reversed
        /// </summary>
        /// <param name="serialPort"></param>
        public void RunComTest(SerialPort serialPort, int buttonPressed)
        {
            UTF8Encoding enc = new UTF8Encoding();
 
            try
            {
                switch (buttonPressed)
                {
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_9:
                        serialPort.Write(enc.GetBytes("A white circle is painted to the display.  "), 0, enc.GetBytes("A white circle is painted to the display.  ").Length);
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_17:
                        serialPort.Write(enc.GetBytes("A blue circle is painted to the display.  "), 0, enc.GetBytes("A blue circle is painted to the display.  ").Length);
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_16:
                        serialPort.Write(enc.GetBytes("A light blue circle is painted to the display.  "), 0, enc.GetBytes("A light blue circle is painted to the display.  ").Length);
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_11:
                        serialPort.Write(enc.GetBytes("A purple circle is painted to the display.  "), 0, enc.GetBytes("A purple circle is painted to the display.  ").Length);
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_8:
                        serialPort.Write(enc.GetBytes("A grey circle is painted to the display.  "), 0, enc.GetBytes("A grey circle is painted to the display.  ").Length);
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_10:
                        serialPort.Write(enc.GetBytes("A green circle is painted to the display.  "), 0, enc.GetBytes("A green circle is painted to the display.  ").Length);
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_12:
                        serialPort.Write(enc.GetBytes("A yellow circle is painted to the display.  "), 0, enc.GetBytes("A yellow circle is painted to the display.  ").Length);
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_13:
                        serialPort.Write(enc.GetBytes("A lime green circle is painted to the display.  "), 0, enc.GetBytes("A lime green circle is painted to the display.  ").Length);
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_14:
                        serialPort.Write(enc.GetBytes("An orange circle is painted to the display.  "), 0, enc.GetBytes("An orange circle is painted to the display.  ").Length);
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_15:
                        serialPort.Write(enc.GetBytes("A red circle is painted to the display.  "), 0, enc.GetBytes("A red circle is painted to the display.  ").Length);
                        break;
                    default:
                        break;
                }
            }
            catch (Exception _except)
            {
                Debug.Print(_except.Message);
                Debug.Print(_except.StackTrace);
            }

        }

        /// <summary>
        /// Running LCD test.  Pixel at random location on the screen will be set
        /// </summary>
        /// <param name="bmp"></param>
        public void RunLcdTest(Bitmap bmp, int buttonPressed)
        {
            int x = 0, y = 0;                               // Location of the pixel to light up for the LCD sample
            Microsoft.SPOT.Presentation.Media.Color color = 0x000000; // Color of the circle 

            Debug.Print("Drawing on the LCD");

            try
            {

                switch (buttonPressed)
                {
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_9:
                        color = (Microsoft.SPOT.Presentation.Media.Color)0xFFFFFF;
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_17:
                        color = (Microsoft.SPOT.Presentation.Media.Color)0xFF0000;
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_16:
                        color = (Microsoft.SPOT.Presentation.Media.Color)0xFFCC77;
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_11:
                        color = (Microsoft.SPOT.Presentation.Media.Color)0xFF00FF;
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_8:
                        color = (Microsoft.SPOT.Presentation.Media.Color)0x77777B;
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_10:
                        color = (Microsoft.SPOT.Presentation.Media.Color)0x00FF00;
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_12:
                        color = (Microsoft.SPOT.Presentation.Media.Color)0x00CFFF;
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_13:
                        color = (Microsoft.SPOT.Presentation.Media.Color)0x77FFAA;
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_14:
                        color = (Microsoft.SPOT.Presentation.Media.Color)0x007FFF;
                        break;
                    case (int)Microsoft.SPOT.Hardware.FreescaleMXSDemo.Pins.GPIO_PORT_B_15:
                        color = (Microsoft.SPOT.Presentation.Media.Color)0x000FFF;
                        break;
                    // Don't care about the pin that just changed.
                    default:
                        break;
                }
                // Picking random location
                x = Microsoft.SPOT.Math.Random(bmp.Width);
                y = Microsoft.SPOT.Math.Random(bmp.Height);

                // Ligthning up the pixel
                bmp.DrawEllipse(color, x, y, 20, 20);

                // Flushing the bitmap.  The emulator fires an event at this point
                bmp.Flush();
            }
            catch (Exception _except)
            {
                Debug.Print(_except.Message);
                Debug.Print(_except.StackTrace);
            }
        }

        private static void ipButton0_OnInterrupt(Cpu.Pin Pin, bool State, TimeSpan timeout)
        {
            MXS.ipButton0Pressed = true;
        }
        private static void ipButton1_OnInterrupt(Cpu.Pin Pin, bool State, TimeSpan timeout)
        {
            ipButton1Pressed = true;
        }
        private static void ipButton2_OnInterrupt(Cpu.Pin Pin, bool State, TimeSpan timeout)
        {
            ipButton2Pressed = true;
        }
        private static void ipButton3_OnInterrupt(Cpu.Pin Pin, bool State, TimeSpan timeout)
        {
            ipButton3Pressed = true;
        }
        private static void ipButton4_OnInterrupt(Cpu.Pin Pin, bool State, TimeSpan timeout)
        {
            ipButton4Pressed = true;
        }
        private static void ipButton5_OnInterrupt(Cpu.Pin Pin, bool State, TimeSpan timeout)
        {
            ipButton5Pressed = true;
        }
        private static void ipButton6_OnInterrupt(Cpu.Pin Pin, bool State, TimeSpan timeout)
        {
            ipButton6Pressed = true;
        }
        private static void ipButton7_OnInterrupt(Cpu.Pin Pin, bool State, TimeSpan timeout)
        {
            ipButton7Pressed = true;
        }
        private static void ipButton8_OnInterrupt(Cpu.Pin Pin, bool State, TimeSpan timeout)
        {
            ipButton8Pressed = true;
        }
        private static void ipButton9_OnInterrupt(Cpu.Pin Pin, bool State, TimeSpan timeout)
        {
            ipButton9Pressed = true;
        }


    }

}
