﻿/*  
	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.Media;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Microsoft.Phone.Tasks;
using VideoResult = WPCordovaClassLib.Cordova.UI.VideoCaptureTask.VideoResult;

namespace WPCordovaClassLib.Cordova.UI
{
    public partial class VideoRecorder : PhoneApplicationPage
    {

        #region Constants

        /// <summary>
        /// Caption for record button in ready state
        /// </summary>
        private const string RecordingStartCaption = "Record";

        /// <summary>
        /// Caption for record button in recording state
        /// </summary>
        private const string RecordingStopCaption = "Stop";

        /// <summary>
        /// Start record icon URI
        /// </summary>
        private const string StartIconUri = "/Images/appbar.feature.video.rest.png";

        /// <summary>
        /// Stop record icon URI
        /// </summary>
        private const string StopIconUri = "/Images/appbar.stop.rest.png";

        /// <summary>
        /// Folder to save video clips
        /// </summary>
        private const string LocalFolderName = "VideoCache";

        /// <summary>
        /// File name format
        /// </summary>
        private const string FileNameFormat = "Video-{0}.mp4";

        /// <summary>
        /// Temporary file name
        /// </summary>
        private const string defaultFileName = "NewVideoFile.mp4";

        #endregion

        #region Callbacks
        /// <summary>
        /// Occurs when a video recording task is completed.
        /// </summary>
        public event EventHandler<VideoResult> Completed;

        #endregion

        #region Fields

        /// <summary>
        /// Viewfinder for capturing video
        /// </summary>
        private VideoBrush videoRecorderBrush;

        /// <summary>
        /// Path to save video clip
        /// </summary>
        private string filePath;

        /// <summary>
        /// Source for capturing video. 
        /// </summary>
        private CaptureSource captureSource;

        /// <summary>
        /// Video device
        /// </summary>
        private VideoCaptureDevice videoCaptureDevice;

        /// <summary>
        /// File sink so save recording video in Isolated Storage
        /// </summary>
        private FileSink fileSink;

        /// <summary>
        /// For managing button and application state 
        /// </summary>
        private enum VideoState { Initialized, Ready, Recording, CameraNotSupported };

        /// <summary>
        /// Current video state
        /// </summary>
        private VideoState currentVideoState;

        /// <summary>
        /// Stream to return result
        /// </summary>
        private MemoryStream memoryStream;

        /// <summary>
        /// Recording result, dispatched back when recording page is closed
        /// </summary>
        private VideoResult result = new VideoResult(TaskResult.Cancel);

        #endregion

        /// <summary>
        /// Initializes components
        /// </summary>
        public VideoRecorder()
        {
            InitializeComponent();

            PhoneAppBar = (ApplicationBar)ApplicationBar;
            PhoneAppBar.IsVisible = true;
            btnStartRecording = ((ApplicationBarIconButton)ApplicationBar.Buttons[0]);
            btnTakeVideo = ((ApplicationBarIconButton)ApplicationBar.Buttons[1]);
        }

        /// <summary>
        /// Initializes the video recorder then page is loading
        /// </summary>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            this.InitializeVideoRecorder();
        }

        /// <summary>
        /// Disposes camera and media objects then leave the page
        /// </summary>
        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            this.DisposeVideoRecorder();

            if (this.Completed != null)
            {
                this.Completed(this, result);
            }
            base.OnNavigatedFrom(e);
        }

        /// <summary>
        /// Handles TakeVideo button click
        /// </summary>
        private void TakeVideo_Click(object sender, EventArgs e)
        {
            this.result = this.SaveVideoClip();
            this.NavigateBack();
        }

        private void NavigateBack()
        {
            if (this.NavigationService.CanGoBack)
            {
                this.NavigationService.GoBack();
            }
        }

        /// <summary>
        /// Resaves video clip from temporary directory to persistent 
        /// </summary>
        private VideoResult SaveVideoClip()
        {
            try
            {
                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    if (string.IsNullOrEmpty(filePath) || (!isoFile.FileExists(filePath)))
                    {
                        return new VideoResult(TaskResult.Cancel);
                    }

                    string fileName = String.Format(FileNameFormat, Guid.NewGuid().ToString());
                    string newPath = Path.Combine("/" + LocalFolderName + "/", fileName);
                    isoFile.CopyFile(filePath, newPath);
                    isoFile.DeleteFile(filePath);

                    memoryStream = new MemoryStream();
                    using (IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(newPath, FileMode.Open, isoFile))
                    {
                        fileStream.CopyTo(memoryStream);
                    }

                    VideoResult result = new VideoResult(TaskResult.OK);
                    result.VideoFileName = newPath;
                    result.VideoFile = this.memoryStream;
                    result.VideoFile.Seek(0, SeekOrigin.Begin);
                    return result;
                }

            }
            catch (Exception)
            {
                return new VideoResult(TaskResult.None);
            }
        }

        /// <summary>
        /// Updates the buttons on the UI thread based on current state. 
        /// </summary>
        /// <param name="currentState">current UI state</param>
        private void UpdateUI(VideoState currentState)
        {
            Dispatcher.BeginInvoke(delegate
            {
                switch (currentState)
                {
                    case VideoState.CameraNotSupported:
                        btnStartRecording.IsEnabled = false;
                        btnTakeVideo.IsEnabled = false;
                        break;

                    case VideoState.Initialized:
                        btnStartRecording.Text = RecordingStartCaption;
                        btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
                        btnTakeVideo.IsEnabled = false;
                        break;

                    case VideoState.Ready:
                        btnStartRecording.Text = RecordingStartCaption;
                        btnStartRecording.IconUri = new Uri(StartIconUri, UriKind.Relative);
                        btnTakeVideo.IsEnabled = true;
                        break;

                    case VideoState.Recording:
                        btnStartRecording.Text = RecordingStopCaption;
                        btnStartRecording.IconUri = new Uri(StopIconUri, UriKind.Relative);
                        btnTakeVideo.IsEnabled = false;
                        break;

                    default:
                        break;
                }
                currentVideoState = currentState;
            });
        }

        /// <summary>
        /// Initializes VideoRecorder
        /// </summary>
        public void InitializeVideoRecorder()
        {
            if (captureSource == null)
            {
                captureSource = new CaptureSource();
                fileSink = new FileSink();
                videoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();

                if (videoCaptureDevice != null)
                {
                    videoRecorderBrush = new VideoBrush();
                    videoRecorderBrush.SetSource(captureSource);
                    viewfinderRectangle.Fill = videoRecorderBrush;
                    captureSource.Start();
                    this.UpdateUI(VideoState.Initialized);
                }
                else
                {
                    this.UpdateUI(VideoState.CameraNotSupported);
                }
            }
        }

        /// <summary>
        /// Sets recording state: start recording 
        /// </summary>
        private void StartVideoRecording()
        {
            try
            {
                if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
                {
                    captureSource.Stop();
                    fileSink.CaptureSource = captureSource;
                    filePath = System.IO.Path.Combine("/" + LocalFolderName + "/", defaultFileName);

                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        if (!isoFile.DirectoryExists(LocalFolderName))
                        {
                            isoFile.CreateDirectory(LocalFolderName);
                        }

                        if (isoFile.FileExists(filePath))
                        {
                            isoFile.DeleteFile(filePath);
                        }
                    }

                    fileSink.IsolatedStorageFileName = filePath;
                }

                if (captureSource.VideoCaptureDevice != null
                    && captureSource.State == CaptureState.Stopped)
                {
                    captureSource.Start();
                }
                this.UpdateUI(VideoState.Recording);
            }
            catch (Exception)
            {
                this.result = new VideoResult(TaskResult.None);
                this.NavigateBack();
            }
        }

        /// <summary>
        /// Sets the recording state: stop recording
        /// </summary>
        private void StopVideoRecording()
        {
            try
            {
                if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
                {
                    captureSource.Stop();
                    fileSink.CaptureSource = null;
                    fileSink.IsolatedStorageFileName = null;
                    this.StartVideoPreview();
                }
            }
            catch (Exception)
            {
                this.result = new VideoResult(TaskResult.None);
                this.NavigateBack();
            }
        }

        /// <summary>
        /// Sets the recording state: display the video on the viewfinder. 
        /// </summary>
        private void StartVideoPreview()
        {
            try
            {
                if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Stopped))
                {
                    videoRecorderBrush.SetSource(captureSource);
                    viewfinderRectangle.Fill = videoRecorderBrush;
                    captureSource.Start();
                    this.UpdateUI(VideoState.Ready);
                }
            }
            catch (Exception)
            {
                this.result = new VideoResult(TaskResult.None);
                this.NavigateBack();
            }
        }

        /// <summary>
        /// Starts video recording 
        /// </summary>
        private void StartRecording_Click(object sender, EventArgs e)
        {
            if (currentVideoState == VideoState.Recording)
            {
                this.StopVideoRecording();
            }
            else
            {
                this.StartVideoRecording();
            }
        }

        /// <summary>
        /// Releases resources
        /// </summary>
        private void DisposeVideoRecorder()
        {
            if (captureSource != null)
            {
                if ((captureSource.VideoCaptureDevice != null) && (captureSource.State == CaptureState.Started))
                {
                    captureSource.Stop();
                }
                captureSource = null;
                videoCaptureDevice = null;
                fileSink = null;
                videoRecorderBrush = null;
            }
        }

    }
}