using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Runtime.InteropServices;
// für Netzwerk
using System.IO;
using System.Net.Sockets;
using System.Net;


namespace SEW_Application
{
    public partial class Form1 : Form
    {
        //#region DLL
        //[DllImport("C:\\Users\\ALMA\\Desktop\\TcpUdp\\Debug\\TcpUdp.dll", EntryPoint = "sendUDPimagePerClient",ExactSpelling= true,CharSet= CharSet.Auto)]
        //public static extern int sendUDPimagePerClient(ref byte[] serv_addr, ushort port);

        //[DllImport("C:\\Users\\ALMA\\Desktop\\TcpUdp\\Debug\\TcpUdp.dll", EntryPoint = "sendUDPimagePerClient", ExactSpelling = true, CharSet = CharSet.Auto)]
        //public static extern int recvUDPimagePerServer(ref byte[] filename, ref byte[] serv_addr, ushort port);
        //#endregion DLL
        UdpClient udpclient = new UdpClient(11000);
        byte[] daten = new byte[120000];
        byte[] daten2 = new byte[60000];
        byte[] daten3 = new byte[60000];


        Thread Sender; // Thread zum Senden von Bildern
        Thread Receiver; // Thread zum Empfangen von Bildern

        
        //UdpClient udpclient = new UdpClient("169.254.123.79", 6666);

        bool Closing = false; // true wenn Formular beendet werden soll
        bool winOrLabel, NDset;
        String ClosingString = "FORM#CLOSING"; //Nachricht, die bei Beendigung geschickt wird
        byte[] ClosingBytes; // Byte - Darstellung der Nachricht
        ASCIIEncoding ByteConverter = new ASCIIEncoding(); // Objekt zur Konvertierung von Strings in byte - Arrays und umgekehrt
        List<Control> m_MovebleControls;
        Control label_temp;
        Label label_window;
        string str_temp, partnerIP, partnerPort;
    
        //Form
        public Form1()
        {
            InitializeComponent();

        }
        private void Form1_Load(object sender, EventArgs e)
        {
            m_MovebleControls = new List<Control>();
            m_MovebleControls.Add(panel_actPosCam);
            m_MovebleControls.Add(panel_leftCam);
            m_MovebleControls.Add(panel_rightCam);
            m_MovebleControls.Add(panel_stereoCam);

            foreach (Control control in m_MovebleControls)
            {
                control.MouseMove += new MouseEventHandler(Control_MouseMove);
            }
            this.setToolTips();
        }
        
