using System;
using System.ComponentModel;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;

namespace Mix.Tool
{
    /// <summary>
    /// カラーピッカークラス
    /// </summary>
    [ToolboxItem(true)]
    public class ColorPicker : System.Windows.Forms.Control
    {
        #region Private constant

        private const int MARGIN = 2;
        private const int MARGIN2 = MARGIN * 2;

        private const int MIN_SC_HEIGHT = 16;

        #endregion

        private class ScrollController
        {
            public const int MIN_VALUE = 0;
            public const int MAX_VALUE = 255;
            public const float MAX_VALUE_F = 255.0f;

            private const int MIN_HEIGHT = 17;

            private const int ALLOW_WIDTH = 17;
            private const int ALLOW_WIDTH_X2 = ALLOW_WIDTH * 2;
            private const int THUMB_WIDTH = 20;

            private System.Windows.Forms.Control parent = null;

            private int _value = 0;
            private float stepRatio = 1.0f;

            private bool visible = true;
            private Rectangle trackRect = Rectangle.Empty;
            private Rectangle allowRectL = Rectangle.Empty;
            private Rectangle allowRectR = Rectangle.Empty;
            private Rectangle thumbRect = Rectangle.Empty;

            private bool movingThumb = false;
            private Point startPos = Point.Empty;
            private int startOffset = 0;

            private System.Windows.Forms.VisualStyles.ScrollBarArrowButtonState allowStateL = System.Windows.Forms.VisualStyles.ScrollBarArrowButtonState.LeftNormal;
            private System.Windows.Forms.VisualStyles.ScrollBarArrowButtonState allowStateR = System.Windows.Forms.VisualStyles.ScrollBarArrowButtonState.RightNormal;
            private System.Windows.Forms.VisualStyles.ScrollBarState thumbState = System.Windows.Forms.VisualStyles.ScrollBarState.Normal;

            public Point Location
            {
                get { return this.trackRect.Location; }
                set
                {
                    this.trackRect.Location = value;
                    this.UpdateLayout();
                    this.UpdateThumbFromValue();
                }
            }

            public Size Size
            {
                get { return this.trackRect.Size; }
                set
                {
                    if (value.Height >= MIN_HEIGHT)
                    {
                        this.trackRect.Size = value;
                    }
                    else
                    {
                        this.trackRect.Size = new Size( value.Width, MIN_HEIGHT);
                    }

                    this.UpdateLayout();
                    this.UpdateThumbFromValue();
                }
            }

            public bool Visible
            {
                get { return this.visible; }
                set { this.visible = value; }
            }

            public int Value
            {
                get { return this._value; }
                set
                {
                    this._value = (value <= MAX_VALUE) ? value : MAX_VALUE;

                    this.UpdateThumbFromValue();
                    this.parent.Invalidate(this.trackRect);

                    this.NotifyValueChanged();
                }
            }

            public event System.EventHandler ValueChanged = null;

            public ScrollController(System.Windows.Forms.Control _parent)
            {
                if (_parent == null)
                {
                    throw new System.ArgumentNullException("_parent");
                }

                this.parent = _parent;

                this.UpdateLayout();

                this.parent.MouseDown += new MouseEventHandler(parent_MouseDown);
                this.parent.MouseUp += new MouseEventHandler(parent_MouseUp);
                this.parent.MouseMove += new MouseEventHandler(parent_MouseMove);
                this.parent.Paint += new PaintEventHandler(parent_Paint);
            }

            private void parent_MouseDown(object sender, MouseEventArgs e)
            {
                if (this.Visible == false)
                {
                    return;
                }

                if (this.allowRectL.Contains(e.Location) == true)
                {
                    if (this._value > 0)
                    {
                        this._value--;
                        this.allowStateL = System.Windows.Forms.VisualStyles.ScrollBarArrowButtonState.LeftPressed;

                        this.UpdateThumbFromValue();
                        this.NotifyValueChanged();

                        this.parent.Invalidate(this.trackRect);
                    }
                }
                else if (this.allowRectR.Contains(e.Location) == true)
                {
                    if (this._value < MAX_VALUE)
                    {
                        this._value++;
                        this.allowStateR = System.Windows.Forms.VisualStyles.ScrollBarArrowButtonState.RightPressed;

                        this.UpdateThumbFromValue();
                        this.NotifyValueChanged();

                        this.parent.Invalidate(this.trackRect);
                    }
                }
                else if (this.thumbRect.Contains(e.Location) == true)
                {
                    this.movingThumb = true;
                    this.startPos = new Point(e.Location.X, e.Location.Y);
                    this.startOffset = this.thumbRect.X - e.Location.X;

                    this.parent.Invalidate(this.trackRect);
                }
            }

