using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Drawing;
using System.Windows.Forms;

using LumiSoft.Net.UPnP.NAT;

namespace UPnP_NAT
{
    /// <summary>
    /// Add new NAT map entry.
    /// </summary>
    public class wfrm_Add : Form
    {
        private Label         mt_Enabled     = null;
        private CheckBox      m_pEnabled     = null;
        private Label         mt_Description = null;
        private TextBox       m_pDescription = null;
        private Label         mt_Protocol    = null;
        private ComboBox      m_pProtocol    = null;
        private Label         mt_RemoteHost  = null;
        private TextBox       m_pRemoteHost  = null;
        private Label         mt_RemotePort  = null;
        private NumericUpDown m_pRemotePort  = null;
        private Label         mt_LocalHost   = null;
        private TextBox       m_pLocalHost   = null;
        private Label         mt_LocalPort   = null;
        private NumericUpDown m_pLocalPort   = null;
        private Label         mt_Expires     = null;
        private NumericUpDown m_pExpires     = null;
        private Button        m_pCancel      = null;
        private Button        m_pOk          = null;

        private UPnP_NAT_Client m_pUpnPNat = null;

        /// <summary>
        /// Defaul constructor.
        /// </summary>
        /// <param name="upnpNat">UPnP nat client.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>upnpNat</b> is null reference.</exception>
        public wfrm_Add(UPnP_NAT_Client upnpNat)
        {
            if(upnpNat == null){
                throw new ArgumentNullException("upnpNat");
            }

            InitUI();

            m_pUpnPNat = upnpNat;
        }

        #region method InitUI

