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 System.Device.Location;
using System.ComponentModel;
using System.Net;
using System.Diagnostics;

namespace BingMapsImageryDemo {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {

        GeoCoordinateWatcher geoWatcher = new System.Device.Location.GeoCoordinateWatcher(GeoPositionAccuracy.High);
        string ClientToken;

        public MainWindow() {
            InitializeComponent();

            this.ClientToken = GetClientToken();

            geoWatcher.MovementThreshold = 1000; //in meters!!!
            geoWatcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(geoWatcher_StatusChanged);
            geoWatcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(geoWatcher_PositionChanged);
            geoWatcher.Start();
        }

        private void Window_Closed(object sender, EventArgs e) {
            geoWatcher.Stop();
        }


        void geoWatcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e) {
            lblLatitude.Content = e.Position.Location.Latitude.ToString(@"\N 0.00000;\S 0.00000;\-");
            lblLongitude.Content = e.Position.Location.Longitude.ToString(@"\E 0.00000;\W 0.00000;\-");

            var request = WebRequest.Create(GetMapImageUri(e.Position.Location));
            using (var response = request.GetResponse()) {
                var imageDecoder = new JpegBitmapDecoder(response.GetResponseStream(), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);
                if (imageDecoder.Frames.Count > 0) {
                    Map.Source = imageDecoder.Frames[0];
                }
            }
        }

        void geoWatcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e) {
            lblStatus.Content = e.Status.ToString();
        }


        private string GetClientToken() {
            var commonService = new CommonService.CommonService();
            commonService.Url = "https://staging.common.virtualearth.net/find-30/common.asmx";
            commonService.Credentials = new System.Net.NetworkCredential(App.BingMapsUserID, App.BingMapsUserPassword);

            var tokenSpecification = new CommonService.TokenSpecification();
            tokenSpecification.ClientIPAddress = "0.0.0.0";
            tokenSpecification.TokenValidityDurationMinutes = 480; //maximum

            return commonService.GetClientToken(tokenSpecification);
        }

        private Uri GetMapImageUri(GeoCoordinate location) {
            var mapUriRequest = new ImageryService.MapUriRequest();

            mapUriRequest.Credentials = new ImageryService.Credentials();
            mapUriRequest.Credentials.Token = this.ClientToken;

            mapUriRequest.Center = new ImageryService.Location();
            mapUriRequest.Center.Latitude = location.Latitude;
            mapUriRequest.Center.Longitude = location.Longitude;

            mapUriRequest.Options = new ImageryService.MapUriOptions();
            mapUriRequest.Options.ImageType = ImageryService.ImageType.Jpeg;
            mapUriRequest.Options.ZoomLevel = 13;

            mapUriRequest.Options.ImageSize = new ImageryService.SizeOfint();
            mapUriRequest.Options.ImageSize.Width = (int)Map.Width;
            mapUriRequest.Options.ImageSize.Height = (int)Map.Height;


            var imageryService = new ImageryService.ImageryServiceClient();
            var mapUriResponse = imageryService.GetMapUri(mapUriRequest);

            if (mapUriResponse.ResponseSummary.StatusCode == ImageryService.ResponseStatusCode.Success) {
                string uri = mapUriResponse.Uri.Replace("{token}", ClientToken);
                return new Uri(mapUriResponse.Uri);
            } else {
                return null;
            }
        }

    }
}