            private void parent_MouseUp(object sender, MouseEventArgs e)
            {
                this.movingThumb = false;
            }

            private void parent_MouseMove(object sender, MouseEventArgs e)
            {
                if (this.Visible == false)
                {
                    return;
                }

                bool invalidate = false;

                System.Windows.Forms.VisualStyles.ScrollBarArrowButtonState nextAllowStateL;
                System.Windows.Forms.VisualStyles.ScrollBarArrowButtonState nextAllowStateR;
                System.Windows.Forms.VisualStyles.ScrollBarState nextThumbState;

                ////////////////////////////////////////////////////////////////////////////////////////////////////

                // Allow ( Left )
                if ((this.movingThumb == false) && (this.allowRectL.Contains(e.Location) == true))
                {
                    if (e.Button != MouseButtons.Left)
                    {
                        nextAllowStateL = System.Windows.Forms.VisualStyles.ScrollBarArrowButtonState.LeftHot;
                    }
                    else
                    {
                        nextAllowStateL = this.allowStateL;
                    }
                }
                else
                {
                    nextAllowStateL = System.Windows.Forms.VisualStyles.ScrollBarArrowButtonState.LeftNormal;
                }

                // Allow ( Right )
                if ((this.movingThumb == false) && (this.allowRectR.Contains(e.Location) == true))
                {
                    if (e.Button != MouseButtons.Left)
                    {
                        nextAllowStateR = System.Windows.Forms.VisualStyles.ScrollBarArrowButtonState.RightHot;
                    }
                    else
                    {
                        nextAllowStateR = this.allowStateR;
                    }
                }
                else
                {
                    nextAllowStateR = System.Windows.Forms.VisualStyles.ScrollBarArrowButtonState.RightNormal;
                }

                // Thumb
                if (this.thumbRect.Contains(e.Location) == true)
                {
                    if (e.Button == MouseButtons.Left)
                    {
                        nextThumbState = System.Windows.Forms.VisualStyles.ScrollBarState.Pressed;
                    }
                    else
                    {
                        nextThumbState = System.Windows.Forms.VisualStyles.ScrollBarState.Hot;
                    }
                }
                else
                {
                    nextThumbState = System.Windows.Forms.VisualStyles.ScrollBarState.Normal;
                }

                ////////////////////////////////////////////////////////////////////////////////////////////////////

                if (this.allowStateL != nextAllowStateL)
                {
                    this.allowStateL = nextAllowStateL;
                    invalidate = true;
                }

                if (this.allowStateR != nextAllowStateR)
                {
                    this.allowStateR = nextAllowStateR;
                    invalidate = true;
                }

                if (this.thumbState != nextThumbState)
                {
                    this.thumbState = nextThumbState;
                    invalidate = true;
                }

                ////////////////////////////////////////////////////////////////////////////////////////////////////

                if (this.movingThumb == true)
                {
                    int nextValue;

                    this.thumbRect.X = this.startPos.X + (e.Location.X - this.startPos.X) + this.startOffset;

                    if (this.thumbRect.X < this.allowRectL.Right)
                    {
                        this.thumbRect.X = this.allowRectL.Right;
                    }
                    else if (this.thumbRect.Right > this.allowRectR.X)
                    {
                        this.thumbRect.X = this.allowRectR.X - this.thumbRect.Width;
                    }

                    nextValue = Convert.ToByte((float)Convert.ToDouble(this.thumbRect.X - this.allowRectL.Right) * this.stepRatio);
                    if (this._value != nextValue)
                    {
                        this._value = nextValue;
                        this.NotifyValueChanged();
                    }

                    invalidate = true;
                }

                if (invalidate == true)
                {
                    this.parent.Invalidate(this.trackRect);
                }
            }

