using Amazon;
using Amazon.Rekognition;
using Amazon.Rekognition.Model;
using Amazon.Runtime;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;




namespace Reko
{
    public partial class MainWindow : Window
    {
		//*******************************************************
		//Définir votre région et vos paramètres d'identification
		//*******************************************************
		private static readonly RegionEndpoint regAWS = RegionEndpoint.EUWest1;
		private static readonly string AWSAccessKey = "";
		private static readonly string AWSSecretKey = "";

		private static readonly BasicAWSCredentials AWSCred = new BasicAWSCredentials(AWSAccessKey, AWSSecretKey);

		private BitmapSource imageSource;
        private Stream stream=null;
        private string path = "";
        private string strPolice;

        String strResultat = "";
        int orientationjpg = 0;
        // Orientations.
        public const int OrientationId = 0x0112;
        public enum ExifOrientations
        {
            Unknown = 0,
            TopLeft = 1,
            TopRight = 2,
            BottomRight = 3,
            BottomLeft = 4,
            LeftTop = 5,
            RightTop = 6,
            RightBottom = 7,
            LeftBottom = 8,
        }

        public MainWindow()
        {
            InitializeComponent();
            
        }

        private void BtnRekoS3_Click(object sender, RoutedEventArgs e)
        {
			this.Cursor = Cursors.Wait;
			Visage();
            txtResultat.Text = strResultat;
            txtPolice.Text = strPolice;
			this.Cursor = Cursors.Arrow;

		}

		public BitmapSource imageAffiche(Stream stream)
        {
            orientationjpg = 0;
            BitmapFrame bitmapFrame = BitmapFrame.Create(stream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
            BitmapMetadata bitmapMetadata = bitmapFrame.Metadata as BitmapMetadata;

            if ((bitmapMetadata != null) && (bitmapMetadata.ContainsQuery("System.Photo.Orientation")))
            {
                object o = bitmapMetadata.GetQuery("System.Photo.Orientation");

                if (o != null)
                {
                    switch ((ushort)o)
                    {
                        case 6:
                            orientationjpg = 90;
                            break;
                        case 3:
                            orientationjpg = 180;
                            break;
                        case 8:
                            orientationjpg = 270;
                            break;
                    }
                }
            }

            imageSource = new BitmapImage(new Uri(path));
            if (orientationjpg != 0)
            {
                TransformedBitmap tb = new TransformedBitmap();
                tb.BeginInit();
                tb.Source = imageSource;
                RotateTransform transform = new RotateTransform(orientationjpg);
                tb.Transform = transform;
                tb.EndInit();
                return tb;
            }
            else
            {
                return imageSource;
            }
        }
        public Amazon.Rekognition.Model.Image GetImageFromFile()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
			//Indiquer le répertoire contenant la photo à analyser
			openFileDialog.InitialDirectory = "C:\\";
            openFileDialog.ShowDialog();
            path = openFileDialog.FileName;

            Amazon.Rekognition.Model.Image image = new Amazon.Rekognition.Model.Image();
            try
            {
                stream = openFileDialog.OpenFile();
                
                byte[] data = new byte[stream.Length];
                stream.Read(data, 0, (int)stream.Length);
                image.Bytes = new MemoryStream(data);
                stream.Position = 0;

                return image;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
                return null;
            }
			
		}

