// <summary>ソースコード：モデル用プロパティ画面用 .net のフォーム</summary>
// <author>CommonMP</author>

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

using CommonMP.HYSSOP.Interface.HSData;
using CommonMP.HYSSOP.Interface.HSController;
using CommonMP.HYSSOP.Interface.HSViewer;
using CommonMP.HYSSOP.CoreImpl.HSData;
using CommonMP.HYSSOP.CoreImpl.HSController;
using CommonMP.HYSSOP.CoreImpl.HSTools;

using CommonMP.HYMCO.Interface;
using CommonMP.HYMCO.Interface.Viewer;
using CommonMP.HYMCO.Interface.Data;
using CommonMP.HYMCO.CoreImpl.Controller;
using CommonMP.HYMCO.CoreImpl.Data;
using CommonMP.HYMCO.CoreOptions.McViewer.DotNetViewer;

namespace CommonMP.HYMCO.OptionImpl.McDimensionConversionForDevelop
{
    /// <summary><para>class outline:</para>
    /// <para>モデル用プロパティ画面用 .net のフォーム</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2012/02/07][新規作成]</para>
    /// <para>remarks:</para>
    /// <para>必ず　McDotNetModelCellPropertyDetailBaseForm, McModelCellPropertyDetailFormIFから派生の事</para>
    /// </remarks>
    public partial class McDimensionConversionForm : McDotNetModelCellPropertyDetailBaseForm, McModelCellPropertyDetailFormIF
    {
        /// <summary>全コントロール</summary>
        private Dictionary<string, Control> m_csAllControls;

        /// <summary>
        /// <para>method outline:</para>
        /// <para>デフォルトコンストラクタ</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>McDimensionConversionForm csPropertyDetailForm = new McDimensionConversionForm();</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public McDimensionConversionForm()
        {
            InitializeComponent();
            this.Text = McDimensionConversionDefine.DIMENSION_CONVERSION_NAME.ToString();

            // 全コントロールをハッシュテーブルにセットする
            m_csAllControls = new Dictionary<string, Control>();
            GetAllControls(this, m_csAllControls);
        }

        /// <summary>
        /// <para>method outline:</para>
        /// <para>プロパティ表示編集</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>EditParameter( );</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void EditParameter()
        {
            // プロパティ情報より、パラメータを画面に初期表示する
            SetPropertyInfo();
        }

        /// <summary><para>method outline:</para>
        /// <para>設定処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>ParaSet_Click(sender,e);</para>
        /// </example>
        /// <param name="sender">object</param>
        /// <param name="e">Event</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>「設定」ボタンを押下された時の処理を記述</para>
        /// </remarks>
        private void ParaSet_Click(object sender, EventArgs e)
        {
            // 設定内容チェック
            if (CheckParaSet() == false)
            {   // 異常ありの場合、何もしない
                return;
            }

            // 設定内容登録
            if (ParaRegist() == true)
            {
                DialogResult = DialogResult.OK;
            }
            else
            {
                DialogResult = DialogResult.Cancel;
            }

            Close();
        }

        /// <summary>
        /// <para>method outline:</para>
        /// <para>設定内容登録処理</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>ParaRegist();</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true:正常 false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private bool ParaRegist()
        {
            // プロパティ情報の登録
            return RegistPropertyInfo();
        }

