// <summary>ソースコード：>データグリッドビュー専用日付入力列データクラス</summary>
// <author>CommonMP</author>

using System;
using System.Windows.Forms;

namespace CommonMP.HYSSOP.OptionImpl.HSViewer.DotNetViewer
{
    /// <summary><para>class outline:</para>
    /// <para>データグリッドビュー専用の日付入力列データクラス</para>
    /// </summary>
    /// <remarks><para>remarks:</para>
    /// <para>無し</para>
    /// </remarks>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2009/07/01][新規作成]</para>
    /// </remarks>
    public class HySReportCalendarColumn : DataGridViewColumn
    {
        /// <summary><para>method outline:</para>
        /// <para>デフォルトコンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>HySReportCalendarColumn csCalendarColumn = new HySReportCalendarColumn()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>HySReportCalendarColumn  生成したインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySReportCalendarColumn()
            : base(new HysReportCalendarCell())
        {
        }

        /// <summary><para>method outline:</para>
        /// <para>列テンプレート定義取得・設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>DataGridViewCell cDataGridViewCell = csCalendarColumn.CellTemplate</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>DataGridViewCell  列テンプレート定義値</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override DataGridViewCell CellTemplate
        {
            get
            {
                return base.CellTemplate; // 列テンプレート定義値を返す
            }
            set
            {
                // 該当日付入力テンプレート取り出し
                if (value != null &&
                    !value.GetType().IsAssignableFrom(typeof(HysReportCalendarCell)))
                {
                    throw new InvalidCastException("Must be a CalendarCell");
                }
                base.CellTemplate = value; // 列テンプレート定義値設定
            }
        }
    }

    /// <summary><para>class outline:</para>
    /// <para>日時形式列テンプレートクラス</para>
    /// </summary>
    /// <remarks><para>remarks:</para>
    /// <para>無し</para>
    /// </remarks>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2009/07/01][新規作成]</para>
    /// </remarks>
    public class HysReportCalendarCell : DataGridViewTextBoxCell
    {
        /// <summary><para>method outline:</para>
        /// <para>日時形式列テンプレートクラス</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>HysReportCalendarCell csCalendarCell = new HysReportCalendarCell()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>HysReportCalendarCell 日時形式列テンプレートインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HysReportCalendarCell()
            : base()
        {
            //this.Style.Format = "yyyy/MM/dd"; // データフォーマット設定
            this.Style.Format = System.Threading.Thread.CurrentThread.CurrentUICulture.DateTimeFormat.ShortDatePattern.ToString(); // データフォーマット設定
        }

