﻿/*  
	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.IO;
using System.IO.IsolatedStorage;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Media;
using Microsoft.Phone.Controls;
using System.Diagnostics;
using System.Windows.Resources;

namespace WPCordovaClassLib.Cordova.Commands
{

    /// <summary>
    /// Implements audio record and play back functionality.
    /// </summary>
    internal class AudioPlayer : IDisposable
    {
        #region Constants

        // AudioPlayer states
        private const int PlayerState_None = 0;
        private const int PlayerState_Starting = 1;
        private const int PlayerState_Running = 2;
        private const int PlayerState_Paused = 3;
        private const int PlayerState_Stopped = 4;

        // AudioPlayer messages
        private const int MediaState = 1;
        private const int MediaDuration = 2;
        private const int MediaPosition = 3;
        private const int MediaError = 9;

        // AudioPlayer errors
        private const int MediaErrorPlayModeSet = 1;
        private const int MediaErrorAlreadyRecording = 2;
        private const int MediaErrorStartingRecording = 3;
        private const int MediaErrorRecordModeSet = 4;
        private const int MediaErrorStartingPlayback = 5;
        private const int MediaErrorResumeState = 6;
        private const int MediaErrorPauseState = 7;
        private const int MediaErrorStopState = 8;

        //TODO: get rid of this callback, it should be universal
        //private const string CallbackFunction = "CordovaMediaonStatus";

        #endregion


        /// <summary>
        /// The AudioHandler object
        /// </summary>
        private Media handler;

        /// <summary>
        /// Temporary buffer to store audio chunk
        /// </summary>
        private byte[] buffer;

        /// <summary>
        /// Xna game loop dispatcher
        /// </summary>
        DispatcherTimer dtXna;

        

        /// <summary>
        /// Output buffer
        /// </summary>
        private MemoryStream memoryStream;

        /// <summary>
        /// The id of this player (used to identify Media object in JavaScript)
        /// </summary>
        private String id;

        /// <summary>
        /// State of recording or playback
        /// </summary>
        private int state = PlayerState_None;

        /// <summary>
        /// File name to play or record to
        /// </summary>
        private String audioFile = null;

        /// <summary>
        /// Duration of audio
        /// </summary>
        private double duration = -1;

        /// <summary>
        /// Audio player object
        /// </summary>
        private MediaElement player = null;

        /// <summary>
        /// Audio source
        /// </summary>
        private Microphone recorder;

        /// <summary>
        /// Internal flag specified that we should only open audio w/o playing it
        /// </summary>
        private bool prepareOnly = false;

        /// <summary>
        /// Creates AudioPlayer instance
        /// </summary>
        /// <param name="handler">Media object</param>
        /// <param name="id">player id</param>
        public AudioPlayer(Media handler, String id)
        {
            this.handler = handler;
            this.id = id;
        }

       

        /// <summary>
        /// Destroys player and stop audio playing or recording
        /// </summary>
        public void Dispose()
        {
            if (this.player != null)
            {
                this.stopPlaying();
                this.player = null;
            }
            if (this.recorder != null)
            {
                this.stopRecording();
                this.recorder = null;
            }

            this.FinalizeXnaGameLoop();
        }

        private void InvokeCallback(int message, string value, bool removeHandler)
        {
            string args = string.Format("('{0}',{1},{2});", this.id, message, value);
            string callback = @"(function(id,msg,value){
                try {
                    if (msg == Media.MEDIA_ERROR) {
                        value = {'code':value};
                    }
                    Media.onStatus(id,msg,value);
                }
                catch(e) {
                    console.log('Error calling Media.onStatus :: ' + e);
                }
            })" + args;
            this.handler.InvokeCustomScript(new ScriptCallback("eval", new string[] { callback }), false);
        }

        private void InvokeCallback(int message, int value, bool removeHandler)
        {
            InvokeCallback(message, value.ToString(), removeHandler);
        }

        private void InvokeCallback(int message, double value, bool removeHandler)
        {
            InvokeCallback(message, value.ToString(), removeHandler);
        }

        /// <summary>
        /// Starts recording, data is stored in memory
        /// </summary>
        /// <param name="filePath"></param>
        public void startRecording(string filePath)
        {
            if (this.player != null)
            {
                InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
            }
            else if (this.recorder == null)
            {
                try
                {
                    this.audioFile = filePath;
                    this.InitializeXnaGameLoop();
                    this.recorder = Microphone.Default;
                    this.recorder.BufferDuration = TimeSpan.FromMilliseconds(500);
                    this.buffer = new byte[recorder.GetSampleSizeInBytes(this.recorder.BufferDuration)];
                    this.recorder.BufferReady += new EventHandler<EventArgs>(recorderBufferReady);
                    MemoryStream stream  = new MemoryStream();
                    this.memoryStream = stream;
                    int numBits = 16;
                    int numBytes = numBits / 8;

                    // inline version from AudioFormatsHelper
                    stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4);
                    stream.Write(BitConverter.GetBytes(0), 0, 4);
                    stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4);
                    stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4);
                    stream.Write(BitConverter.GetBytes(16), 0, 4);
                    stream.Write(BitConverter.GetBytes((short)1), 0, 2);
                    stream.Write(BitConverter.GetBytes((short)1), 0, 2);
                    stream.Write(BitConverter.GetBytes(this.recorder.SampleRate), 0, 4);
                    stream.Write(BitConverter.GetBytes(this.recorder.SampleRate * numBytes), 0, 4);
                    stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2);
                    stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2);
                    stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4);
                    stream.Write(BitConverter.GetBytes(0), 0, 4);

                    this.recorder.Start();
                    FrameworkDispatcher.Update();
                    this.SetState(PlayerState_Running);
                }
                catch (Exception)
                {
                    InvokeCallback(MediaError, MediaErrorStartingRecording, false);
                    //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingRecording),false);
                }
            }
            else
            {
                InvokeCallback(MediaError, MediaErrorAlreadyRecording, false);
                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorAlreadyRecording),false);
            }
        }

        /// <summary>
        /// Stops recording
        /// </summary>
        public void stopRecording()
        {
            if (this.recorder != null)
            {
                if (this.state == PlayerState_Running)
                {
                    try
                    {
                        this.recorder.Stop();
                        this.recorder.BufferReady -= recorderBufferReady;
                        this.recorder = null;
                        SaveAudioClipToLocalStorage();
                        this.FinalizeXnaGameLoop();
                        this.SetState(PlayerState_Stopped);
                    }
                    catch (Exception)
                    {
                        //TODO 
                    }
                }
            }
        }

        /// <summary>
        /// Starts or resume playing audio file
        /// </summary>
        /// <param name="filePath">The name of the audio file</param>
        /// <summary>
        /// Starts or resume playing audio file
        /// </summary>
        /// <param name="filePath">The name of the audio file</param>
        public void startPlaying(string filePath)
        {
            if (this.recorder != null)
            {
                InvokeCallback(MediaError, MediaErrorRecordModeSet, false);
                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorRecordModeSet),false);
                return;
            }


            if (this.player == null || this.player.Source.AbsolutePath.LastIndexOf(filePath) < 0)
            {
                try
                {
                    // this.player is a MediaElement, it must be added to the visual tree in order to play
                    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)
                            {

                                this.player = grid.FindName("playerMediaElement") as MediaElement;
                                if (this.player == null) // still null ?
                                {
                                    this.player = new MediaElement();
                                    this.player.Name = "playerMediaElement";
                                    grid.Children.Add(this.player);
                                    this.player.Visibility = Visibility.Visible;
                                }
                                if (this.player.CurrentState == System.Windows.Media.MediaElementState.Playing)
                                {
                                    this.player.Stop(); // stop it!
                                }

                                this.player.Source = null; // Garbage collect it.
                                this.player.MediaOpened += MediaOpened;
                                this.player.MediaEnded += MediaEnded;
                                this.player.MediaFailed += MediaFailed;
                            }
                        }
                    }

                    this.audioFile = filePath;

                    Uri uri = new Uri(filePath, UriKind.RelativeOrAbsolute);
                    if (uri.IsAbsoluteUri)
                    {
                        this.player.Source = uri;
                    }
                    else
                    {
                        using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
                        {
                            if (!isoFile.FileExists(filePath))
                            {
                                // try to unpack it from the dll into isolated storage
                                StreamResourceInfo fileResourceStreamInfo = Application.GetResourceStream(new Uri(filePath, UriKind.Relative));
                                if (fileResourceStreamInfo != null)
                                {
                                    using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
                                    {
                                        byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);

                                        string[] dirParts = filePath.Split('/');
                                        string dirName = "";
                                        for (int n = 0; n < dirParts.Length - 1; n++)
                                        {
                                            dirName += dirParts[n] + "/";
                                        }
                                        if (!isoFile.DirectoryExists(dirName))
                                        {
                                            isoFile.CreateDirectory(dirName);
                                        }

                                        using (IsolatedStorageFileStream outFile = isoFile.OpenFile(filePath, FileMode.Create))
                                        {
                                            using (BinaryWriter writer = new BinaryWriter(outFile))
                                            {
                                                writer.Write(data);
                                            }
                                        }
                                    }
                                }
                            }
                            if (isoFile.FileExists(filePath))
                            {
                                using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, isoFile))
                                {
                                    this.player.SetSource(stream);
                                }
                            }
                            else
                            {
                                InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
                                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, 1), false);
                                return;
                            }
                        }
                    }
                    this.SetState(PlayerState_Starting);
                }
                catch (Exception e)
                {
                    Debug.WriteLine("Error in AudioPlayer::startPlaying : " + e.Message);
                    InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
                    //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingPlayback),false);
                }
            }
            else
            {
                if (this.state != PlayerState_Running)
                {
                    this.player.Play();
                    this.SetState(PlayerState_Running);
                }
                else
                {
                    InvokeCallback(MediaError, MediaErrorResumeState, false);
                    //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorResumeState),false);
                }
            }
        }

        /// <summary>
        /// Callback to be invoked when the media source is ready for playback
        /// </summary>
        private void MediaOpened(object sender, RoutedEventArgs arg)
        {
            if (this.player != null)
            {
                this.duration = this.player.NaturalDuration.TimeSpan.TotalSeconds;
                InvokeCallback(MediaDuration, this.duration, false);
                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaDuration, this.duration),false);
                if (!this.prepareOnly)
                {
                    this.player.Play();
                    this.SetState(PlayerState_Running);
                }
                this.prepareOnly = false;
            }
            else
            {
                // TODO: occasionally MediaOpened is signalled, but player is null
            }
        }

        /// <summary>
        /// Callback to be invoked when playback of a media source has completed
        /// </summary>
        private void MediaEnded(object sender, RoutedEventArgs arg)
        {
            this.SetState(PlayerState_Stopped);
        }

        /// <summary>
        /// Callback to be invoked when playback of a media source has failed
        /// </summary>
        private void MediaFailed(object sender, RoutedEventArgs arg)
        {
            player.Stop();
            InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
            //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError.ToString(), "Media failed"),false);
        }

        /// <summary>
        /// Seek or jump to a new time in the track
        /// </summary>
        /// <param name="milliseconds">The new track position</param>
        public void seekToPlaying(int milliseconds)
        {
            if (this.player != null)
            {
                TimeSpan tsPos = new TimeSpan(0, 0, 0, 0, milliseconds);
                this.player.Position = tsPos;
                InvokeCallback(MediaPosition, milliseconds / 1000.0f, false);
                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, milliseconds / 1000.0f),false);
            }
        }

        /// <summary>
        /// Set the volume of the player
        /// </summary>
        /// <param name="vol">volume 0.0-1.0, default value is 0.5</param>
        public void setVolume(double vol)
        {
            if (this.player != null)
            {
                this.player.Volume = vol;
            }
        }

        /// <summary>
        /// Pauses playing
        /// </summary>
        public void pausePlaying()
        {
            if (this.state == PlayerState_Running)
            {
                this.player.Pause();
                this.SetState(PlayerState_Paused);
            }
            else
            {
                InvokeCallback(MediaError, MediaErrorPauseState, false);
                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorPauseState),false);
            }
        }


        /// <summary>
        /// Stops playing the audio file
        /// </summary>
        public void stopPlaying()
        {
            if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
            {
                this.player.Stop();

                this.player.Position = new TimeSpan(0L);
                this.SetState(PlayerState_Stopped);
            }
            //else // Why is it an error to call stop on a stopped media?
            //{
            //    this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStopState), false);
            //}
        }

        /// <summary>
        /// Gets current position of playback
        /// </summary>
        /// <returns>current position</returns>
        public double getCurrentPosition()
        {
            if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
            {
                double currentPosition = this.player.Position.TotalSeconds;
                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, currentPosition),false);
                return currentPosition;
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// Gets the duration of the audio file
        /// </summary>
        /// <param name="filePath">The name of the audio file</param>
        /// <returns>track duration</returns>
        public double getDuration(string filePath)
        {
            if (this.recorder != null)
            {
                return (-2);
            }

            if (this.player != null)
            {
                return this.duration;

            }
            else
            {
                this.prepareOnly = true;
                this.startPlaying(filePath);
                return this.duration;
            }
        }

        /// <summary>
        /// Sets the state and send it to JavaScript
        /// </summary>
        /// <param name="state">state</param>
        private void SetState(int state)
        {
            if (this.state != state)
            {
                InvokeCallback(MediaState, state, false);
                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaState, state),false);
            }

            this.state = state;
        }

        #region record methods

        /// <summary>
        /// Copies data from recorder to memory storages and updates recording state
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void recorderBufferReady(object sender, EventArgs e)
        {
            this.recorder.GetData(this.buffer);
            this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
        }

        /// <summary>
        /// Writes audio data from memory to isolated storage
        /// </summary>
        /// <returns></returns>
        private void SaveAudioClipToLocalStorage()
        {
            if (memoryStream == null || memoryStream.Length <= 0)
            {
                return;
            }

            long position = memoryStream.Position;
            memoryStream.Seek(4, SeekOrigin.Begin);
            memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 8), 0, 4);
            memoryStream.Seek(40, SeekOrigin.Begin);
            memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 44), 0, 4);
            memoryStream.Seek(position, SeekOrigin.Begin);

            try
            {
                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    string directory = Path.GetDirectoryName(audioFile);

                    if (!isoFile.DirectoryExists(directory))
                    {
                        isoFile.CreateDirectory(directory);
                    }

                    this.memoryStream.Seek(0, SeekOrigin.Begin);

                    using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(audioFile))
                    {
                        this.memoryStream.CopyTo(fileStream);
                    }
                }
            }
            catch (Exception)
            {
                //TODO: log or do something else
                throw;
            }
        }

        #region Xna loop
        /// <summary>
        /// Special initialization required for the microphone: XNA game loop
        /// </summary>
        private void InitializeXnaGameLoop()
        {
            // Timer to simulate the XNA game loop (Microphone is from XNA)
            this.dtXna = new DispatcherTimer();
            this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
            this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
            this.dtXna.Start();
        }
        /// <summary>
        /// Finalizes XNA game loop for microphone
        /// </summary>
        private void FinalizeXnaGameLoop()
        {
            // Timer to simulate the XNA game loop (Microphone is from XNA)
            if (this.dtXna != null)
            {
                this.dtXna.Stop();
                this.dtXna = null;
            }
        }

        #endregion

        #endregion
    }
}