        /// <summary>
        /// <para>method outline:</para>
        /// <para>プロパティ情報の登録</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>ParaRegist();</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true:正常 false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private bool RegistPropertyInfo()
        {
            McModelPropertyInfo csModelPropertyInfo = m_csPropertyInfo as McModelPropertyInfo;
            if (csModelPropertyInfo == null)
            {   // キャスト失敗時
                return false;
            }

            // 演算間隔
            double dTimeStep = double.Parse(txtTimeStep.Text);
            csModelPropertyInfo.SetStepTime(dTimeStep);

            // 受信側
            RadioButton csReceive = null;
            foreach (RadioButton csRadioButton in grpReceiveType.Controls)
            {
                if (csRadioButton.Checked)
                {
                    csReceive = csRadioButton;
                    break;
                }
            }
            if (csReceive != null)
            {
                string sType = csReceive.Name.Replace("rdoReceive", "");
                McDimensionConversionDefine.DimensionType type 
                    = (McDimensionConversionDefine.DimensionType)Enum.Parse(typeof(McDimensionConversionDefine.DimensionType), sType);
                csModelPropertyInfo.SetInfo("m_lReceiveType", (long)type);
            }
            else
            {
                csModelPropertyInfo.SetInfo("m_lReceiveType", (long)McDimensionConversionDefine.DimensionType.SingleCellSerial);    // 初期値
            }
            csModelPropertyInfo.SetInfo("m_lReceiveDataPosDim1", long.Parse(txtReceivePosDim1.Text));
            csModelPropertyInfo.SetInfo("m_lReceiveDataPosDim2", long.Parse(txtReceivePosDim2.Text));

            // 送信側
            RadioButton csSend = null;
            foreach (RadioButton csRadioButton in grpSendType.Controls)
            {
                if (csRadioButton.Checked)
                {
                    csSend = csRadioButton;
                    break;
                }
            }
            if (csSend != null)
            {
                string sType = csSend.Name.Replace("rdoSend", "");
                McDimensionConversionDefine.DimensionType type
                    = (McDimensionConversionDefine.DimensionType)Enum.Parse(typeof(McDimensionConversionDefine.DimensionType), sType);
                csModelPropertyInfo.SetInfo("m_lSendType", (long)type);
            }
            else
            {
                csModelPropertyInfo.SetInfo("m_lSendType", (long)McDimensionConversionDefine.DimensionType.D1CellSerial);   // 初期値
            }
            csModelPropertyInfo.SetInfo("m_lSendDataPosDim1", long.Parse(txtSendPosDim1.Text));
            csModelPropertyInfo.SetInfo("m_lSendDataPosDim2", long.Parse(txtSendPosDim2.Text));

            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>キャンセル処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Cancel_Click(sender,e);</para>
        /// </example>
        /// <param name="sender">Object</param>
        /// <param name="e">Event</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>「キャンセル」ボタンを押下された時の処理を記述</para>
        /// </remarks>
        private void Cancel_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.Cancel;
            Close();
        }

