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

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

namespace EhLib
{
  public interface IRadioButtonDataCellHolder
  {
    void SetCheckedStateAsChecked(PropertyAxisBar propAxisBar, object listItemBar);
  }

  [DataAxisGridDataCellDesignTimeVisibleAttribute(true)]
  public class DataAxisGridRadioButtonDataCell : DataAxisGridButtonBaseCell
  {

    #region privates
    //private static Type checkStateType = typeof(System.Windows.Forms.CheckState);
    private static readonly Type BooleanType = typeof(bool);

    object trueValue;
    object falseValue;
    private FlatStyle flatStyle;
    #endregion privates

    public DataAxisGridRadioButtonDataCell()
    {
    }

    #region properties
    [DefaultValue(null)]
    [TypeConverter(typeof(StringConverter))]
    public object TrueValue
    {
      get
      {
        return this.trueValue;
      }
      set
      {
        if (this.trueValue != value)
        {
          this.trueValue = value;
          if (Grid != null)
            Grid.InvalidateGrid();
        }
      }
    }

    [DefaultValue(null)]
    [TypeConverter(typeof(StringConverter))]
    public object FalseValue
    {
      get
      {
        return this.falseValue;
      }
      set
      {
        if (this.falseValue != value)
        {
          this.falseValue = value;
          if (Grid != null)
            Grid.InvalidateGrid();
        }
      }
    }

    [DefaultValue(FlatStyle.Standard)]
    public FlatStyle FlatStyle
    {
      get
      {
        return this.flatStyle;
      }
      set
      {
        if (this.flatStyle != value)
        {
          flatStyle = value;
          if (Grid != null)
            Grid.InvalidateGrid();
        }
      }
    }
    #endregion

    #region Methods
    public bool GetCheckedStateFromValue(object value)
    {
      if ((value != null) && (value.Equals(true)))
        return true;
      else
        return false;
    }

    public void SetCheckedStateAsChecked(PropertyAxisBar propAxisBar, object listItemBar)
    {
      IRadioButtonDataCellHolder radioButtonHolder = propAxisBar as IRadioButtonDataCellHolder;
      if (radioButtonHolder != null)
        radioButtonHolder.SetCheckedStateAsChecked(propAxisBar, listItemBar);
    }

    public virtual bool GetCheckedState(PropertyAxisBar propAxisBar, object listItemBar)
    {
      object value = propAxisBar.GetValue(listItemBar);
      bool result = GetCheckedStateFromValue(value);
      return result;
    }

    public RadioButtonState GetRadioButtonState(PropertyAxisBar propAxisBar, object listItemBar)
    {
      bool cState = GetCheckedState(propAxisBar, listItemBar);
      if (cState == true)
        return RadioButtonState.CheckedNormal;
      else
        return RadioButtonState.UncheckedNormal;
    }

    public void SetCheckedState(PropertyAxisBar propAxisBar, object listItemBar, bool isChecked)
    {
      if (isChecked == true)
      {
        //object value = GetDataValueFromCheckState(column, row, isChecked);
        SetCheckedStateAsChecked(propAxisBar, listItemBar);
      }
    }

    public object GetDataValueFromCheckState(PropertyAxisBar propAxisBar, object listItemBar, bool isChecked)
    {
      object result = null;

      if (isChecked)
      {
        if (TrueValue != null)
        {
          result = TrueValue;
        }
        else
        {
          if (propAxisBar.DataType != null && propAxisBar.DataType.IsAssignableFrom(BooleanType))
            result = true;
        }
      }
      else
      {
        if (FalseValue != null)
        {
          result = FalseValue;
        }
        else
        {
          if (propAxisBar.DataType != null && propAxisBar.DataType.IsAssignableFrom(BooleanType))
            result = false;
        }
      }

      return result;
    }

    public bool NextCheckedState(bool checkedState)
    {
      return true;
    }

    public override void Toggle(int dataColIndex, int dataRowIndex)
    {
      PropertyAxisBar propAxisBar;
      object listItemBar;
      AxisObjectsByDataColRowIndex(dataColIndex, dataRowIndex, out propAxisBar, out listItemBar);

      bool cbState = GetCheckedState(propAxisBar, listItemBar);
      cbState = NextCheckedState(cbState);
      SetCheckedState(propAxisBar, listItemBar, cbState);
    }

    protected override void PaintForeground(DataAxisGridDataCellPaintEventArgs e)
    {
      Rectangle chRect = new Rectangle();
      bool isHot = false;
      bool isDown = false;
      int gridColIndex;
      int gridRowIndex;
      GridCoord mouseHolderCellCoord = Grid.MouseHolderCellCoord;

      RadioButtonState cbState = GetRadioButtonState(e.PropAxisBar, e.ListItemBar);
      Size cbSize = RadioButtonRenderer.GetGlyphSize(e.Graphics, cbState);
      chRect.Size = cbSize;
      chRect = EhLibUtils.RectCenter(chRect, e.CellRect);

      AreaCellPosToGridCellPos(e.AreaColIndex, e.AreaRowIndex, out gridColIndex, out gridRowIndex);

      if (DownState && (Grid.CurrentDataRowIndex == e.AreaRowIndex))
      {
        isDown = true;
      }
      else if (!DownState &&
                mouseHolderCellCoord.X == gridColIndex &&
                mouseHolderCellCoord.Y == gridRowIndex
                )
      {
        isHot = true;
      }

      //      ButtonState
      cbState = EhLibUtilsInternal.FixRadioButtonStateByState(cbState, isHot, isDown, true);

      RadioButtonRenderer.DrawRadioButton(e.Graphics, chRect.Location, cbState);
    }

    #endregion Methods
  }
}