        /// <summary>
        /// Creates and initializes UI.
        /// </summary>
        private void InitUI()
        {
            this.ClientSize = new Size(250,240);
            this.StartPosition = FormStartPosition.CenterScreen;
            this.MaximizeBox = false;
            this.Text = "Add new NAT map entry.";
            this.Icon = UPnP_NAT.Resources.ResManager.GetIcon("add.ico");

            mt_Enabled = new Label();
            mt_Enabled.Size = new Size(100,20);
            mt_Enabled.Location = new Point(0,5);
            mt_Enabled.Text = "Enabled:";
            mt_Enabled.TextAlign = ContentAlignment.MiddleRight;

            m_pEnabled = new CheckBox();
            m_pEnabled.Size = new Size(140,20);
            m_pEnabled.Location = new Point(105,5);
            m_pEnabled.Checked = true;

            mt_Description = new Label();
            mt_Description.Size = new Size(100,20);
            mt_Description.Location = new Point(0,30);
            mt_Description.Text = "Description:";
            mt_Description.TextAlign = ContentAlignment.MiddleRight;

            m_pDescription = new TextBox();
            m_pDescription.Size = new Size(140,20);
            m_pDescription.Location = new Point(105,30);

            mt_Protocol = new Label();
            mt_Protocol.Size = new Size(100,20);
            mt_Protocol.Location = new Point(0,55);
            mt_Protocol.Text = "Protocol:";
            mt_Protocol.TextAlign = ContentAlignment.MiddleRight;

            m_pProtocol = new ComboBox();
            m_pProtocol.Size = new Size(70,20);
            m_pProtocol.Location = new Point(105,55);
            m_pProtocol.DropDownStyle = ComboBoxStyle.DropDownList;
            m_pProtocol.Items.Add("TCP");
            m_pProtocol.Items.Add("UDP");
            m_pProtocol.SelectedIndex = 0;

            mt_RemoteHost = new Label();
            mt_RemoteHost.Size = new Size(100,20);
            mt_RemoteHost.Location = new Point(0,80);
            mt_RemoteHost.Text = "Remote Host:";
            mt_RemoteHost.TextAlign = ContentAlignment.MiddleRight;

            m_pRemoteHost = new TextBox();
            m_pRemoteHost.Size = new Size(140,20);
            m_pRemoteHost.Location = new Point(105,80);

            mt_RemotePort = new Label();
            mt_RemotePort.Size = new Size(100,20);
            mt_RemotePort.Location = new Point(0,105);
            mt_RemotePort.Text = "Remote Port:";
            mt_RemotePort.TextAlign = ContentAlignment.MiddleRight;

            m_pRemotePort = new NumericUpDown();
            m_pRemotePort.Size = new Size(70,20);
            m_pRemotePort.Location = new Point(105,105);
            m_pRemotePort.Minimum = 0;
            m_pRemotePort.Maximum = short.MaxValue;
            m_pRemotePort.TextAlign = HorizontalAlignment.Right;

            mt_LocalHost = new Label();
            mt_LocalHost.Size = new Size(100,20);
            mt_LocalHost.Location = new Point(0,130);
            mt_LocalHost.Text = "Local Host:";
            mt_LocalHost.TextAlign = ContentAlignment.MiddleRight;

            m_pLocalHost = new TextBox();
            m_pLocalHost.Size = new Size(140,20);
            m_pLocalHost.Location = new Point(105,130);
            m_pLocalHost.Text = GetLocalIP();

            mt_LocalPort = new Label();
            mt_LocalPort.Size = new Size(100,20);
            mt_LocalPort.Location = new Point(0,155);
            mt_LocalPort.Text = "Local Port:";
            mt_LocalPort.TextAlign = ContentAlignment.MiddleRight;

            m_pLocalPort = new NumericUpDown();
            m_pLocalPort.Size = new Size(70,20);
            m_pLocalPort.Location = new Point(105,155);
            m_pLocalPort.Minimum = 0;
            m_pLocalPort.Maximum = short.MaxValue;
            m_pLocalPort.TextAlign = HorizontalAlignment.Right;

            mt_Expires = new Label();
            mt_Expires.Size = new Size(100,20);
            mt_Expires.Location = new Point(0,180);
            mt_Expires.Text = "Expires:";
            mt_Expires.TextAlign = ContentAlignment.MiddleRight;

            m_pExpires = new NumericUpDown();
            m_pExpires.Size = new Size(70,20);
            m_pExpires.Location = new Point(105,180);
            m_pExpires.Minimum = 0;
            m_pExpires.Maximum = short.MaxValue;
            m_pExpires.TextAlign = HorizontalAlignment.Right;

            m_pCancel = new Button();
            m_pCancel.Size = new Size(70,20);
            m_pCancel.Location = new Point(105,215);
            m_pCancel.Text = "Cancel";
            m_pCancel.Click += new EventHandler(m_pCancel_Click);

            m_pOk = new Button();
            m_pOk.Size = new Size(70,20);
            m_pOk.Location = new Point(175,215);
            m_pOk.Text = "Ok";
            m_pOk.Click += new EventHandler(m_pOk_Click);
                        
            this.Controls.Add(mt_Enabled);
            this.Controls.Add(m_pEnabled);
            this.Controls.Add(mt_Description);
            this.Controls.Add(m_pDescription);
            this.Controls.Add(mt_Protocol);
            this.Controls.Add(m_pProtocol);
            this.Controls.Add(mt_RemoteHost);
            this.Controls.Add(m_pRemoteHost);
            this.Controls.Add(mt_RemotePort);
            this.Controls.Add(m_pRemotePort);
            this.Controls.Add(mt_LocalHost);
            this.Controls.Add(m_pLocalHost);
            this.Controls.Add(mt_LocalPort);
            this.Controls.Add(m_pLocalPort);
            this.Controls.Add(mt_Expires);
            this.Controls.Add(m_pExpires);
            this.Controls.Add(m_pCancel);
            this.Controls.Add(m_pOk);
        }
                                
        #endregion


        #region Events handling

        #region method m_pCancel_Click

        private void m_pCancel_Click(object sender,EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }

        #endregion

        #region method m_pOk_Click

        private void m_pOk_Click(object sender, EventArgs e)
        {
            try{
                m_pUpnPNat.AddPortMapping(m_pEnabled.Checked,m_pDescription.Text,m_pProtocol.Text,m_pRemoteHost.Text,(int)m_pRemotePort.Value,new IPEndPoint(IPAddress.Parse(m_pLocalHost.Text),(int)m_pLocalPort.Value),(int)m_pExpires.Value);

                this.DialogResult = DialogResult.OK;
            }
            catch(Exception x){
                MessageBox.Show(this,"Error: " + x.Message,"Error:",MessageBoxButtons.OK,MessageBoxIcon.Error);
            }
        }

        #endregion

        #endregion


        #region method GetLocalIP

        /// <summary>
        /// Gets first local IPv4 address.
        /// </summary>
        /// <returns>Returns first local IPv4 address.</returns>
        private string GetLocalIP()
        {
            foreach(IPAddress ip in  Dns.GetHostAddresses("")){
                if(ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork){
                    return ip.ToString();
                }
            }

            return null;
        }

        #endregion
    }
}