        /// <summary><para>method outline:</para>
        /// <para>全コントロールをハッシュテーブルにセットする</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>GetAllControls();</para>
        /// </example>
        /// <param name="csTopControl">最上位のコントロール</param>
        /// <param name="csControls">コントロールを格納するハッシュテーブル</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>GroupBox内のコントロールはGroupBoxのControlsプロパティからしかアクセスできないので、再帰的に処理</para>
        /// </remarks>
        private void GetAllControls(Control csTopControl, Dictionary<string, Control> csControls)
        {
            foreach (Control csControl in csTopControl.Controls)
            {
                if (csControl.Name == string.Empty)
                {
                    continue;
                }
                csControls.Add(csControl.Name, csControl);
                GetAllControls(csControl, csControls);
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>プロパティ情報より、パラメータを画面に初期表示する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetPropertyInfo();</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private void SetPropertyInfo()
        {
            // 登録プロパティ情報があれば処理を行う
            McModelPropertyInfo csModelPropertyInfo = m_csPropertyInfo as McModelPropertyInfo;
            if (csModelPropertyInfo == null)
            {   // キャスト失敗時
                return;
            }

            // 演算間隔
            double dTimeStep = csModelPropertyInfo.GetStepTime();
            txtTimeStep.Text = dTimeStep.ToString();

            // 受信側
            long lValue = 0;
            csModelPropertyInfo.GetInfo("m_lReceiveType", ref lValue);
            McDimensionConversionDefine.DimensionType receiveType = (McDimensionConversionDefine.DimensionType)lValue;
            string sReceiveType = receiveType.ToString();
            RadioButton csReceiveType = m_csAllControls[string.Format("rdoReceive{0}", sReceiveType)] as RadioButton;
            csReceiveType.Checked = true;
            csModelPropertyInfo.GetInfo("m_lReceiveDataPosDim1", ref lValue);
            txtReceivePosDim1.Text = lValue.ToString();
            csModelPropertyInfo.GetInfo("m_lReceiveDataPosDim2", ref lValue);
            txtReceivePosDim2.Text = lValue.ToString();

            // 送信側
            csModelPropertyInfo.GetInfo("m_lSendType", ref lValue);
            McDimensionConversionDefine.DimensionType sendType = (McDimensionConversionDefine.DimensionType)lValue;
            string sSendType = sendType.ToString();
            RadioButton csSendType = m_csAllControls[string.Format("rdoSend{0}", sSendType)] as RadioButton;
            csSendType.Checked = true;
            csModelPropertyInfo.GetInfo("m_lSendDataPosDim1", ref lValue);
            txtSendPosDim1.Text = lValue.ToString();
            csModelPropertyInfo.GetInfo("m_lSendDataPosDim2", ref lValue);
            txtSendPosDim2.Text = lValue.ToString();
        }

        /// <summary>
        /// <para>method outline:</para>
        /// <para>設定内容チェック処理</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>CheckParaSet();</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true:正常 false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private bool CheckParaSet()
        {
            return CheckPropertyInfo();
        }

        /// <summary>
        /// <para>method outline:</para>
        /// <para>プロパティ情報チェック処理</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>CheckPropertyInfo();</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true:正常 false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>配分箇所数により、有効/無効を設定する</para>
        /// </remarks>
        private bool CheckPropertyInfo()
        {
            // 送受信の組合せをチェック
            if (CheckSendReceivePatternCombination() == false)
            {
                // メッセージ:送受信の組合せが不適切です。
                CommonControlLibrary.CommonLib.ShowInputError(Properties.McDimensionConversionPropertyResources.MSG_ERROR_WRONG_COMBINATION_SENDING_RECEIVING);
                return false;
            }

            // 演算間隔チェック
            Regex csRegex = new Regex("^[1-9][0-9]*$");
            if (csRegex.IsMatch(txtTimeStep.Text) == false)
            {
                // メッセージ:演算間隔の値が不適切です。
                CommonControlLibrary.CommonLib.ShowInputError(Properties.McDimensionConversionPropertyResources.MSG_ERROR_WRONG_CALCULATION_INTERVAL);
                txtTimeStep.Focus();
                return false;
            }

            // データ位置をチェック
            csRegex = new Regex("^[0-9]+$");
            if (csRegex.IsMatch(txtReceivePosDim1.Text) == false)
            {
                // メッセージ:データ位置(受信側:1次元)の値が不適切です。
                CommonControlLibrary.CommonLib.ShowInputError(Properties.McDimensionConversionPropertyResources.MSG_ERROR_WRONG_DATA_POSITION_1_DIMENSION_RECEIVER);
                txtReceivePosDim1.Focus();
                return false;
            }

            if (csRegex.IsMatch(txtReceivePosDim2.Text) == false)
            {
                // メッセージ:データ位置(受信側:2次元)の値が不適切です。
                CommonControlLibrary.CommonLib.ShowInputError(Properties.McDimensionConversionPropertyResources.MSG_ERROR_WRONG_DATA_POSITION_2_DIMENSION_RECEIVER);
                txtReceivePosDim2.Focus();
                return false;
            }

            if (csRegex.IsMatch(txtSendPosDim1.Text) == false)
            {
                // メッセージ:データ位置(送信側:1次元)の値が不適切です。
                CommonControlLibrary.CommonLib.ShowInputError(Properties.McDimensionConversionPropertyResources.MSG_ERROR_WRONG_DATA_POSITION_1_DIMENSION_SENDER);
                txtSendPosDim1.Focus();
                return false;
            }

            if (csRegex.IsMatch(txtSendPosDim2.Text) == false)
            {
                // メッセージ:データ位置(送信側:2次元)の値が不適切です。
                CommonControlLibrary.CommonLib.ShowInputError(Properties.McDimensionConversionPropertyResources.MSG_ERROR_WRONG_DATA_POSITION_2_DIMENSION_SENDER);
                txtSendPosDim2.Focus();
                return false;
            }

            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>送受信の組合せをチェックする</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>CheckSendReceivePatternCombination();</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private bool CheckSendReceivePatternCombination()
        {
            if (rdoReceiveSingleCellSerial.Checked && rdoSendSingleCellSerial.Checked)
            {
                return false;
            }

            if (rdoReceiveD1CellSerial.Checked || rdoReceiveD2CellSerial.Checked)
            {
                if (!rdoSendSingleCellSerial.Checked)
                {
                    return false;
                }
            }

            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>ポイント時系列ラジオボタン(受信側)選択イベントハンドラ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>rdoReceiveSingleCellSerial_CheckedChanged(sender,e);</para>
        /// </example>
        /// <param name="sender">object</param>
        /// <param name="e">Event</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private void rdoReceiveSingleCellSerial_CheckedChanged(object sender, EventArgs e)
        {
            if (!rdoReceiveSingleCellSerial.Checked)
            {
                return;
            }

            txtReceivePosDim1.Enabled = false;
            txtReceivePosDim2.Enabled = false;
        }

        /// <summary><para>method outline:</para>
        /// <para>ポイント時系列ラジオボタン(送信側)選択イベントハンドラ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>rdoSendSingleCellSerial_CheckedChanged(sender,e);</para>
        /// </example>
        /// <param name="sender">object</param>
        /// <param name="e">Event</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private void rdoSendSingleCellSerial_CheckedChanged(object sender, EventArgs e)
        {
            if (!rdoSendSingleCellSerial.Checked)
            {
                return;
            }

            txtSendPosDim1.Enabled = false;
            txtSendPosDim2.Enabled = false;
        }

        /// <summary><para>method outline:</para>
        /// <para>1次元時系列ラジオボタン(受信側)選択イベントハンドラ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>rdoReceiveD1CellSerial_CheckedChanged(sender,e);</para>
        /// </example>
        /// <param name="sender">object</param>
        /// <param name="e">Event</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private void rdoReceiveD1CellSerial_CheckedChanged(object sender, EventArgs e)
        {
            if (!rdoReceiveD1CellSerial.Checked)
            {
                return;
            }

            txtReceivePosDim1.Enabled = true;
            txtReceivePosDim2.Enabled = false;
        }

        /// <summary><para>method outline:</para>
        /// <para>1次元時系列ラジオボタン(送信側)選択イベントハンドラ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>rdoSendD1CellSerial_CheckedChanged(sender,e);</para>
        /// </example>
        /// <param name="sender">object</param>
        /// <param name="e">Event</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private void rdoSendD1CellSerial_CheckedChanged(object sender, EventArgs e)
        {
            if (!rdoSendD1CellSerial.Checked)
            {
                return;
            }

            txtSendPosDim1.Enabled = true;
            txtSendPosDim2.Enabled = false;
        }

        /// <summary><para>method outline:</para>
        /// <para>2次元時系列ラジオボタン(受信側)選択イベントハンドラ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>rdoReceiveD2CellSerial_CheckedChanged(sender,e);</para>
        /// </example>
        /// <param name="sender">object</param>
        /// <param name="e">Event</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private void rdoReceiveD2CellSerial_CheckedChanged(object sender, EventArgs e)
        {
            if (!rdoReceiveD2CellSerial.Checked)
            {
                return;
            }

            txtReceivePosDim1.Enabled = true;
            txtReceivePosDim2.Enabled = true;
        }

        /// <summary><para>method outline:</para>
        /// <para>2次元時系列ラジオボタン(送信側)選択イベントハンドラ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>rdoSendD2CellSerial_CheckedChanged(sender,e);</para>
        /// </example>
        /// <param name="sender">object</param>
        /// <param name="e">Event</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private void rdoSendD2CellSerial_CheckedChanged(object sender, EventArgs e)
        {
            if (!rdoSendD2CellSerial.Checked)
            {
                return;
            }

            txtSendPosDim1.Enabled = true;
            txtSendPosDim2.Enabled = true;
        }
    }
}