/* 
 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the
 * License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using MySQL.Utilities;
using System.ComponentModel;

namespace MySQL.Controls
{
  public class HeaderPanel : System.Windows.Forms.Panel
  {
    /// <summary> 
	  /// Required designer variable.
	  /// </summary>
	  private System.ComponentModel.Container components = null;

    private Padding headerPadding = new Padding(5, 0, 0, 0);
    private Color headerColor = Color.FromArgb(255, 73, 97, 132);

    #region Construction and destruction

    public HeaderPanel()
	  {
		  // This call is required by the Windows.Forms Form Designer.
		  InitializeComponent();

		  // Some special styles for the control.
		  SetStyle(ControlStyles.UserPaint, true);
		  SetStyle(ControlStyles.AllPaintingInWmPaint, true);
		  SetStyle(ControlStyles.DoubleBuffer, true);
		  SetStyle(ControlStyles.SupportsTransparentBackColor, true);
		  SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
      UpdateStyles();

      Padding = new Padding(0, 24, 0, 0);
      BackColor = Color.FromArgb(0xff, 0x49, 0x61, 0x84);
      ForeColor = Color.White;
    }

    #endregion

    #region Drawing the control and its parts.

    override protected void OnPaint(PaintEventArgs e)
    {
      base.OnPaint(e);
      DrawControl(e.Graphics);
    }

    override protected void OnPaintBackground(PaintEventArgs e)
    {
      base.OnPaintBackground(e);

      using (GraphicsPath path = new GraphicsPath())
      {
        float cornerSize = 6;

        RectangleF bounds = ClientRectangle;
        bounds.X -= 0.5f;
        bounds.Y -= 0.5f;
        bounds.Height = Padding.Top;
        path.AddLine(bounds.Right, bounds.Bottom, bounds.Left, bounds.Bottom);
        path.AddLine(bounds.Left, bounds.Bottom, bounds.Left, bounds.Top - cornerSize);
        path.AddArc(bounds.Left, bounds.Top, cornerSize, cornerSize, 180, 90);
        path.AddLine(bounds.Left + cornerSize, bounds.Top, bounds.Right - cornerSize, bounds.Top);
        path.AddArc(bounds.Right - cornerSize, bounds.Top, cornerSize, cornerSize, -90, 90);
        path.AddLine(bounds.Right, bounds.Top + cornerSize, bounds.Right, bounds.Bottom);

        e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
        if (ControlUtilities.IsHierarchyFocused(this))
        {
          ColorBlend gradientTupels = new ColorBlend();
          gradientTupels.Colors = new Color[] {
                Color.FromArgb(0xff, 0xff, 0xe9, 0xb6),
                Color.FromArgb(0xff, 0xff, 0xe9, 0xb7),
                Color.FromArgb(0xff, 0xff, 0xf3, 0xd9),
                Color.FromArgb(0xff, 0xff, 0xfa, 0xf4)
              };

          gradientTupels.Positions = new float[] {
                0, 0.34f, 0.43f, 1
              };

          using (LinearGradientBrush gradientBrush = new LinearGradientBrush(
            new RectangleF(bounds.Left, bounds.Top, 1, bounds.Height),
            Color.Black, Color.White,
            LinearGradientMode.Vertical))
          {
            gradientBrush.InterpolationColors = gradientTupels;
            gradientBrush.ScaleTransform(-1, -1);

            e.Graphics.FillPath(gradientBrush, path);
          }
        }
        else
        {
          using (Brush brush = new SolidBrush(headerColor))
            e.Graphics.FillPath(brush, path);
        }
      }
    }

	  internal void DrawControl(Graphics g)
	  {
      using (StringFormat stringFormat = new StringFormat())
      {
        stringFormat.Alignment = StringAlignment.Near;
        stringFormat.LineAlignment = StringAlignment.Center;

        Brush brush;
        if (ControlUtilities.IsHierarchyFocused(this))
          brush = new SolidBrush(Color.Black);
        else
          brush = new SolidBrush(ForeColor);
        Rectangle bounds = ClientRectangle;
        bounds.Height = Padding.Top;
        bounds.X = headerPadding.Left;
        bounds.Y = headerPadding.Top;
        bounds.Width -= headerPadding.Horizontal;
        bounds.Height -= headerPadding.Vertical;
        g.DrawString(Text, Font, brush, bounds, stringFormat);
        brush.Dispose();
      }
    }

    #endregion

    #region Event handling

    protected override void OnEnter(EventArgs e)
    {
      base.OnEnter(e);
      Invalidate();
    }

    protected override void OnLeave(EventArgs e)
    {
      base.OnLeave(e);
      Invalidate();
    }

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

      Form container = Application.OpenForms[0].TopLevelControl as Form;
      if (container != null)
      {
        container.Deactivate += new EventHandler(ActivationChanged);
        container.Activated += new EventHandler(ActivationChanged);
      }
    }

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

      // Unregister our activation listener from the application's main form.
      // This assumes the main form hasn't changed in the meantime (which should be the case in 99.99% of all cases).
      if (Application.OpenForms.Count > 0)
      {
        Form container = Application.OpenForms[0].TopLevelControl as Form;
        if (container != null)
        {
          container.Deactivate -= ActivationChanged;
          container.Activated -= ActivationChanged;
        }
      }
    }

    private void ActivationChanged(object sender, EventArgs e)
    {
      Invalidate();
    }

    #endregion

    #region Component Designer generated code

    /// <summary>
	  /// Required method for Designer support - do not modify 
	  /// the contents of this method with the code editor.
	  /// </summary>
	  private void InitializeComponent()
	  {
		  components = new System.ComponentModel.Container();
	  }

	  #endregion

    #region Properties

    public Padding HeaderPadding
    {
      get { return headerPadding; }
      set
      {
        headerPadding = value;
        Invalidate();
      }
    }

    public Color HeaderColor
    {
      get { return headerColor; }
      set
      {
        if (headerColor != value)
        {
          headerColor = value;
          Invalidate();
        }
      }
    }

    [EditorBrowsable(EditorBrowsableState.Always)]
    [Bindable(true)]
    [Browsable(true)]
    public override string Text { get; set; }

    #endregion
  }
}
