using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace ImageBlockz.Gui
{
    class ThumbnailBox : PictureBox
    {
        private Rectangle border = new Rectangle();
        private Rectangle selection = new Rectangle();
        private Rectangle pictureView = new Rectangle();

        private Size pictureSize = new Size();
        private Size thumbnailSize = new Size();

        private bool enabled = true;

        public ThumbnailBox()
        {

        }

        public MainWindow MainWindow
        {
            get;
            set;
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            base.OnPaint(pe);
            Graphics g = pe.Graphics;

            if (enabled)
            {
               g.DrawRectangle(Pens.Red, selection);   
            }
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            if (e.Button == MouseButtons.Left)
            {
                ProcessMouse(e);
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (e.Button == MouseButtons.Left)
            {
                ProcessMouse(e);
            }
        }

        private void ProcessMouse(MouseEventArgs e)
        {
            if (enabled != true)
            {
                return;
            }

            if (border.Contains(e.Location))
            {
                PointF relativeLocation = new PointF();
                Point upLeftCorner = new Point();

                upLeftCorner.X = e.Location.X - (selection.Size.Width / 2);
                upLeftCorner.Y = e.Location.Y - (selection.Size.Height / 2);

                selection.Location = upLeftCorner;
                
                if (selection.Top < border.Top)
                {
                    selection.Offset(0, border.Top - selection.Top);
                }

                if (selection.Right > border.Right)
                {
                    selection.Offset(border.Right - selection.Right - 1, 0);
                }

                if (selection.Bottom > border.Bottom)
                {
                    selection.Offset(0, border.Bottom - selection.Bottom - 1);
                }

                if (selection.Left < border.Left)
                {
                    selection.Offset(border.Left - selection.Left, 0);
                }

                relativeLocation.X = (selection.X - border.X) / (float)border.Width;
                relativeLocation.Y = (selection.Y - border.Y) / (float)border.Height;

                if (NavigationEvent != null)
                {
                    NavigationEvent(this, new NavigationEventArgs(relativeLocation));
                }

                Invalidate();
            }
        }

        public void SetPictureView(Size pictureSize, Rectangle pictureView)
        {
            this.pictureSize = pictureSize;
            this.pictureView = pictureView;

            UpdateSelection();
        }

        private void UpdateBorder()
        {
            border.X = (this.Width - thumbnailSize.Width) / 2;
            border.Y = (this.Height - thumbnailSize.Height) / 2;
            border.Size = thumbnailSize;
        }

        private void UpdateSelection()
        {
            selection.X = (int)Math.Round(pictureView.Location.X / (double)pictureSize.Width * thumbnailSize.Width);
            selection.Y = (int)Math.Round(pictureView.Location.Y / (double)pictureSize.Height * thumbnailSize.Height);

            selection.Offset(border.Location);

            selection.Width = (int)Math.Round(pictureView.Width / (double)pictureSize.Width * thumbnailSize.Width);
            selection.Height = (int)Math.Round(pictureView.Height / (double)pictureSize.Height * thumbnailSize.Height);

            selection.Width = Math.Min(selection.Width, border.Width);
            selection.Height = Math.Min(selection.Height, border.Height);

            enabled = selection.Size != border.Size;

            Invalidate();
        }

        public new Image Image
        {
            get
            {
                return base.Image;
            }
            set
            {
                if (value == null)
                {
                    return;
                }

                Image thumbnail = GetThumbnail(value);

                pictureSize = value.Size;
                thumbnailSize = thumbnail.Size;

                UpdateBorder();
                UpdateSelection();

                base.Image = thumbnail;
            }
        }

        private Image GetThumbnail(Image image)
        {
            double ratio = image.Height / (double) Height;
            int width = (int) Math.Round(image.Width / ratio);

            Image.GetThumbnailImageAbort abort = new Image.GetThumbnailImageAbort(this.ThumbnailCallback); 

            return image.GetThumbnailImage(width, Height, abort, IntPtr.Zero);
        }

        private bool ThumbnailCallback()
        {
            return false;
        }

        public delegate void NavigationHandler(object sender, NavigationEventArgs e);
        public event NavigationHandler NavigationEvent;

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);

            UpdateBorder();
            UpdateSelection();
        }
    }
}