            private void parent_Paint(object sender, PaintEventArgs e)
            {
                if (this.Visible == false)
                {
                    return;
                }

                ScrollBarRenderer.DrawLeftHorizontalTrack(e.Graphics, this.trackRect, System.Windows.Forms.VisualStyles.ScrollBarState.Normal);

                ScrollBarRenderer.DrawArrowButton(e.Graphics, this.allowRectL, this.allowStateL);
                ScrollBarRenderer.DrawArrowButton(e.Graphics, this.allowRectR, this.allowStateR);

                ScrollBarRenderer.DrawHorizontalThumb(e.Graphics, this.thumbRect, this.thumbState);
                ScrollBarRenderer.DrawHorizontalThumbGrip(e.Graphics, this.thumbRect, this.thumbState);
            }

            private void UpdateThumbFromValue()
            {
                this.thumbRect.X = this.allowRectL.Right + Convert.ToInt32((float)Convert.ToDouble(this._value) / this.stepRatio);
            }

            private void UpdateLayout()
            {
                int allowWidth = ( ALLOW_WIDTH_X2 >= this.trackRect.Width )? this.trackRect.Width / 2 : ALLOW_WIDTH;
                int length = this.trackRect.Width - allowWidth * 2;
                int thumbWidth;

                if (length > MAX_VALUE)
                {
                    thumbWidth = length - MAX_VALUE;
                    this.stepRatio = 1.0f;
                }
                else
                {
                    thumbWidth = THUMB_WIDTH;

                    if (length > 0)
                    {
                        this.stepRatio = MAX_VALUE_F / (float)Convert.ToDouble(length - thumbWidth);
                    }
                    else
                    {
                        this.stepRatio = 1.0f;
                    }
                }

                this.allowRectL = new Rectangle(this.trackRect.X, this.trackRect.Y, allowWidth, this.trackRect.Height);
                this.allowRectR = new Rectangle(this.trackRect.Right - allowWidth, this.trackRect.Y, allowWidth, this.trackRect.Height);
                this.thumbRect = new Rectangle(this.allowRectL.Right, this.trackRect.Y, thumbWidth, this.trackRect.Height);
            }

            private void NotifyValueChanged()
            {
                if (this.ValueChanged != null)
                {
                    this.ValueChanged.Invoke(this, new EventArgs());
                }
            }
        };

        #region Private value

        private Color color = Color.White;
        private Rectangle colorRect = new Rectangle();
        private Rectangle colorRectE = new Rectangle();
        private Size defSize = new Size();
        private Size editSize = new Size();
        private Point[] opPoints = new Point[4];
        private Point[] trPoints = new Point[4];

        private ScrollController redScrollBar = null;
        private ScrollController greenScrollBar = null;
        private ScrollController blueScrollBar = null;
        private ScrollController alphaScrollBar = null;

        private TextBox redTextBox = new TextBox();
        private TextBox greenTextBox = new TextBox();
        private TextBox blueTextBox = new TextBox();
        private TextBox alphaTextBox = new TextBox();

        private Point redTextPos = new Point();
        private Point greenTextPos = new Point();
        private Point blueTextPos = new Point();
        private Point alphaTextPos = new Point();

        private bool mouseEntered = false;
        private bool editingColor = false;

        private bool alphaEnabled = false;
        private bool alphaReflection = false;

        #endregion

        #region Public property

        /// <summary>
        /// 色の取得、または設定
        /// </summary>
        [Category("表示")]
        [Description("編集する色を指定します。")]
        public Color EditColor
        {
            get { return this.color; }
            set
            {
                Color temp = value;

                this.redScrollBar.Value = temp.R;
                this.greenScrollBar.Value = temp.G;
                this.blueScrollBar.Value = temp.B;
                this.alphaScrollBar.Value = temp.A;
            }
        }

        /// <summary>
        /// 不透明度を編集できるようにするかどうかの取得、または設定
        /// </summary>
        [Category("表示")]
        [Description("不透明度を編集できるようにするかどうかを指定します。")]
        public bool EditAlphaEnabled
        {
            get { return this.alphaEnabled; }
            set
            {
                this.alphaEnabled = value;
                this.Control_Layout();
            }
        }

