// Copyright 2012 Effective Objects
//
// This example demonstrates using ProLat for .Net with Windows Phone

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.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using ProLatNet;

namespace ProLatWPA
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // Initialize the default input coordinate system definition. App variables are in App.xaml.cs
            App.csDefs[0] = new App.CSDef();
            App.csDefs[0].Group = "LAT_LONG";
            App.csDefs[0].System = "LAT-LONG";
            App.csDefs[0].Datum = "WGS84";
            App.csDefs[0].Units = "METERS";  // For lat/long coordinate systems, the units do not matter
            App.csDefs[0].UseProj4 = false;
            App.csDefs[0].Proj4 = "proj=longlat datum=WGS84"; // Use a default string

            // Initialize the default output coordinate system definition
            App.csDefs[1] = new App.CSDef();
            App.csDefs[1].Group = "UTM";
            App.csDefs[1].System = "UTM-17N";
            App.csDefs[1].Datum = "WGS84";
            App.csDefs[1].Units = "METERS";  // For lat/long coordinate systems, the units do not matter
            App.csDefs[1].UseProj4 = false;
            App.csDefs[1].Proj4 = "proj=utm zone=17 datum=WGS84"; // Use a default string

            // Initialize the fields with default values
            editInX.Text = "82 15.2 W";
            editInY.Text = "41 55.0 N";

            FillFields();
        }

        private void FillFields()
        {
            if (App.csDefs[0].UseProj4)
                textInput.Text = "Input: " + App.csDefs[0].Proj4;
            else
                textInput.Text = "Input: " + App.csDefs[0].Group + ", " + App.csDefs[0].System +
                ", " + App.csDefs[0].Datum + ", " + App.csDefs[0].Units;

            if (App.csDefs[1].UseProj4)
                textOutput.Text = "Output: " + App.csDefs[1].Proj4;
            else
                textOutput.Text = "Output: " + App.csDefs[1].Group + ", " + App.csDefs[1].System +
                ", " + App.csDefs[1].Datum + ", " + App.csDefs[1].Units;
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            FillFields();
        }

        private void buttonIn_Click(object sender, RoutedEventArgs e)
        {
            App.csDefToChange = 0;  // Select the input coordinate system definition

            NavigationService.Navigate(new Uri("/ChangeCS.xaml", UriKind.Relative));
        }

        private void buttonOut_Click(object sender, RoutedEventArgs e)
        {
            App.csDefToChange = 1;  // Select the output coordinate system definition

            NavigationService.Navigate(new Uri("/ChangeCS.xaml", UriKind.Relative));
        }


        private void buttonAtoB_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (editInX.Text.Length == 0 || editInY.Text.Length == 0)
                    return;

                CoordSys csA, csB;

                if (App.csDefs[0].UseProj4)
                    csA = CoordSys.GetCS(App.csDefs[0].Proj4);
                else
                    csA  = CoordSys.GetCS(App.csDefs[0].Group, App.csDefs[0].System, App.csDefs[0].Datum, App.csDefs[0].Units);

                if (App.csDefs[1].UseProj4)
                    csB = CoordSys.GetCS(App.csDefs[1].Proj4);
                else
                    csB = CoordSys.GetCS(App.csDefs[1].Group, App.csDefs[1].System, App.csDefs[1].Datum, App.csDefs[1].Units);

                double lon_x = editInX.Text.Length > 0 ? DMS.GetLon(editInX.Text) : 0.0;
                double lat_y = editInY.Text.Length > 0 ? DMS.GetLat(editInY.Text) : 0.0;
                double hgt_z = editInZ.Text.Length > 0 ? double.Parse(editInZ.Text) : 0.0;

                double[] x = new double[] { lon_x };  // Store in arrays for conversion in place
                double[] y = new double[] { lat_y };
                double[] z = new double[] { hgt_z };

                CoordSys.Transform(csA, csB, x, y, z, 1);

                if (csB.is_latlong)
                {
                    // Round to 8 decimal places for lat/long
                    editOutX.Text = Math.Round(x[0], 8).ToString();
                    editOutY.Text = Math.Round(y[0], 8).ToString();
                    editOutZ.Text = Math.Round(z[0], 8).ToString();
                }
                else
                {
                    // Round to 3 decimal places for projections
                    editOutX.Text = Math.Round(x[0], 3).ToString();
                    editOutY.Text = Math.Round(y[0], 3).ToString();
                    editOutZ.Text = Math.Round(z[0], 3).ToString();
                }
            }
            catch (CSConfigException ex)
            {
                MessageBoxResult result =
                    MessageBox.Show(ex.Message,
                    "ProLat Config message", MessageBoxButton.OK);
            }
            catch (Exception ex)
            {
                MessageBoxResult result =
                    MessageBox.Show(ex.Message,
                    "ProLat error", MessageBoxButton.OK);
            }

        }

        private void buttonBtoA_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (editInX.Text.Length == 0 || editInY.Text.Length == 0)
                    return;

                CoordSys csA, csB;

                if (App.csDefs[0].UseProj4)
                    csA = CoordSys.GetCS(App.csDefs[0].Proj4);
                else
                    csA = CoordSys.GetCS(App.csDefs[0].Group, App.csDefs[0].System, App.csDefs[0].Datum, App.csDefs[0].Units);

                if (App.csDefs[1].UseProj4)
                    csB = CoordSys.GetCS(App.csDefs[1].Proj4);
                else
                    csB = CoordSys.GetCS(App.csDefs[1].Group, App.csDefs[1].System, App.csDefs[1].Datum, App.csDefs[1].Units);

                double lon_x = editOutX.Text.Length > 0 ? DMS.GetLon(editOutX.Text) : 0.0;
                double lat_y = editOutY.Text.Length > 0 ? DMS.GetLat(editOutY.Text) : 0.0;
                double hgt_z = editOutZ.Text.Length > 0 ? double.Parse(editOutZ.Text) : 0.0;

                double[] x = new double[] { lon_x };  // Store in arrays for conversion in place
                double[] y = new double[] { lat_y };
                double[] z = new double[] { hgt_z };

                CoordSys.Transform(csB, csA, x, y, z, 1);

                if (csA.is_latlong)
                {
                    // Round to 8 decimal places for lat/long
                    editInX.Text = Math.Round(x[0], 8).ToString();
                    editInY.Text = Math.Round(y[0], 8).ToString();
                    editInZ.Text = Math.Round(z[0], 8).ToString();
                }
                else
                {
                    // Round to 3 decimal places for projections
                    editInX.Text = Math.Round(x[0], 3).ToString();
                    editInY.Text = Math.Round(y[0], 3).ToString();
                    editInZ.Text = Math.Round(z[0], 3).ToString();
                }
            }
            catch (CSConfigException ex)
            {
                MessageBoxResult result =
                    MessageBox.Show(ex.Message,
                    "ProLat Config message", MessageBoxButton.OK);
            }
            catch (Exception ex)
            {
                MessageBoxResult result =
                    MessageBox.Show(ex.Message,
                    "ProLat error", MessageBoxButton.OK);
            }
        }

        private void editInX_TextChanged(object sender, TextChangedEventArgs e)
        {

        }

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
        }

        private void buttonClear_Click(object sender, RoutedEventArgs e)
        {
            editInX.Text = "";
            editInY.Text = "";
            editInZ.Text = "";
            editOutX.Text = "";
            editOutY.Text = "";
            editOutZ.Text = "";
        }

        private void buttonHelp_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/PageHelp.xaml", UriKind.Relative));
        }
    }
}