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

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;

namespace EhLib
{

  public class BaseGridCellEventArgs : EventArgs
  {
    private readonly int colIndex;
    private readonly int rowIndex;
    private readonly int areaRowIndex;
    private readonly int areaColIndex;
    private readonly Rectangle cellRect;

    public BaseGridCellEventArgs(int colIndex, int rowIndex, int areaColIndex, int areaRowIndex, Rectangle cellRect)
    {
      this.colIndex = colIndex;
      this.rowIndex = rowIndex;
      this.areaColIndex = areaColIndex;
      this.areaRowIndex = areaRowIndex;
      this.cellRect = cellRect;
    }

    public int ColIndex
    {
      get { return colIndex; }
    }

    public int RowIndex
    {
      get { return rowIndex; }
    }

    public int AreaColIndex
    {
      get { return this.areaColIndex; }
    }

    public int AreaRowIndex
    {
      get { return this.areaRowIndex; }
    }

    public Rectangle CellRect
    {
      get { return cellRect; }
    }

    public override string ToString()
    {
      return string.Format("ColIndex = {0} RowIndex = {1}",
        ColIndex, RowIndex);
    }

  }

  public class BaseGridCellMouseEventArgs : HandledEventArgs
  {
    private readonly int colIndex;
    private readonly int rowIndex;
    private readonly int areaRowIndex;
    private readonly int areaColIndex;
    private readonly Rectangle cellRect;

    private readonly int inCellX;
    private readonly int inCellY;
    private readonly MouseEventArgs gridMouseArgs;
    private readonly BaseGridCellManager cellManager;

    public BaseGridCellMouseEventArgs(
      BaseGridCellManager cellManager,
      int colIndex, int rowIndex,
      int areaColIndex, int areaRowIndex,
      int inCellX, int inCellY,
      Rectangle cellRect,
      MouseEventArgs e)
    {
      if (colIndex < -1)
        throw new ArgumentOutOfRangeException("colIndex");
      if (rowIndex < -1)
        throw new ArgumentOutOfRangeException("rowIndex");
      this.colIndex = colIndex;
      this.rowIndex = rowIndex;
      this.areaColIndex = areaColIndex;
      this.areaRowIndex = areaRowIndex;
      this.inCellX = inCellX;
      this.inCellY = inCellY;
      this.cellRect = cellRect;
      this.cellManager = cellManager;
      gridMouseArgs = e;
    }

    public BaseGridCellManager CellManager
    {
      get { return this.cellManager; }
    }

    public int ColIndex
    {
      get { return colIndex; }
    }

    public int RowIndex
    {
      get { return rowIndex; }
    }

    public int AreaColIndex
    {
      get { return this.areaColIndex; }
    }

    public int AreaRowIndex
    {
      get { return this.areaRowIndex; }
    }

    public int InCellX
    {
      get { return inCellX; }
    }

    public int InCellY
    {
      get { return inCellY; }
    }

    public MouseEventArgs GridMouseArgs
    {
      get { return gridMouseArgs; }
    }

    public MouseButtons Button
    {
      get { return gridMouseArgs.Button; }
    }

    public Rectangle CellRect
    {
      get { return cellRect; }
    }

    public override string ToString()
    {
      return string.Format("ColIndex = {0} RowIndex = {1} InCellX = {2} InCellY = {3} Button = {4}",
        ColIndex, RowIndex, InCellX, InCellY, Button);
    }
  }

  public class BaseGridCellBorderEventArgs : EventArgs
  {
    private readonly int colIndex;
    private readonly int rowIndex;
    private readonly GridCellBorderType borderType;
    private readonly int areaRowIndex;
    private readonly int areaColIndex;

    private bool visible;
    private Color color;
    private DashStyle style;
    private bool isExtent;

    public BaseGridCellBorderEventArgs(int colIndex, int rowIndex, int areaColIndex, int areaRowIndex, GridCellBorderType borderType)
    {
      this.colIndex = colIndex;
      this.rowIndex = rowIndex;
      this.areaColIndex = areaColIndex;
      this.areaRowIndex = areaRowIndex;
      this.borderType = borderType;
    }

    public int ColIndex
    {
      get { return colIndex; }
    }

    public int RowIndex
    {
      get { return rowIndex; }
    }

    public int AreaColIndex
    {
      get { return this.areaColIndex; }
    }

    public int AreaRowIndex
    {
      get { return this.areaRowIndex; }
    }

    public GridCellBorderType BorderType
    {
      get { return borderType; }
    }

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

    public Color Color
    {
      get { return color; }
      set { color = value; }
    }