        /// <summary>
        /// 不透明度を反映させるかどうかの取得、または設定
        /// </summary>
        [Category("表示")]
        [Description("不透明度を反映するかどうかを指定します。")]
        public bool EditAlphaReflection
        {
            get { return this.alphaReflection; }
            set
            {
                this.alphaReflection = value;
                this.Invalidate();
            }
        }

        /// <summary>
        /// 色が変更された際のイベント
        /// </summary>
        [Browsable(true)]
        [EditorBrowsable(EditorBrowsableState.Always)]
        [Description("色が変更された際に発生するイベントです。")]
        public event EventHandler ChangedEditColor;

        #endregion

        #region Public method

        public ColorPicker()
        {
            this.MouseLeave += new EventHandler(this.Control_MouseLeave);

            this.redScrollBar = new ScrollController(this);
            this.redScrollBar.Value = this.color.R;
            this.redScrollBar.ValueChanged += new EventHandler(this.ScrollBar_ValueChanged);

            this.greenScrollBar = new ScrollController(this);
            this.greenScrollBar.Value = this.color.G;
            this.greenScrollBar.ValueChanged += new EventHandler(this.ScrollBar_ValueChanged);

            this.blueScrollBar = new ScrollController(this);
            this.blueScrollBar.Value = this.color.B;
            this.blueScrollBar.ValueChanged += new EventHandler(this.ScrollBar_ValueChanged);

            this.alphaScrollBar = new ScrollController(this);
            this.alphaScrollBar.Value = this.color.A;
            this.alphaScrollBar.ValueChanged += new EventHandler(this.ScrollBar_ValueChanged);

            this.redTextBox.Text = this.redScrollBar.Value.ToString();
            this.redTextBox.TextAlign = HorizontalAlignment.Center;
            this.redTextBox.MouseLeave += new EventHandler(this.Control_MouseLeave);
            this.redTextBox.TextChanged += new EventHandler(this.TextBox_TextChanged);

            this.greenTextBox.Text = this.greenScrollBar.Value.ToString();
            this.greenTextBox.TextAlign = HorizontalAlignment.Center;
            this.greenTextBox.MouseLeave += new EventHandler(this.Control_MouseLeave);
            this.greenTextBox.TextChanged += new EventHandler(this.TextBox_TextChanged);

            this.blueTextBox.Text = this.blueScrollBar.Value.ToString();
            this.blueTextBox.TextAlign = HorizontalAlignment.Center;
            this.blueTextBox.MouseLeave += new EventHandler(this.Control_MouseLeave);
            this.blueTextBox.TextChanged += new EventHandler(this.TextBox_TextChanged);

            this.alphaTextBox.Text = this.alphaScrollBar.Value.ToString();
            this.alphaTextBox.TextAlign = HorizontalAlignment.Center;
            this.alphaTextBox.MouseLeave += new EventHandler(this.Control_MouseLeave);
            this.alphaTextBox.TextChanged += new EventHandler(this.TextBox_TextChanged);
        }

        #endregion

        #region Protected method

        protected override void OnCreateControl()
        {
            this.DoubleBuffered = true;

            this.Control_Enabled(false);
            this.Control_Layout();

            this.Controls.Add(this.redTextBox);
            this.Controls.Add(this.greenTextBox);
            this.Controls.Add(this.blueTextBox);
            this.Controls.Add(this.alphaTextBox);

            base.OnCreateControl();
        }

        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            base.OnPaint(e);

