﻿/*  
	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.Collections.Generic;
using Microsoft.Phone.Tasks;
using System.Runtime.Serialization;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows.Media.Imaging;
using Microsoft.Phone;
using Microsoft.Xna.Framework.Media;
using System.Diagnostics;

namespace WPCordovaClassLib.Cordova.Commands
{
    public class Camera : BaseCommand
    {

        /// <summary>
        /// Return base64 encoded string
        /// </summary>
        private const int DATA_URL = 0;

        /// <summary>
        /// Return file uri
        /// </summary>
        private const int FILE_URI = 1;

        /// <summary>
        /// Choose image from picture library
        /// </summary>
        private const int PHOTOLIBRARY = 0;

        /// <summary>
        /// Take picture from camera
        /// </summary>

        private const int CAMERA = 1;

        /// <summary>
        /// Choose image from picture library
        /// </summary>
        private const int SAVEDPHOTOALBUM = 2;

        /// <summary>
        /// Take a picture of type JPEG
        /// </summary>
        private const int JPEG = 0;

        /// <summary>
        /// Take a picture of type PNG
        /// </summary>
        private const int PNG = 1;

        /// <summary>
        /// Folder to store captured images
        /// </summary>
        private const string isoFolder = "CapturedImagesCache";

        /// <summary>
        /// Represents captureImage action options.
        /// </summary>
        [DataContract]
        public class CameraOptions
        {
            /// <summary>
            /// Source to getPicture from.
            /// </summary>
            [DataMember(IsRequired = false, Name = "sourceType")]
            public int PictureSourceType { get; set; }

            /// <summary>
            /// Format of image that returned from getPicture.
            /// </summary>
            [DataMember(IsRequired = false, Name = "destinationType")]
            public int DestinationType { get; set; }

            /// <summary>
            /// Quality of saved image
            /// </summary>
            [DataMember(IsRequired = false, Name = "quality")]
            public int Quality { get; set; }

            /// <summary>
            /// Controls whether or not the image is also added to the device photo album.
            /// </summary>
            [DataMember(IsRequired = false, Name = "saveToPhotoAlbum")]
            public bool SaveToPhotoAlbum { get; set; }

            /// <summary>
            /// Ignored
            /// </summary>
            [DataMember(IsRequired = false, Name = "correctOrientation")]
            public bool CorrectOrientation { get; set; }

            

            /// <summary>
            /// Ignored
            /// </summary>
            [DataMember(IsRequired = false, Name = "allowEdit")]
            public bool AllowEdit { get; set; }

                        /// <summary>
            /// Height in pixels to scale image
            /// </summary>
            [DataMember(IsRequired = false, Name = "encodingType")]
            public int EncodingType { get; set; }

                        /// <summary>
            /// Height in pixels to scale image
            /// </summary>
            [DataMember(IsRequired = false, Name = "mediaType")]
            public int MediaType { get; set; }


            /// <summary>
            /// Height in pixels to scale image
            /// </summary>
            [DataMember(IsRequired = false, Name = "targetHeight")]
            public int TargetHeight { get; set; }


            /// <summary>
            /// Width in pixels to scale image
            /// </summary>
            [DataMember(IsRequired = false, Name = "targetWidth")]
            public int TargetWidth { get; set; }

            /// <summary>
            /// Creates options object with default parameters
            /// </summary>
            public CameraOptions()
            {
                this.SetDefaultValues(new StreamingContext());
            }

            /// <summary>
            /// Initializes default values for class fields.
            /// Implemented in separate method because default constructor is not invoked during deserialization.
            /// </summary>
            /// <param name="context"></param>
            [OnDeserializing()]
            public void SetDefaultValues(StreamingContext context)
            {
                PictureSourceType = CAMERA;
                DestinationType = FILE_URI;
                Quality = 80;
                TargetHeight = -1;
                TargetWidth = -1;
                SaveToPhotoAlbum = false;
                CorrectOrientation = true;
                AllowEdit = false;
                MediaType = -1;
                EncodingType = -1;
            }
        }

        /// <summary>
        /// Used to open photo library
        /// </summary>
        PhotoChooserTask photoChooserTask;

        /// <summary>
        /// Used to open camera application
        /// </summary>
        CameraCaptureTask cameraTask;

        /// <summary>
        /// Camera options
        /// </summary>
        CameraOptions cameraOptions;

        public void takePicture(string options)
        {
            try
            {
                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
                // ["quality", "destinationType", "sourceType", "targetWidth", "targetHeight", "encodingType",
                //     "mediaType", "allowEdit", "correctOrientation", "saveToPhotoAlbum" ]
                this.cameraOptions = new CameraOptions();
                this.cameraOptions.Quality = int.Parse(args[0]);
                this.cameraOptions.DestinationType = int.Parse(args[1]);
                this.cameraOptions.PictureSourceType = int.Parse(args[2]);
                this.cameraOptions.TargetWidth = int.Parse(args[3]);
                this.cameraOptions.TargetHeight = int.Parse(args[4]);
                this.cameraOptions.EncodingType = int.Parse(args[5]);
                this.cameraOptions.MediaType = int.Parse(args[6]);
                this.cameraOptions.AllowEdit = bool.Parse(args[7]);
                this.cameraOptions.CorrectOrientation = bool.Parse(args[8]);
                this.cameraOptions.SaveToPhotoAlbum = bool.Parse(args[9]);
                
                //this.cameraOptions = String.IsNullOrEmpty(options) ?
                //        new CameraOptions() : JSON.JsonHelper.Deserialize<CameraOptions>(options);
            }
            catch (Exception ex)
            {
                this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
                return;
            }

            //TODO Check if all the options are acceptable


            if (cameraOptions.PictureSourceType == CAMERA)
            {
                cameraTask = new CameraCaptureTask();
                cameraTask.Completed += onCameraTaskCompleted;
                cameraTask.Show();
            }
            else
            {
                if ((cameraOptions.PictureSourceType == PHOTOLIBRARY) || (cameraOptions.PictureSourceType == SAVEDPHOTOALBUM))
                {
                    photoChooserTask = new PhotoChooserTask();
                    photoChooserTask.Completed += onPickerTaskCompleted;
                    photoChooserTask.Show();
                }
                else
                {
                    DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
                }
            }

        }

        public void onCameraTaskCompleted(object sender, PhotoResult e)
        {
            if (e.Error != null)
            {
                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
                return;
            }

            switch (e.TaskResult)
            {
                case TaskResult.OK:
                    try
                    {
                        string imagePathOrContent = string.Empty;

                        if (cameraOptions.DestinationType == FILE_URI)
                        {
                            // Save image in media library
                            if (cameraOptions.SaveToPhotoAlbum)
                            {
                                MediaLibrary library = new MediaLibrary();
                                Picture pict = library.SavePicture(e.OriginalFileName, e.ChosenPhoto); // to save to photo-roll ...
                            }

                            int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto);
                            int newAngle = 0;
                            switch (orient)
                            {
                                case ImageExifOrientation.LandscapeLeft:
                                    newAngle = 90;
                                    break;
                                case ImageExifOrientation.PortraitUpsideDown:
                                    newAngle = 180;
                                    break;
                                case ImageExifOrientation.LandscapeRight:
                                    newAngle = 270;
                                    break;
                                case ImageExifOrientation.Portrait:
                                default: break; // 0 default already set
                            }

                            Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle);

                            // we should return stream position back after saving stream to media library
                            rotImageStream.Seek(0, SeekOrigin.Begin);

                            WriteableBitmap image = PictureDecoder.DecodeJpeg(rotImageStream);

                            imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));


                        }
                        else if (cameraOptions.DestinationType == DATA_URL)
                        {
                            imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
                        }
                        else
                        {
                            // TODO: shouldn't this happen before we launch the camera-picker?
                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
                            return;
                        }

                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));

                    }
                    catch (Exception)
                    {
                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
                    }
                    break;

                case TaskResult.Cancel:
                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
                    break;

                default:
                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
                    break;
            }

        }

        public void onPickerTaskCompleted(object sender, PhotoResult e)
        {
            if (e.Error != null)
            {
                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
                return;
            }

            switch (e.TaskResult)
            {
                case TaskResult.OK:
                    try
                    {
                        string imagePathOrContent = string.Empty;

                        if (cameraOptions.DestinationType == FILE_URI)
                        {
                            WriteableBitmap image = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
                            imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
                        }
                        else if (cameraOptions.DestinationType == DATA_URL)
                        {
                            imagePathOrContent = this.GetImageContent(e.ChosenPhoto);

                        }
                        else
                        {
                            // TODO: shouldn't this happen before we launch the camera-picker?
                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType"));
                            return;
                        }

                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));

                    }
                    catch (Exception)
                    {
                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
                    }
                    break;

                case TaskResult.Cancel:
                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
                    break;

                default:
                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
                    break;
            }
        }

        /// <summary>
        /// Returns image content in a form of base64 string
        /// </summary>
        /// <param name="stream">Image stream</param>
        /// <returns>Base64 representation of the image</returns>
        private string GetImageContent(Stream stream)
        {
            int streamLength = (int)stream.Length;
            byte[] fileData = new byte[streamLength + 1];
            stream.Read(fileData, 0, streamLength);

            //use photo's actual width & height if user doesn't provide width & height
            if (cameraOptions.TargetWidth < 0 && cameraOptions.TargetHeight < 0)
            {
                stream.Close();
                return Convert.ToBase64String(fileData);
            }
            else
            {
                // resize photo
                byte[] resizedFile = ResizePhoto(stream, fileData);
                stream.Close();
                return Convert.ToBase64String(resizedFile);
            }
        }

        /// <summary>
        /// Resize image
        /// </summary>
        /// <param name="stream">Image stream</param>
        /// <param name="fileData">File data</param>
        /// <returns>resized image</returns>
        private byte[] ResizePhoto(Stream stream, byte[] fileData)
        {
            int streamLength = (int)stream.Length;
            int intResult = 0;

            byte[] resizedFile;

            stream.Read(fileData, 0, streamLength);

            BitmapImage objBitmap = new BitmapImage();
            MemoryStream objBitmapStream = new MemoryStream(fileData);
            MemoryStream objBitmapStreamResized = new MemoryStream();
            WriteableBitmap objWB;
            objBitmap.SetSource(stream);
            objWB = new WriteableBitmap(objBitmap);

            // resize the photo with user defined TargetWidth & TargetHeight
            Extensions.SaveJpeg(objWB, objBitmapStreamResized, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);

            //Convert the resized stream to a byte array. 
            streamLength = (int)objBitmapStreamResized.Length;
            resizedFile = new Byte[streamLength]; //-1 
            objBitmapStreamResized.Position = 0;
            //for some reason we have to set Position to zero, but we don't have to earlier when we get the bytes from the chosen photo... 
            intResult = objBitmapStreamResized.Read(resizedFile, 0, streamLength);

            return resizedFile;
        }

        /// <summary>
        /// Saves captured image in isolated storage
        /// </summary>
        /// <param name="imageFileName">image file name</param>
        /// <returns>Image path</returns>
        private string SaveImageToLocalStorage(WriteableBitmap image, string imageFileName)
        {

            if (image == null)
            {
                throw new ArgumentNullException("imageBytes");
            }
            try
            {


                var isoFile = IsolatedStorageFile.GetUserStoreForApplication();

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

                string filePath = System.IO.Path.Combine("///" + isoFolder + "/", imageFileName);

                using (var stream = isoFile.CreateFile(filePath))
                {
                    // resize image if Height and Width defined via options 
                    if (cameraOptions.TargetHeight > 0 && cameraOptions.TargetWidth > 0)
                    {
                        image.SaveJpeg(stream, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
                    }
                    else
                    {
                        image.SaveJpeg(stream, image.PixelWidth, image.PixelHeight, 0, cameraOptions.Quality);
                    }
                }

                return new Uri(filePath, UriKind.Relative).ToString();
            }
            catch (Exception)
            {
                //TODO: log or do something else
                throw;
            }
        }

    }
}
