using C1.Xaml;
using C1.Xaml.Maps;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using Windows.Foundation;
using Windows.Storage;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;



namespace ControlExplorer.Controls.Maps
{
    public partial class VectorMap
        : UserControl, IExposeApplicationBarItems
    {
        AppBarButton btnLegend = new AppBarButton();
        AppBarButton btnZoomOrigin = new AppBarButton();
        Countries countries = new Countries();
        C1VectorLayer vl;

        public VectorMap()
        {
            InitializeComponent();

            btnLegend.Icon = new SymbolIcon(Symbol.Help);
            btnLegend.Label = "legend";
            btnLegend.Click += btnLegend_Click;

            btnZoomOrigin.Icon = new BitmapIcon { UriSource = new Uri("ms-appx:///Resources/AppBar/zoom_1-1.png") };
            btnZoomOrigin.Label = "zoom out";
            btnZoomOrigin.Click += btnZoomOrigin_Click;

            Loaded += VectorMap_Loaded;
            Unloaded += VectorMap_Unloaded;
        }

        void VectorMap_Unloaded(object sender, RoutedEventArgs e)
        {
            countries.Clear();
            maps.Layers.Clear();
            vl.Dispose();
            maps.TargetZoomChanged -= maps_TargetZoomChanged;
        }

        void btnZoomOrigin_Click(object sender, RoutedEventArgs e)
        {
            maps.TargetZoom = 0;
            maps.TargetCenter = new Point();
        }

        private async void VectorMap_Loaded(object sender, RoutedEventArgs e)
        {
            // create VectorLayer
            if (maps.Layers.Count != 0)
            {
                vl = maps.Layers[0] as C1VectorLayer;
                vl.Children.Clear();
            }
            else
            {
                vl = new C1VectorLayer()
                {
                    Foreground = new SolidColorBrush(Color.FromArgb(255, 0x97, 0x35, 0x35))
                };
                maps.Layers.Add(vl);
            }
            vl.LabelVisibility = LabelVisibility.Hidden;
            // read text data from resources            
            var resource = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Resources/Maps/gdp-ppp.txt"));
            if (resource == null)
                return;

            using (Stream stream = await resource.OpenStreamForReadAsync())
            {
                using (StreamReader sr = new StreamReader(stream))
                {
                    for (; !sr.EndOfStream; )
                    {
                        string s = sr.ReadLine();

                        string[] ss = s.Split(new char[] { '\t' },
                          StringSplitOptions.RemoveEmptyEntries);

                        countries.Add(new Country() { Name = ss[1].Trim(), Value = double.Parse(ss[2], CultureInfo.InvariantCulture) });
                    }
                }
            }

            // create palette
            ColorValues cvals = new ColorValues();
            cvals.Add(new ColorValue() { Color = Color.FromArgb(255, 241, 244, 255), Value = 0 });
            cvals.Add(new ColorValue() { Color = Color.FromArgb(255, 241, 244, 255), Value = 5000 });
            cvals.Add(new ColorValue() { Color = Color.FromArgb(255, 224, 224, 246), Value = 10000 });
            cvals.Add(new ColorValue() { Color = Color.FromArgb(255, 203, 205, 255), Value = 20000 });
            cvals.Add(new ColorValue() { Color = Color.FromArgb(255, 179, 182, 230), Value = 50000 });
            cvals.Add(new ColorValue() { Color = Color.FromArgb(255, 156, 160, 240), Value = 100000 });
            cvals.Add(new ColorValue() { Color = Color.FromArgb(255, 127, 132, 243), Value = 200000 });
            cvals.Add(new ColorValue() { Color = Color.FromArgb(255, 89, 97, 230), Value = 500000 });
            cvals.Add(new ColorValue() { Color = Color.FromArgb(255, 56, 64, 217), Value = 1000000 });
            cvals.Add(new ColorValue() { Color = Color.FromArgb(255, 19, 26, 148), Value = 2000000 });
            cvals.Add(new ColorValue() { Color = Color.FromArgb(255, 0, 3, 74), Value = 1.001 * countries.GetMax() });

            countries.Converter = cvals;

            // read world map from resources
            await Utils.LoadKMZFromResources(vl, new Uri("ms-appx:///Resources/Maps/WorldMap.kmz"), true, ProcessWorldMap);
            maps.Zoom = 0;
            maps.TargetCenter = new Point(0, 0);
            maps.TargetZoomChanged += maps_TargetZoomChanged;

            InitLegend();
        }

        void btnLegend_Click(object sender, RoutedEventArgs e)
        {
            legendPanel.Visibility = legendPanel.Visibility == Visibility.Collapsed
                ? Visibility.Visible
                : Visibility.Collapsed;
        }

        void maps_TargetZoomChanged(object sender, PropertyChangedEventArgs<double> e)
        {
            if (e.NewValue >= 2)
                vl.LabelVisibility = LabelVisibility.AutoHide;
            else
                vl.LabelVisibility = LabelVisibility.Hidden;
        }

        bool ProcessWorldMap(C1VectorItemBase v)
        {
            string name = ToolTipService.GetToolTip(v) as string;

            Country country = countries[name];
            if (country != null)
                v.Fill = country.Fill;
            else
                v.Fill = null;

            return true;
        }

        void InitLegend()
        {
            ColorValues cvals = (ColorValues)countries.Converter;
            var legendItems = new List<LegendItem>();

            for (int i = 0; i < cvals.Count - 1; i++)
            {
                ColorValue cv = cvals[i];

                LinearGradientBrush lgb = new LinearGradientBrush() { StartPoint = new Point(0, 0), EndPoint = new Point(0, 1) };
                lgb.GradientStops.Add(new GradientStop() { Color = cv.Color, Offset = 0 });
                lgb.GradientStops.Add(new GradientStop() { Color = cvals[i + 1].Color, Offset = 1 });

                legendItems.Add(new LegendItem()
                {
                    Brush = lgb,
                    Text = cv.Value.ToString("N0")
                });
            }
            legend.ItemsSource = legendItems;
        }


        #region IExposeApplicationBarItems Members

        public IEnumerable<ICommandBarElement> ApplicationBarItems
        {
            get
            {
                yield return btnLegend;

                yield return btnZoomOrigin;
            }
        }

        #endregion
        private void legend_DoubleTapped(object sender, Windows.UI.Xaml.Input.DoubleTappedRoutedEventArgs e)
        {
            e.Handled = true;
        }
    }

    public class LegendItem
    {
        public Brush Brush { get; set; }
        public string Text { get; set; }
    }
}