//+--------------------------------------------------------------------------+
//|                                                                          |
//|                           SkinTrackbar class                             |
//|                                                                          |
//+--------------------------------------------------------------------------+
//|                                                                          |
//|                         Author Patrice TERRIER                           |
//|                           copyright (c) 2006                             |
//|                                                                          |
//|                        pterrier@zapsolution.com                          |
//|                                                                          |
//|                          www.zapsolution.com                             |
//|                                                                          |
//+--------------------------------------------------------------------------+
//|                  Project started on : 11-06-2006 (MM-DD-YYYY)            |
//|                        Last revised : 11-07-2006 (MM-DD-YYYY)            |
//+--------------------------------------------------------------------------+

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

//using System.Diagnostics;
using Win32;
using SkinEngine;

namespace Planet3D
{
    public partial class TRACK_Back : UserControl
    {
        private const bool Vert = false;
        private const bool Horz = true;

        private double value = 50;
        private double minimum = 0;
        private double maximum = 100;

        private bool ThumbMoving = false;

        public TRACK_Back()
        {
            InitializeComponent();
        }

        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case Api.WM_ERASEBKGND:

                    // Do it first to draw over the Win32 DC
                    base.WndProc(ref m);

                    Graphics g = Graphics.FromHdc(m.WParam);
                    Pen PenDark = new Pen(Color.FromArgb(82, 82, 82));
                    Pen PenGray = new Pen(Color.FromArgb(119, 119, 119));
                    Pen PenLight = new Pen(Color.FromArgb(157, 157, 157));

                    if (Orientation() == Horz)
                    {

                        int y = BTN_Thumb.Top + BTN_Thumb.Height / 2;

                        // if (ShowRange) {
                        SolidBrush myBrush = new SolidBrush(Color.FromArgb(32, 0, 0, 0));
                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        if (Minimum > Maximum)
                        {
                            Point[] p = { new Point(ClientRectangle.Width - 1, y - 2), 
                                          new Point(0, 0), 
                                          new Point(0, ClientRectangle.Height - 1),
                                          new Point(ClientRectangle.Width - 1, y + 1)};
                            g.FillPolygon(myBrush, p);
                        }
                        else
                        {
                            Point[] p = { new Point(0, y - 2), 
                                          new Point(ClientRectangle.Width - 1, 0), 
                                          new Point(ClientRectangle.Width - 1, ClientRectangle.Height - 2),
                                          new Point(0, y + 1)};
                            g.FillPolygon(myBrush, p);
                        }
                        myBrush.Dispose();
                        // }

                        g.DrawLine(PenDark, new Point(0, y), new Point(0, y - 1));
                        g.DrawLine(PenDark, new Point(0, y - 1), new Point(ClientRectangle.Width - 1, y - 1));
                        g.DrawLine(PenLight, new Point(1, y), new Point(ClientRectangle.Width - 1, y));
                        g.DrawLine(PenGray, new Point(ClientRectangle.Width - 1, y - 1), new Point(ClientRectangle.Width, y - 1));
                    }
                    else
                    {
                        int x = BTN_Thumb.Left + BTN_Thumb.Width / 2;

                        // if (ShowRange) {
                        SolidBrush myBrush = new SolidBrush(Color.FromArgb(32, 0, 0, 0));
                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        if (Minimum > Maximum)
                        {
                            Point[] p = { new Point(x - 2, ClientRectangle.Height - 1), 
                                          new Point(0, 0), 
                                          new Point(ClientRectangle.Width - 1, 0),
                                          new Point(x + 1, ClientRectangle.Height - 1)};
                            g.FillPolygon(myBrush, p);
                        }
                        else
                        {
                            Point[] p = { new Point(x + 1, 0), 
                                          new Point(ClientRectangle.Width - 1, ClientRectangle.Height - 1), 
                                          new Point(0, ClientRectangle.Height - 1),
                                          new Point(x - 2, 0)};
                            g.FillPolygon(myBrush, p);
                        }
                        myBrush.Dispose();
                        // }

                        g.DrawLine(PenDark, new Point(x - 1, 0), new Point(x, 0));
                        g.DrawLine(PenDark, new Point(x - 1, 0), new Point(x - 1, ClientRectangle.Height - 1));
                        g.DrawLine(PenLight, new Point(x, 1), new Point(x, ClientRectangle.Height - 1));
                        g.DrawLine(PenGray, new Point(x - 1, ClientRectangle.Height - 1), new Point(x - 1, ClientRectangle.Height));
                    }

                    PenLight.Dispose();
                    PenGray.Dispose();
                    PenDark.Dispose();
                    g.Dispose();
                    break;