    public DashStyle Style
    {
      get { return style; }
      set { style = value; }
    }

    public bool IsExtent
    {
      get { return isExtent; }
      set { isExtent = value; }
    }
  }

  public class BaseGridCellPaintEventArgs : HandledEventArgs
  {
    private Graphics graphics;
    private int colIndex;
    private int rowIndex;
    private Rectangle cellRect;
    private Rectangle cellClientRect;
    private BasePaintCellStates state;
    private int areaColIndex;
    private int areaRowIndex;
    private Point inCellMousePos;
    private BaseGridCellManager cellManager;

    public BaseGridCellPaintEventArgs(BaseGridCellManager cellManager, Graphics graphics, int colIndex, int rowIndex,
      Rectangle cellRect, BasePaintCellStates state, int areaColIndex, int areaRowIndex, Point inCellMousePos)
    {
      this.graphics = graphics;
      this.colIndex = colIndex;
      this.rowIndex = rowIndex;
      this.cellRect = cellRect;
      this.cellClientRect = cellRect;
      this.state = state;
      this.areaColIndex = areaColIndex;
      this.areaRowIndex = areaRowIndex;
      this.inCellMousePos = inCellMousePos;
      this.cellManager = cellManager;
    }

    public void Reset(Graphics graphics, int colIndex, int rowIndex, Rectangle cellRect,
      BasePaintCellStates state, int areaColIndex, int areaRowIndex, Point inCellMousePos)
    {
      this.graphics = graphics;
      this.colIndex = colIndex;
      this.rowIndex = rowIndex;
      this.cellRect = cellRect;
      this.cellClientRect = cellRect;
      this.state = state;
      this.areaColIndex = areaColIndex;
      this.areaRowIndex = areaRowIndex;
      this.inCellMousePos = inCellMousePos;
    }

    public BaseGridCellManager CellManager
    {
      get { return this.cellManager; }
    }

    public Graphics Graphics
    {
      get { return this.graphics; }
    }

    public int ColIndex
    {
      get { return this.colIndex; }
    }

    public int RowIndex
    {
      get { return this.rowIndex; }
    }

    public Rectangle CellRect
    {
      get { return this.cellRect; }
      set { cellRect = value; }
    }

    public Rectangle CellClientRect
    {
      get { return this.cellClientRect; }
      set { this.cellClientRect = value; }
    }

    public BasePaintCellStates State
    {
      get { return this.state; }
      set { state = value; }
    }

    public int AreaColIndex
    {
      get { return this.areaColIndex; }
    }

    public int AreaRowIndex
    {
      get { return this.areaRowIndex; }
    }

    public Point InCellMousePos
    {
      get { return this.inCellMousePos; }
    }

    public virtual void Paint(BaseGridCellPaintEventArgs e)
    {
      CellManager.OnPaint(e);
    }

    public virtual void PaintBackground(BaseGridCellPaintEventArgs e)
    {
      CellManager.OnPaintBackground(e);
    }

    public virtual void PaintForeground(BaseGridCellPaintEventArgs e)
    {
      CellManager.OnPaintForeground(e);
    }

  }

  public class BaseGridCellQueryCursorEventArgs : BaseGridCellMouseEventArgs
  {
    private Cursor cursor;

    public BaseGridCellQueryCursorEventArgs(
      BaseGridCellManager cellManager,
      int colIndex, int rowIndex,
      int areaColIndex, int areaRowIndex,
      int inCellX, int inCellY,
      Rectangle cellRect,
      MouseEventArgs e) 
      : base (cellManager, colIndex, rowIndex, areaColIndex, areaRowIndex, inCellX, inCellY, cellRect, e)
    {
    }

    public Cursor Cursor
    {
      get { return this.cursor; }
      set { this.cursor = value; }
    }

  }

  public class ControlPaintEventArgs : HandledEventArgs
  {
    private readonly PaintEventArgs paintEventArgs;
    private readonly Control control;

    public ControlPaintEventArgs(PaintEventArgs paintEventArgs, Control control)
    {
      this.paintEventArgs = paintEventArgs;
      this.control = control;
    }

    public Rectangle ClipRectangle
    {
      get
      {
        return paintEventArgs.ClipRectangle;
      }
    }

    public System.Drawing.Graphics Graphics
    {
      get
      {
        return paintEventArgs.Graphics;
      }
    }

    public Control Control
    {
      get
      {
        return control;
      }
    }

    public PaintEventArgs BasePaintEventArgs
    {
      get
      {
        return paintEventArgs;
      }
    }

    public virtual void Paint(ControlPaintEventArgs e)
    {

    }
  }