            if ((this.alphaEnabled == true) &&
                (this.alphaReflection == true))
            {
                RectangleF oldClipRect = e.Graphics.ClipBounds;
                Bitmap tileImage = Properties.Resources.Tile;
                Size tileSize = tileImage.Size;
                Point tilePoint = new Point();

                int tx = colorRect.Width / tileSize.Width + 1;
                int ty = colorRect.Height / tileSize.Height + 1;

                // タイル

                if (mouseEntered == true)
                {
                    e.Graphics.SetClip(colorRectE);
                }
                else
                {
                    e.Graphics.SetClip(colorRect);
                }

                for (int x = 0; x < tx; x++)
                {
                    tilePoint.X = tileSize.Width * x;

                    for (int y = 0; y < ty; y++)
                    {
                        tilePoint.Y = tileSize.Height * y;

                        e.Graphics.DrawImage(tileImage, tilePoint);
                    }
                }

                e.Graphics.SetClip(oldClipRect);

                // 不透明の描画

                using (Brush colorBrush = new SolidBrush(Color.FromArgb(255, this.color.R, this.color.G, this.color.B)))
                {
                    e.Graphics.FillPolygon(colorBrush, this.opPoints);
                }

                // 半透明の描画

                using (Brush colorBrush = new SolidBrush(Color.FromArgb(this.color.A, this.color.R, this.color.G, this.color.B)))
                {
                    e.Graphics.FillPolygon(colorBrush, this.trPoints);
                }
            }
            else
            {
                // 不透明の描画

                using (Brush colorBrush = new SolidBrush(Color.FromArgb(255, this.color.R, this.color.G, this.color.B)))
                {
                    if (mouseEntered == true)
                    {
                        e.Graphics.FillRectangle(colorBrush, colorRectE);
                    }
                    else
                    {
                        e.Graphics.FillRectangle(colorBrush, colorRect);
                    }
                }
            }

            // 枠

            if (mouseEntered == true)
            {
                using ( Brush frameBrush = new SolidBrush( SystemColors.ControlDark ) )
                {
                    using (Pen framePen = new Pen(frameBrush))
                    {
                        e.Graphics.DrawRectangle(framePen, this.colorRectE);
                    }
                }
            }

            // 色の文字

            using (Brush textBrush = new SolidBrush(SystemColors.ControlText))
            {
                e.Graphics.DrawString("R", this.Font, textBrush, this.redTextPos);
                e.Graphics.DrawString("G", this.Font, textBrush, this.greenTextPos);
                e.Graphics.DrawString("B", this.Font, textBrush, this.blueTextPos);
                e.Graphics.DrawString("A", this.Font, textBrush, this.alphaTextPos);
            }
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            this.mouseEntered = true;

            this.Invalidate();

            base.OnMouseEnter(e);
        }

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

            this.BringToFront();

            this.Control_Enabled(true);

