using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
//Kamerazugriff
using Microsoft.Devices;
//MediaLibrary
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework;
//IsolatedStorageSettings
using System.IO.IsolatedStorage;
//WriteableBitmapEx
using System.Windows.Media.Imaging;

namespace SLCamera
{
    public partial class MainPage : PhoneApplicationPage
    {
        //Kamera deklarieren
        PhotoCamera kamera = new PhotoCamera();
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            //Die Kamera im Dispatcher angelegen
            this.Dispatcher.BeginInvoke(delegate()
            {
                //Kamera anlegen
                kamera = new PhotoCamera();
                //Wird aufgerufen wenn die Kamera initialisiert ist
                kamera.Initialized += new EventHandler<CameraOperationCompletedEventArgs>(kamera_Initialized);
                //Wird aufgerufen wenn der Aufnahmevorgang abgeschlossen ist
                kamera.CaptureCompleted += new EventHandler<CameraOperationCompletedEventArgs>(kamera_CaptureCompleted);
                //Wird aufgerufen wenn der Aufnahmevorgang startet
                kamera.CaptureStarted += new EventHandler(kamera_CaptureStarted);
                //Wird aufgerufen wenn das aufgenommene Bild vorhanden ist
                kamera.CaptureImageAvailable += new EventHandler<ContentReadyEventArgs>(kamera_CaptureImageAvailable);
                //Kamera Hardwarebutton: Halb gedrückt
                CameraButtons.ShutterKeyHalfPressed += new EventHandler(CameraButtons_ShutterKeyHalfPressed);
                //Kamera Hardwarebutton: Vollständig gedrückt.
                CameraButtons.ShutterKeyPressed += new EventHandler(CameraButtons_ShutterKeyPressed);
                //VideoBrush festlegen
                kameraBildBrush.SetSource(kamera);
            });
        }

        void CameraButtons_ShutterKeyPressed(object sender, EventArgs e)
        {
            try
            {
                //Eine Aufnahme starten
                kamera.CaptureImage();
            }
            catch (Exception ex)
            {
                this.Dispatcher.BeginInvoke(delegate()
                {
                    txtStatus.Text = ex.Message;
                });
            }
        }

        void CameraButtons_ShutterKeyHalfPressed(object sender, EventArgs e)
        {
            this.Dispatcher.BeginInvoke(delegate()
            {
                txtStatus.Text = "Fokussiere (Auto)";
            });
            try
            {
                //Auto Fokussierung starten
                kamera.Focus();
            }
            catch (Exception ex)
            {
                this.Dispatcher.BeginInvoke(delegate()
                {
                    txtStatus.Text = ex.Message;
                });
            }
        }

        void kamera_CaptureImageAvailable(object sender, ContentReadyEventArgs e)
        {
            Dispatcher.BeginInvoke(delegate()
            {
                txtStatus.Text = "Speichere Bild...";
            });
            //Kurz warten im die UI Änderung durchzuführen
            System.Threading.Thread.Sleep(1);
            this.Dispatcher.BeginInvoke(delegate()
            {
                string strFile = "SLKamera.jpg";
                if (schnurrbart.Visibility == System.Windows.Visibility.Collapsed)
                {
                    //Das Bild kann direkt gespeichert werden
                    MediaLibrary medLib = new MediaLibrary();
                    medLib.SavePictureToCameraRoll(strFile, e.ImageStream);
                }
                else
                {
                    //Die beiden Bilder (Aufnahme + Schnurrbart) übereinanderlegen
                    //1.Auflösung auslesen
                    int Width = Convert.ToInt32(kamera.Resolution.Width);
                    int Height = Convert.ToInt32(kamera.Resolution.Height);
                    //WritableBitmap erstellen und den Fotostream einlesen
                    WriteableBitmap stream = new WriteableBitmap(Width, Height);
                    stream.LoadJpeg(e.ImageStream);
                    //WriteableBitmap erstellen und die Fotoeffekt Grafik laden
                    WriteableBitmap bart = new WriteableBitmap(0, 0).FromResource("Schnurrbart.png");
                    //Fotoeffekt Grafik an die Auflösung anpassen
                    bart = bart.Resize(Width, Height, WriteableBitmapExtensions.Interpolation.Bilinear);
                    //Die Grafiken übereinanderlegen
                    Rect rc = new Rect(0, 0, Width, Height);
                    stream.Blit(rc, bart, rc, WriteableBitmapExtensions.BlendMode.Alpha);
                    //Über die Extension Methode der WritebleBitmapEx Klasse speichern
                    stream.SaveToCameraRoll(strFile);
                }
                txtStatus.Text = "Bild gespeichert...";
            });
        }

