// <summary>ソースコード：ＨＹＭＣＯポータブルデータグループ名変更画面クラス</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.IO;
using Microsoft.VisualBasic;

using CommonMP.HYSSOP.CoreImpl.HSData;
using CommonMP.HYSSOP.CoreImpl.HSTools;
using CommonMP.HYSSOP.OptionImpl.HSViewer.DotNetViewer;

using CommonMP.HYMCO.CoreImpl.Tool.Msg;

namespace CommonMP.HYMCO.CoreOptions.McViewer.DotNetViewer
{
    /// <summary><para>class outline:</para>
    /// <para>ポータブルデータグループ名変更画面</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.1.0][2010/12/23][新規作成]</para>
    /// </remarks>
    /// 
    public partial class McDotNetPortableGroupNameChangeForm : HySDotNetForm
    {
        ///// <summary>クラス名称</summary>
        //static private readonly string CLASS_NAME = "McDotNetPortableGroupNameChangeForm";

        /// <summary>重複プロジェクトグループ名</summary>
        private HySDataHashTable m_csGroupHashTable = null;

        /// <summary>
        /// メッセージボックスタイトル『プロジェクト管理機能』
        /// </summary>
        private static readonly string MSGBOX_TITLE = McMessage.GetString("MC_MSG_TITLE_PROJECT_MANAGEMENT");
        /// <summary>メッセージボックスメッセージ『使用できない文字が指定されています。』 </summary>
        static private readonly string MSG_WARNING_PROJECTGROUP_NGNAME = McMessage.GetString("MC_MSG_WARNING_PROJECTGROUP_NGNAME");
        /// <summary>メッセージボックスメッセージ『重複するグループ名称が指定されています。』 </summary>
        static private readonly string MSG_WARNING_PROJECTGROUP_DNAME = McMessage.GetString("MC_MSG_WARNING_PROJECTGROUP_DNAME");
        /// <summary>メッセージ「プロジェクトグループが指定されていません。」 </summary>
        static private string MSG_CHK_INMPUT_PROJECTGROUP = McMessage.GetString("MC_MSG_CHECK_INMPUT_PROJECTGROUP");

        /// <summary><para>method outline:</para>
        /// <para>デフォルトコンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McDotNetPortableGroupNameChangeForm csDotNetPortableGroupNameChangeForm = new McDotNetPortableGroupNameChangeForm();</para>
        /// </example>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public McDotNetPortableGroupNameChangeForm()
        {
            InitializeComponent();
        }

        /// <summary><para>method outline:</para>
        /// <para>コンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McDotNetPortableGroupNameChangeForm csDotNetPortableGroupNameChangeForm = new McDotNetPortableGroupNameChangeForm(csGroupHashTable);</para>
        /// </example>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public McDotNetPortableGroupNameChangeForm(HySDataHashTable csGroupHashTable)
        {
            InitializeComponent();
            m_csGroupHashTable = new HySDataHashTable();
            HySDataLinkedList csList = csGroupHashTable.GetKeyList(); // キーリスト一覧取得

            HySString csKeyID = null;
            HySString csData = null;

            //一覧にグループ名を表示
            for (long lNum = 0; lNum < csList.GetCount(); lNum++)
            {
                csKeyID = (HySString)csList.GetData(lNum);
                csData = (HySString)csGroupHashTable.GetObject(csKeyID);

                // ver1.6 グループ名の名称変更の候補表示
                if (csData.GetLength() == 0)
                {
                    csData = new HySString(CreateNewGroupName(csKeyID.ToString()));

                    if ((HySEnvInf.GetDataHomeDirectory().ToString() + "\\" + csData.ToString()).Length > 247)
                    {
                        // System.IO.Directory.cs-   Windows ベースのプラットフォームの場合、
                        // パスの長さは 248 文字未満、ファイル名の長さは 260 文字未満である必要があります。
                        csData = new HySString("");
                    }
                }
                
                ProjectGroup_DataGridView.Rows.Add(1);
                ProjectGroup_DataGridView["CheckColumn", (int)lNum].Value = true;
                ProjectGroup_DataGridView["OrgGroupName", (int)lNum].Value = csKeyID.ToString();
                ProjectGroup_DataGridView["NewGroupName", (int)lNum].Value = csData.ToString();

                if (csData.Equal(new HySString("")) == true)
                {
                    ProjectGroup_DataGridView["OrgGroupName", (int)lNum].Style.BackColor = Color.Yellow;
                    ProjectGroup_DataGridView["OrgGroupName", (int)lNum].Style.SelectionBackColor = Color.Yellow;
                    ProjectGroup_DataGridView["OrgGroupName", (int)lNum].Style.SelectionForeColor = Color.LightGray;
                    ProjectGroup_DataGridView["NewGroupName", (int)lNum].Style.BackColor = Color.Yellow;
                    ProjectGroup_DataGridView["NewGroupName", (int)lNum].Style.SelectionBackColor = Color.Yellow;
                    ProjectGroup_DataGridView["NewGroupName", (int)lNum].Style.SelectionForeColor = Color.LightGray;
                }
            }

        }