            this.editingColor = true;
            this.Size = this.editSize;
            this.Invalidate();
        }

        protected override void OnClientSizeChanged(EventArgs e)
        {
            if (this.editingColor == false)
            {
                this.Control_Layout();
            }

            base.OnClientSizeChanged(e);
        }

        protected override void OnLostFocus(EventArgs e)
        {
            if (this.mouseEntered == true)
            {
                this.Control_Close();
            }

            base.OnLostFocus(e);
        }

        #endregion

        #region Private method

        private void ScrollBar_ValueChanged(object sender, EventArgs e)
        {
            this.UpdateRGBA();

            if (sender == this.redScrollBar)
            {
                this.redTextBox.Text = this.color.R.ToString();
            }
            else if (sender == this.greenScrollBar)
            {
                this.greenTextBox.Text = this.color.G.ToString();
            }
            else if (sender == this.blueScrollBar)
            {
                this.blueTextBox.Text = this.color.B.ToString();
            }
            else if (sender == this.alphaScrollBar)
            {
                this.alphaTextBox.Text = this.color.A.ToString();
            }

            this.Invalidate(this.colorRect);
        }

        private void TextBox_TextChanged(object sender, EventArgs e)
        {
            if (sender == this.redTextBox)
            {
                CheckInputChar(this.redTextBox, this.redScrollBar);
            }
            else if (sender == this.greenTextBox)
            {
                CheckInputChar(this.greenTextBox, this.greenScrollBar);
            }
            else if (sender == this.blueTextBox)
            {
                CheckInputChar(this.blueTextBox, this.blueScrollBar);
            }
            else if (sender == this.alphaTextBox)
            {
                CheckInputChar(this.alphaTextBox, this.alphaScrollBar);
            }

            this.UpdateRGBA();

            this.Invalidate(this.colorRect);
        }

        private void Control_MouseLeave(object sender, EventArgs e)
        {
            Point mousePos = this.PointToClient(Control.MousePosition);

            if ((mousePos.X < 0) ||
                (mousePos.Y < 0) ||
                (mousePos.X >= this.Width) ||
                (mousePos.Y >= this.Height))
            {
                this.Control_Close();
            }
        }

        private void Control_Enabled(bool state)
        {
            this.greenTextBox.Enabled = state;
            this.blueTextBox.Enabled = state;
            this.alphaTextBox.Enabled = state;
        }

        private void Control_Close()
        {
            this.mouseEntered = false;

            if (this.editingColor == true)
            {
                this.Size = defSize;
                this.editingColor = false;
            }

            this.Control_Enabled(false);

            this.Invalidate();
        }

        private void Control_Layout()
        {
            int offsetX;
            int scOffsetX;
            int scOffsetY;
            int tOffsetY;
            int tbOffsetX;
            int tWidth;
            int tbWidth;
            int scHeight;
            int scWidth;
            int intervalY;
            int editHeight;

            offsetX = MARGIN;
            scOffsetY = this.Height + MARGIN;

            tWidth = this.Font.Height;

            tbWidth = this.Font.Height * 3;
            tbOffsetX = this.Width - tbWidth - MARGIN;

            scOffsetX = offsetX + tWidth + MARGIN;
            scWidth = this.Width - scOffsetX - MARGIN2 - tbWidth;
            scHeight = (MIN_SC_HEIGHT > this.Font.Height) ? MIN_SC_HEIGHT : this.Font.Height;

            tOffsetY = scOffsetY + (scHeight - this.Font.Height) / 2;

            intervalY = scHeight + MARGIN;

            if (this.alphaEnabled == false)
            {
                editHeight = scHeight * 3 + MARGIN * 6;
            }
            else
            {
                editHeight = scHeight * 4 + MARGIN * 7;
            }

            //R(レッド)のテキスト表示位置
            this.redTextPos.X = offsetX;
            this.redTextPos.Y = tOffsetY;

            //G(グリーン)のテキスト表示位置
            this.greenTextPos.X = offsetX;
            this.greenTextPos.Y = tOffsetY + intervalY;

            //B(ブルー)のテキスト表示位置
            this.blueTextPos.X = offsetX;
            this.blueTextPos.Y = tOffsetY + intervalY + intervalY;

            //A(アルファ)のテキスト表示位置
            this.alphaTextPos.X = offsetX;
            this.alphaTextPos.Y = tOffsetY + intervalY + intervalY + intervalY;

            //カラーボックスの矩形
            this.colorRect.X = 0;
            this.colorRect.Y = 0;
            this.colorRect.Width = this.Width;
            this.colorRect.Height = this.Height;

            //マウスカーソルがカラーボックス内に入ってる際の矩形
            this.colorRectE.X = 0;
            this.colorRectE.Y = 0;
            this.colorRectE.Width = this.Width - 1;
            this.colorRectE.Height = this.Height - 1;

            //デフォルトのサイズ
            this.defSize.Width = this.Width;
            this.defSize.Height = this.Height;

            //編集中のサイズ
            this.editSize.Width = this.Width;
            this.editSize.Height = this.Height + editHeight;

            //半透明を反映する際のポリゴン
            if (this.Height < this.Width)
            {
                int gap = this.Height / 4;

                this.opPoints[0].X = colorRect.X;
                this.opPoints[0].Y = colorRect.Y;
                this.opPoints[1].X = colorRect.X + colorRect.Width / 2 + gap;
                this.opPoints[1].Y = colorRect.Y;
                this.opPoints[2].X = colorRect.X + colorRect.Width / 2 - gap;
                this.opPoints[2].Y = colorRect.Bottom;
                this.opPoints[3].X = colorRect.X;
                this.opPoints[3].Y = colorRect.Bottom;

                this.trPoints[0].X = colorRect.X + colorRect.Width / 2 + gap;
                this.trPoints[0].Y = colorRect.Y;
                this.trPoints[1].X = colorRect.Right;
                this.trPoints[1].Y = colorRect.Y;
                this.trPoints[2].X = colorRect.Right;
                this.trPoints[2].Y = colorRect.Bottom;
                this.trPoints[3].X = colorRect.X + colorRect.Width / 2 - gap;
                this.trPoints[3].Y = colorRect.Bottom;
            }
            else
            {
                int gap = this.Width / 4;

                this.opPoints[0].X = colorRect.X;
                this.opPoints[0].Y = colorRect.Y;
                this.opPoints[1].X = colorRect.Right;
                this.opPoints[1].Y = colorRect.Y;
                this.opPoints[2].X = colorRect.Right;
                this.opPoints[2].Y = colorRect.Y + colorRect.Height / 2 - gap;
                this.opPoints[3].X = colorRect.X;
                this.opPoints[3].Y = colorRect.Y + colorRect.Height / 2 + gap;

                this.trPoints[0].X = colorRect.X;
                this.trPoints[0].Y = colorRect.Y + colorRect.Height / 2 + gap;
                this.trPoints[1].X = colorRect.Right;
                this.trPoints[1].Y = colorRect.Y + colorRect.Height / 2 - gap;
                this.trPoints[2].X = colorRect.Right;
                this.trPoints[2].Y = colorRect.Bottom;
                this.trPoints[3].X = colorRect.X;
                this.trPoints[3].Y = colorRect.Bottom;
            }

            //レッドスクロールバー
            this.redScrollBar.Location = new Point(scOffsetX, scOffsetY);
            this.redScrollBar.Size = new Size(scWidth, scHeight);

            //グリーンスクロールバー
            this.greenScrollBar.Location = new Point(scOffsetX, scOffsetY + intervalY);
            this.greenScrollBar.Size = new Size(scWidth, scHeight);

            //ブルースクロールバー
            this.blueScrollBar.Location = new Point(scOffsetX, scOffsetY + intervalY + intervalY);
            this.blueScrollBar.Size = new Size(scWidth, scHeight);

            //アルファスクロールバー
            this.alphaScrollBar.Location = new Point(scOffsetX, scOffsetY + intervalY + intervalY + intervalY);
            this.alphaScrollBar.Size = new Size(scWidth, scHeight);
            this.alphaScrollBar.Visible = this.alphaEnabled;

            //レッドテキストボックス
            this.redTextBox.Location = new Point(tbOffsetX, scOffsetY);
            this.redTextBox.Size = new Size(tbWidth, scHeight);

            //グリーンテキストボックス
            this.greenTextBox.Location = new Point(tbOffsetX, scOffsetY + intervalY);
            this.greenTextBox.Size = new Size(tbWidth, scHeight);

            //ブルーテキストボックス
            this.blueTextBox.Location = new Point(tbOffsetX, scOffsetY + intervalY + intervalY);
            this.blueTextBox.Size = new Size(tbWidth, scHeight);

            //アルファテキストボックス
            this.alphaTextBox.Location = new Point(tbOffsetX, scOffsetY + intervalY + intervalY + intervalY);
            this.alphaTextBox.Size = new Size(tbWidth, scHeight);
            this.alphaTextBox.Visible = this.alphaEnabled;
        }

        private void UpdateRGBA()
        {
            int red = this.redScrollBar.Value;
            int green = this.greenScrollBar.Value;
            int blue = this.blueScrollBar.Value;
            int alpha = this.alphaScrollBar.Value;

            this.color = Color.FromArgb(alpha, red, green, blue);

            if (this.ChangedEditColor != null)
            {
                this.ChangedEditColor(this, new EventArgs());
            }
        }

        private static void CheckInputChar(TextBox textBox, ScrollController scrollBar)
        {
            int value;

            if (int.TryParse(textBox.Text, out value) == true)
            {
                if (value < 0)
                {
                    value = 0;
                }
                else if (value > ScrollController.MAX_VALUE)
                {
                    value = ScrollController.MAX_VALUE;
                }
            }
            else
            {
                if (textBox.Text.Length == 0)
                {
                    value = 0;
                }
                else
                {
                    value = scrollBar.Value;
                }
            }

            scrollBar.Value = value;
            textBox.Text = value.ToString();
        }

        private static int Color_FloatToInt(float value)
        {
            int ret = Convert.ToInt32(value * 255);

            if (ScrollController.MIN_VALUE > ret)
            {
                ret = ScrollController.MIN_VALUE;
            }
            else if (ScrollController.MAX_VALUE < ret)
            {
                ret = ScrollController.MAX_VALUE;
            }

            return ret;
        }

        private static float Color_IntToFloat(int value)
        {
            float ret = (float)Convert.ToDouble(value) / ScrollController.MAX_VALUE_F;

            if (ret < 0.0f)
            {
                ret = 0.0f;
            }
            else if (ret > 1.0f)
            {
                ret = 1.0f;
            }

            return ret;
        }

        #endregion
    }
}
