using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;


namespace ScreenShotOCR
{
    /// <summary>
    /// CaptureWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class CaptureWindow : Window
    {
        public EventHandlerGrab m_handlerGrab = null;

        Bitmap bitmap = null;
        Bitmap crop = null;
        Image bg = null;

        int screen_w = (int)SystemParameters.PrimaryScreenWidth;
        int screen_h = (int)SystemParameters.PrimaryScreenHeight;
        System.Drawing.Rectangle roi = new System.Drawing.Rectangle();
        float resX = 1.0f;
        float resY = 1.0f;
        bool bClicked = false;
        System.Drawing.PointF pt = new System.Drawing.PointF();


        public CaptureWindow()
        {
            InitializeComponent();
            SetTransparent(true);

            m_handlerGrab = delegate ()
            {
                var crop = bitmap.Clone(roi, bitmap.PixelFormat);
                return crop;
            };
        }

        public void SetTransparent(bool enable)
        {
            if (enable)
            {
                this.Background = System.Windows.Media.Brushes.Transparent;
                ScreenView.Source = null;
            }
            else
            {
                this.Background = System.Windows.Media.Brushes.White;
            }
        }

        private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.DragMove();
        }

        public void copyBtn_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                //new Task(delegate
                //{
                SetTransparent(false);
                if (bitmap != null) bitmap.Dispose();
                if (bg != null) { bg.Dispose(); }
                bitmap = new Bitmap(screen_w, screen_h, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                var gr = Graphics.FromImage(bitmap);
                gr.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
                string name = "snapshot.png";
                bg = ResizeImage(bitmap, new System.Drawing.Size(screen_w, screen_h));
                ScreenView.Source = ConvertToImageSource(bg);
                bitmap.Save(name, ImageFormat.Png);
                gr.Dispose();
                //}, TaskCreationOptions.DenyChildAttach).Start();
            }
            catch (Exception ex)
            {

            }
        }

        public static Bitmap ResizeImage(Bitmap imgToResize, System.Drawing.Size size)
        {
            try
            {
                Bitmap b = new Bitmap(size.Width, size.Height);
                using (Graphics g = Graphics.FromImage((Image)b))
                {
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g.DrawImage(imgToResize, 0, 0, size.Width, size.Height);
                }
                return b;
            }
            catch
            {
                Console.WriteLine("Bitmap could not be resized");
                return imgToResize;
            }
        }

        private ImageSource ConvertToImageSource(Image image)
        {
            using (var ms = new MemoryStream())
            {
                image.Save(ms, ImageFormat.Bmp);
                ms.Seek(0, SeekOrigin.Begin);

                var bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.StreamSource = ms;
                bitmapImage.EndInit();

                return bitmapImage;
            }
        }

        private void ClearBtn_Click(object sender, RoutedEventArgs e)
        {
            SetTransparent(true);
        }

        private void Close_Click(object sender, RoutedEventArgs e)
        {
            this.Visibility = Visibility.Hidden;
        }

        private void ScreenView_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (!bClicked)
            {
                bClicked = true;
                var p = e.GetPosition(ScreenView);
                float x = Convert.ToSingle(Math.Round(p.X * resX));
                float y = Convert.ToSingle(Math.Round(p.Y * resY));
                pt = new System.Drawing.PointF(x, y);
                roi.X = Convert.ToInt32(x);
                roi.Y = Convert.ToInt32(y);
            }
        }

        private void ScreenView_MouseMove(object sender, MouseEventArgs e)
        {
            if (bClicked)
            {
                var p = e.GetPosition(ScreenView);
                float x = Convert.ToSingle(p.X);
                float y = Convert.ToSingle(p.Y);
                var w = (float)Math.Round(x * resX - pt.X);
                var h = (float)Math.Round(y * resY - pt.Y);
                roi.Width = Convert.ToInt32(w);
                roi.Height = Convert.ToInt32(h);
                CheckROI();
                DrawROI();
            }
        }

        private void ScreenView_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (bClicked)
            {
                var p = e.GetPosition(ScreenView);
                float x = Convert.ToSingle(p.X);
                float y = Convert.ToSingle(p.Y);
                var w = (float)Math.Round(x * resX - pt.X);
                var h = (float)Math.Round(y * resY - pt.Y);
                roi.Width = Convert.ToInt32(w);
                roi.Height = Convert.ToInt32(h);
                CheckROI();
                DrawROI();
                bClicked = false;         
            }
        }

        private void CheckROI()
        {
            int x = roi.X;
            if (x < 0) { x = 0; } else if (x >= screen_w) { x = screen_w - 1; }
            int y = roi.Y;
            if (y < 0) { y = 0; } else if (y >= screen_h) { y = screen_h - 1; }
            int w = roi.Width;
            if (w < 0) { w = 0; } else if (x + w >= screen_w) { w = screen_w - 1 - x; }
            int h = roi.Height;
            if (h < 0) { h = 0; } else if (y + h >= screen_h) { h = screen_h - 1 - y; }
            roi = new System.Drawing.Rectangle(x, y, w, h);
        }

        private void DrawROI()
        {
            if (bg == null) return;
            try
            {
                int x = (int)Math.Round(Convert.ToSingle(roi.X / resX));
                int y = (int)Math.Round(Convert.ToSingle(roi.Y / resY));
                int w = (int)Math.Round(Convert.ToSingle(roi.Width / resX));
                int h = (int)Math.Round(Convert.ToSingle(roi.Height / resY));

                System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Red, 1);
                System.Drawing.Rectangle rect = new System.Drawing.Rectangle(x, y, w, h);
                var tmp = (Bitmap)bg.Clone();
                var gr = Graphics.FromImage(tmp);
                gr.DrawRectangle(pen, rect);
                ScreenView.Source = ConvertToImageSource(tmp);

                //posX.Text = roi.X.ToString();
                //posY.Text = roi.Y.ToString();
                //posW.Text = roi.Width.ToString();
                //posH.Text = roi.Height.ToString();

                gr.Dispose();
                tmp.Dispose();
            }
            catch
            {
            }
        }

    }
}
