using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;
using System.Text.RegularExpressions;
using Microsoft.Win32;
using MSAPI = Microsoft.WindowsAPICodePack;
using System.IO;

namespace CSRender
{
    public partial class MainWindow : Window
    {
        //フォルダ指定のためにファイルをドラッグ
        private void textBox_PreviewDragOver(object sender, System.Windows.DragEventArgs e)
        {
            if (e.Data.GetDataPresent(System.Windows.DataFormats.FileDrop, true))
            {
                e.Effects = System.Windows.DragDropEffects.Copy;
            }
            else
            {
                e.Effects = System.Windows.DragDropEffects.None;
            }
            e.Handled = true;
        }

        //エクスプローラーからテキストボックスにドロップして指定フォルダの場所をペースト
        private void TargetBox_Drop(object sender, System.Windows.DragEventArgs e)
        {
            var dropFiles = e.Data.GetData(System.Windows.DataFormats.FileDrop) as string[];
            if (dropFiles == null) return;
            //カーソルを終端に置く
            targetBox.Text = dropFiles[0];
            targetBox.Focus();
            targetBox.Select(this.targetBox.Text.Length, 0);
        }
        private void RefBox_Drop(object sender, System.Windows.DragEventArgs e)
        {
            var dropFiles = e.Data.GetData(System.Windows.DataFormats.FileDrop) as string[];
            if (dropFiles == null) return;
            //カーソルを終端に置く
            referenceBox.Text = dropFiles[0];
            referenceBox.Focus();
            referenceBox.Select(this.referenceBox.Text.Length, 0);
        }
        private void WorkBox_Drop(object sender, System.Windows.DragEventArgs e)
        {
            var dropFiles = e.Data.GetData(System.Windows.DataFormats.FileDrop) as string[];
            if (dropFiles == null) return;
            //カーソルを終端に置く
            workBox.Text = dropFiles[0];
            workBox.Focus();
            workBox.Select(this.workBox.Text.Length, 0);
            if (!Directory.Exists(System.IO.Path.Combine(workBox.Text, "report")))
            {
                Directory.CreateDirectory(System.IO.Path.Combine(workBox.Text, "report"));
            }
        }

        private void ReportBox_Drop(object sender, System.Windows.DragEventArgs e)
        {
            var dropFiles = e.Data.GetData(System.Windows.DataFormats.FileDrop) as string[];
            if (dropFiles == null) return;
            //カーソルを終端に置く
            reportBox.Text = dropFiles[0];
            reportBox.Focus();
            reportBox.Select(this.reportBox.Text.Length, 0);
        }

