using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Effects;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Geometry;

namespace GeoDashboard
{
    public partial class MainPage : UserControl
    {
        Storyboard _sb;
        DropShadowEffect _shadow;
        static Brush _brTransparent = new SolidColorBrush(Colors.Transparent);

        public MainPage()
        {
            InitializeComponent();

            // refresh model information when the map extent changes
            _sb = new Storyboard();
            _sb.Duration = new Duration(TimeSpan.FromMilliseconds(500));
            _sb.Completed += _sb_Completed;
            _map.ExtentChanged += _map_ExtentChanged;

            // go to current location when user clicks the link
            _goToCurrentLocation.Click += (s, e) =>
                {
                    System.Windows.Browser.HtmlPage.Window.Invoke("getLocation", new Action<string>(result =>
                    {
                        var lonLat = result.Split(',');
                        if (lonLat.Length == 2)
                        {
                            var pt = new Point(double.Parse(lonLat[0]), double.Parse(lonLat[1]));
                            _map.PanTo(GeoToMap(pt));
                        }
                        else
                        {
                            MessageBox.Show(result);
                            _goToCurrentLocation.IsEnabled = false;
                        }
                    }));
                };

            // create shadow effect to apply to currently selected tile
            _shadow = new System.Windows.Media.Effects.DropShadowEffect()
            {
                Color = Colors.Black,
                BlurRadius = 8,
                Opacity = 0.5
            };

            // show layer with info relative to the tile that was clicked
            _gTiles.MouseLeftButtonDown += TileClick;
        }

        // show layer with info relative to the tile that was clicked
        void TileClick(object sender, MouseEventArgs e)
        {
            // get tile layer, hide it
            var layer = _map.Layers["_demographics"] as ArcGISTiledMapServiceLayer;
            layer.Visible = false;

            // scan tile elements and show the one that was clicked
            foreach (UserControl tile in _gTiles.Children)
            {
                var rc = new Rect(0, 0, tile.ActualWidth, tile.ActualHeight);
                if (rc.Contains(e.GetPosition(tile)))
                {
                    var root = tile.Content as Grid;
                    var infoSource = root.DataContext as InfoSource;
                    if (infoSource != null)
                    {
                        layer.Url = infoSource.GetTileUrl();
                        layer.Visible = true;
                    }
                    tile.Effect = _shadow;
                }
                else
                {
                    tile.Effect = null;
                }
            }
        }

        // refresh model information when the map extent changes
        void _map_ExtentChanged(object sender, ESRI.ArcGIS.Client.ExtentEventArgs e)
        {
            _sb.Stop();
            _sb.Seek(TimeSpan.Zero);
            _sb.Begin();
        }
        void _sb_Completed(object sender, EventArgs e)
        {
            var model = Resources["_vm"] as ViewModel;
            if (model != null)
            {
                model.Extent = _map.Extent;
            }
        }

        // convert geo coordinates (lat/lon) to and from map coordinates
        // (assuming WebMercator projection).
        static ESRI.ArcGIS.Client.Projection.WebMercator _wm = new ESRI.ArcGIS.Client.Projection.WebMercator();
        ESRI.ArcGIS.Client.Geometry.MapPoint GeoToMap(Point point)
        {
            var mapPoint = new ESRI.ArcGIS.Client.Geometry.MapPoint(point.X, point.Y);
            return _wm.FromGeographic(mapPoint) as ESRI.ArcGIS.Client.Geometry.MapPoint;
        }
        Point MapToGeo(ESRI.ArcGIS.Client.Geometry.MapPoint mapPoint)
        {
            mapPoint = _wm.ToGeographic(mapPoint) as ESRI.ArcGIS.Client.Geometry.MapPoint;
            return new Point(mapPoint.X, mapPoint.Y);
        }
    }
}
