using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using HistoryWallEditTool.EventArg;

namespace HistoryWallEditTool.Controls
{
    /// <summary>
    /// ColorPicker.xaml 的互動邏輯
    /// </summary>
    public partial class ColorPicker : UserControl
    {
        #region Class Members

        private Point selectPoint;
        private Color selectColor = Colors.White;
        private bool isMouseDown;

        #endregion

        #region Properties

        public Point SelectPoint
        {
            get { return selectPoint; }
            set
            {
                selectPoint = value;
                uxEllipsePixel.SetValue(Canvas.LeftProperty, selectPoint.X);
                uxEllipsePixel.SetValue(Canvas.TopProperty, selectPoint.Y);
            }
        }

        public Color SelectColor
        {
            get { return selectColor; }
            set
            {
                selectColor = value;
                uxGrdientColor.Color = Color.FromArgb(255, selectColor.R, selectColor.G, selectColor.B);
                uxColorValueR.Text = selectColor.R.ToString();
                uxColorValueG.Text = selectColor.G.ToString();
                uxColorValueB.Text = selectColor.B.ToString();
                uxAlphaSlider.Value = selectColor.A;
                uxAlphaSlider.ValueChanged += new RoutedPropertyChangedEventHandler<double>(uxAlphaSlider_ValueChanged);
            }
        }

        #endregion

        #region Constructor

        public ColorPicker(bool large = true)
        {
            InitializeComponent();
            if (!large)
            {
                this.Height = 282;
                uxColorImage.Width = uxCanvasImage.Width = this.Width = 270;
                uxRowDefine1.Height = new GridLength(40);
                uxRowDefine2.Height = new GridLength(177);
                uxRowDefine3.Height = new GridLength(40);
                uxRowDefine4.Height = new GridLength(25);
                uxColorImage.Source = new BitmapImage(new Uri("pack://application:,,,/HistoryWallEditTool;component/Image/color270x177.png"));
            }
            uxCanvasImage.MouseDown += new MouseButtonEventHandler(uxCanvasImage_MouseDown);
            uxCanvasImage.MouseMove += new MouseEventHandler(uxCanvasImage_MouseMove);
            uxCanvasImage.MouseLeave += new MouseEventHandler(uxCanvasImage_MouseLeave);
            uxCanvasImage.MouseUp += new MouseButtonEventHandler(uxCanvasImage_MouseUp);
            uxColorValueR.KeyUp += new KeyEventHandler(uxColorValue_KeyUp);
            uxColorValueG.KeyUp += new KeyEventHandler(uxColorValue_KeyUp);
            uxColorValueB.KeyUp += new KeyEventHandler(uxColorValue_KeyUp);
            colorImgBmp = new System.Drawing.Bitmap(GlobalFunction.thumbPath + "color322x212.png");
        }

        #endregion

        #region Events & EventHandler

        public event EventHandler<ColorEventArgs> OnColorChanged;

        protected virtual void ColorChanged(Object obj, ColorEventArgs e)
        {
            if (OnColorChanged != null)
            {
                OnColorChanged(obj, e);
            }
        }

        private void uxColorValue_KeyUp(object sender, KeyEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            int value;
            bool isNumber = int.TryParse(textBox.Text, out value);
            if (isNumber)
            {
                if (value > 255)
                {
                    textBox.Text = "255";
                }
                else if (value < 0)
                {
                    textBox.Text = "0";
                }
                else
                {
                    textBox.Text = int.Parse(textBox.Text).ToString();
                }
            }
            else
            {
                textBox.Text = "0";
            }
            try
            {
                selectColor = Color.FromArgb(
                    (byte)uxAlphaSlider.Value,
                    byte.Parse(uxColorValueR.Text),
                    byte.Parse(uxColorValueG.Text),
                    byte.Parse(uxColorValueB.Text));
                uxGrdientColor.Color = selectColor;
                Point pt = FindPixelLocation(selectColor.R, selectColor.G, selectColor.B);
                selectPoint = pt == new Point(-1, -1) ? selectPoint : pt;
                uxEllipsePixel.SetValue(Canvas.LeftProperty, selectPoint.X);
                uxEllipsePixel.SetValue(Canvas.TopProperty, selectPoint.Y);
                ColorChanged(this, new ColorEventArgs(selectColor, selectPoint));
            }
            catch
            {
                Debug.WriteLine("Error");
            }
        }