        /// <summary><para>method outline:</para>
        /// <para>日時形式列テンプレート初期定義</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>InitializeEditingControl(iRowIndex,csInitialFormattedValue,csDataGridViewCellStyle)</para>
        /// </example>
        /// <param name="iRowIndex">行数</param>
        /// <param name="csInitialFormattedValue">フォーマット定義初期値</param>
        /// <param name="csDataGridViewCellStyle">データグリッドビュー列スタイル</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void InitializeEditingControl(int iRowIndex, object
            csInitialFormattedValue, DataGridViewCellStyle csDataGridViewCellStyle)
        {
            // システム初期値設定
            base.InitializeEditingControl(iRowIndex, csInitialFormattedValue,
                csDataGridViewCellStyle);
            // 日時形式列テンプレート定義設定
            HysReportCalendarEditingControl csCtl =
                DataGridView.EditingControl as HysReportCalendarEditingControl;

            if (this.Value is DateTime)
            {  // 時刻付き日付型式データの場合
                csCtl.Value = (DateTime)this.Value;
            }
            else
            {  // 時刻付き日付型式データ以外の場合
                if (this.Value != null)
                {  // データが有る場合
                    if (this.Value.ToString().Length > 0)
                    {  // 入力データが有る場合
                        this.Value = DateTime.Parse(this.Value.ToString());
                        if (this.Value is DateTime)
                        {  // 時刻付き日付型式データの場合
                            csCtl.Value = (DateTime)this.Value;
                        }
                    }
                }
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>列編集型取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Type csType = CalendarCell.EditType</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>Type 列編集型</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override Type EditType
        {
            get
            {
                return typeof(HysReportCalendarEditingControl); // 日付形式テンプレート型を返す
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>列データ型取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Type csType = CalendarCell.ValueType</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>Type 列データ型</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override Type ValueType
        {
            get
            {
                return typeof(DateTime); // 日付形式型を返す
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>列データ初期値取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>object csObject = CalendarCell.DefaultNewRowValue</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>object 列データ初期値</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override object DefaultNewRowValue
        {
            get
            {
                return null; // 初期値（デフォルト）を返す
            }
        }
    }

    /// <summary><para>class outline:</para>
    /// <para>日時形式列入力制御クラス</para>
    /// </summary>
    /// <remarks><para>remarks:</para>
    /// <para>無し</para>
    /// </remarks>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2009/07/01][新規作成]</para>
    /// </remarks>
    class HysReportCalendarEditingControl : DateTimePicker, IDataGridViewEditingControl
    {
        /// <summary>データグリッドビュー</summary>
        DataGridView csDataGridView;
        /// <summary>変更有無フラグ</summary>
        private bool bValueChanged = false;
        /// <summary>行インデックス</summary>
        int iRowIndex;

        /// <summary><para>method outline:</para>
        /// <para>日時形式列入力制御クラス</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>HysReportCalendarEditingControl csCalendarEditingControl = new HysReportCalendarEditingControl()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>HysReportCalendarEditingControl 日時形式列入力テンプレートインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HysReportCalendarEditingControl()
        {
            //this.Format = DateTimePickerFormat.Custom; // 日付型設定
            //this.CustomFormat = "yyyy/MM/dd";          // フォーマット定義設定
            this.Format = DateTimePickerFormat.Short; // 日付型設定
            this.ShowUpDown = true;                   // 日付+時刻入力定義設定
        }

        /// <summary><para>method outline:</para>
        /// <para>日時形式列データプロパティ取得・設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>object csObject = CalendarEditingControl.EditingControlFormattedValue</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>object 日時形式列データオブジェクト</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public object EditingControlFormattedValue
        {
            get
            {
                return this.Value.ToString(); // 日時形式列データプロパティ取得
            }
            set
            {
                String sNewValue = value as String;
                if (sNewValue != null)
                {
                    this.Value = DateTime.Parse(sNewValue); // 日時形式列データプロパティ設定
                }
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>日時データフォーマット取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>object csObject = GetEditingControlFormattedValue(csContext)</para>
        /// </example>
        /// <param name="csContext">エラーコンテキスト</param>
        /// <returns>object 日時データフォーマットオブジェクト</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public object GetEditingControlFormattedValue(
            DataGridViewDataErrorContexts csContext)
        {
            return EditingControlFormattedValue;
        }

        /// <summary><para>method outline:</para>
        /// <para>日時データセルスタイル設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>ApplyCellStyleToEditingControl(csDataGridViewCellStyle)</para>
        /// </example>
        /// <param name="csDataGridViewCellStyle">データグリッドビューセルスタイル</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void ApplyCellStyleToEditingControl(
            DataGridViewCellStyle csDataGridViewCellStyle)
        {
            this.Font = csDataGridViewCellStyle.Font;
            this.CalendarForeColor = csDataGridViewCellStyle.ForeColor;
            this.CalendarMonthBackground = csDataGridViewCellStyle.BackColor;
        }

        /// <summary><para>method outline:</para>
        /// <para>行位置取得・設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>int iIndex = CalendarEditingControl.EditingControlRowIndex</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>int 行位置</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public int EditingControlRowIndex
        {
            get
            {
                return iRowIndex; // 現在の行位置を返す
            }
            set
            {
                iRowIndex = value; // 行位置を設定
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>入力キーの妥当性判定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = EditingControlWantsInputKey(csKey,csDataGridViewWantsInputKey)</para>
        /// </example>
        /// <param name="csKey">入力キー</param>
        /// <param name="csDataGridViewWantsInputKey"></param>
        /// <returns>int 行位置</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public bool EditingControlWantsInputKey(
            Keys csKey, bool csDataGridViewWantsInputKey)
        {
            // 入力キーによる妥当性の判定
            switch (csKey & Keys.KeyCode)
            {
                case Keys.Left:
                case Keys.Up:
                case Keys.Down:
                case Keys.Right:
                case Keys.Home:
                case Keys.End:
                case Keys.PageDown:
                case Keys.PageUp:
                    return true;  // キー無効
                default:
                    return false; // キー有効
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>PrepareEditingControlForEditメソッドの実装</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>PrepareEditingControlForEdit(bSelectAll)</para>
        /// </example>
        /// <param name="bSelectAll">選択状態</param>
        /// <returns>int 行位置</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void PrepareEditingControlForEdit(bool bSelectAll)
        {
            // 無処理
        }

        /// <summary><para>method outline:</para>
        /// <para>RepositionEditingControlOnValueChangeメソッドの実装</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = CalendarEditingControl.RepositionEditingControlOnValueChange</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>bool 変更可否（=true:許可 =false:不可）</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public bool RepositionEditingControlOnValueChange
        {
            get
            {
                return false; // 変更不可を返す
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>EditingControlDataGridViewメソッドの実装</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>DataGridView csDataGridView = CalendarEditingControl.EditingControlDataGridView</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>DataGridView データグリッドビュー</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public DataGridView EditingControlDataGridView
        {
            get
            {
                return csDataGridView; // DataGridView取得
            }
            set
            {
                csDataGridView = value; // DataGridView設定
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>EditingControlValueChangedメソッドの実装</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>DataGridView csDataGridView = CalendarEditingControl.EditingControlValueChanged</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>bool 変更状態</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public bool EditingControlValueChanged
        {
            get
            {
                return bValueChanged;
            }
            set
            {
                bValueChanged = value;
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>EditingPanelCursorメソッドの実装</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Cursor csCursor = CalendarEditingControl.EditingPanelCursor</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>Cursor カーソル情報</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public Cursor EditingPanelCursor
        {
            get
            {
                return base.Cursor;
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>OnValueChangedメソッドの実装</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>OnValueChanged(csEventargs)</para>
        /// </example>
        /// <param name="csEventargs">変更イベント情報</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected override void OnValueChanged(EventArgs csEventargs)
        {
            bValueChanged = true;
            this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
            base.OnValueChanged(csEventargs);
        }
    }
}