        void kamera_CaptureStarted(object sender, EventArgs e)
        {
            this.Dispatcher.BeginInvoke(delegate()
            {
                txtStatus.Text = "Aufnahme gestartet";
            });
        }

        void kamera_CaptureCompleted(object sender, CameraOperationCompletedEventArgs e)
        {
            this.Dispatcher.BeginInvoke(delegate()
            {
              //  txtStatus.Text = "Aufnahme beendet";
            });
        }

        void kamera_Initialized(object sender, CameraOperationCompletedEventArgs e)
        {
            //Die Blitz Einstellung, Auflösung und Schnurrbart Effekt auswerten und setzen
            if (e.Succeeded)
            {
                string strBlitz = "";
                string strAufloesung = "";
                bool boSchnurrbart = false;
                try
                {
                    if (IsolatedStorageSettings.ApplicationSettings.Contains("Blitz"))
                        strBlitz = (string)IsolatedStorageSettings.ApplicationSettings["Blitz"];
                    if (IsolatedStorageSettings.ApplicationSettings.Contains("Aufloesung"))
                        strAufloesung = (string)IsolatedStorageSettings.ApplicationSettings["Aufloesung"];
                    if (IsolatedStorageSettings.ApplicationSettings.Contains("Schnurrbart"))
                        boSchnurrbart = (bool)IsolatedStorageSettings.ApplicationSettings["Schnurrbart"];

                }
                catch (Exception ex)
                {
                   
                }

                switch (strBlitz)
                {
                    case "An":
                        kamera.FlashMode = FlashMode.On;
                        break;
                    case "Aus":
                        kamera.FlashMode = FlashMode.Off;
                        break;
                    case "Rote Augen Reduktion":
                        kamera.FlashMode = FlashMode.RedEyeReduction;
                        break;
                    case "Automatisch":
                        kamera.FlashMode = FlashMode.Auto;
                        break;
                }
                if (strAufloesung.Length > 0)
                {
                    double dbWidth = 800;
                    double dbHeight = 600;
                    string[] strSizes = strAufloesung.Split('x');
                    double.TryParse(strSizes[0], out dbWidth);
                    double.TryParse(strSizes[1], out dbHeight);
                    IEnumerable<Size> lstAufloesungen = kamera.AvailableResolutions;
                    int Count = lstAufloesungen.Count<Size>();
                    Size curAufloesung;
                    for (int i = 0; i < Count; i++)
                    {
                        curAufloesung = lstAufloesungen.ElementAt<Size>(i);
                        if (curAufloesung.Height == dbHeight && curAufloesung.Width == dbWidth)
                        {
                            kamera.Resolution = curAufloesung;
                            break;
                        }
                    }
                }

                this.Dispatcher.BeginInvoke(delegate()
                {
                    if (boSchnurrbart)
                        schnurrbart.Visibility = System.Windows.Visibility.Visible;
                    else
                        schnurrbart.Visibility = System.Windows.Visibility.Collapsed;
                    txtStatus.Text = "Kamera fertig...";
                });
            }

        }

        private void Einstellungen_Click(object sender, System.EventArgs e)
        {
        	NavigationService.Navigate(new Uri("/Einstellungen.xaml",UriKind.Relative));
        }

        private void KameraBild_DoubleTap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            //An den Handler weiterleiten
            HandleDoubleTap(sender, e);
        }

        private void schnurrbart_DoubleTap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            //An den Handler weiterleiten
            HandleDoubleTap(sender, e);
        }

        private void HandleDoubleTap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            //Fokusierung auf bestimmten Punkt wird nicht von jedem Gerät unterstützt
            if (kamera.IsFocusAtPointSupported)
            {
                //Die genaue Position innerhalb des Viewfinders bestimmen
                UIElement uiElem = sender as UIElement;
                double d1 = (uiElem.RenderSize.Width - e.GetPosition(sender as UIElement).X) / (uiElem.RenderSize.Width / 100);
                double x = 1 - (d1 / 100);
                double d2 = (uiElem.RenderSize.Height - e.GetPosition(sender as UIElement).Y) / (uiElem.RenderSize.Height / 100);
                double y = 1 - (d2 / 100);
                this.Dispatcher.BeginInvoke(delegate()
                {
                    txtStatus.Text = "Fokussiere" + x.ToString() + "," + y.ToString();
                });
                try
                {
                    //Den Punkt fokusieren
                    kamera.FocusAtPoint(x, y);
                }
                catch (Exception ex)
                {
                    this.Dispatcher.BeginInvoke(delegate()
                    {
                        txtStatus.Text = ex.Message;
                    });
                }
            }
        }
    }
}