//----------------------------------------------------------------------------
// ColorPickerControl.cs
//
// Contains ColorPickerControl.
//
// This is a part of the C1ReportDesigner package.
// Copyright (C) GrapeCity, Inc
// All rights reserved.
//
// This source code is intended as a supplement to the
// C1ReportDesigner control and related documentation 
// provided with the product.
// See these sources for detailed information regarding the
// C1ReportDesigner product.
//----------------------------------------------------------------------------
// uncomment this define to swith to ColorPickerOfficeForm
//#define OFFICE_COLOR_PICKER
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Reflection;

namespace C1.Design
{
    /// <summary>
    /// Represents the color picker control.
    /// </summary>
    internal partial class ColorPickerControl : ComboBox
    {
#if OFFICE_COLOR_PICKER
        private ColorPickerOfficeForm _colorPickerForm = null;
#else
        private ColorPickerForm _colorPickerForm = null;
#endif
        private Color _clr = Color.Transparent;
        private string _text = string.Empty;

        public ColorPickerControl()
        {
            this.DropDownStyle = ComboBoxStyle.DropDownList;
            this.DrawMode = DrawMode.OwnerDrawVariable;
            this.Items.Add(this.Text);
            this.SelectedIndex = 0;
        }

        protected override void OnMeasureItem(System.Windows.Forms.MeasureItemEventArgs e)
        {
            if (e.Index > -1)
            {
                string fontstring = this.Text;
                Graphics g = CreateGraphics();
                e.ItemHeight = (int)g.MeasureString(this.Text, this.Font).Height;
                e.ItemWidth = System.Math.Max((int)g.MeasureString(this.Text, this.Font).Width, this.Width);

            }
            base.OnMeasureItem(e);
        }

        protected override void OnDrawItem(System.Windows.Forms.DrawItemEventArgs e)
        {
            if (e.Index > -1 && (e.State & DrawItemState.ComboBoxEdit) != 0 )
            {
                SolidBrush backbrush = null;
                SolidBrush textbrush = null;
                    backbrush = new SolidBrush(SystemColors.Window);
                    textbrush = new SolidBrush(SystemColors.WindowText);

                e.Graphics.FillRectangle(backbrush,
                        e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);

                e.Graphics.DrawString(this.Text, this.Font, textbrush,
                        e.Bounds.X, e.Bounds.Y);

                int width = 1;
                if (this.Text.Length > 0)
                    width += (int)e.Graphics.MeasureString(this.Text, this.Font).Width+4;
                Brush b = new SolidBrush(this.Color);
                Rectangle r = e.Bounds;
                r.X += width;
                r.Width -= width;
                ControlPaint.DrawFocusRectangle(e.Graphics, r);
                r.Inflate(-1, -1);
                e.Graphics.FillRectangle(b, r);
                b.Dispose();

            }
            base.OnDrawItem(e);
        }

        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);
            if (this._colorPickerForm != null && _colorPickerForm.Visible)
            {
                this._colorPickerForm.Close();
            }
            else
            {
#if OFFICE_COLOR_PICKER
                this._colorPickerForm = new ColorPickerOfficeForm();
#else
                this._colorPickerForm = new ColorPickerForm();
#endif
                this._colorPickerForm.Color = this._clr;
                Rectangle r = this.ClientRectangle;
                r = this.Bounds;
                r = this.Parent.RectangleToScreen(r);
                this._colorPickerForm.Location = new Point(r.X, r.Y + r.Height);
                this._colorPickerForm.Width = r.Width;
                this._colorPickerForm.FormClosed += new FormClosedEventHandler(_colorPickerForm_FormClosed);
                this._colorPickerForm.Show();
            }
        }

        void _colorPickerForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            this._colorPickerForm.FormClosed -= new FormClosedEventHandler(_colorPickerForm_FormClosed);
            this.Color = _colorPickerForm.Color;
            this.OnDropDownClosed(EventArgs.Empty);
        }

        public Color Color
        {
            get { return this._clr; }
            set 
            { 
                _clr = value; 
                Invalidate(); 
            }
        }

        internal static Color[] GetConstants(Type enumType)
        {
            MethodAttributes attributes1 = MethodAttributes.Static | MethodAttributes.Public;
            PropertyInfo[] infoArray1 = enumType.GetProperties();
            List<Color> result = new List<Color>();
            for (int i = 0; i < infoArray1.Length; i++)
            {
                PropertyInfo info1 = infoArray1[i];
                if (info1.PropertyType == typeof(Color))
                {
                    MethodInfo info2 = info1.GetGetMethod();
                    if ((info2 != null) && ((info2.Attributes & attributes1) == attributes1))
                    {
                        object[] objArray1 = null;
                        result.Add((Color)info1.GetValue(null, objArray1));
                    }
                }
            }
            return result.ToArray();
        }

        #region Nested types
        internal class SystemColorComparer : IComparer<Color>
        {
            public static readonly SystemColorComparer Instance = new SystemColorComparer();

            public int Compare(Color x, Color y)
            {
                return string.Compare(x.Name, y.Name, false, CultureInfo.InvariantCulture);
            }
        }

        internal class ColorComparer : IComparer<Color>
        {
            public static readonly ColorComparer Instance = new ColorComparer();

            public int Compare(Color x, Color y)
            {
                byte a1 = x.A, a2 = y.A;
                float h1 = x.GetHue(), h2 = y.GetHue();
                float s1 = x.GetSaturation(), s2 = y.GetSaturation();
                float b1 = x.GetBrightness(), b2 = y.GetBrightness();

                h1 = (float)Math.Round(h1, 6, MidpointRounding.ToEven);
                h2 = (float)Math.Round(h2, 6, MidpointRounding.ToEven);
                s1 = (float)Math.Round(s1, 6, MidpointRounding.ToEven);
                s2 = (float)Math.Round(s2, 6, MidpointRounding.ToEven);
                b1 = (float)Math.Round(b1, 6, MidpointRounding.ToEven);
                b2 = (float)Math.Round(b2, 6, MidpointRounding.ToEven);

                int rv = 0;

                if (a1 < a2)
                    rv = -1;
                else if (a1 > a2)
                    rv = 1;
                else if (h1 < h2)
                    rv = -1;
                else if (h1 > h2)
                    rv = 1;
                else if (s1 < s2)
                    rv = -1;
                else if (s1 > s2)
                    rv = 1;
                else if (b1 < b2)
                    rv = -1;
                else if (b1 > b2)
                    rv = 1;

                return rv;
            }
        }
        #endregion
    }
}
