// <summary>ソースコード：>ＨＹＭＣＯポータブルデータ取込クラス</summary>
// <author>CommonMP</author>

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Diagnostics;

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

using CommonMP.HYMCO.Interface;
using CommonMP.HYMCO.CoreImpl.Data.ProjectCtl;
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 class McPortableDataImport
    {
        /// <summary>クラス名称</summary>
        static private readonly string CLASS_NAME = "McPortableDataImport";

        /// <summary>ポータブルデータ取込画面タイトル</summary>
        static private readonly string PORTABLE_IMPORT_DLG_TITLE = Properties.McDotNetViewerResources.ResourceManager.GetString("FILE_DLG_TITLE_IMPORT_PORTABLE");
        /// <summary>ポータブルデータ取込画面フィルター</summary>
        static private readonly string PORTABLE_IMPORT_DLG_FILTER = Properties.McDotNetViewerResources.ResourceManager.GetString("FILE_DLG_FILTER_ARCHIVE");
        /// <summary>ポータブルデータ取込画面フィルター</summary>
        static private readonly string PRJDB_IMPORT_DLG_FILTER = Properties.McDotNetViewerResources.ResourceManager.GetString("FILE_DLG_FILTER_PRJDB");

        /// <summary>メッセージタイトル </summary>
        static private readonly string MSGBOX_TITLE = McMessage.GetString("MC_MSG_TITLE_PROJECT_MANAGEMENT");
        /// <summary>メッセージ「正常終了」 </summary>
        static private string MSG_COMPLETE_IMPORT_PORTABLE = McMessage.GetString("MC_MSG_INFO_COMPLETE_IMPORT_PORTABLE");
        /// <summary>メッセージ「異常終了」 </summary>
        static private readonly string MSG_ERR_IMPORT_PORTABLE = McMessage.GetString("MC_MSG_ERROR_IMPORT_PORTABLE");
        /// <summary>メッセージ「選択されたファイルに取込み可能なデータが存在しませんでした。」 </summary>
        static private readonly string MSG_ERR_IMPORT_PORTABLE_NONDATA = McMessage.GetString("MC_MSG_ERROR_IMPORT_PORTABLE_NONDATA");

        /// <summary>ビューア </summary>
        private HySViewer m_csViewer;
        
        /// <summary><para>method outline:</para>
        /// <para>コンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McPortableDataImport csPortableDataImport = new McPortableDataImport( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public McPortableDataImport()
        {
        }

        /// <summary><para>method outline:</para>
        /// <para>コンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McPortableDataImport csPortableDataImport = new McPortableDataImport( csViewer )</para>
        /// </example>
        /// <param name="csViewer">ビューア</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public McPortableDataImport(HySViewer csViewer)
        {
            m_csViewer = csViewer;
        }

        /// <summary><para>method outline:</para>
        /// <para>ポータブルデータ取込処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>ImportData(); </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>0,1:成功 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public void ImportData()
        {
            long lRtn = 0;

            OpenFileDialog csOpenFileDialog = new OpenFileDialog();
            csOpenFileDialog.Title = PORTABLE_IMPORT_DLG_TITLE;
            csOpenFileDialog.Filter = PORTABLE_IMPORT_DLG_FILTER + "|" + PRJDB_IMPORT_DLG_FILTER;
            csOpenFileDialog.InitialDirectory = HySEnvInf.GetDataHomeDirectory().ToString();
            csOpenFileDialog.RestoreDirectory = true;

            // ポータブルデータファイル選択画面表示
            if (csOpenFileDialog.ShowDialog() == DialogResult.OK)
            {
                ((HySDotNetViewer)(m_csViewer)).GetMainForm().Cursor = Cursors.WaitCursor;

                if (csOpenFileDialog.FileName.EndsWith(".prjdb") == true)
                {// DBエクスポートデータ変換処理
                    HySString csFileName = new HySString(csOpenFileDialog.FileName);

                    // プロジェクトデータ取込要求
                    HySEventObject csEventObject = new HySEventObject(HySSysEvent.OBJID_BUSIPROCEDURE, HySEventObject.CMND_DB_COMMON);
                    csEventObject.SetToSimKind(McDefine.SIMULATOR_KIND);
                    csEventObject.SetSubEventNo(McDefine.HYM_PRJDATA_CONVERT);
                    csEventObject.SetData(csFileName);
                    if (!m_csViewer.PutEvent(csEventObject))
                    {
                       // ver1.5 エラートレース日本語対応
                        HySLog.LogOut(HySLog.ONLINE, "McPortableDataImport:ImportData", 
                            Properties.McDotNetViewerResources.STATEMENT_SEND_FAILURE );
                       // HySLog.LogOut(HySLog.ONLINE, "McPortableDataImport:ImportData", "イベント送信失敗");
                    }

                    return;
                }
                else
                {// ポータブルデータ

                    HySDataHashTable csNewProjectGroups = new HySDataHashTable();
                    lRtn = ExpandPortableData(csOpenFileDialog.FileName, ref csNewProjectGroups);

                    if (csNewProjectGroups.GetCount() > 0)
                    {// プロジェクトグループ情報変更
                        lRtn = EditProjectFile(csNewProjectGroups);
                    }
                }

                ((HySDotNetViewer)(m_csViewer)).GetMainForm().Cursor = Cursors.Default;

            }

            // 終了メッセージ
            if (lRtn == 1)
            {// 正常終了
                MessageBox.Show(MSG_COMPLETE_IMPORT_PORTABLE, MSGBOX_TITLE);
            }
            else if(lRtn == -1)
            {// 異常終了
                MessageBox.Show(MSG_ERR_IMPORT_PORTABLE, MSGBOX_TITLE);
            }
            else if (lRtn == -2)
            {// 取込みデータ無し
                MessageBox.Show(MSG_ERR_IMPORT_PORTABLE_NONDATA, MSGBOX_TITLE);
            }

            return ;
        }

        /// <summary><para>method outline:</para>
        /// <para>圧縮ファイル展開</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = ImportData(csFileName, csNewProjectGroups); </para>
        /// </example>
        /// <param name="csFileName">ファイル名称</param>
        /// <param name="csNewProjectGroups">プロジェクトグループ名</param>
        /// <returns>0:キャンセル 1:成功 -1:異常　-2:データ無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private long ExpandPortableData(string csFileName, ref HySDataHashTable csNewProjectGroups)
        {
            try
            {
                long lRtn = 1;

                HySDataHashTable csGroupHashTable = new HySDataHashTable();
                HySDataHashTable csExpandGroupHashTable = new HySDataHashTable();

                // Zipファイル指定
                HySString csFileFullPath = new HySString(csFileName);
                HySDotNetZipExpander csZip = new HySDotNetZipExpander(csFileFullPath);

                // 重複用
                List<HySStringRoot> csEntryList = csZip.GetAllEntryName();
                if (csEntryList.Count > 0)
                {
                    // グループ名情報を取得
                    foreach (HySString targetEntry in csEntryList)
                    {
                        int iCase = targetEntry.IndexOf("\\");
                        if (iCase > 1)
                        {
                            string sGroupName = targetEntry.ToString();
                            HySString csGroupName = new HySString(sGroupName.Substring(0, iCase));

                            if (csGroupHashTable.GetObject(csGroupName) == null)
                            {
                                // 重複フォルダーチェック
                                if (Directory.Exists(HySEnvInf.GetDataHomeDirectory().ToString() + "\\" + csGroupName.ToString()) == true)
                                {
                                    csGroupHashTable.AddObject(csGroupName, new HySString(""));
                                }
                                else
                                {
                                    csGroupHashTable.AddObject(csGroupName, csGroupName);
                                }
                            }
                        }
                    }

                }

                if (csGroupHashTable.GetCount() == 0)
                {// 取込みデータ無し
                    return -2;
                }

                ((HySDotNetViewer)(m_csViewer)).GetMainForm().Cursor = Cursors.WaitCursor;
                McDotNetPortableGroupNameChangeForm csForm = new McDotNetPortableGroupNameChangeForm(csGroupHashTable);
                if (csForm.ShowDialog() == DialogResult.Cancel)
                {// キャンセル
                    return 0;
                }

                ((HySDotNetViewer)(m_csViewer)).GetMainForm().Cursor = Cursors.Default;

                csExpandGroupHashTable = csForm.GetProjectGroupHash();

                // 展開用
                if (csZip.Read() == 0)
                {
                    // プロジェクトグループ名置き換え
                    foreach (HySString targetEntry in csEntryList)
                    {
                        int iCase = targetEntry.IndexOf("\\");
                        if (iCase > 1)
                        {
                            string sGroupName = targetEntry.ToString();
                            HySString csOrgGroupName = new HySString(sGroupName.Substring(0, iCase));

                            HySString csNewGroupName = (HySString)csExpandGroupHashTable.GetObject(csOrgGroupName);
                            if ((object)csNewGroupName != null)
                            {// 展開対象
                                if (csNewGroupName.Equal(csOrgGroupName) == false)
                                {// プロジェクトグループ名の変更有り
                                    HySString csPathStr = new HySString();

                                    targetEntry.Substring(iCase, ref csPathStr);
                                    HySString csNewEntry = csNewGroupName + csPathStr;
                                    csZip.ChangeFileName(targetEntry, csNewEntry);

                                    csZip.AddTargetEntry(csNewEntry);
                                }
                                else
                                {// プロジェクトグループ名の変更無し
                                    csZip.AddTargetEntry(targetEntry);
                                }
                            }
                        }
                    }

                    // 展開
                    csZip.EditExpand(HySEnvInf.GetDataHomeDirectory());
                    csZip.Dispose();
                }

                // プロジェクトグループ名変更情報作成
                csNewProjectGroups.ClearAllObject();
                HySString csKeyID = null;
                HySString csData = null;
                HySDataLinkedList csList = csExpandGroupHashTable.GetKeyList();
                for (long lNum = 0; lNum < csList.GetCount(); lNum++)
                {
                    csKeyID = (HySString)csList.GetData(lNum);
                    csData = (HySString)csExpandGroupHashTable.GetObject(csKeyID);
                    if (csKeyID.Equal(csData) == false)
                    {
                        csNewProjectGroups.AddObject(csKeyID, csData);
                    }

                }

                return lRtn;
            }
            catch(Exception ex)
            {
               // ver1.5 エラートレース日本語対応
                HySLog.LogOut(HySLog.ONLINE, CLASS_NAME, "ExpandPortableData", 
                    Properties.McDotNetViewerResources.STATEMENT_COMPR_FILE_NG + Environment.NewLine + ex.ToString());
               // HySLog.LogOut(HySLog.ONLINE, CLASS_NAME, "ExpandPortableData", "圧縮ファイル展開処理で例外発生:" + Environment.NewLine + ex.ToString());
                return -1;
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>プロジェクトデータ編集</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = EditProjectFile(); </para>
        /// </example>
        /// <param name="csNewProjectGroups">プロジェクトグループ名情報</param>
        /// <returns>1:成功 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private long EditProjectFile(HySDataHashTable csNewProjectGroups)
        {
            long lRtn = 1;
            HySDataLinkedList csList = csNewProjectGroups.GetKeyList(); // キーリスト一覧取得

            HySString csKeyID = null;
            HySString csData = null;

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

                string csProjectGroupName = HySEnvInf.GetDataHomeDirectory().ToString() + "\\" + csData.ToString();
                string[] sFiles = Directory.GetFiles(csProjectGroupName, "*.cmprj", SearchOption.TopDirectoryOnly);                // 対象ファイル

                //対象ファイルを取得
                foreach (string sFileItem in sFiles)
                {
                    HySString csFileName = new HySString(sFileItem);
                    if (WriteProjectFile(csFileName, csData) != 0)
                    {
                        //更新異常
                        lRtn = -1;
                    }
                }
            }
            return lRtn;
        }


        /// <summary><para>method outline:</para>
        /// <para>プロジェクトファイル更新</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = WriteProjectFile(csFileName, csNewProjectGroup); </para>
        /// </example>
        /// <param name="csFileName">ファイル名称</param>
        /// <param name="csNewProjectGroup">プロジェクトグループ</param>
        /// <returns>0:成功 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private long WriteProjectFile(HySString csFileName, HySString csNewProjectGroup)
        {
            long lRtn = -1;

            HySSimulationDataContainer csContainer = null;
            HySFile csFile = new HySFile(csFileName);
            try
            {
                if (csFile.Open(HySFile.OPEN_MODE.OPEN, HySFile.READ_WRITE_MODE.READ_WRITE, HySFile.DIRECTORY_MODE.NOT_MK_DIR) != 0)
                {// ファイルオープン失敗
                   // ver1.5 エラートレース日本語対応
                    HySLog.LogOut(HySLog.ONLINE, CLASS_NAME, "WriteProjectFile", 
                        Properties.McDotNetViewerResources.STATEMENT_PROJ_FOPEN_NG + csFileName.ToString());
                   // HySLog.LogOut(HySLog.ONLINE, CLASS_NAME, "WriteProjectFile", "プロジェクトファイル更新処理でファイルオープン失敗:" + csFileName.ToString());
                    return lRtn;
                }

                csContainer = csFile.DataRead() as HySSimulationDataContainer;
                csFile.Close();

                if (csContainer != null)
                {// コンテナ情報あり
                    // プロジェクトグループ名情報変更
                    McProjectInfData csProjectInf = (McProjectInfData)csContainer.GetData(McDefine.HYM_DATA_PROJECT_INFO);
                    HySString csProjectName = csProjectInf.GetProjectName();
                    csProjectInf.SetProjectGroupName(csNewProjectGroup);
                    csProjectInf.SetDispProjectName(csNewProjectGroup + "_" + csProjectName);
                    csContainer.SetData(McDefine.HYM_DATA_PROJECT_INFO, csProjectInf);

                    if (csFile.Open(HySFile.OPEN_MODE.TRANCATE, HySFile.READ_WRITE_MODE.READ_WRITE, HySFile.DIRECTORY_MODE.NOT_MK_DIR) == 0)
                    {// ファイルオープン成功
                        csFile.DataWrite(csContainer);
                        csFile.Close();
                        lRtn = 0;
                    }
                    else
                    {// ファイルオープン失敗 
                       // ver1.5 エラートレース日本語対応
                        HySLog.LogOut(HySLog.ONLINE, CLASS_NAME, "WriteProjectFile",
                            Properties.McDotNetViewerResources.STATEMENT_PROJ_FOPEN_NG + csFileName.ToString());
                       // HySLog.LogOut(HySLog.ONLINE, CLASS_NAME, "WriteProjectFile", "プロジェクトファイル更新処理でファイルオープン失敗:" + csFileName.ToString());
                    }

                    csFile = null;
                }

            }
            catch(Exception ex)
            {
                // エラー
                if (csFile != null)
                {
                    csFile.Close();
                    csFile = null;
                }
               // ver1.5 エラートレース日本語対応 
                HySLog.LogOut(HySLog.ONLINE, CLASS_NAME, "WriteProjectFile", 
                    Properties.McDotNetViewerResources.STATEMENT_PROJ_UPDATE_ERR + Environment.NewLine + ex.ToString());
               // HySLog.LogOut(HySLog.ONLINE, CLASS_NAME, "WriteProjectFile", "プロジェクトファイル更新処理で例外発生:" + Environment.NewLine + ex.ToString());
                lRtn = -1;
            }

            return lRtn;
        }
    }
}
