//------------------------------------------------------------------------------
// <copyright file=”*.cs” company=”EhLib Team”>
//     Copyright (c) 2017 Dmitry V. Bolshakov   
// </copyright>
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace EhLib
{
  [TypeConverter(typeof(ExpandableObjectConverter))]
  public class DataVertGridRowTitle : DataAxisGridBarTitle
  {
    #region Privates
    //private readonly CellBackFiller backFiller;
    #endregion privates

    public DataVertGridRowTitle(PropertyAxisBar propBar) : base(propBar)
    {
      //backFiller = new CellBackFiller(this);
    }

    #region design-time properties
    [DefaultValue(null)]
    public virtual ContextMenuStrip ContextMenuStrip { get; set; }
    #endregion

    #region public properties
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    [Browsable(false)]
    public DataVertGridRow Row
    {
      get { return (DataVertGridRow)base.PropBar; }
    }
    #endregion

    #region internal properties
    [Browsable(false)]
    public new DataVertGridEh Grid
    {
      get
      {
        return (DataVertGridEh)base.Grid;
      }

      protected internal set
      {
        base.Grid = value;
      }
    }
    #endregion

    #region methods

    //Other
    public virtual int CalcHeight()
    {
      Size sz;
      int th;

      sz = TextRenderer.MeasureText(EhLibUtils.DisplayGraphicsCash, "0", Font);
      th = sz.Height * 1;
      th = th + Padding.Top + Padding.Bottom;

      if (ImageBox.Visible)
      {
        int imageHeight = ImageBox.Size.Height + Padding.Top + Padding.Bottom;
        if (ImageBox.TextImageRelation == TextImageRelation.ImageBeforeText ||
            ImageBox.TextImageRelation == TextImageRelation.TextBeforeImage ||
            ImageBox.TextImageRelation == TextImageRelation.Overlay)
        {
          if (imageHeight > th)
            th = imageHeight;
        }
        else
        {
          th = th + imageHeight;
        }
      }

      return th;
    }

    public virtual string DefaultCaption()
    {
      return Row.DataPropertyName;
    }

    protected internal virtual void TitleFilterChanged()
    {
      Row.Grid.Invalidate();
    }

    //private Font DefaultFont()
    //{
    //  if (Row.Grid != null)
    //    return Row.Grid.TitleColumn.Font;
    //  else
    //    return null;
    //}

    //private HorizontalAlignment DefaultHorzAlign()
    //{
    //  return Row.Grid.TitleColumn.HorzAlign;
    //}

    //private VerticalAlignment DefaultVertAlign()
    //{
    //  return Row.Grid.TitleColumn.VertAlign;
    //}

    //private void FontChanged()
    //{
    //  if (Row.Grid != null)
    //    Row.Grid.UpdateBaseFixedBands();
    //}

    //private void HeightAutoExpandChanged()
    //{
    //  if (Row.Grid != null)
    //    Row.Grid.UpdateBaseFixedBands();
    //}

    protected internal override void PerformLayout()
    {
      //TODO ?
      //Grid.TitleCell.PerformLayout(this);
    }

    protected internal override void UpdateMetrics(Size cellSize)
    {
      //if (Grid != null)
      //  Grid.GetDrawStyle().GetInTitleFilterButtonMetrics(Grid, cellSize, FilterButtonMetrics);
    }
    #endregion Methods

  }

  public class DataVertGridTitleColumnCellMan : DataVertGridRowCellManager
  {

    #region fields
    #endregion fields

    public DataVertGridTitleColumnCellMan()
    {
    }

    #region properites
    [Browsable(false)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public new DataVertGridEh Grid
    {
      get { return (DataVertGridEh)base.Grid; }
      set { base.Grid = value; }
    }
    #endregion properites

    #region methods
    public override void AreaCellPosToGridCellPos(int areaColIndex, int areaRowIndex, out int gridColIndex, out int gridRowIndex)
    {
      gridColIndex = areaColIndex;
      gridRowIndex = areaRowIndex + Grid.FixedRowCount;
    }

    public override void GridCellPosToAreaCellPos(int gridColIndex, int gridRowIndex, out int areaColIndex, out int areaRowIndex)
    {
      areaColIndex = gridColIndex;
      areaRowIndex = gridRowIndex - Grid.FixedRowCount; 
    }

    public override string GetDisplayText(DataVertGridRow row, int dataColIndex)
    {
      return row.Title.Text;
    }

    protected internal virtual bool CanDrawWordBreak(DataGridTextWrapMode wrapMode, Graphics graphics,
      Rectangle paintRect, Font font)
    {
      if (wrapMode == DataGridTextWrapMode.Auto)
      {
        Size sz = TextRenderer.MeasureText(EhLibUtils.DisplayGraphicsCash, "0", font);
        int th = paintRect.Height; // - padding.Top - padding.Bottom;

        if (th >= sz.Height * 2)
          return true;
        else
          return false;
      }
      else if (wrapMode == DataGridTextWrapMode.WordWrap)
        return true;
      else
        return false;
    }

    protected internal override void OnPaintEmptyArea(BaseGridCellPaintEventArgs e)
    {
      OnPaint(e);
    }

    protected internal override void OnPaint(BaseGridCellPaintEventArgs e)
    {
      Region clientClip = null;
      bool clipped = false;
      Rectangle paintRect;

      DataVertGridTitleCellPaintParams paintParams = new DataVertGridTitleCellPaintParams
      {
        ColIndex = e.ColIndex,
        RowIndex = e.RowIndex,
        CellRect = e.CellRect,
        PaintState = e.State,
        DataColIndex = e.AreaColIndex,
        DataRowIndex = e.AreaRowIndex,
        PaintEventArgs = e
      };

      if (e.AreaRowIndex >= 0)
        paintParams.Row = Grid.VisibleRows[e.AreaRowIndex];
      else
        paintParams.Row = null;

      GetCellPaintParams(paintParams);

      //if ((state & BasePaintCellStates.Selected) != 0)
      //  paintParams.ForeColor = Grid.GetDrawStyle().GetFixedSelectedForeColor(Grid, paintParams.BackColor, paintParams.ForeColor);

      PaintBackground(e.Graphics, paintParams);

      PaintSurround(e.Graphics, paintParams);
      if (e.AreaColIndex >= 0)
        PaintForeground(e.Graphics, paintParams);

      paintRect = e.CellRect;
      if (clipped)
      {
        e.Graphics.Clip = clientClip;
        paintRect.Offset(new Point(-1, -1));
      }

      //TODO: Grid.DesignMode
      //if (Grid.DesignMode)
      //{
      //  IDesignerHost idh = (IDesignerHost)Grid.GetService(typeof(IDesignerHost));
      //  Debug.Assert(idh != null, "idh != null");
      //  var grd = idh.GetDesigner(Grid) as IDataGridDesigner;
      //  if (grd != null)
      //    grd.PaintCellDesignData(Grid, graphics, col, row, ref paintRect, state);
      //}

    }

    protected internal override void OnGetCellBorderParams(BaseGridCellBorderEventArgs e)
    {
      base.OnGetCellBorderParams(e);

      if (e.BorderType == GridCellBorderType.Right || e.BorderType == GridCellBorderType.Left)
      {
        GridLine gl = Grid.TitleBar.VertLine;
        e.Visible = gl.Visible;
        e.Color = gl.Color;
        e.Style = gl.Style;
        e.IsExtent = true;
      }
      else
      {
        GridLine gl = Grid.TitleBar.HorzLine;
        e.Visible = gl.Visible;
        e.Color = gl.Color;
        e.Style = gl.Style;
        e.IsExtent = true;
      }
    }

    protected internal virtual void GetCellPaintParams(DataVertGridTitleCellPaintParams paintParams)
    {
      if (paintParams.Row != null)
      {
        paintParams.AlignFlags = EhLibUtils.TranslateAlignmentToTextFormatFlags(paintParams.Row.Title.HorzAlign,
                                                                                paintParams.Row.Title.VertAlign);
        //aligntFlags = EhLibUtils.TranslateContentAlignmentToTextFormatFlags(Column.Title.TextAlign);
        paintParams.Padding = paintParams.Row.Title.Padding;
        paintParams.Font = paintParams.Row.Title.Font;
        paintParams.BackColor = paintParams.Row.Title.BackFiller.Color;
        paintParams.ForeColor = paintParams.Row.Title.ForeColor;
        paintParams.EndEllipsis = paintParams.Row.Title.EndEllipsis;
        //paintParams.TextOrientation = paintParams.Row.Title.TextOrientation;
      }
      else
      {
        paintParams.AlignFlags = TextFormatFlags.Left | TextFormatFlags.VerticalCenter;
        paintParams.Padding = Grid.TitleColumn.Padding;
        paintParams.Font = Grid.TitleColumn.Font;
        paintParams.BackColor = Grid.TitleColumn.BackFiller.Color;
        paintParams.ForeColor = Grid.TitleColumn.ForeColor;
        paintParams.EndEllipsis = Grid.TitleColumn.EndEllipsis;
        paintParams.TextOrientation = Orientation.Horizontal;
      }
      paintParams.ContentRect = paintParams.CellRect;
    }

    protected internal virtual void PaintBackground(Graphics graphics, DataVertGridTitleCellPaintParams paintParams)
    {
      BaseGridFillFixedCellEventArgs styledPaintArgs = new BaseGridFillFixedCellEventArgs
      {
        CellRect = paintParams.CellRect,
        Graphics = graphics,
        IsHot = this.IsHot(paintParams.DataColIndex, paintParams.DataRowIndex) && !Grid.DesignMode,
        IsPressed = false,
        IsSelected = (paintParams.PaintState & BasePaintCellStates.Selected) != 0,
        BackColor = paintParams.BackColor
      };

      if (paintParams.Row != null)
      {
        styledPaintArgs.FillStyle = paintParams.Row.Title.BackFiller.FillStyle;
        styledPaintArgs.InnerBorder = paintParams.Row.Title.BackFiller.InnerBorder;
        styledPaintArgs.FillColor = paintParams.Row.Title.BackFiller.Color;
        styledPaintArgs.SecondFillColor = paintParams.Row.Title.BackFiller.SecondColor;
      }
      else
      {
        styledPaintArgs.FillStyle = Grid.TitleColumn.BackFiller.FillStyle;
        styledPaintArgs.InnerBorder = Grid.TitleColumn.BackFiller.InnerBorder;
        styledPaintArgs.FillColor = Grid.TitleColumn.BackFiller.Color;
        styledPaintArgs.SecondFillColor = Grid.TitleColumn.BackFiller.SecondColor;
      }

      //Grid.GetDrawStyle().FillTitleCell(Grid, styledPaintArgs);
      EhLibDrawStyle.DefaultBaseGridDrawStyle.FillFixedCell(Grid, styledPaintArgs);

      paintParams.ContentRect = EhLibUtils.TrimPadding(paintParams.ContentRect, paintParams.Padding);
    }

    protected internal virtual void PaintSurround(Graphics gr, DataVertGridTitleCellPaintParams p)
    {
      if ((p.Row != null) && (p.Row.Title.ImageBox.Image != null))
      {
        Rectangle imageRect;
        Rectangle textRect;

        TextLayoutParams tlp = new TextLayoutParams()
        {
          Text = p.Row.Title.Text,
          Font = p.Row.Title.Font,
          HorzAlign = p.Row.Title.HorzAlign,
          VertAlign = p.Row.Title.VertAlign,
          WrapMode = Grid.TitleColumn.WrapMode
        };
        p.Row.Title.ImageBox.LayoutImageAndText(p.ContentRect, tlp, out imageRect, out textRect);

        CellImageBoxPaintEventArgs ibe = new CellImageBoxPaintEventArgs(p.Row.Title.ImageBox, gr, imageRect, p.PaintEventArgs);
        p.Row.Title.ImageBox.OnPaint(ibe);

        p.ContentRect = textRect;
      }
    }

    protected internal virtual void PaintForeground(Graphics graphics, DataVertGridTitleCellPaintParams p)
    {
      bool wordBreak;

      Rectangle textRect = EhLibUtils.TrimPadding(p.ContentRect, p.Row.Title.Padding);

      if (CanDrawWordBreak(Grid.TitleColumn.WrapMode, graphics, textRect, p.Font))
        wordBreak = true;
      else
        wordBreak = false;

      string text = GetDisplayText(p.DataColIndex, p.DataRowIndex);
      Grid.PaintingDrawText(graphics, text, p.Font, p.ContentRect, p.ForeColor,
          p.Row.Title.HorzAlign, p.Row.Title.VertAlign, wordBreak);
    }

    protected internal override void PrintCell(PrintServiceEventArgs e,
      Rectangle paintRect, int areaColIndex,
      int areaRowIndex,
      PrintServiceEventArgs printContext
        )
    {
      Font font = null;
      Rectangle textRect;
      DataVertGridRow gridRow = Grid.VisibleRows[areaRowIndex];
      Font drawFont = gridRow.Title.Font;
      TextFormatFlagsEh flags = 0;

      string text = GetDisplayText(areaColIndex, areaRowIndex);
      textRect = EhLibUtils.TrimPadding(paintRect, gridRow.Title.Padding);
      if (CanDrawWordBreak(Grid.TitleColumn.WrapMode, e.Graphics, textRect, drawFont))
        flags = flags | TextFormatFlagsEh.WordBreak;

      e.PrintText(text, drawFont, textRect, Color.Black, gridRow.Title.HorzAlign, gridRow.Title.VertAlign, flags);

      if (font != null)
        font.Dispose();
    }

    protected internal override void OnMouseCaptureCanceled()
    {
      //if (pressedColumTitleIndex >= 0 || filterButtonDownTitleIndex >= 0)
      //{
      //  pressedColumTitleIndex = -1;
      //  filterButtonDownTitleIndex = -1;
      //  //filterButtonDown = false;
      //  Grid.InvalidateGrid();
      //}
    }

    protected internal override void OnMouseDown(BaseGridCellMouseEventArgs e)
    {
      base.OnMouseDown(e);
    }

    protected internal override void OnMouseMove(BaseGridCellMouseEventArgs e)
    {
      base.OnMouseMove(e);
    }

    protected internal override void OnMouseUp(BaseGridCellMouseEventArgs e)
    {
      base.OnMouseUp(e);
    }

    protected internal override void OnMouseClick(BaseGridCellMouseEventArgs e)
    {
      base.OnMouseClick(e);
    }

    protected internal override BaseGridCellEnterEventArgs CreateCellEnterEventArgs(
      int colIndex, int rowIndex, int areaColIndex, int areaRowIndex, Rectangle cellRect, int leaveColIndex, int leaveRowIndex)
    {
      DataVertGridRow row;
      if (areaRowIndex < Grid.VisibleRows.Count)
        row = Grid.VisibleRows[areaRowIndex];
      else
        row = null;

      var de = new DataVertGridRowTitleCellMouseEventArgs(colIndex, rowIndex, areaColIndex, areaRowIndex, cellRect, leaveColIndex, leaveRowIndex, row.Title);
      return de;
    }

    protected internal override void OnMouseEnter(BaseGridCellEnterEventArgs e)
    {
      base.OnMouseEnter(e);

      var de = (DataVertGridRowTitleCellMouseEventArgs)e;

      string cellText = GetCellNonfitToolTipText(de);

      if (!string.IsNullOrEmpty(cellText))
      {
        Grid.ShowCellNonFitToolTip(cellText, e);
      }

    }

    protected internal override void OnMouseLeave(BaseGridCellLeaveEventArgs e)
    {
      base.OnMouseLeave(e);
      Grid.HideCellNonFitToolTip();
      Grid.HideCellHintToolTip();
    }

    protected override void OnMouseHover(BaseGridCellMouseEventArgs e)
    {
      DataVertGridRow row;
      if (e.AreaRowIndex < Grid.VisibleRows.Count)
        row = Grid.VisibleRows[e.AreaRowIndex];
      else
        row = null;

      if (!string.IsNullOrEmpty(row.Title.ToolTipText))
      {
        Grid.ShowCellHintTooltip(row.Title.ToolTipText, 0);
      }
    }

    private bool IsHot(int dataColIndex, int dataRowIndex)
    {
      return false;
    }

    public virtual string GetCellNonfitToolTipText(DataVertGridRowTitleCellMouseEventArgs e)
    {
      if (!Grid.TitleColumn.NonfitTooltips) return "";

      Size sf;
      Graphics g = EhLibUtils.DisplayGraphicsCash;
      string cellText = GetDisplayText(e.AreaColIndex, e.AreaRowIndex);
      Rectangle textRect = e.CellRect;

      textRect = EhLibUtils.TrimPadding(textRect, e.RowTitle.Padding);

      bool wordWrap = CanDrawWordBreak(Grid.TitleColumn.WrapMode, g, textRect, e.RowTitle.Font);

      sf = EhLibUtils.MeasureText(g, cellText, Grid.Font, textRect.Size, Grid.TitleColumn.WrapMode);

      if (sf.Width > textRect.Width)
        return cellText;
      else
        return "";
    }
    #endregion methods

  }

  public class DataVertGridTitleCellPaintParams
  {
    public int ColIndex { get; internal set; }
    public int RowIndex { get; internal set; }

    public int DataColIndex { get; internal set; }
    public int DataRowIndex { get; internal set; }
    public DataVertGridRow Row { get; internal set; }

    public Rectangle CellRect { get; internal set; }
    public Rectangle ContentRect { get; set; }

    public BasePaintCellStates PaintState { get; internal set; }

    public TextFormatFlags AlignFlags { get; set; }
    public Color BackColor { get; set; }
    public bool EndEllipsis { get; set; }
    public Font Font { get; set; }
    public Color ForeColor { get; set; }
    public Padding Padding { get; set; }
    public Orientation TextOrientation { get; set; }

    public BaseGridCellPaintEventArgs PaintEventArgs { get; set; }
  }

  public class DataVertGridRowTitleCellMouseEventArgs : BaseGridCellEnterEventArgs
  {
    private DataVertGridRowTitle rowTitle;

    public DataVertGridRowTitleCellMouseEventArgs(
      int colIndex, int rowIndex, int areaColIndex, int areaRowIndex, Rectangle cellRect, int leaveColIndex, int leaveRowIndex,
      DataVertGridRowTitle rowTitle)
      : base(colIndex, rowIndex, areaColIndex, areaRowIndex, cellRect, leaveColIndex, leaveRowIndex)
    {
      this.rowTitle = rowTitle;
    }

    public DataVertGridRowTitle RowTitle
    {
      get { return rowTitle; }
    }
  }

}
