﻿/*  
	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.Windows;
using System.Windows.Controls;
using Microsoft.Devices;
using System.Runtime.Serialization;
using System.Threading;
using System.Windows.Resources;
using Microsoft.Phone.Controls;
using Microsoft.Xna.Framework.Audio;
using WPCordovaClassLib.Cordova.UI;


namespace WPCordovaClassLib.Cordova.Commands
{
    public class Notification : BaseCommand
    {
        static ProgressBar progressBar = null;
        const int DEFAULT_DURATION = 5;

        private NotificationBox notifyBox;

        private PhoneApplicationPage Page
        {
            get
            {
                PhoneApplicationPage page = null;
                PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
                if (frame != null)
                {
                    page = frame.Content as PhoneApplicationPage;
                }
                return page;
            }
        }

        // blink api - doesn't look like there is an equivalent api we can use...
        
        [DataContract]
        public class AlertOptions
        {
            [OnDeserializing]
            public void OnDeserializing(StreamingContext context)
            {
                // set defaults
                this.message = "message";
                this.title = "Alert";
                this.buttonLabel = "ok";
            }

            /// <summary>
            /// message to display in the alert box
            /// </summary>
            [DataMember]
            public string message;

            /// <summary>
            /// title displayed on the alert window
            /// </summary>
            [DataMember]
            public string title;

            /// <summary>
            /// text to display on the button
            /// </summary>
            [DataMember]
            public string buttonLabel;
        }

        public void alert(string options)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
                AlertOptions alertOpts = new AlertOptions();
                alertOpts.message = args[0];
                alertOpts.title = args[1];
                alertOpts.buttonLabel = args[2];

                PhoneApplicationPage page = Page;
                if (page != null)
                {
                    Grid grid = page.FindName("LayoutRoot") as Grid;
                    if (grid != null)
                    {
                        var previous = notifyBox;
                        notifyBox = new NotificationBox();
                        notifyBox.Tag = previous;
                        notifyBox.PageTitle.Text = alertOpts.title;
                        notifyBox.SubTitle.Text = alertOpts.message;
                        Button btnOK = new Button();
                        btnOK.Content = alertOpts.buttonLabel;
                        btnOK.Click += new RoutedEventHandler(btnOK_Click);
                        btnOK.Tag = 1;
                        notifyBox.ButtonPanel.Children.Add(btnOK);
                        grid.Children.Add(notifyBox);

                        if (previous == null)
                        {
                            page.BackKeyPress += page_BackKeyPress;
                        }
                    }
                }
                else
                {
                    DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
                }
            });
        }

        public void confirm(string options)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
                AlertOptions alertOpts = new AlertOptions();
                alertOpts.message = args[0];
                alertOpts.title = args[1];
                alertOpts.buttonLabel = args[2];

                PhoneApplicationPage page = Page;
                if (page != null)
                {
                    Grid grid = page.FindName("LayoutRoot") as Grid;
                    if (grid != null)
                    {
                        var previous = notifyBox;
                        notifyBox = new NotificationBox();
                        notifyBox.Tag = previous; 
                        notifyBox.PageTitle.Text = alertOpts.title;
                        notifyBox.SubTitle.Text = alertOpts.message;

                        string[] labels = alertOpts.buttonLabel.Split(',');
                        for (int n = 0; n < labels.Length; n++)
                        {
                            Button btn = new Button();
                            btn.Content = labels[n];
                            btn.Tag = n;
                            btn.Click += new RoutedEventHandler(btnOK_Click);
                            notifyBox.ButtonPanel.Children.Add(btn);
                        }

                        grid.Children.Add(notifyBox);
                        if (previous == null)
                        {
                            page.BackKeyPress += page_BackKeyPress;
                        }
                    }
                }
                else
                {
                    DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));
                }
            });
        }

        void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
        {
            PhoneApplicationPage page = sender as PhoneApplicationPage;

            if (page != null && notifyBox != null)
            {
                Grid grid = page.FindName("LayoutRoot") as Grid;
                if (grid != null)
                {
                    grid.Children.Remove(notifyBox);
                    notifyBox = notifyBox.Tag as NotificationBox;
                }
                if (notifyBox == null)
                {
                    page.BackKeyPress -= page_BackKeyPress;
                }
                e.Cancel = true;
            }

            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, 0));
        }

        void btnOK_Click(object sender, RoutedEventArgs e)
        {
            Button btn = sender as Button;
            FrameworkElement notifBoxParent = null;
            int retVal = 0;
            if (btn != null)
            {
                retVal = (int)btn.Tag + 1;

                notifBoxParent = btn.Parent as FrameworkElement;
                while ((notifBoxParent = notifBoxParent.Parent as FrameworkElement) != null &&
                       !(notifBoxParent is NotificationBox));
            }
            if (notifBoxParent != null)
            {
                PhoneApplicationPage page = Page;
                if (page != null)
                {
                    Grid grid = page.FindName("LayoutRoot") as Grid;
                    if (grid != null)
                    {
                        grid.Children.Remove(notifBoxParent);
                    }
                    notifyBox = notifBoxParent.Tag as NotificationBox;
                    if (notifyBox == null)
                    {
                        page.BackKeyPress -= page_BackKeyPress;
                    }
                }
                
            }
            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, retVal));
        }



        public void beep(string options)
        {
            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
            int times = int.Parse(args[0]);

            string resourcePath = BaseCommand.GetBaseURL() + "resources/notification-beep.wav";

            StreamResourceInfo sri = Application.GetResourceStream(new Uri(resourcePath, UriKind.Relative));

            if (sri != null)
            {
                SoundEffect effect = SoundEffect.FromStream(sri.Stream);
                SoundEffectInstance inst = effect.CreateInstance();
                ThreadPool.QueueUserWorkItem((o) =>
                {
                    // cannot interact with UI !!
                    do
                    {
                        inst.Play();
                        Thread.Sleep(effect.Duration + TimeSpan.FromMilliseconds(100));
                    }
                    while (--times > 0);

                });

            }

            // TODO: may need a listener to trigger DispatchCommandResult after the alarm has finished executing...
            DispatchCommandResult();
        }

        // Display an indeterminate progress indicator
        public void activityStart(string unused)
        {

            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;

                if (frame != null)
                {
                    PhoneApplicationPage page = frame.Content as PhoneApplicationPage;

                    if (page != null)
                    {
                        var temp = page.FindName("LayoutRoot");
                        Grid grid = temp as Grid;
                        if (grid != null)
                        {
                            if (progressBar != null)
                            {
                                grid.Children.Remove(progressBar);
                            }
                            progressBar = new ProgressBar();
                            progressBar.IsIndeterminate = true;
                            progressBar.IsEnabled = true;

                            grid.Children.Add(progressBar);
                        }
                    }
                }
            });
        }


        // Remove our indeterminate progress indicator
        public void activityStop(string unused)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                if (progressBar != null)
                {
                    progressBar.IsEnabled = false;
                    PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
                    if (frame != null)
                    {
                        PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
                        if (page != null)
                        {
                            Grid grid = page.FindName("LayoutRoot") as Grid;
                            if (grid != null)
                            {
                                grid.Children.Remove(progressBar);
                            }
                        }
                    }
                    progressBar = null;
                }
            });
        }

        public void vibrate(string vibrateDuration)
        {
            
            int msecs = 200; // set default

            try
            {
                string[] args = JSON.JsonHelper.Deserialize<string[]>(vibrateDuration);

                msecs = int.Parse(args[0]);
                if (msecs < 1)
                {
                    msecs = 1;
                }
            }
            catch (FormatException)
            {

            }

            VibrateController.Default.Start(TimeSpan.FromMilliseconds(msecs));

            // TODO: may need to add listener to trigger DispatchCommandResult when the vibration ends...
            DispatchCommandResult();
        }
    }
}