        //Controls
        private void Control_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                Control controlToMove = (Control)sender;
                controlToMove.BringToFront();
                controlToMove.Location = new Point(controlToMove.Location.X + e.Location.X - 10,
                   controlToMove.Location.Y + e.Location.Y - 10);
            }
        }
        private void control_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            label_temp = (Control)sender;
            RichTextBox temp = new RichTextBox();
            this.Controls.Add(temp);
            temp.Size = new Size((int)100, (int)25);
            temp.Enabled = true;
            temp.Visible = true;
            Point locationOnForm = label_temp.FindForm().PointToClient(label_temp.Parent.PointToScreen(label_temp.Location));
            temp.Location = locationOnForm;
            temp.BringToFront();
            
            temp.KeyPress +=new KeyPressEventHandler(temp_KeyPress);
        }
        private void temp_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                Control c = (Control)sender;
                str_temp = c.Text;
                c.Dispose();
                this.Controls.Remove(c);
                if (winOrLabel)
                    label_temp.Text = str_temp;
                else
                    label_window.Text = str_temp;
            }
        }


        //Timer
        private void timer_move_Tick(object sender, EventArgs e)
        {
        }

        //MainWindow ContextMenu
        private void toolStripMenuItem_PictureBox_Click(object sender, EventArgs e)
        {
            Panel panel = new Panel();
            panel.Size = panel_leftCam.Size;
            panel.BackColor = panel_leftCam.BackColor;
            panel.BorderStyle = panel_leftCam.BorderStyle;
            panel.Location = new Point(MousePosition.X, MousePosition.Y);
            panel.Visible = true;
            panel.Enabled = true;
            this.Controls.Add(panel);
            panel.BringToFront();
            panel.ContextMenuStrip = this.contextMenuStrip_Controls;

            PictureBox pic = new PictureBox();
            pic.Size = pictureBox_Cam_l.Size;
            pic.Enabled = true;
            pic.Visible = true;
            pic.BorderStyle = BorderStyle.Fixed3D;
            pic.BackColor = pictureBox_Cam_l.BackColor;
            pic.ContextMenuStrip = this.contextMenuStrip_Controls;
            this.Controls.Add(pic);
            

            label_window = new Label();
            label_window.Size = this.label_Cam_l.Size;
            label_window.Font = this.label_Cam_l.Font;
            label_window.Enabled = true;
            label_window.Visible = true;
            label_window.Text = "NAME";
            this.Controls.Add(label_window);
            label_window.ContextMenuStrip = this.contextMenuStrip_Controls;

            panel.Controls.Add(pic);
            panel.Controls.Add(label_window);
            pic.Location = pictureBox_Cam_l.Location;
            label_window.Location = label_Cam_l.Location;
            pic.BringToFront();
            label_window.BringToFront();

            m_MovebleControls.Add(panel);
            Control control = panel;
            control.MouseMove += new MouseEventHandler(Control_MouseMove);
            control = label_window;
            control.MouseDoubleClick += new MouseEventHandler(control_MouseDoubleClick);
            this.toolTip1.SetToolTip(label_window, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");
            this.toolTip1.SetToolTip(panel, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");
            this.toolTip1.SetToolTip(pic, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");
        }
        private void textboxInputToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.creatInOrOutPut();
        }
        private void textboxOuToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.creatInOrOutPut();
        }
        private void newWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form1 newWindow = new Form1();
            newWindow.Controls.Clear();
            newWindow.Show();

        }
        private void labelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Label label = new Label();
            label.Size = this.label_Cam_l.Size;
            label.Font = this.label_Cam_l.Font;
            label.Location = Cursor.Position;
            label.Enabled = true;
            label.Visible = true;
            label.Text = "NAME";
            this.Controls.Add(label);
            label.BringToFront();
            label.ContextMenuStrip = this.contextMenuStrip_Controls;

            m_MovebleControls.Add(label);
            Control control = label;
            control.MouseMove += new MouseEventHandler(Control_MouseMove);
            control.MouseDoubleClick += new MouseEventHandler(control_MouseDoubleClick);
            winOrLabel = true;
        }
        private void creatInOrOutPut()
        {
            Panel panel = new Panel();
            RichTextBox textb = new RichTextBox();
            Label label = new Label();

            panel.Size = this.panel_template.Size;
            panel.BackColor = this.panel_template.BackColor;
            panel.Visible = true;
            panel.Enabled = true;
            panel.BorderStyle = panel_template.BorderStyle;
            this.Controls.Add(panel);
            panel.Location = new Point(Cursor.Position.X, Cursor.Position.Y);
            panel.ContextMenuStrip = panel_template.ContextMenuStrip;

            textb.Size = richTextBox_template.Size;
            textb.Location = richTextBox_template.Location;
            textb.Visible = true;
            textb.Enabled = true;
            textb.ContextMenuStrip = richTextBox_template.ContextMenuStrip;

            label.Size = label_template.Size;
            label.Location = label_template.Location;
            label.Visible = true;
            label.Enabled = true;
            label.Text = label_template.Text;
            label.Font = label_template.Font;

            panel.Controls.Add(textb);
            panel.Controls.Add(label);
            panel.BringToFront();
            textb.BringToFront();
            label.BringToFront();

            m_MovebleControls.Add(panel);
            Control control = panel;
            control.MouseMove += new MouseEventHandler(Control_MouseMove);
            control = label;
            control.MouseDoubleClick += new MouseEventHandler(control_MouseDoubleClick);
            winOrLabel = true;
            this.toolTip1.SetToolTip(panel, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");
            this.toolTip1.SetToolTip(textb, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");
            this.toolTip1.SetToolTip(label, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");
        }
        
        //Controls_MenuStrip
        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Controls.Remove(this.contextMenuStrip_Controls.SourceControl);
        }
        private void connectToToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Thread zum Empfangen des Partnerbildes starten
            Form_NetworkData ND = new Form_NetworkData(this);
            ND.Show();
        }
        public void setND(string IP, string Port)
        {
            partnerPort = Port;
            partnerIP = IP;
            startConnection();
        }
        public void startConnection()
        {
            Receiver = new Thread(new ParameterizedThreadStart(Receive));
            Receiver.Start(partnerPort + "-" + partnerIP);
            //ClosingBytes = ByteConverter.GetBytes(ClosingString);
        }
        
        //Networking
        private void Receive(object portip)
        {
            udpclient.Connect(partnerIP, Convert.ToInt16(partnerPort));
            IPEndPoint ipendpoint = new IPEndPoint(IPAddress.Any, 0);
            while (true)
            {
                try
                {
                    daten2 = udpclient.Receive(ref ipendpoint);
                    //    daten3 = udpclient.Receive(ref ipendpoint);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
                //for(int i=0;i<60000;i++)
                //{
                //    daten[i] = daten2[i];
                //    daten[i+60000] = daten3[i];
                //}

                FileStream fstream = new FileStream("R2D2.jpeg", FileMode.Create);
                fstream.Write(daten2, 0, daten2.Length);
                fstream.Close();

                try
                { this.pictureBox_Cam_r.Load("R2D2.jpeg"); }
                catch (Exception ex)
                { }

            }
            #region Stuff befor
            //// portip hat die Form "port-ip"
            //string[] Parameter = portip.ToString().Split('-');
            //System.Net.IPAddress IP = System.Net.IPAddress.Parse(Parameter[1]);

            //TcpClient Exchange = new TcpClient();
            //NetworkStream ExchangeStream = null;

            //Image TempImage;

            //// alle 3 Sekunden versuchen eine Verbindung herzustellen
            //while (true)
            //{
            //    try
            //    {
            //        Exchange.Connect(IP, int.Parse(Parameter[0]));
            //        ExchangeStream = Exchange.GetStream();
            //        break;
            //    }
            //    catch
            //    {
            //        Thread.Sleep(3000);
            //    }
            //}

            //while (true)
            //{
            //    if (Closing)
            //        break; // Beendigung

            //    try
            //    {
            //        // versuchen, das empfangene Bild zu lesen darzustellen
            //        // bei Erfolg
            //        TempImage = ReadImage(ExchangeStream);
            //        if (TempImage == null)
            //            throw new Exception();

            //        pictureBox_Cam_l.BackgroundImage = TempImage;
            //        LastImageReceived = (Image)pictureBox_Cam_l.BackgroundImage.Clone();
            //        Thread.Sleep(100);
            //    }
            //    catch
            //    {
            //        try
            //        {   // bei Fehler das Backupbild darstellen
            //            pictureBox_Cam_l.BackgroundImage = LastImageReceived;
            //        }
            //        catch { }
            //    }
            //}
            #endregion Stuff befor
        }
        private Image ReadImage(NetworkStream stream)
        {
            Image Result;
            int BytesRead;

            // die ersten 20 Bytes des Streams einlesen, denn in diesen ist die Größe kodiert
            byte[] ImageSize = new byte[20];
            BytesRead = stream.Read(ImageSize, 0, 20);

            /* konnten nur 12 Bytes gelesen werden und haben diese den Inhalt des
            Closing Strings, so soll beendet werden */
            if (BytesRead == 12)
            {
                if (ByteConverter.GetString(ImageSize, 0, 12) == "FORM#CLOSING")
                {
                    Closing = true;
                    return null;
                }
            }

            byte[] ErrorBuffer = new byte[100000000];

            ASCIIEncoding Decoder = new ASCIIEncoding();
            string ImageSizeString = Decoder.GetString(ImageSize).Replace("x", "");

            int TestSize;

            if (!int.TryParse(ImageSizeString, out TestSize))
            {
                stream.Read(ErrorBuffer, 0, ErrorBuffer.Length);
                return null;
            }

            byte[] ImageFile = new byte[int.Parse(ImageSizeString)];

            stream.Read(ImageFile, 0, ImageFile.Length);

            MemoryStream temps = new MemoryStream();

            try
            {
                temps.Write(ImageFile, 0, ImageFile.Length);
                Result = Image.FromStream(temps);
                return Result;
            }
            catch
            {
                return null;
            }
        }
        
        //ToolTip
        private void toolTip1_Popup(object sender, PopupEventArgs e)
        {
            
        }
        private void setToolTips()
        {
            toolTip1.SetToolTip(this.pictureBox_actualPosition, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");
            toolTip1.SetToolTip(this.pictureBox_Cam_l, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");
            toolTip1.SetToolTip(this.pictureBox_Cam_r,"If you want move the Control, please push the right mousebutton on the gray field and hold it.");
            toolTip1.SetToolTip(this.pictureBox_Stereovision, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");

            toolTip1.SetToolTip(this.label_actualPosition, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");
            toolTip1.SetToolTip(this.label_Cam_l, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");
            toolTip1.SetToolTip(this.label_Cam_r, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");
            toolTip1.SetToolTip(this.label_Stereovision, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");

            toolTip1.SetToolTip(this.panel_actPosCam, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");
            toolTip1.SetToolTip(this.panel_leftCam, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");
            toolTip1.SetToolTip(this.panel_rightCam, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");
            toolTip1.SetToolTip(this.panel_stereoCam, "If you want move the Control, please push the right mousebutton on the gray field and hold it.");
        }

        //Eigenschaften
        public string PartnerIP
        {
            //get { return this.richTextBoxIP.Text; }
            set { partnerIP= value; }
        }
        public string PartnerPort
        {
            //get { return this.richTextBoxPort.Text; }
            set { this.partnerPort = value; }
        }
    }
}