                default:
                    base.WndProc(ref m);
                    break;
            }
        }

        private void SendNotification()
        {
            Api.SendMessage(Api.GetForegroundWindow(), Api.WM_COMMAND, (uint)this.Handle, (int)this.Handle);
        }

        private void SetThumbLocation()
        {
            Point pos = PointToClient(Cursor.Position);

            if (Orientation() == Horz)
            {
                BTN_Thumb.Left = Math.Min(Math.Max(pos.X - BTN_Thumb.Width / 2, 0), BTN_Thumb.Parent.Width - BTN_Thumb.Width);

                int range = ClientRectangle.Width - BTN_Thumb.Width;
                double increment = (maximum - minimum) / range;
                value = (increment * BTN_Thumb.Left) + minimum;
            }
            else
            {
                BTN_Thumb.Top = Math.Min(Math.Max(pos.Y - BTN_Thumb.Height / 2, 0), BTN_Thumb.Parent.Height - BTN_Thumb.Height);

                int range = ClientRectangle.Height - BTN_Thumb.Height;
                double increment = (maximum - minimum) / range;
                value = (increment * BTN_Thumb.Top) + minimum;
            }
            Value = value;
            SetToolTip();

            SendNotification();
        }

        private void THUMB_MouseDown(object sender, MouseEventArgs e)
        {
            ThumbMoving = true;
        }

        private void THUMB_MouseMove(object sender, MouseEventArgs e)
        {
            if (ThumbMoving) SetThumbLocation();
        }

        private void TRACK_MouseDown(object sender, MouseEventArgs e)
        {
            ThumbMoving = true;
            SetThumbLocation();
        }

        private void THUMB_MouseUp(object sender, MouseEventArgs e)
        {
            ThumbMoving = false;
        }

        // Retrieve the control orientation
        private bool Orientation()
        {
            bool orientation = Vert;
            if (this.Width > this.Height) orientation = Horz;
            return orientation;
        }

        // Update tooltip message
        private void SetToolTip()
        {
            toolTip.SetToolTip(BTN_Thumb, ((int)value).ToString());
        }

        private void CreateThumbRegion()
        {
            // Save current NameSpace
            string WasNameSpace = SK.UseNameSpace;
            // Switch NameSpace to this module
            SK.UseNameSpace = this.GetType().Namespace;
            Bitmap bmp = SK.GetBitmapFromResource(BTN_Thumb.Name);
            // Restore the original NameSpace
            SK.UseNameSpace = WasNameSpace;

            if (bmp == null) return;// Bail out if bmp is null

            // Save current TransparencyColor mode
            bool WasUseTransparencyColorTopLeft = SK.UseTransparencyColorTopLeft;
            SK.UseTransparencyColorTopLeft = true;

            // Create the region
            GraphicsPath path = SK.CreateRegion(bmp);

            // Restore previous TransparencyColor mode
            SK.UseTransparencyColorTopLeft = WasUseTransparencyColorTopLeft;

            // Apply new region
            BTN_Thumb.Region = new Region(path);
            // Clean up
            bmp.Dispose();
            path.Dispose();
        }

        private void TRACK_Load(object sender, EventArgs e)
        {
            CreateThumbRegion();

            if (minimum == 0 && maximum == 0)
            {
                // Set default value
                value = 50;
                if (Orientation() == Horz)
                { minimum = 0; maximum = 100; }
                else
                { minimum = 100; maximum = 0; }
            }
            // FORM_Tooltip colors
            toolTip.BackColor = SK.TooltipBackColor;
            toolTip.ForeColor = SK.TooltipForeColor;
            SetToolTip();
        }

        public double Minimum
        {
            get
            {
                return (minimum);
            }
            set
            {
                double minimumBackup = minimum;
                minimum = value;
                ShowThumbPos();
            }
        }

        public double Maximum
        {
            get
            {
                return (maximum);
            }
            set
            {
                double maximumBackup = maximum;
                maximum = value;
                ShowThumbPos();
            }
        }

        public double Value
        {
            get
            {
                return (value);
            }
            set
            {
                double valueBackup = this.value;
                if (minimum > maximum)
                {
                    this.value = Math.Max(Math.Min(value, minimum), maximum);
                }
                else
                {
                    this.value = Math.Max(Math.Min(value, maximum), minimum);
                }
                SetToolTip();
                ShowThumbPos();
            }
        }

        private void ShowThumbPos()
        {
            if (Orientation() == Horz)
            {
                int range = ClientRectangle.Width - BTN_Thumb.Width;
                double increment = (maximum - minimum) / range;
                BTN_Thumb.Left = (int)((value - minimum) / increment);
            }
            else
            {
                int range = ClientRectangle.Height - BTN_Thumb.Height;
                double increment = (maximum - minimum) / range;
                BTN_Thumb.Top = (int)((value - minimum) / increment);
            }
        }

    }
}