  public class BaseGridControlPaintEventArgs : ControlPaintEventArgs
  {
    public BaseGridControlPaintEventArgs(PaintEventArgs paintEventArgs, Control control)
      : base(paintEventArgs, control)
    {
    }

    public override void Paint(ControlPaintEventArgs e)
    {
      (Control as BaseGridControl).PaintInternal(e.BasePaintEventArgs);
    }
  }

  public class BaseGridCellEnterEventArgs : BaseGridCellEventArgs
  {
    private readonly int leaveColIndex;
    private readonly int leaveRowIndex;

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

    public int LeaveColIndex
    {
      get { return leaveColIndex; }
    }

    public int LeaveRowIndex
    {
      get { return leaveRowIndex; }
    }

    public override string ToString()
    {
      return string.Format("ColIndex = {0} RowIndex = {1} LeaveColIndex = {2} LeaveRowIndex = {3}",
        ColIndex, RowIndex, LeaveColIndex, LeaveRowIndex);
    }

  }

  public class BaseGridCellLeaveEventArgs : BaseGridCellEventArgs
  {
    private readonly int enterColIndex;
    private readonly int enterRowIndex;

    public BaseGridCellLeaveEventArgs(int colIndex, int rowIndex, int areaColIndex, int areaRowIndex, Rectangle cellRect, int enterColIndex, int enterRowIndex)
      : base(colIndex, rowIndex, areaColIndex, areaRowIndex, cellRect)
    {
      this.enterColIndex = enterColIndex;
      this.enterRowIndex = enterRowIndex;
    }

    public int EnterColIndex
    {
      get { return enterColIndex; }
    }

    public int EnterRowIndex
    {
      get { return enterRowIndex; }
    }

    public override string ToString()
    {
      return string.Format("ColIndex = {0} RowIndex = {1} EnterColIndex = {2} EnterRowIndex = {3}",
        ColIndex, RowIndex, EnterColIndex, EnterRowIndex);
    }

  }

  public class BaseGridCellContextMenuStripNeededEventArgs : HandledEventArgs
  {
    private readonly int colIndex;
    private readonly int rowIndex;
    private readonly int areaRowIndex;
    private readonly int areaColIndex;
    private readonly Rectangle cellRect;

    private readonly int inCellX;
    private readonly int inCellY;
    private readonly int mousePosX;
    private readonly int mousePosY;
    private readonly BaseGridCellManager cellManager;

    private ContextMenuStrip contextMenuStrip;

    public BaseGridCellContextMenuStripNeededEventArgs(
      BaseGridCellManager cellManager,
      int colIndex, int rowIndex,
      int areaColIndex, int areaRowIndex,
      int inCellX, int inCellY,
      Rectangle cellRect,
      int MousePosX, int MousePosY)
    {
      if (colIndex < -1)
        throw new ArgumentOutOfRangeException("colIndex");
      if (rowIndex < -1)
        throw new ArgumentOutOfRangeException("rowIndex");
      this.colIndex = colIndex;
      this.rowIndex = rowIndex;
      this.areaColIndex = areaColIndex;
      this.areaRowIndex = areaRowIndex;
      this.inCellX = inCellX;
      this.inCellY = inCellY;
      this.cellRect = cellRect;
      this.cellManager = cellManager;
      this.mousePosX = MousePosX;
      this.mousePosY = MousePosY;
    }

    public BaseGridCellManager CellManager
    {
      get { return this.cellManager; }
    }

    public int ColIndex
    {
      get { return colIndex; }
    }

    public int RowIndex
    {
      get { return rowIndex; }
    }

    public int AreaColIndex
    {
      get { return this.areaColIndex; }
    }

    public int AreaRowIndex
    {
      get { return this.areaRowIndex; }
    }

    public int InCellX
    {
      get { return inCellX; }
    }

    public int InCellY
    {
      get { return inCellY; }
    }

    public Rectangle CellRect
    {
      get { return cellRect; }
    }

    public int MousePosX
    {
      get { return mousePosX; }
    }

    public int MousePosY
    {
      get { return mousePosY; }
    }

    public ContextMenuStrip ContextMenuStrip
    {
      get { return this.contextMenuStrip; }
      set { this.contextMenuStrip = value; }
    }

    public override string ToString()
    {
      return string.Format("ColIndex = {0} RowIndex = {1} InCellX = {2} InCellY = {3}",
        ColIndex, RowIndex, InCellX, InCellY);
    }

    public virtual void SetContextMenuStrip(BaseGridCellContextMenuStripNeededEventArgs e)
    {
      e.CellManager.OnContextMenuStripNeeded(e);
    }
  }

}
