using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using ThinkGeo.MapSuite.SilverlightCore;
using ThinkGeo.MapSuite.SilverlightEdition;

namespace CSharp_Silverlight_HowDoISamples.Samples
{
    public partial class RouteAvoidingCertainArea : UserControl
    {
        private SimpleMarkerOverlay markerOverlay;
        private InMemoryFeatureLayer routeLayer;
        private PolygonShape avoidableArea;

        public RouteAvoidingCertainArea()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(RouteAvoidingCertainArea_Loaded);
        }

        void RouteAvoidingCertainArea_Loaded(object sender, RoutedEventArgs e)
        {
            Map1.MapUnit = GeographyUnit.DecimalDegree;
            Map1.CurrentExtent = new RectangleShape(-97.763384, 30.299707, -97.712382, 30.259309);

            WorldMapKitWmsSilverlightOverlay baseOverlay = new WorldMapKitWmsSilverlightOverlay();
            Map1.Overlays.Add(baseOverlay);

            // Add the start and end flag
            markerOverlay = new SimpleMarkerOverlay();
            Map1.Overlays.Add("SimpleMarkerOverlay", markerOverlay);
            GetStartPointByFeatureId(txtStartId.Text);

            LayerOverlay overlay = new LayerOverlay();
            Map1.Overlays.Add("routeOverlay", overlay);

            InMemoryFeatureLayer avoidableAreaLayer = new InMemoryFeatureLayer();
            avoidableAreaLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.FillSolidBrush = new GeoSolidBrush(GeoColor.FromArgb(100, GeoColor.StandardColors.Blue));
            avoidableAreaLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            avoidableArea = new PolygonShape(txtWkt.Text);
            avoidableAreaLayer.InternalFeatures.Add("avoidableArea", new Feature(avoidableArea));
            overlay.Layers.Add("avoidableAreaLayer", avoidableAreaLayer);

            routeLayer = new InMemoryFeatureLayer();
            routeLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = new LineStyle(new GeoPen(GeoColor.FromArgb(100, GeoColor.StandardColors.Purple), 5));
            routeLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle.OuterPen.LineJoin = DrawingLineJoin.Round;
            routeLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle.OuterPen.StartCap = GeoDashCap.Round;
            routeLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle.OuterPen.EndCap = GeoDashCap.Round;
            routeLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            overlay.Layers.Add("routeLayer", routeLayer);
            
            Route();
        }

        private void chkAvoidArea_Checked(object sender, RoutedEventArgs e)
        {
            if (chkAvoidArea.IsChecked == true)
            {
                GetRouteAvoidAreaService.GetRouteAvoidingAreaClient client = new CSharp_Silverlight_HowDoISamples.GetRouteAvoidAreaService.GetRouteAvoidingAreaClient();
                client.GetRouteAvoidingCertainAreaCompleted += new EventHandler(client_GetRouteInCertainAreaCompleted);
                client.GetRouteAvoidingCertainAreaAsync(txtStartId.Text, txtEndId.Text, txtWkt.Text);
            }
            else
            {
                Route();
            }
        }

        void client_GetRouteInCertainAreaCompleted(object sender, CSharp_Silverlight_HowDoISamples.GetRouteAvoidAreaService.GetRouteAvoidingCertainAreaCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                string wkt = e.Result;
                LineShape route = LineShape.CreateShapeFromWellKnownData(wkt) as LineShape;

                routeLayer.InternalFeatures.Clear();
                routeLayer.InternalFeatures.Add(new Feature(route));
                Map1.Refresh();
            }
        }

        private void Route()
        {
            GeoDataService.GeoDataGettingClient client = new CSharp_Silverlight_HowDoISamples.GeoDataService.GeoDataGettingClient();
            client.GetRouteCompleted += new EventHandler(client_GetRouteCompleted);
            client.GetRouteAsync("4226", "8094", String.Empty);
        }

        void client_GetRouteCompleted(object sender, CSharp_Silverlight_HowDoISamples.GeoDataService.GetRouteCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                string wkt = e.Result;
                LineShape route = LineShape.CreateShapeFromWellKnownData(wkt) as LineShape;

                routeLayer.InternalFeatures.Clear();
                routeLayer.InternalFeatures.Add(new Feature(route));
                Map1.Refresh();
            }
        }

        internal void GetStartPointByFeatureId(string featureId)
        {
            GeoDataService.GeoDataGettingClient client = new CSharp_Silverlight_HowDoISamples.GeoDataService.GeoDataGettingClient();
            client.GetPointShapeByIdCompleted += new EventHandler(client_GetStartPointShapeByIdCompleted);
            client.GetPointShapeByIdAsync(featureId);
        }

        void client_GetStartPointShapeByIdCompleted(object sender, CSharp_Silverlight_HowDoISamples.GeoDataService.GetPointShapeByIdCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                string[] positions = e.Result.Split(',');
                PointShape pointShape = new PointShape(double.Parse(positions[0], CultureInfo.InvariantCulture), double.Parse(positions[1], CultureInfo.InvariantCulture));

                RenderMarker(pointShape, "start");
                GetEndPointByFeatureId(txtEndId.Text);
            }
        }

        internal void GetEndPointByFeatureId(string featureId)
        {
            GeoDataService.GeoDataGettingClient client = new CSharp_Silverlight_HowDoISamples.GeoDataService.GeoDataGettingClient();
            client.GetPointShapeByIdCompleted += new EventHandler(client_GetEndPointShapeByIdCompleted);
            client.GetPointShapeByIdAsync(featureId);
        }

        void client_GetEndPointShapeByIdCompleted(object sender, CSharp_Silverlight_HowDoISamples.GeoDataService.GetPointShapeByIdCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                string[] positions = e.Result.Split(',');
                PointShape pointShape = new PointShape(double.Parse(positions[0], CultureInfo.InvariantCulture), double.Parse(positions[1], CultureInfo.InvariantCulture));

                RenderMarker(pointShape, "end");
            }
        }

        private void RenderMarker(PointShape pointShape, string renderTag)
        {
            Marker marker = new Marker(pointShape);
            if (renderTag == "start")
            {
                marker.ImageSource = new BitmapImage(new Uri("/theme/StartpointMarker.png", UriKind.RelativeOrAbsolute));
            }
            else if (renderTag == "end")
            {
                marker.ImageSource = new BitmapImage(new Uri("/theme/EndpointMarker.png", UriKind.RelativeOrAbsolute));
            }
            marker.ImageOffsetY = -10;
            markerOverlay.Markers.Add(marker);
            Map1.Refresh();
        }
    }
}