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 System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Windows.Threading;
using System.Threading;

namespace CSRender
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        //comboBoxのインスタンス
        private ObservableCollection<ComboBoxSet> PagePattern = new ObservableCollection<ComboBoxSet>();
        private ObservableCollection<ComboBoxSet> FilePattern = new ObservableCollection<ComboBoxSet>();
        public MainWindow()
        {
            InitializeComponent();
            
            //ページ入力メニューの設定
            PagePattern.Add((new ComboBoxSet { Id = 1, Item = "全ページ"}));
            PagePattern.Add((new ComboBoxSet { Id = 2, Item = "指定" }));
            PageRange.ItemsSource = PagePattern;

            pageBox.GotFocus += PageBox_GotFocusSelectAll;

            //出力ファイル形式メニューの設定
            FilePattern.Add((new ComboBoxSet { Id = 1, Item = "JPG" }));
            FilePattern.Add((new ComboBoxSet { Id = 2, Item = "JPEG" }));
            FilePattern.Add((new ComboBoxSet { Id = 3, Item = "PNG" }));
            FilePattern.Add((new ComboBoxSet { Id = 4, Item = "TIF" }));
            FilePattern.Add((new ComboBoxSet { Id = 5, Item = "TIFF" }));
            FilePattern.Add((new ComboBoxSet { Id = 6, Item = "GIF" }));
            FilePattern.Add((new ComboBoxSet { Id = 7, Item = "BMP" }));
            FileSelect.ItemsSource = FilePattern;

            //PureVerifyの内部変数(PureVerifyDlg.env)を編集
            EditEnvFile();
            
            //デフォルトに前回の設定値を表示
            ResolutionBox.Value = Properties.Settings.Default.resolutionSetting;
            FileSelect.Text = Properties.Settings.Default.formatSetting;
            PositionBox.Value = Properties.Settings.Default.shiftPixelSetting;
            GradationBox.Value = Properties.Settings.Default.colorMarginSetting;
            SmallDiffBox.Value = Properties.Settings.Default.removePointSetting;
            VisualBox.Value = Properties.Settings.Default.shadingOffSetting;
            workBox.Text = Properties.Settings.Default.workSpaceSetting;
            targetBox.Text = Properties.Settings.Default.targetSetting;
            referenceBox.Text = Properties.Settings.Default.referenceSetting;
            reportBox.Text = Properties.Settings.Default.reportPathSetting;

            //ドラッグ&ドロップイベントの追加
            targetBox.AddHandler(TextBox.DragOverEvent, new DragEventHandler(textBox_PreviewDragOver), true);
            targetBox.AddHandler(TextBox.DropEvent, new DragEventHandler(TargetBox_Drop), true);
            referenceBox.AddHandler(TextBox.DragOverEvent, new DragEventHandler(textBox_PreviewDragOver), true);
            referenceBox.AddHandler(TextBox.DropEvent, new DragEventHandler(RefBox_Drop), true);
            workBox.AddHandler(TextBox.DragOverEvent, new DragEventHandler(textBox_PreviewDragOver), true);
            workBox.AddHandler(TextBox.DropEvent, new DragEventHandler(WorkBox_Drop), true);
            reportBox.AddHandler(TextBox.DragOverEvent, new DragEventHandler(textBox_PreviewDragOver), true);
            reportBox.AddHandler(TextBox.DropEvent, new DragEventHandler(ReportBox_Drop), true);
        }

        //Closeボタン実行
        private void CloseButton_Click(object sender, RoutedEventArgs e) =>
    Close();

        private CancellationTokenSource CancelToken = null;
        //private CancellationToken Canceller;

        //Cancelボタン実行
        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            isCanceled = true;
            ResultConsole.Text += "　処理を中断します\r\n";
            if (CancelToken == null) { return; }
            else { CancelToken.Cancel(); }
            //if (CancelToken?.IsCancellationRequested == false)
            //{ CancelToken.Cancel(); }
        }

        /// <summary>
        /// キャンセルフラグ
        /// </summary>
        private bool isCanceled = false;

        /// <summary>
        /// 比較ボタンを実行する。
        /// </summary>
        /// <param name="targetBoxText">選択された対象フォルダ（ファイル）のパス</param>
        /// <param name="mainWindow">アプリケーションのメインウインドウ</param>
        /// <param name="ResultConsoleText">出力メニューのテキストボックス</param>
        /// <param name="referenceBoxText">選択されたリファレンスフォルダ（ファイル）のパス</param>
        /// <param name="workBoxText">選択された作業フォルダのパス</param>
        /// <param name="shiftPixel">位置ズレ許容量のパラメータ</param>
        /// <param name="colorMargin">諧調差許容量のパラメータ</param>
        /// <param name="removePoint">微小差異許容量のパラメータ</param>
        /// <param name="shadingOff">視覚的あいまい量のパラメータ</param>
        /// <param name="pageFlag">ページ範囲を指定するかどうかを示すフラグ</param>
        /// <param name="selectedPage">TIFF変換するページ範囲</param>
        /// <param name="PageRange.Text">検査範囲を選択するプルダウンメニューで選択された内容の文字列</param>
        /// <param name="pageBox.Text">入力されたページを表す文字列</param>
        /// <param name="targetTIFFPath">対象フォルダのTIFF画像を配置するフォルダのパス</param>
        /// <param name="referenseTIFFPath">リファレンスフォルダのTIFF画像を配置するフォルダのパス</param>
        /// <param name="workDir">PureVerify内部の作業フォルダのパス</param>
        /// <param name="PDFName">検版レポートのファイル名</param>
        /// <param name="reportFlag">PureVerify実行の際にレポート名の引数を加えるかどうかを示すフラグ</param>
        /// <param name="pdfReportPath">検版レポートの出力先パス</param>

        private async void CompareButtonClick(object sender, RoutedEventArgs e)
        {
            killButton();//メニューを非活性化

            isCanceled = false;//Cancelフラグを初期化
            CancelToken = new CancellationTokenSource();
            var Canceller = CancelToken.Token;

            //前回のOUT_DIFFフォルダを削除
            string OldOutDiff = System.IO.Path.Combine(Properties.Settings.Default.workSpaceSetting, "OUT_DIFF");
            if (Directory.Exists(OldOutDiff))
            {
                Directory.Delete(OldOutDiff, true);
            }

            //各種パスの指定先の取得
            string workBoxText = workBox.Text;
            string reportBoxText = reportBox.Text;
            string targetBoxText = targetBox.Text;
            string referenceBoxText = referenceBox.Text;
            //検版パラメータの取得
            string shiftPixel = PositionBox.Text;
            string colorMargin = GradationBox.Text;
            string removePoint = SmallDiffBox.Text;
            string shadingOff = VisualBox.Text;
            //検版処理関係の変数
            string appPath = System.Reflection.Assembly.GetExecutingAssembly().Location;  //モジュールのパスを取得
            string appDirectory = appPath.Substring(0, appPath.LastIndexOf(@"\") + 1);    //モジュールの存在するディレクトリを取得
            string workDir = System.IO.Path.Combine(appDirectory, "PureVerify.Data", "RipVerify");//PureVerifyのworkパス
            string exePath = System.IO.Path.Combine(workDir, "bin", "x64");//exeのpathを取得
            int allPDFNum = 0;        //検版するPDFの総数
            int NGPDFNum = 0;         //検版でNGだったPDFの総数
            bool reportFlag = false;  //レポート名を変えるかどうか判別するフラグ
            string reportContentsInfo = "";//レポートに記述する内容
            bool pageFlag = false;    //ページ数の指定かあるかどうかのフラグ
            string selectedPage = ""; //指定されたページ数
            bool dummyFlag = false;   //ダミーのファイルを作るかどうかのフラグ
            string dummyFileName = "";//ダミーのファイル名

            //対象フォルダのpathチェック
            if (!Directory.Exists(targetBoxText) && !File.Exists(targetBoxText))
            {
                CustomMsgBox.Show(mainWindow, "指定されたファイルあるいはフォルダが存在しません。" +
                    "\nもう一度設定してください。", "The specified file or folder does not exist", MessageBoxButton.OK, MessageBoxImage.Information);
                ResultConsole.Text += "　指定された対象ファイルあるいはフォルダを発見できませんでした\r\n";
                ResultConsole.Text += "<TIFF変換中止>\r\n";
                ResultConsole.ScrollToEnd();
                Properties.Settings.Default.targetSetting = "";
                Properties.Settings.Default.Save();

                reviveButton();//終了前にメニューを復帰
                return;
            }

            //リファレンスファイルのpathチェック
            if (!Directory.Exists(referenceBoxText) && !File.Exists(referenceBoxText))
            {
                CustomMsgBox.Show(mainWindow, "指定されたリファレンスファイルあるいはフォルダが存在しません。" +
                    "\nもう一度設定してください。", "The specified reference file or folder does not exist", MessageBoxButton.OK, MessageBoxImage.Information);
                ResultConsole.Text += "　指定されたリファレンスファイルあるいはフォルダを発見できませんでした\r\n";
                ResultConsole.Text += "<TIFF変換中止>\r\n";
                ResultConsole.ScrollToEnd();
                Properties.Settings.Default.referenceSetting = "";
                Properties.Settings.Default.Save();

                reviveButton();//終了前にメニューを復帰
                return;
            }

            //検版対象がファイル名の場合、ファイル名が対象とリファレンスとで一致しなくても検版するように仕込み
            if (File.Exists(referenceBoxText) && File.Exists(targetBoxText))
            {
                dummyFileName = SelectFileTarget(dummyFlag, targetBoxText, referenceBoxText, workBoxText);
            }

            //出力ファイルpathのチェック
            if (!Directory.Exists(workBoxText) && !File.Exists(workBoxText))
            {
                CustomMsgBox.Show(mainWindow, "指定された作業フォルダが存在しません。" +
                    "\nもう一度設定してください。", "The work space folder does not exist", MessageBoxButton.OK, MessageBoxImage.Information);
                ResultConsole.Text += "　指定された作業フォルダを発見できませんでした\r\n";
                ResultConsole.Text += "<TIFF変換中止>\r\n";
                ResultConsole.ScrollToEnd();
                workBox.Text = "";
                Properties.Settings.Default.workSpaceSetting = workBoxText;
                Properties.Settings.Default.Save();

                reviveButton();//終了前にメニューを復帰
                return;
            }

            //前回のログが内部に残っていれば削除（エラー防止）
            CompareTIFF.deleteOldLog(System.IO.Path.Combine(workDir, "report"));

            string workLogPath = System.IO.Path.Combine(reportBoxText, "Log");//reportフォルダのパス
            checkDirPath(workLogPath);//なければ作成
            string outDiffPath = System.IO.Path.Combine(workBoxText, "OUT_DIFF");//DIFF画像の出力先パス
            checkDirPath(outDiffPath);//なければ作成
            
            try
            {
                //検版レポートの入力チェック
                reportFlag = checkReportPath();
                if (reportBoxText == "")
                {
                    reportBoxText = reportBox.Text;
                }
            }
            catch (Exception ex)
            {
                string WorkCategory = "レポート名の確認";
                ExceptionMessage(ex, workLogPath, WorkCategory);
            }

            //RIP処理時間の計測
            var ripTime = new System.Diagnostics.Stopwatch();
            ripTime.Start();//計測開始

            //必要に応じてページ引数を指定
            if (PageRange.Text == "指定")
            {
                pageFlag = true;
                selectedPage = pageBox.Text;
            }

            //実処理スタート
            try
            {
                //TIFF画像の生成
                ResultConsole.Text += "< TIFF変換開始 >\r\n";
                ResultConsole.Text += "　対象ファイルをTIFF画像に変換中\r\n";
                ResultConsole.ScrollToEnd();
                DoEvents();

                //対象フォルダ
                string targetTIFFPath = System.IO.Path.Combine(workBoxText, "work", "targetTIFF");
                DeleteOldDir(targetTIFFPath); //指定先に古いTIFF用フォルダがあれば削除し、新たに作成（前回作業時の生成物との混同防止）

                if (isCanceled)
                {
                    // キャンセルされたら終了
                    ResultConsole.Text += "　処理が中断されました\r\n";
                    DoEvents();
                    DelDirCancel(workBoxText);
                    reviveButton();
                    return;
                }

                //CSRenderの実行
                try
                {
                    await Task.Run(() =>
                    //await Task.Factory.StartNew(() =>
                    {
                        //string targetTIFFResult =
                        OutputTIFF.runCSRender(ResolutionBox.Text, "TIFF", pageFlag, selectedPage, targetBoxText, targetTIFFPath, Canceller, isCanceled);

                    }, Canceller);

                    //string targetTIFFResult = await OutputTIFF.runCSRender(ResolutionBox.Text, "TIFF", pageFlag, selectedPage, targetBoxText, targetTIFFPath, Canceller, isCanceled);
                }
                catch (OperationCanceledException)
                {
                    CancelToken.Dispose();
                    CancelToken = null;
                    ResultConsole.Text += "　処理が中断されました\r\n";
                    DelDirCancel(workBoxText);
                    reviveButton();
                    DoEvents();
                    return;
                }
                catch (Exception ex)
                {
                    string WorkCategory = "対象PDFのTIFF画像生成";
                    ExceptionMessage(ex, workLogPath, WorkCategory);
                }

                if (!isCanceled)
                {
                    ResultConsole.Text += "　リファレンスファイルをTIFF画像に変換中\r\n";
                    ResultConsole.ScrollToEnd();
                }

                //リファレンスフォルダ
                string referenceTIFFPath = System.IO.Path.Combine(workBoxText, "work", "referenceTIFF");
                DeleteOldDir(referenceTIFFPath); //指定先に古いTIFF用フォルダがあれば削除し、新たに作成（前回作業時の生成物との混同防止）

                if (isCanceled)
                {
                    // キャンセルされたら終了
                    ResultConsole.Text += "　処理が中断されました\r\n";
                    DelDirCancel(workBoxText);
                    DoEvents();
                    reviveButton();
                    return;
                }

                //CSRenderの実行
                try
                {
                    await Task.Run(() =>
                    {
                        //string referenceTIFFResult =
                        OutputTIFF.runCSRender(ResolutionBox.Text, "TIFF", pageFlag, selectedPage, referenceBoxText, referenceTIFFPath, Canceller, isCanceled);
                    }, Canceller);

                    //string referenceTIFFResult = await OutputTIFF.runCSRender(ResolutionBox.Text, "TIFF", pageFlag, selectedPage, referenceBoxText, referenceTIFFPath, Canceller, isCanceled);
                }
                catch (OperationCanceledException)
                {
                    CancelToken.Dispose();
                    CancelToken = null;
                    ResultConsole.Text += "　処理が中断されました\r\n";
                    DelDirCancel(workBoxText);
                    reviveButton();
                    DoEvents();
                    return;
                }
                catch (Exception ex)
                {
                    string WorkCategory = "リファレンスPDFのTIFF画像生成";
                    ExceptionMessage(ex, workLogPath, WorkCategory);
                }

                if (isCanceled)
                {
                    // キャンセルされたら終了
                    ResultConsole.Text += "　処理が中断されました\r\n";
                    DelDirCancel(workBoxText);
                    reviveButton();
                    return;
                }

                ripTime.Stop();//RIP時間の計測終了
                TimeSpan timeResult = ripTime.Elapsed;
                var allRipTime = $"{timeResult}".Substring(0, 8);

                ResultConsole.Text += "　[RIP処理時間　" + allRipTime + "]\r\n";
                ResultConsole.Text += "< TIFF変換完了 >\r\n";
                ResultConsole.ScrollToEnd();
                DoEvents();

                if (isCanceled)
                {
                    // キャンセルされたら終了
                    ResultConsole.Text += "　処理が中断されました\r\n";
                    DelDirCancel(workBoxText);
                    reviveButton();
                    return;
                }

                try
                {
                    //レポートへの出力内容を編集
                    //editReport(allRipTime, workBoxText);
                    reportContentsInfo = CompareTIFF.getReportInfo(allRipTime, workBoxText,
                        targetBoxText, referenceBoxText, ResolutionBox.Text, PageRange.Text, pageBox.Text);
                }
                catch (Exception ex)
                {
                    string WorkCategory = "検版レポートの編集";
                    ExceptionMessage(ex, workLogPath, WorkCategory);
                }

                //この時点での出力文字列を取得
                string tiffString = ResultConsole.Text;
                try
                {
                    // 日付取得
                    DateTime NowTime = DateTime.Now;
                    //検版対象ファイル名の取得
                    string[] inspectionTargets = CompareTIFF.GetTargetList(targetBoxText, referenceBoxText);
                    allPDFNum = CompareTIFF.getNumOfTiff(inspectionTargets, targetTIFFPath);//検版する画像ファイルの総数

                    //出力メニューの進捗表示を初期化
                    resetProgressText(allPDFNum);

                    // 並列処理オプションの設定
                    ParallelOptions parallelOptions = new ParallelOptions();
                    parallelOptions.MaxDegreeOfParallelism = 4;// 並行数(プロセス数) 
                                                               //parallelOptions.CancellationToken = CancelToken.Token;
                    var logicalProcessNum = Environment.ProcessorCount;//PCの論理CPUの数
                    if (logicalProcessNum >= 10)
                    {
                        parallelOptions.MaxDegreeOfParallelism = logicalProcessNum - 4;
                    }

                    //並列処理内で固定の引数を事前に処理
                    string verifyArgs = CompareTIFF.makeFixityArg(targetTIFFPath, referenceTIFFPath,
                                shiftPixel, colorMargin, removePoint, shadingOff, appDirectory);

                    await Task.Factory.StartNew(() => {

                        if (isCanceled)
                        {
                            // キャンセルされたら終了
                            ResultConsole.Text += "　処理を中断します\r\n";
                            CancelToken.Cancel();
                            DoEvents();
                            reviveButton();
                            return;
                        }

                        Parallel.ForEach(inspectionTargets, parallelOptions, targetPDFName =>
                        {
                            //キャンセルフラグONなら終了
                            if (isCanceled)
                            {
                                return;
                            }
                            //PureVerifyの実行
                            int[] NGTiffNum = CompareTIFF.runPureVerify(targetTIFFPath, referenceTIFFPath,
                                shiftPixel, colorMargin, removePoint, shadingOff, reportFlag, reportBoxText,
                                outDiffPath, targetPDFName, NowTime, reportContentsInfo, appDirectory, exePath, verifyArgs);
                            //キャンセルフラグONなら終了
                            if (isCanceled)
                            {
                                return;
                            }
                            ResultConsole.Dispatcher.Invoke(new Action(() =>
                            {
                                outProgressToUI(tiffString, NGTiffNum, allPDFNum);
                            }));

                        });
                    });

                }
                catch (OperationCanceledException)
                {
                    CancelToken.Dispose();
                    CancelToken = null;
                    ResultConsole.Text += "　処理が中断されました\r\n";
                    DelDirCancel(workBoxText);
                    reviveButton();
                    DoEvents();
                    return;
                }
                catch (Exception ex)
                {
                    string WorkCategory = "検版処理";
                    ExceptionMessage(ex, workLogPath, WorkCategory);
                }

                try
                {
                    //レポートを出力
                    //outputLog(System.IO.Path.Combine(workDir, "report"));
                    NGPDFNum = CompareTIFF.getNGNum(System.IO.Path.Combine(workDir, "report"));

                    if (isCanceled)
                    {
                        // キャンセルされたら終了
                        ResultConsole.Text += "　処理が中断されました\r\n";
                        DelDirCancel(workBoxText);
                        DoEvents();
                        reviveButton();
                        return;
                    }

                    //UIの更新
                    ResultConsole.Text = tiffString;
                    outResultToUI(allPDFNum, NGPDFNum, referenceTIFFPath, targetTIFFPath);
                }
                catch (Exception ex)
                {
                    string WorkCategory = "検版ログの出力";
                    ExceptionMessage(ex, workLogPath, WorkCategory);
                }

                string PDFName = "";
                try
                {

                    if (isCanceled)
                    {
                        // キャンセルされたら終了
                        ResultConsole.Text += "　処理が中断されました\r\n";
                        DelDirCancel(workBoxText);
                        reviveButton();
                        return;
                    }

                    //レポート名を取得
                    if (reportBox.Text != "") { PDFName = reportBoxText; }
                    else { PDFName = CompareTIFF.getReportName(workDir); }
                }
                catch (Exception ex)
                {
                    string WorkCategory = "レポート名の取得";
                    ExceptionMessage(ex, workLogPath, WorkCategory);
                }

                try
                {

                    if (isCanceled)
                    {
                        // キャンセルされたら終了
                        ResultConsole.Text += "　処理が中断されました\r\n";
                        DelDirCancel(workBoxText);
                        DoEvents();
                        reviveButton();
                        return;
                    }

                    //指定先にレポートを移動
                    CompareTIFF.moveReport(reportBoxText, workDir);
                }
                catch (Exception ex)
                {
                    string WorkCategory = "ログファイルの移動";
                    ExceptionMessage(ex, workLogPath, WorkCategory);
                }

                //レポートのパスを表示
                ResultConsole.Text += "　検版レポートのパス：";
                ResultConsole.Text += System.IO.Path.Combine(workBoxText, PDFName);
                ResultConsole.Text += "\r\n";
                if (reportBox.Text == "")
                {
                    reportBox.Text = System.IO.Path.Combine(workBoxText, "report", PDFName);
                }

                //リファレンスファイルを発見できず検版回数0の場合、メッセージを出力して通知
                if (allPDFNum == 0)
                {
                    CustomMsgBox.Show(mainWindow, "指定先のリファレンスフォルダから、対象フォルダ内のファイルと対応するファイルを発見できませんでした。",
                        "検版対象を発見できませんでした。", MessageBoxButton.OK, MessageBoxImage.Warning);
                }

                //生成したレポートinf.txtを全削除
                CompareTIFF.deleteReportTexts();

                //生成したダミーファイルを削除
                if (dummyFlag)
                {
                    CompareTIFF.deleteDummyFile(System.IO.Path.Combine(workBoxText, "Dummy", "Target"), dummyFileName);
                    CompareTIFF.deleteDummyFile(System.IO.Path.Combine(workBoxText, "Dummy", "Reference"), dummyFileName);
                }

                //パラメータを次回初期値用に保存
                Properties.Settings.Default.resolutionSetting = ResolutionBox.Value;
                Properties.Settings.Default.formatSetting = FileSelect.Text;
                Properties.Settings.Default.shiftPixelSetting = PositionBox.Value;
                Properties.Settings.Default.colorMarginSetting = GradationBox.Value;
                Properties.Settings.Default.removePointSetting = SmallDiffBox.Value;
                Properties.Settings.Default.shadingOffSetting = VisualBox.Value;
                Properties.Settings.Default.workSpaceSetting = workBoxText;
                Properties.Settings.Default.targetSetting = targetBox.Text;
                Properties.Settings.Default.referenceSetting = referenceBox.Text;
                Properties.Settings.Default.reportPathSetting = reportBoxText;
                Properties.Settings.Default.Save();

                reviveButton();
            }
            catch (OperationCanceledException)
            {
                // キャンセルされたら終了
                ResultConsole.Text += "　処理が中断されました\r\n";
                DelDirCancel(workBoxText);
                CancelToken.Dispose();
                CancelToken = null;
                DoEvents();
                reviveButton();
                return;
            }
        }

        /// <summary>
        /// UIに検版結果を出力する。
        /// </summary>
        /// <param name="reportFiles">作業フォルダ内のlogファイルを全て格納する配列</param>
        /// <param name="logfileName">作成されたlogファイルの名称</param>
        /// <param name="logString">logファイルを読み取るリーダー</param>
        /// <param name="tranceString">リーダーで読み取った行の文字列</param>
        /// <param name="lineCount">リーダーがその時点で読み込んでいる行数</param>
        private void outputLog(string workDir)
        {
            //logファイルを読み取り（1行ずつ）
            int fileCount = 0;
            string[] reportFiles = System.IO.Directory.GetFiles(workDir, "*.pdf.log", System.IO.SearchOption.TopDirectoryOnly);
            foreach (var logfileName in reportFiles)
            {
                string cutLogPath = System.IO.Path.GetFileName(logfileName);
                string outputFileName = "\r\n【" + cutLogPath.Remove(cutLogPath.IndexOf(".log")) + "】";
                ResultConsole.Text += outputFileName + "\r\n";
                StreamReader logString = new StreamReader(logfileName, Encoding.GetEncoding("Shift-JIS"));//Shift-JISでエンコーディング
                string tranceString = "";
                int lineCount = 0;
                
                //ファイルから読み取った結果をUIに出力
                while (logString.EndOfStream == false)
                {
                    tranceString = logString.ReadLine();
                    lineCount++;
                    if(fileCount == 0)
                    {
                        ResultConsole.Text += tranceString + "\r\n";
                        ResultConsole.ScrollToEnd();
                        DoEvents();
                    }
                    else
                    {
                        if ((lineCount > 13 && lineCount < 27) || lineCount == 6)//必要なところだけをUIに記述
                        {
                            ResultConsole.Text += tranceString + "\r\n";
                            ResultConsole.ScrollToEnd();
                            DoEvents();
                        }
                    }
                    //ResultConsole.Text += tranceString + "\r\n";
                }
                logString.Close();
                fileCount++;

            }
            ResultConsole.Text += "< 検版終了 >\r\n";
            ResultConsole.ScrollToEnd();
            DoEvents();
            //string logfileName = reportFiles[0];


        }

        /// <summary>
        /// UIに途中経過を出力する
        /// </summary>
        /// <param name="inTiffResult">メニューに出力されたRIP処理の処理結果</param>
        /// <param name="inNGNum">直前に処理したPDFの検版結果（画像数とNG数）を含む数列</param>
        /// <param name="inAllNum">検版を行う画像の総数</param>
        /// <param name="NowNum">実行時点での残りの画像数</param>
        /// <param name="NowNG">実行時点でのNG数</param>
        /// <param name="NowOK">実行時点でのOK数</param>
        /// <param name="NGNumOfPDF">直前に処理したPDFに含まれたNG数</param>
        /// <param name="AllNumOfPD">直前に処理したPDFに含まれた画像数</param>
        /// <param name="OKNumOfPDF">直前に処理したPDFに含まれたOK数</param>
        private void outProgressToUI(string inTiffResult, int[] inNGNum,int inAllNum)
        {
            int NowNum = int.Parse(allNumBox.Text);//現在の残り画像数を隠しメニューから取得
            int NowNG = int.Parse(NGNumBox.Text);       //現在の残りNG数を同上
            int NowOK = int.Parse(OKNumBox.Text);       //現在の残りOK数を同上

            int NGNumOfPDF = inNGNum[0];
            int AllNumOfPDF = inNGNum[1];
            int OKNumOfPDF = AllNumOfPDF - NGNumOfPDF; 

            NowNG += NGNumOfPDF;
            NowOK += OKNumOfPDF;
            NowNum -= AllNumOfPDF;

            //隠しメニューの数値を更新
            allNumBox.Text = NowNum.ToString();
            NGNumBox.Text = NowNG.ToString();
            OKNumBox.Text = NowOK.ToString();

            //出力メニューの表示を更新
            inTiffResult += "< 検版処理状況 >";
            inTiffResult += "\r\n　処理待ち数：";
            inTiffResult += NowNum.ToString() + "/" + inAllNum;
            inTiffResult += "\r\n　OKファイル数：" + NowOK.ToString();
            inTiffResult += "\r\n　NGファイル数：" + NowNG.ToString();
            ResultConsole.Text = inTiffResult + "\r\n";
            ResultConsole.ScrollToEnd();
        }

        /// <summary>
        /// UIに検版結果を出力する
        /// </summary>
        /// <param name="inAllPDFNum">検版する画像の総数</param>
        /// <param name="inNGPDFNum">NGだった画像の総数</param>
        /// <param name="refTiffPath">リファレンス画像を生成したディレクトリのパス</param>
        /// <param name="tarTiffPath">対象画像を生成したディレクトリのパス</param>
        /// <param name="tarTiffNum">リファレンス画像の総数</param>
        /// <param name="refTiffNum">対象画像の総数</param>
        /// <param name="OKPDFNum">OKだった画像の総数</param>
        private void outResultToUI(int inAllPDFNum, int inNGPDFNum, string refTiffPath, string tarTiffPath)
        {
            //記述用の情報を取得
            string[] tarTiffNum = System.IO.Directory.GetFiles(tarTiffPath, "*.tiff", System.IO.SearchOption.TopDirectoryOnly);//画像数
            string[] refTiffNum = System.IO.Directory.GetFiles(refTiffPath, "*.tiff", System.IO.SearchOption.TopDirectoryOnly);
            int OKPDFNum = inAllPDFNum - inNGPDFNum;//OKの数

            //検版結果を出力
            ResultConsole.Text += "\r\n< 検版結果 >\r\n";
            ResultConsole.Text += "　リファレンスPDFパス：";
            ResultConsole.Text += referenceBox.Text;
            ResultConsole.Text += "\r\n　リファレンス画像ファイル数：";
            ResultConsole.Text += refTiffNum.Length.ToString();
            ResultConsole.ScrollToEnd();

            ResultConsole.Text += "\r\n　対象PDFパス：";
            ResultConsole.Text += targetBox.Text;
            ResultConsole.Text += "\r\n　対象画像ファイル数：";
            ResultConsole.Text += tarTiffNum.Length.ToString();
            ResultConsole.ScrollToEnd();

            ResultConsole.Text += "\r\n　[検版パラメータ]";
            ResultConsole.Text += "\r\n　　位置ズレ許容量  ：";
            ResultConsole.Text += PositionBox.Text;
            ResultConsole.Text += " pixel\r\n　　諧調差許容量    ：";
            ResultConsole.Text += GradationBox.Text;
            ResultConsole.Text += "\r\n　　微小差異許容量：";
            ResultConsole.Text += SmallDiffBox.Text;
            ResultConsole.Text += "\r\n　　視覚的あいまい量：";
            ResultConsole.Text += VisualBox.Text;
            ResultConsole.ScrollToEnd();

            ResultConsole.Text += " pixel\r\n　[検版結果]";
            ResultConsole.Text += "\r\n　　ALL：";
            ResultConsole.Text += inAllPDFNum.ToString();
            ResultConsole.Text += "\r\n　　OK ：";
            ResultConsole.Text += OKPDFNum.ToString();
            ResultConsole.Text += "\r\n　　NG ：";
            ResultConsole.Text += inNGPDFNum.ToString();

            ResultConsole.Text += "\r\n　　OK-バイナリ比較：0";
            ResultConsole.Text += "\r\n　　OK-完全一致検版：0";
            ResultConsole.Text += "\r\n　　OK-ゆすらせ検版：";
            ResultConsole.Text += OKPDFNum.ToString();
            ResultConsole.Text += "\r\n　　NG-完全一致検版：0";
            ResultConsole.Text += "\r\n　　NG-ゆすらせ検版：";
            ResultConsole.Text += inNGPDFNum.ToString();

            ResultConsole.Text += "\r\n< 検版終了 >\r\n";
            ResultConsole.ScrollToEnd();
            DoEvents();
            //string logfileName = reportFiles[0];
        }

        /// <summary>
        /// 検版処理の進捗表示を初期化
        /// </summary>
        private void resetProgressText(int allPDFNum)
        {
            //隠しメニューの数値を初期化
            allNumBox.Text = allPDFNum.ToString();
            NGNumBox.Text = "0";
            OKNumBox.Text = "0";

            //出力メニューの表示を更新
            ResultConsole.Text += "< 検版処理状況 >";
            ResultConsole.Text += "\r\n　処理待ち数：";
            ResultConsole.Text += allPDFNum.ToString() + "/" + allPDFNum.ToString();
            ResultConsole.Text += "\r\n　OKファイル数：0";
            ResultConsole.Text += "\r\n　NGファイル数：0\r\n";
            ResultConsole.ScrollToEnd();
        }

        /// <summary>
        /// キャンセル実行時に生成済みのファイルを削除
        /// </summary>
        private void canceledFile(string inWorkPath, string inReportPath)
        {

        }



        /// <summary>
        /// TIFF画像化を実行する
        /// </summary>
        /// <param name="pageFlag">ページ範囲の指定があるかどうかを示すフラグ</param>
        /// <param name="selectedPage">入力されたページ数</param>
        /// <param name="TIFFresult">CSRenderの処理出力文</param>
        /// 
        private async void TIFFButtonClick(object sender, RoutedEventArgs e)
        {
            isCanceled = false;//Cancelフラグを初期化
            //キャンセルトークン生成
            //CancellationTokenSource CancelToken = new CancellationTokenSource();
            var Canceller = CancelToken.Token;

            //出力メニューにメッセージを出力
            ResultConsole.Text += "<変換開始>\r\n";
            ResultConsole.Text += "　PDFを" + FileSelect.Text + "に変換します\r\n";
            ResultConsole.Text += "\r\n";
            DoEvents();

            //必要に応じてページ引数を指定
            bool pageFlag = false;
            string selectedPage = "";
            if (PageRange.Text == "指定")
            {
                pageFlag = true;
                selectedPage = pageBox.Text;
            }

            //対象フォルダのpathが存在するかチェック
            if (!Directory.Exists(targetBox.Text) && !File.Exists(targetBox.Text))
            {
                CustomMsgBox.Show(mainWindow, "指定されたファイルあるいはフォルダが存在しません。" +
                    "\nもう一度TIFF出力する対象を設定してください。", "The specified file or folder does not exist", MessageBoxButton.OK, MessageBoxImage.Information);
                ResultConsole.Text += "　指定された対象ファイルあるいはフォルダを発見できませんでした\r\n";
                ResultConsole.Text += "<変換中止>\r\n";
                Properties.Settings.Default.targetSetting = "";
                Properties.Settings.Default.Save();

                reviveButton();//終了前にメニューを復帰
                return;
            }

            //出力フォルダのpathチェック
            if (workBox.Text != "")
            {
                if (!Directory.Exists(workBox.Text) && !File.Exists(workBox.Text))//pathのチェック
                {
                    CustomMsgBox.Show(mainWindow, "指定された作業フォルダが存在しません。" +
                        "\nもう一度設定してください。", "The specified reference file or folder does not exist", MessageBoxButton.OK, MessageBoxImage.Information);
                    ResultConsole.Text += "　指定された作業フォルダを発見できませんでした\r\n";
                    ResultConsole.Text += "<変換中止>\r\n";
                    workBox.Text = "";
                    Properties.Settings.Default.workSpaceSetting = "";
                    Properties.Settings.Default.Save();

                    reviveButton();//終了前にメニューを復帰
                    return;
                }
            }
            
            //CSRenderの実行
            //string TIFFresult = 
                OutputTIFF.runCSRender(ResolutionBox.Text, FileSelect.Text, pageFlag, selectedPage, targetBox.Text, workBox.Text, Canceller, isCanceled);
            
            //ResultConsole.Text += TIFFresult;
            ResultConsole.Text += "\r\n<変換終了>\r\n";
            ResultConsole.ScrollToEnd();

            //パラメータを次回初期値用に保存
            Properties.Settings.Default.resolutionSetting = ResolutionBox.Value;
            Properties.Settings.Default.formatSetting = FileSelect.Text;
            Properties.Settings.Default.workSpaceSetting = workBox.Text;
            Properties.Settings.Default.targetSetting = targetBox.Text;
            Properties.Settings.Default.Save();
        }

        //例外発生時のメッセージボックス
        private void ExceptionMessage(Exception ex, string workLogPath, string inErrorWork)
        {
            if (!Directory.Exists(workLogPath))
            {
                Directory.CreateDirectory(workLogPath);
            }
            CustomMsgBox.Show(mainWindow, ex.Message, "エラーが発生しました", MessageBoxButton.OK, MessageBoxImage.Warning);
            //ログ記述
            DateTime faileTIme = DateTime.Now;
            string logText = "[" + faileTIme + "]" + Environment.NewLine;
            logText += "例外の生じた処理：" + inErrorWork + Environment.NewLine;
            logText += ex.Message + "\n" + ex.StackTrace + Environment.NewLine;
            File.AppendAllText(System.IO.Path.Combine(workLogPath, "CSRender.log"), logText);
        }

        //メニュを明示的に更新する
        private void DoEvents()
        {
            DispatcherFrame frame = new DispatcherFrame();
            var callback = new DispatcherOperationCallback(ExitFrames);
            Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, callback, frame);
            Dispatcher.PushFrame(frame);
        }

        //実行中のオブジェクトを読み込み
        private object ExitFrames(object obj)
        {
            ((DispatcherFrame)obj).Continue = false;
            return null;
        }

        //全てのボタンをグレー化
        private void killButton()
        {
            targetButton.IsEnabled = false;
            referenceButton.IsEnabled = false;
            workButton.IsEnabled = false;
            reportButton.IsEnabled = false;
            TIFFButton.IsEnabled = false;
            CompareButton.IsEnabled = false;
            closeButton.IsEnabled = false;
            targetBox.IsEnabled = false;
            referenceBox.IsEnabled = false;
            reportBox.IsEnabled = false;
            workBox.IsEnabled = false;
            PageRange.IsEnabled = false;
            FileSelect.IsEnabled = false;
            ResolutionBox.Enabled = false;
            PositionBox.Enabled = false;
            GradationBox.Enabled = false;
            SmallDiffBox.Enabled = false;
            VisualBox.Enabled = false;
            pageBox.IsEnabled = false;
        }

        //全てのボタンを元にもどす
        private void reviveButton()
        {
            targetButton.IsEnabled = true;
            referenceButton.IsEnabled = true;
            workButton.IsEnabled = true;
            reportButton.IsEnabled = true;
            TIFFButton.IsEnabled = true;
            CompareButton.IsEnabled = true;
            closeButton.IsEnabled = true;
            targetBox.IsEnabled = true;
            referenceBox.IsEnabled = true;
            reportBox.IsEnabled = true;
            workBox.IsEnabled = true;
            PageRange.IsEnabled = true;
            FileSelect.IsEnabled = true;
            ResolutionBox.Enabled = true;
            PositionBox.Enabled = true;
            GradationBox.Enabled = true;
            SmallDiffBox.Enabled = true;
            VisualBox.Enabled = true;
            pageBox.IsEnabled = true;
        }
        
    }
}