        private System.Drawing.Bitmap colorImgBmp;

        private Point FindPixelLocation(byte r, byte g, byte b)
        {
            for (int x = 0; x < uxColorImage.Width; x++)
            {
                for (int y = 0; y < uxColorImage.Height; y++)
                {
                    System.Drawing.Color c = colorImgBmp.GetPixel(x, y);
                    if ((c.R >= r - 30 && c.R <= r + 30) &&
                        (c.B >= b - 30 && c.B <= b + 30) &&
                        (c.G >= g - 30 && c.G <= g + 30))
                    {
                        return new Point(x, y);
                    }
                }
            }
            return new Point(-1, -1);
        }

        private void uxAlphaSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            selectColor = Color.FromArgb((byte)uxAlphaSlider.Value, selectColor.R, selectColor.G, selectColor.B);
            ColorChanged(this, new ColorEventArgs(selectColor, selectPoint));
        }

        private void uxCanvasImage_MouseUp(object sender, MouseButtonEventArgs e)
        {
            isMouseDown = false;
            e.Handled = true;
        }

        private void uxCanvasImage_MouseLeave(object sender, MouseEventArgs e)
        {
            isMouseDown = false;
            e.Handled = true;
        }

        private void uxCanvasImage_MouseMove(object sender, MouseEventArgs e)
        {
            if (!isMouseDown)
            {
                return;
            }
            e.Handled = true;
            try
            {
                CroppedBitmap cb = new CroppedBitmap(uxColorImage.Source as BitmapSource, new Int32Rect((int)Mouse.GetPosition(uxCanvasImage).X,
                        (int)Mouse.GetPosition(uxCanvasImage).Y, 1, 1));
                byte[] pixels = new byte[4];
                try
                {
                    cb.CopyPixels(pixels, 4, 0);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }
                selectPoint.X = (double)(Mouse.GetPosition(uxCanvasImage).X - 5);
                selectPoint.Y = (double)(Mouse.GetPosition(uxCanvasImage).Y - 5);
                uxEllipsePixel.SetValue(Canvas.LeftProperty, selectPoint.X);
                uxEllipsePixel.SetValue(Canvas.TopProperty, selectPoint.Y);
                uxCanvasImage.InvalidateVisual();
                selectColor = Color.FromArgb((byte)uxAlphaSlider.Value, pixels[2], pixels[1], pixels[0]);
                uxColorValueR.Text = pixels[2].ToString();
                uxColorValueG.Text = pixels[1].ToString();
                uxColorValueB.Text = pixels[0].ToString();
                uxGrdientColor.Color = selectColor;
                ColorChanged(this, new ColorEventArgs(selectColor, selectPoint));
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        private void uxCanvasImage_MouseDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            isMouseDown = true;
            try
            {
                CroppedBitmap cb = new CroppedBitmap(uxColorImage.Source as BitmapSource,
                    new Int32Rect((int)Mouse.GetPosition(uxCanvasImage).X,
                        (int)Mouse.GetPosition(uxCanvasImage).Y, 1, 1));

                byte[] pixels = new byte[4];

                try
                {
                    cb.CopyPixels(pixels, 4, 0);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }
                selectPoint.X = (double)(Mouse.GetPosition(uxCanvasImage).X - 5);
                selectPoint.Y = (double)(Mouse.GetPosition(uxCanvasImage).Y - 5);
                uxEllipsePixel.SetValue(Canvas.LeftProperty, selectPoint.X);
                uxEllipsePixel.SetValue(Canvas.TopProperty, selectPoint.Y);
                uxCanvasImage.InvalidateVisual();
                selectColor = Color.FromArgb((byte)uxAlphaSlider.Value, pixels[2], pixels[1], pixels[0]);
                uxColorValueR.Text = pixels[2].ToString();
                uxColorValueG.Text = pixels[1].ToString();
                uxColorValueB.Text = pixels[0].ToString();
                uxGrdientColor.Color = selectColor;
                ColorChanged(this, new ColorEventArgs(selectColor, selectPoint));
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        #endregion
    }
}
