using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using SharpPcap.WinPcap;
using GMap.NET.MapProviders;
using GMap.NET.WindowsPresentation;
using Skyffer.Properties;
using System.Configuration;
using System.Threading;

namespace Skyffer
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Location.Init();

            foreach (WinPcapDevice dev in PacketIPHelper.Devices)
                cboDevices.Items.Add(dev.Interface.FriendlyName);
            cboDevices.SelectedIndex = 0;
            MainMap.MapProvider = GoogleMapProvider.Instance;

            txtPort.Text = Config.Default.Port;
            if (cboDevices.Items.Contains(Config.Default.Device))
                cboDevices.SelectedValue = Config.Default.Device;

            PacketIPHelper.LocationAdded += new PacketIPHelper.LocationEventHandler(WinPCap_LocationAdded);
            PacketIPHelper.LocationRemoved += new PacketIPHelper.LocationEventHandler(WinPCap_LocationRemoved);

            Console.WriteLine(PacketIPHelper._IPHistory == null);
            grdIPs.ItemsSource = PacketIPHelper._IPHistory;

        }


        void WinPCap_LocationRemoved(Location loc)
        {
            lock (this)
            {
                Dispatcher.Invoke(new Action(() =>
                {
                    var rem = (from x in MainMap.Markers where x.Tag == loc select x);
                    if (rem.Count() > 0)
                        MainMap.Markers.Remove(rem.First());
                }));
            }
        }

        void WinPCap_LocationAdded(Location loc)
        {
            lock (this)
            {
                Dispatcher.Invoke(new Action(() =>
                {
                    var currentMarker = new GMapMarker(new GMap.NET.PointLatLng(loc.Lat, loc.Lon));
                    {
                        currentMarker.Shape = new CustomMarkerRed(this, currentMarker, loc.LocationDesc, loc);
                        currentMarker.Shape.IsHitTestVisible = false;
                        currentMarker.Offset = new System.Windows.Point(-15, -15);
                        currentMarker.ZIndex = int.MaxValue;
                        currentMarker.Tag = loc;
                        MainMap.Markers.Add(currentMarker);
                    }

                    if (!loc.AlreadyAdded)
                    {
                        loc.AlreadyAdded = true;
                        PacketIPHelper._IPHistory.Add(loc);
                        while (PacketIPHelper._IPHistory.Count > PacketIPHelper.MAX_HISTORY)
                            PacketIPHelper._IPHistory.RemoveAt(0);
                    }
                }));
            }
        }

        private void TextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            int temp;
            if (!int.TryParse(txtPort.Text, out temp))
                lblPortError.Visibility = System.Windows.Visibility.Visible;
            else
                if (temp > 65535 || temp < 1)
                    lblPortError.Visibility = System.Windows.Visibility.Visible;
                else
                    lblPortError.Visibility = System.Windows.Visibility.Collapsed;
        }

        private void Start_Click(object sender, RoutedEventArgs e)
        {
            TextBox_LostFocus(null, null);
            if (lblPortError.Visibility == System.Windows.Visibility.Visible)
                return;

            Config.Default.Device = cboDevices.SelectedValue.ToString();
            Config.Default.Port = txtPort.Text;
            Config.Default.Save();

            PacketIPHelper.Start(cboDevices.SelectedIndex, int.Parse(txtPort.Text));
            cboDevices.IsEnabled = false;
            txtPort.IsEnabled = false;
            btnStart.IsEnabled = false;
            btnStop.IsEnabled = true;
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            string s = "";
            foreach (var x in PacketIPHelper._IPHistory)
                s = s + x.Serialize() + "#";
            Config.Default.LastIPs = s;
            Config.Default.Save();
            PacketIPHelper.Stop();
        }

        private void Stop_Click(object sender, RoutedEventArgs e)
        {
            PacketIPHelper.Stop();
            cboDevices.IsEnabled = true;
            txtPort.IsEnabled = true;
            btnStart.IsEnabled = true;
            btnStop.IsEnabled = false;
        }

        private void Lokalizuj_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var loc = new Location(txtManualIP.Text);

                if (PacketIPHelper._LastIPs.ContainsKey(txtManualIP.Text))
                    PacketIPHelper._LastIPs.Remove(txtManualIP.Text);

                //if (loc.GeoLocated)
                PacketIPHelper._LastIPs.Add(txtManualIP.Text, loc);
            }
            catch
            {
                global::System.Windows.Forms.MessageBox.Show("Neplatná IP adresa!", "Chyba", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            foreach (var x in Config.Default.LastIPs.Split('#'))
                Location.Deserialize(x);
        }

        private void DeleteIP_Click(object sender, RoutedEventArgs e)
        {
            {
                var loc = ((FrameworkElement)sender).DataContext as Location;
                PacketIPHelper._IPHistory.Remove(loc);
                PacketIPHelper.NotifyRemove(loc);
            }
        }

        private void MapChange(object sender, RoutedEventArgs e)
        {
            switch ((sender as Button).Tag.ToString())
            {
                case "gmap":
                    MainMap.MapProvider = GoogleMapProvider.Instance;
                    break;
                case "gterr":
                    MainMap.MapProvider = GoogleTerrainMapProvider.Instance;
                    break;
                case "ghybrid":
                    MainMap.MapProvider = GoogleHybridMapProvider.Instance;
                    break;

            }
        }

    }
}