        /// <summary><para>method outline:</para>
        /// <para>グループ名チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = Check_GroupName();</para>
        /// </example>
        /// <returns>0:正常 -1:重複あり -2:入力異常 -3:未選択</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private long Check_GroupName()
        {
            long lRtn = 0;                          //リターン値
            string sErrCharacter = @"\/:,;*?""<>|"; //入力禁止コード

            m_csGroupHashTable.ClearAllObject();

            string sKeyID = null;
            string sData = null;
            bool bCheckFlg = true;
            int iCount = 0;

            for (int iLp = 0; iLp < ProjectGroup_DataGridView.RowCount; iLp++)
            {
                if ((bool)ProjectGroup_DataGridView["CheckColumn", iLp].Value == false)
                {// チェック対象外
                    continue;
                }

                int iFlg = 0;
                iCount++;

                sKeyID = ProjectGroup_DataGridView["OrgGroupName", iLp].Value.ToString();
                if (ProjectGroup_DataGridView["NewGroupName", iLp].Value != null)
                {// 入力済み
                    sData = ProjectGroup_DataGridView["NewGroupName", iLp].Value.ToString();
                    if (sData.Equals("") == true)
                    {// ""指定
                        sData = sKeyID;
                    }
                }
                else
                {// 未入力の場合、オリジナルグループ名とする。
                    sData = sKeyID;
                }

                if (sData.IndexOfAny(sErrCharacter.ToCharArray()) == -1)
                {// 入力文字正常
                    // 重複フォルダーチェック
                    if (Directory.Exists(HySEnvInf.GetDataHomeDirectory().ToString() + "\\" + sData) == true)
                    {// 重複ディレクトリ有り
                        iFlg = -1;
                    }
                    
                    for (int iNLp = 0; iNLp < ProjectGroup_DataGridView.RowCount; iNLp++)
                    {
                        if (iLp == iNLp || (bool)ProjectGroup_DataGridView["CheckColumn", iLp].Value == false)
                        {// チェック対象外
                            continue;
                        }

                        // オリジナルグループ名との比較
                        if (sData.Equals(ProjectGroup_DataGridView["OrgGroupName", iNLp].Value.ToString()) == true)
                        {
                            iFlg = -2;
                            break;
                        }

                        // 入力行グループ名との比較
                        if (ProjectGroup_DataGridView["NewGroupName", iNLp].Value != null)
                        {
                            if (sData.Equals(ProjectGroup_DataGridView["NewGroupName", iNLp].Value.ToString()) == true)
                            {// 取込プロジェクトグループに重複グループ名有り
                                iFlg = -2;
                                break;
                            }
                        }
                    }
                }
                else
                {// 入力値異常
                    iFlg = -2;
                }

                // 追加
                m_csGroupHashTable.AddObject(new HySString(sKeyID), new HySString(sData));

                if (iFlg == -1)
                {// 重複フォルダ有り
                    ProjectGroup_DataGridView["NewGroupName", iLp].Style.BackColor = Color.Yellow;
                    ProjectGroup_DataGridView["NewGroupName", iLp].Style.SelectionBackColor = Color.Yellow;
                    ProjectGroup_DataGridView["NewGroupName", iLp].Style.SelectionForeColor = Color.LightGray;
                    lRtn = -1;
                }
                else if (iFlg == -2)
                {// 入力異常有り
                    ProjectGroup_DataGridView["NewGroupName", iLp].Style.BackColor = Color.Red;
                    ProjectGroup_DataGridView["NewGroupName", iLp].Style.SelectionBackColor = Color.Red;
                    ProjectGroup_DataGridView["NewGroupName", iLp].Style.SelectionForeColor = Color.Empty;
                    bCheckFlg = false;
                }
                else
                {// 入力正常
                    ProjectGroup_DataGridView["NewGroupName", iLp].Style.BackColor = Color.Empty;
                    ProjectGroup_DataGridView["NewGroupName", iLp].Style.SelectionBackColor = Color.Empty;
                    ProjectGroup_DataGridView["NewGroupName", iLp].Style.SelectionForeColor = Color.Empty;
                }
            }

            if (iCount == 0)
            {// 選択無し
                lRtn = -3;
            }
            if (bCheckFlg == false)
            {// 展開処理不可能
                lRtn = -2;
            }
            return lRtn;
        }