        //参照ボタンClickでフォルダ選択のダイアログを表示（対象フォルダ）
        private void TagetButton_Click(object sender, RoutedEventArgs e)
        {
            
            //フォルダ選択の場合
            var selectFile = new MSAPI::Dialogs.CommonOpenFileDialog();
            selectFile.IsFolderPicker = true;
            selectFile.Title = "フォルダを選択してください";
            if(Directory.Exists(targetBox.Text))//前回値が存在する場合はそのフォルダを初期値として表示
            {
                selectFile.InitialDirectory = targetBox.Text.Substring(0, targetBox.Text.LastIndexOf(@"\")); 
            }
            else
            {
                selectFile.InitialDirectory = @"C:";
            }
            if (selectFile.ShowDialog() != MSAPI::Dialogs.CommonFileDialogResult.Ok)
            {
                return;
            }
            //共通部分
            targetBox.Text = selectFile.FileName;
            targetBox.Focus();
            targetBox.Select(this.targetBox.Text.Length, 0);
        }

        //参照ボタンClickでフォルダ選択のダイアログを表示（リファレンスフォルダ）
        private void ReferenceButton_Click(object sender, RoutedEventArgs e)
        {
            
            //フォルダ選択の場合
            var selectFile = new MSAPI::Dialogs.CommonOpenFileDialog();
            selectFile.IsFolderPicker = true;
            selectFile.Title = "フォルダを選択してください";
            if (Directory.Exists(referenceBox.Text))//前回値が存在する場合はそのフォルダを初期値として表示
            {
                selectFile.InitialDirectory = referenceBox.Text.Substring(0, referenceBox.Text.LastIndexOf(@"\")); 
            }
            else
            {
                selectFile.InitialDirectory = @"C:";
            }
            if (selectFile.ShowDialog() != MSAPI::Dialogs.CommonFileDialogResult.Ok)
            {
                return;
            }
            //共通部分
            referenceBox.Text = selectFile.FileName;
            referenceBox.Focus();
            referenceBox.Select(this.referenceBox.Text.Length, 0);
        }

        //参照ボタンClickでフォルダ選択のダイアログを表示（作業フォルダ）
        private void WorkButton_Click(object sender, RoutedEventArgs e)
        {
            
            //フォルダ選択の場合
            var selectFile = new MSAPI::Dialogs.CommonOpenFileDialog();
            selectFile.IsFolderPicker = true;
            selectFile.Title = "フォルダを選択してください";
            if (Directory.Exists(workBox.Text))//前回値が存在する場合はそのフォルダを初期値として表示
            {
                selectFile.InitialDirectory = workBox.Text.Substring(0, workBox.Text.LastIndexOf(@"\")); 
            }
            else
            {
                selectFile.InitialDirectory = @"C:";
            }
            if (selectFile.ShowDialog() != MSAPI::Dialogs.CommonFileDialogResult.Ok)
            {
                return;
            }
            //共通部分
            workBox.Text = selectFile.FileName;
            workBox.Focus();
            workBox.Select(this.workBox.Text.Length, 0);
            if (!Directory.Exists(System.IO.Path.Combine(selectFile.FileName, "report")))
            {
                Directory.CreateDirectory(System.IO.Path.Combine(selectFile.FileName, "report"));
            }
            //reportBox.Text = System.IO.Path.Combine(selectFile.FileName, "report");
        }

        //参照ボタンClickでフォルダ選択のダイアログを表示（検版レポートパス）
        private void ReportButton_Click(object sender, RoutedEventArgs e)
        {
            
            //フォルダ選択の場合
            var selectFile = new MSAPI::Dialogs.CommonOpenFileDialog();
            selectFile.IsFolderPicker = true;
            selectFile.Title = "フォルダを選択してください";
            if (Directory.Exists(workBox.Text))//前回値が存在する場合はそのフォルダを初期値として表示
            {
                selectFile.InitialDirectory = workBox.Text.Substring(0, reportBox.Text.LastIndexOf(@"\")); 
            }
            else
            {
                selectFile.InitialDirectory = @"C:";
            }
            if (selectFile.ShowDialog() != MSAPI::Dialogs.CommonFileDialogResult.Ok)
            {
                return;
            }
            //共通部分
            reportBox.Text = selectFile.FileName;
            reportBox.Focus();
            reportBox.Select(this.reportBox.Text.Length, 0);
        }

        private void EditEnvFile()
        {
            string appPath = System.Reflection.Assembly.GetExecutingAssembly().Location;  //モジュールのパスを取得
            string appDirectory = appPath.Substring(0, appPath.LastIndexOf(@"\") + 1);    //モジュールの存在するディレクトリを取得
            string dataPath = System.IO.Path.Combine("PureVerify.Data", "RipVerify", "setup", "PureVerifyDlg.env");
            string envFilePath = System.IO.Path.Combine(appDirectory, dataPath);//PureVerifyDlg.envまでのフルパス

            //.envファイルに記述する内容
            string equiosCenterPath = System.IO.Path.Combine(appDirectory, "PureVerify.Data", "EquiosCenter");//EquiosCenterのフルパス
            string workFolderPath = System.IO.Path.Combine(appDirectory, "PureVerify.Data", "RipVerify");//内部作業フォルダのフルパス
            string writeText = "**EquiosCenter: \"" + equiosCenterPath + "\"\r\n";
            writeText += "**WorkDirRoot: \"" + workFolderPath + "\"\r\n";
            writeText += "**InspQuality: \"3\"\r\n";
            writeText += "**MarkDistance: \"50\"\r\n";
            writeText += "**ReportEncodeType: \"2\"\r\n";
            writeText += "**WndPosLeft: \"348\"\r\n";
            writeText += "**WndPosTop: \"125\"\r\n";
            writeText += "**WndPosRight: \"933\"\r\n";
            writeText += "**WndPosBottom: \"556\"\r\n";
            writeText += "**ShowOKList: \"1\"\r\n";

            // StreamWriterオブジェクトのインスタンスを生成
            StreamWriter streamWriter = new StreamWriter(envFilePath, false, Encoding.GetEncoding("Shift_JIS"));
            // Writeメソッドで文字列データを書き込む
            streamWriter.Write(writeText);
            // StreamWriterオブジェクトを閉じる
            streamWriter.Close();

        }

        //レポート出力パスの確認
        private bool checkReportPath()
        {
            bool reportFlag = true;
            //string pdfReportPath = "";
            //string pdfReportName = "";
            //int directoryCount = 0;
            if (reportBox.Text != "")//入力があるか
            {
                if (!Directory.Exists(reportBox.Text))
                {
                    Directory.CreateDirectory(reportBox.Text);
                }
                /*
                directoryCount = reportBox.Text.Split(char.Parse(@"\")).Length - 1;//入力文字列がファイル名のみかディレクトリも含むか
                if (directoryCount == 0)//ファイル名のみならば作業ディレクトリのreportフォルダに出力
                {
                    reportBox.Text = NameCalibration(reportBox.Text);
                    reportBox.Text = System.IO.Path.Combine(workBox.Text, "report", reportBox.Text);
                }
                pdfReportPath = reportBox.Text.Substring(0, reportBox.Text.LastIndexOf(@"\"));//メニュー入力から出力パスを取得
                pdfReportName = reportBox.Text.Substring(reportBox.Text.LastIndexOf(@"\"));//メニュー入力からレポートファイル名を取得
                if (!System.IO.Path.IsPathRooted(pdfReportPath))//指定したパス文字列にルートが含まれているかどうか
                {
                    pdfReportPath = System.IO.Path.Combine(workBox.Text, "report", pdfReportPath);//含まれていなければ作業フォルダのreportフォルダに出力
                }
                if (!Directory.Exists(pdfReportPath))//指定先のフォルダが存在するか
                {
                    Directory.CreateDirectory(pdfReportPath);//なければ作成
                }
                pdfReportPath = System.IO.Path.GetFullPath(pdfReportPath);//フルパスを取得

                //レポートファイル名に不正文字が使用されいないかチェック
                pdfReportName = NameCalibration(pdfReportName);

                if (pdfReportName.Length < 4 || pdfReportName.Substring(pdfReportName.Length - 4) != ".pdf")//入力に拡張子がついているか
                {
                    pdfReportName += ".pdf";
                }
                reportBox.Text = pdfReportPath + pdfReportName;
                reportBox.Focus();
                reportBox.Select(this.reportBox.Text.Length, 0);*/
            }
            else
            {
                reportBox.Text = System.IO.Path.Combine(workBox.Text, "report");
                if(!Directory.Exists(System.IO.Path.Combine(workBox.Text, "report")))
                {
                    Directory.CreateDirectory(System.IO.Path.Combine(workBox.Text, "report"));
                }
            }
            return reportFlag;
        }

        //レポート名に使用不可の文字が含まれている場合の処理
        private string NameCalibration(string inFileName)
        {
            string[] charsToRemove = new string[] { "/", ":", "*", "?", "<", ">", "|" };
            char[] charsTocheck = new char[] { '/', ':', '*', '?', '<', '>', '|' };
            if (inFileName.IndexOfAny(charsTocheck) >= 0)
            {
                foreach (var allNg in charsToRemove)
                {
                    inFileName = inFileName.Replace(allNg, string.Empty);
                }
                ResultConsole.Text += "　検版レポート名に使用できない文字が含まれていたため、自動修正しました。";
                ResultConsole.Text += "\r\n\r\n";
                DoEvents();
            }
            
            return inFileName;
        }

        private string SelectFileTarget(bool dummyFlag, string targetBoxText, string referenceBoxText, string workBoxText)
        {
            string dummyFileName = "";
            //対象とリファレンスが同名ファイルであるか確認
            string TarFileName = System.IO.Path.GetFileName(referenceBoxText);
            string RefFileName = System.IO.Path.GetFileName(targetBoxText);
            if (TarFileName != RefFileName)
            {
                //指定した作業フォルダ内にダミー用フォルダを設定（無ければ生成）
                string dummyDir = System.IO.Path.Combine(workBoxText, "Dummy");
                if (!Directory.Exists(dummyDir)) { Directory.CreateDirectory(dummyDir); }
                string dummyTarDir = System.IO.Path.Combine(dummyDir, "Target");
                if (!Directory.Exists(dummyTarDir)) { Directory.CreateDirectory(dummyTarDir); }
                string dummyRefDir = System.IO.Path.Combine(dummyDir, "Reference");
                if (!Directory.Exists(dummyRefDir)) { Directory.CreateDirectory(dummyRefDir); }
                //ダミーファイルを作成
                dummyFileName = CompareTIFF.createDummyFile(targetBoxText, dummyTarDir, dummyFileName);
                dummyFileName = CompareTIFF.createDummyFile(referenceBoxText, dummyRefDir, dummyFileName);
                dummyFlag = true;
                //検版対象をダミーに指定
                targetBoxText = dummyTarDir;
                referenceBoxText = dummyRefDir;
            }

            return dummyFileName;
        }

        //指定のパスにディレクトリが無ければ作成
        private void checkDirPath(string inDirPath)
        {
            if (!Directory.Exists(inDirPath))
            {
                Directory.CreateDirectory(inDirPath);//パスにディレクトリが無ければ作成
            }
            
        }

        //指定のパスにディレクトリがあれば削除し、新たな同名ディレクトリを作成
        private void DeleteOldDir(string inDirPath)
        {
            if (Directory.Exists(inDirPath))
            {
                Directory.Delete(inDirPath,true);//パスにディレクトリがあれば削除
            }
            Directory.CreateDirectory(inDirPath);//同名のディレクトリを作成
        }

        //キャンセルが実行されたときに、途中で生成したファイル群を削除
        private void DelDirCancel(string inWorkPath)
        {
            try
            {
                if (Directory.Exists(System.IO.Path.Combine(inWorkPath, "OUT_DIFF")))
                {
                    Directory.Delete(System.IO.Path.Combine(inWorkPath, "OUT_DIFF"), true);//OUT_DIFFを削除
                }
                if (Directory.Exists(System.IO.Path.Combine(inWorkPath, "work")))
                {
                    Directory.Delete(System.IO.Path.Combine(inWorkPath, "work"), true);//作業(work)ディレクトリを削除
                }
            }
            catch(Exception ex)
            {
                return;
            }
            
        }
    }
}