        public void Visage()
        {
            strPolice = "";
            AmazonRekognitionClient rekCli = new AmazonRekognitionClient(AWSCred, AWSreg);

            DetectFacesRequest detectVisageReq = new DetectFacesRequest()
            {
                Image = GetImageFromFile(),
                Attributes = new List<String>() { "ALL" }
            };

			BitmapSource bitmap = imageAffiche(stream);
            DrawingVisual dv = new DrawingVisual();
            using (DrawingContext dc = dv.RenderOpen())
            {
                dc.DrawImage(bitmap, new Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight));
                //dc.DrawRectangle(Brushes.Green, null, new Rect(20, 20, 150, 100));

                try
                {
                    int i = 0;
                    DetectFacesResponse detectVisageResp = rekCli.DetectFaces(detectVisageReq);

                    //Correction de l'orientation
                    strResultat = $"Correction orientation native : {orientationjpg} degré(s)\n";
                    if (detectVisageResp.OrientationCorrection != null)
                    {
                        strResultat += $"Correction orientation Rekognition : {detectVisageResp.OrientationCorrection.ToString()} degré(s)\n";
                    }
                    else
                    {
                        strResultat += "Correction orientation Rekognition : 0 degré\n";
                    }

                    if (detectVisageReq.Attributes.Contains("ALL"))
                    {

                        foreach (FaceDetail det in detectVisageResp.FaceDetails)
                        {
                            i++;
                            strPolice += $"{i} - L'individu est ";
                            if(det.Gender.Value==GenderType.Male)
                            {
                                strPolice += "un homme, entre ";
                            }
                            else
                            {
                                strPolice += "une femme, entre ";
                            }
                            strResultat += $"{i} - Age entre {det.AgeRange.Low.ToString()} et {det.AgeRange.High.ToString()}\n";
                            strPolice += $"{det.AgeRange.Low.ToString()} et {det.AgeRange.High.ToString()} ans. ";
                            if (det.Beard.Value)
                            {
                                strResultat += $"Barbe présente à {det.Beard.Confidence}%\n";
                                strPolice += "Il porte la barbe. ";
                            }
                            strResultat += $"Émotion(s) :";
                            foreach (Emotion emotion in det.Emotions)
                            {
                                if (emotion.Confidence > 40)
                                {
                                    strResultat += $" {emotion.Type},";
                                }
                            }
                            char[] charsToTrim = { ',' };
                            strResultat = strResultat.TrimEnd(charsToTrim);
                            strResultat += "\n";
                            if (det.Eyeglasses.Value)
                            {
                                strResultat += $"Lunettes à {det.Eyeglasses.Confidence}%\n";
                                strPolice += "Il a des lunettes. ";
                            }
                            if (det.EyesOpen.Value)
                            {
                                strResultat += $"Yeux ouverts à {det.EyesOpen.Confidence}%\n";
                            }
                            else
                            {
                                strResultat += $"Yeux fermés à {det.EyesOpen.Confidence}%\n";
                            }
                            strResultat += $"{det.Gender.Value} à {det.Gender.Confidence}%\n";
                            if (det.MouthOpen.Value)
                            {
                                strResultat += $"Bouche ouverte à {det.MouthOpen.Confidence}%\n";
                            }
                            else
                            {
                                strResultat += $"Bouche fermée à {det.MouthOpen.Confidence}%\n";
                            }
                            if (det.Mustache.Value)
                            {
                                strResultat += $"Moustache à {det.Mustache.Confidence}%\n";
                                strPolice += "Il a une moustache.";
                            }
                            if (det.Smile.Value)
                            {
                                strResultat += $"Sourire à {det.Smile.Confidence}%\n";
                            }
                            if (det.Sunglasses.Value)
                            {
                                strResultat += $"Lunettes de soleil à {det.Sunglasses.Confidence}%\n";
                            }
                            foreach (Landmark landmark in det.Landmarks)
                            {
                                dc.DrawRectangle(Brushes.Lime, null, new Rect(landmark.X * bitmap.PixelWidth, landmark.Y * bitmap.PixelHeight, 2, 2));
                            }
                            dc.DrawRectangle(null, new Pen(Brushes.Cyan, 2), new Rect(det.BoundingBox.Left * bitmap.PixelWidth, det.BoundingBox.Top * bitmap.PixelHeight, det.BoundingBox.Width * bitmap.PixelWidth, det.BoundingBox.Height * bitmap.PixelHeight));
                            dc.DrawText(
                                new FormattedText(i.ToString(),
                                    System.Globalization.CultureInfo.CurrentUICulture,
                                    FlowDirection.LeftToRight,
                                    new Typeface(new FontFamily("Verdana"),
                                        FontStyles.Normal,
                                        FontWeights.Normal,
                                        FontStretches.Normal,
                                        new FontFamily("Calibri")),
                                    48,
                                    Brushes.Cyan),
                                new System.Windows.Point(det.BoundingBox.Left * bitmap.PixelWidth, det.BoundingBox.Top * bitmap.PixelHeight));
                            strResultat += $"Indice de confiance : {det.Confidence.ToString()}%\n";
                            strPolice += "\n";
                        }
                        
                    }
                    
                    strResultat = $"{i} visage(s) détecté(s).\n" + strResultat;



                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }
            }
            RenderTargetBitmap rtb = new RenderTargetBitmap(bitmap.PixelWidth, bitmap.PixelHeight, 96, 96, PixelFormats.Pbgra32);
            rtb.Render(dv);

            imgAnalyse.Source = rtb;
            
        }

    }
}
