﻿/*  
	Licensed under the Apache License, Version 2.0 (the "License");
	you may not use this file except in compliance with the License.
	You may obtain a copy of the License at
	
	http://www.apache.org/licenses/LICENSE-2.0
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
*/

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using DeviceCompass = Microsoft.Devices.Sensors.Compass;
using System.Windows.Threading;
using System.Runtime.Serialization;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Threading;
using Microsoft.Devices.Sensors;

namespace WP7CordovaClassLib.Cordova.Commands
{

    public class Compass : BaseCommand
    {
        #region Static members

        /// <summary>
        /// Status of listener
        /// </summary>
        private static int currentStatus;

        /// <summary>
        /// Id for get getCompass method
        /// </summary>
        private static string getCompassId = "getCompassId";

        /// <summary>
        /// Compass
        /// </summary>
        private static DeviceCompass compass = new DeviceCompass();

        /// <summary>
        /// Listeners for callbacks
        /// </summary>
        private static Dictionary<string, Compass> watchers = new Dictionary<string, Compass>();

        #endregion

        #region Status codes

        public const int Stopped = 0;
        public const int Starting = 1;
        public const int Running = 2;
        public const int ErrorFailedToStart = 4;
        public const int Not_Supported = 20;

        /*
         *   // Capture error codes
            CompassError.COMPASS_INTERNAL_ERR = 0;
            CompassError.COMPASS_NOT_SUPPORTED = 20;
         * */

        #endregion

        #region CompassOptions class
        /// <summary>
        /// Represents Accelerometer options.
        /// </summary>
        [DataContract]
        public class CompassOptions
        {
            /// <summary>
            /// How often to retrieve the Acceleration in milliseconds
            /// </summary>
            [DataMember(IsRequired = false, Name = "frequency")]
            public int Frequency { get; set; }

            /// <summary>
            /// The change in degrees required to initiate a watchHeadingFilter success callback.
            /// </summary>
            [DataMember(IsRequired = false, Name = "filter")]
            public int Filter { get; set; }

            /// <summary>
            /// Watcher id
            /// </summary>
            [DataMember(IsRequired = false, Name = "id")]
            public string Id { get; set; }

        }
        #endregion


        /// <summary>
        /// Time the value was last changed
        /// </summary>
        //private DateTime lastValueChangedTime;

        /// <summary>
        /// Accelerometer options
        /// </summary>
        private CompassOptions compassOptions;

        //bool isDataValid;

        //bool calibrating = false;

        public Compass()
        {

        }

        /// <summary>
        /// Formats current coordinates into JSON format
        /// </summary>
        /// <returns>Coordinates in JSON format</returns>
        private string GetHeadingFormatted(CompassReading reading)
        {
            string result = String.Format("\"magneticHeading\":{0},\"headingAccuracy\":{1},\"trueHeading\":{2},\"timestamp\":{3}",
                            reading.MagneticHeading.ToString("0.0", CultureInfo.InvariantCulture),
                            reading.HeadingAccuracy.ToString("0.0", CultureInfo.InvariantCulture),
                            reading.TrueHeading.ToString("0.0", CultureInfo.InvariantCulture),
                            reading.Timestamp.UtcTicks.ToString());
            result = "{" + result + "}";
            return result;
        }