        /// <summary><para>method outline</para>
        /// <para>「実行」ボタンクリック時処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>this.Action_Button.Click += new System.EventHandler(this.Action);</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 Action(object sender, EventArgs e)
        {
            long lRtc = Check_GroupName();
            if (lRtc == -2)
            {// 入力異常中止
                MessageBox.Show(MSG_WARNING_PROJECTGROUP_NGNAME, MSGBOX_TITLE);
            }
            else if (lRtc == -3)
            {// 選択データなし
                MessageBox.Show(MSG_CHK_INMPUT_PROJECTGROUP, MSGBOX_TITLE);
            }
            else
            {// 実行
                if(lRtc == -1)
                {// 入力異常有り
                    if (MessageBox.Show(MSG_WARNING_PROJECTGROUP_DNAME, MSGBOX_TITLE, MessageBoxButtons.OKCancel) == DialogResult.Cancel)
                    {// 処理中断
                        return;
                    }
                }
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }

        /// <summary><para>method outline</para>
        /// <para>「キャンセル」ボタンクリック時処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>this.Cancel_Button.Click += new System.EventHandler(this.Cancel);</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(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        /// <summary><para>method outline:</para>
        /// <para>プロジェクトグループ名テーブル取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>HySDataHashTable csGroupHashTable = GetProjectGroupHash(); </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>プロジェクトグループ名テーブル</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public HySDataHashTable GetProjectGroupHash()
        {
            return m_csGroupHashTable;
        }

        /// <summary>
        /// <para>method outline:</para>
        /// <para>全て解除処理</para>
        /// </summary>
        /// <example>
        /// <para>usage:</para>
        /// <para>AllReset_Button_Click(sender,e)</para>
        /// </example>
        /// <param name="sender">オブジェクト</param>
        /// <param name="e">イベント</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks>
        /// <para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private void AllReset_Button_Click(object sender, EventArgs e)
        {
            for (int iLp = 0; iLp < this.ProjectGroup_DataGridView.RowCount; iLp++)
            {  // 行数分繰り返す
                this.ProjectGroup_DataGridView["CheckColumn", iLp].Value = false; // チェックボックスを解除する
            }
        }

        /// <summary><para>method outline</para>
        /// <para>ヘルプリンクイベント</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>HelpJump_button_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 HelpJump_button_Click(object sender, EventArgs e)
        {
            // ヘルプ画面の表示
            HySShowHelpNavigator.ShowHelpNavigator(HySShowHelpNavigator.NAV_MSG_PROJECT_0010, null);
        }

        /// <summary><para>method outline</para>
        /// <para>グループ名の名称変更の候補作成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>string name = CreateNewGroupName()</para>
        /// </example>
        /// <param name="sKeyID">既存グループ名称</param>
        /// <returns>プロジェクトグループ名</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>[CommonMP][ver 1.6.0][2016/02/15][新規作成]</para>
        /// </remarks>
        private string CreateNewGroupName(string sKeyID)
        {
            // 命名規定のルール
            //
            // ・既存グループ名称 + 半角スペース + (数字)
            // 　※数字は２以上（重複時は数字をインクリメント）、上限は「99999」。
            //
            // 例１：
            // 「SampleProjectGroup」の場合、「SampleProjectGroup (2)」
            // 　※但し、SampleProjectGroup (2)が既存のプロジェクトグループ名と重複しないことが前提
            //
            // 例２：
            // 「SampleProjectGroup(999)」の場合、「SampleProjectGroup(1000)」
            // 　※但し、SampleProjectGroup(1000)が既存のプロジェクトグループ名と重複しないことが前提
            // 
            // 例３：
            // 「SampleProjectGroup(99998)」の場合、「SampleProjectGroup(99998) (2)」
            // 　※但し、SampleProjectGroup(99999)が既存のプロジェクトグループ名に存在することが前提

            int iLen = sKeyID.Length;
            int iPar1 = sKeyID.LastIndexOf('(');
            int iPar2 = sKeyID.LastIndexOf(')');
            int iIndex = 0;

            string StrIndex;
            string StrConv;
            string stRename = "";

            // 名称の後ろが "(" + 数字 + ")" であるかの判定
            if (iPar1 > 0 && iPar2 > 0 && iPar1 + 1 < iPar2 && iPar2 == iLen - 1)
            {
                // 半角括弧内の文字を抽出
                StrIndex = sKeyID.Substring(iPar1 + 1, iPar2 - iPar1 - 1);

                // 文字を半角に変換
                StrConv = Strings.StrConv(StrIndex, VbStrConv.Narrow, 0);

                try
                {
                    StrConv = StrConv.ToString().Trim();

                    // 半角括弧内の文字を数値に変換
                    iIndex = int.Parse(StrConv);

                    if (iIndex < 99999)
                    {
                        stRename = RenameGroupName(sKeyID.Substring(0, iPar1), iIndex);
                    }
                    else
                    {
                        // 99999 以上は単に数字を付与する
                        stRename = RenameGroupName(sKeyID + " ", 1);
                    }
                }
                catch (Exception)
                {
                    // 数値ではないので単に数字を付与する
                    stRename = RenameGroupName(sKeyID + " ", 1);
                }
            }
            else
            {
                // 数値ではないので単に数字を付与する
                stRename = RenameGroupName(sKeyID + " ", 1);
            }

            for (int i = 0; i < ProjectGroup_DataGridView.RowCount; i++)
            {
                // 直前に作成した候補の名称と一致していたら再度リネームする
                if (stRename == ProjectGroup_DataGridView["NewGroupName", i].Value.ToString())
                {
                    stRename = CreateNewGroupName(stRename);
                }
            }

            return stRename;
        }

        /// <summary><para>method outline</para>
        /// <para>グループ名の名称変更の候補作成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>string sNewName = RenameGroupName()</para>
        /// </example>
        /// <param name="sName">グループ名称</param>
        /// <param name="iIndex">インデックス</param>
        /// <returns>変換グループ名称</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>[CommonMP][ver 1.6.0][2016/02/15][新規作成]</para>
        /// </remarks>
        private string RenameGroupName(string sName, int iIndex)
        {
            string sNewName = sName + "(" + (iIndex + 1).ToString() + ")";

            if (Directory.Exists(HySEnvInf.GetDataHomeDirectory().ToString() + "\\" + sNewName) == true)
            {
                if (iIndex == 99998)
                {
                    sNewName = RenameGroupName(sName + "(99998) ", 1);
                    return sNewName;
                }
                sNewName = RenameGroupName(sName, iIndex + 1);
            }

            return sNewName;
        }
    }
}