        public void getHeading(string options)
        {
            if (!DeviceCompass.IsSupported)
            {
                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{code:" + Not_Supported + "}"));
            }
            else
            {
                //if (compass == null)
                //{
                //    // Instantiate the compass.
                //    compass = new DeviceCompass();
                //    compass.TimeBetweenUpdates = TimeSpan.FromMilliseconds(40);
                //    compass.CurrentValueChanged += new EventHandler<Microsoft.Devices.Sensors.SensorReadingEventArgs<Microsoft.Devices.Sensors.CompassReading>>(compass_CurrentValueChanged);
                //    compass.Calibrate += new EventHandler<Microsoft.Devices.Sensors.CalibrationEventArgs>(compass_Calibrate);
                //}


                //compass.Start();

            }

            try
            {
                if (currentStatus != Running)
                {
                    lock (compass)
                    {
                        compass.CurrentValueChanged += compass_SingleHeadingValueChanged;
                        compass.Start();
                        this.SetStatus(Starting);
                    }

                    long timeout = 2000;
                    while ((currentStatus == Starting) && (timeout > 0))
                    {
                        timeout = timeout - 100;
                        Thread.Sleep(100);
                    }

                    if (currentStatus != Running)
                    {
                        DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
                        return;
                    }
                }
                lock (compass)
                {
                    compass.CurrentValueChanged -= compass_SingleHeadingValueChanged;
                    if (watchers.Count < 1)
                    {
                        compass.Stop();
                        this.SetStatus(Stopped);
                    }
                }
            }
            catch (UnauthorizedAccessException)
            {
                DispatchCommandResult(new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, ErrorFailedToStart));
            }
            catch (Exception)
            {
                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
            }
        }

        void compass_SingleHeadingValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
        {
            this.SetStatus(Running);
            if (compass.IsDataValid)
            {
                // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
                //  magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time. 
                //  A negative value indicates that the true heading could not be determined.
                // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
                //rawMagnetometerReading = e.SensorReading.MagnetometerReading;

                //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));

                PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));

                DispatchCommandResult(result);
            }
        }

        /// <summary>
        /// Starts listening for compass sensor
        /// </summary>
        /// <returns>status of listener</returns>
        private int start()
        {
            if ((currentStatus == Running) || (currentStatus == Starting))
            {
                return currentStatus;
            }
            try
            {
                lock (compass)
                {
                    watchers.Add(getCompassId, this);
                    compass.CurrentValueChanged += watchers[getCompassId].compass_CurrentValueChanged;
                    compass.Start();
                    this.SetStatus(Starting);
                }
            }
            catch (Exception)
            {
                this.SetStatus(ErrorFailedToStart);
            }
            return currentStatus;
        }

        public void startWatch(string options)
        {
            if (!DeviceCompass.IsSupported)
            {
                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, Not_Supported));
            }

            try
            {
                compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
            }
            catch (Exception ex)
            {
                this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
                return;
            }

            if (string.IsNullOrEmpty(compassOptions.Id))
            {
                this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
                return;
            }

            try
            {
                lock (compass)
                {
                    watchers.Add(compassOptions.Id, this);
                    compass.CurrentValueChanged += watchers[compassOptions.Id].compass_CurrentValueChanged;
                    compass.Start();
                    this.SetStatus(Starting);
                }
            }
            catch (Exception)
            {
                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
                return;
            }
        }

        public void stopWatch(string options)
        {
            try
            {
                compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
            }
            catch (Exception ex)
            {
                this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
                return;
            }

            if (string.IsNullOrEmpty(compassOptions.Id))
            {
                this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
                return;
            }

            if (currentStatus != Stopped)
            {
                lock (compass)
                {
                    Compass watcher = watchers[compassOptions.Id];
                    compass.CurrentValueChanged -= watcher.compass_CurrentValueChanged;
                    watchers.Remove(compassOptions.Id);
                    watcher.Dispose();
                }
            }
            this.SetStatus(Stopped);

            this.DispatchCommandResult();
        }

        void compass_Calibrate(object sender, Microsoft.Devices.Sensors.CalibrationEventArgs e)
        {
            //throw new NotImplementedException();
            // TODO: pass calibration error to JS
        }

        void compass_CurrentValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
        {
            this.SetStatus(Running);
            if (compass.IsDataValid)
            {
                // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
                //  magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time. 
                //  A negative value indicates that the true heading could not be determined.
                // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
                //rawMagnetometerReading = e.SensorReading.MagnetometerReading;

                //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));

                PluginResult result = new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(e.SensorReading));
                result.KeepCallback = true;

                DispatchCommandResult(result);
            }
        }

        /// <summary>
        /// Sets current status
        /// </summary>
        /// <param name="status">current status</param>
        private void SetStatus(int status)
        {
            currentStatus = status;
        }

    }
}
