//ライセンス情報はAgeOnフォルダのLISENCEフォルダを参照してください
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Drawing;
using System.Diagnostics;
using System.IO;
using System.Linq;
//using System.Threading.Tasks;

using MecInfoDll;
using nispi.controlclass;

namespace nispi.Analysis
{
    class AnalysisImage2
    {
        public List<AnalysisImageList> analysisImageList;

        DatInfo dat;
        public static bool Visible;

        public bool stoppingBool;
        static Mutex mutex = new Mutex(true, "AnalysisImage2");

        public AnalysisImage2()
        {
            stoppingBool = false;
        }

        public void Open(DatInfo dat)
        {
            try
            {
                this.dat = dat;
                analysisImageList = new List<AnalysisImageList>();

                GetImageHtmlListFromDat(dat);

                DownLoad();
                //Thread t = new Thread(new ThreadStart(DownLoad));
                //t.IsBackground = true;
                //t.Start();
            }
            catch (System.Exception ex)
            {
                Const.debugForm.OutPutDebug("Analysis", ex);
            }
        }
        public void StopDownloading()
        {
            mutex.WaitOne();
            this.stoppingBool = true;
            mutex.ReleaseMutex();
        }
        public bool StoppingTest()
        {
            mutex.WaitOne();
            if (this.stoppingBool == true)
            {
                mutex.ReleaseMutex();
                return true;
            }
            else
            {
                mutex.ReleaseMutex();
                return false;
            }
        }
        public void DownLoad()
        {
            stoppingBool = false;

            string name = Util.DatUrlToDatPath(this.dat.dat_url);
            string saveFolder = name.Substring(0, name.Length - 4);
            string command = "";
            string[] downloadList;
            string[] lines;

            if (System.IO.Directory.Exists(saveFolder) == false)
            {
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(saveFolder);
                di.Create();
            }

            //フォルダーのパスを得る
            string datFolder = Util.DatUrlToDatFileName(this.dat.dat_url);
            string saveFolderMini = Util.DatUrlToDatDirRelativePath(this.dat.dat_url);
            saveFolderMini += Path.DirectorySeparatorChar + datFolder.Substring(0, datFolder.Length - 4);

            //フォルダから画像ファイルのDL済のリストのファイルを得る
            string str = FileIO.ReadUnicode(saveFolderMini, "DownLoadList.txt");
            //アドレスだけ取り出す
            string[] analysisImageArray = analysisImageList.Select(a => a.imageAddress).ToArray();

            //ファイルの中身がある場合
            if (str.Length > 0)
            {
                //DL済のリストと比べて、新たなリストを作る
                lines = StrUtil.GetLineListByStr(str);
                //比較して、リストにないURLだけを抽出
                downloadList = analysisImageArray.Except(lines).ToArray();
            }
            else
            {
                downloadList = analysisImageArray;
            }

            if (downloadList.Length > 0)
            {
                List<string> downloadedList = new List<string>();

                ProgressBarForm progressBarForm = new ProgressBarForm(new ProgressBarForm.SimpleMethod(StopDownloading));
                Thread t = new Thread(new ThreadStart(progressBarForm.SetUpTwo));
                t.IsBackground = true;
                t.Start();

                try
                {
                    int num = 0;


                    Const.form.mainForm.Invoke((Action)(() => progressBarForm.progressBar.Maximum = downloadList.Length));
                    string progressText = "";
                    int max = downloadList.Length;

                    progressText = string.Format("{0}/{1} 受信中です", 0, max);

                    foreach (string address in downloadList)
                    {
                        Debug.WriteLine(address);

                        DownloadBinary downloadBinary = new DownloadBinary();
                        byte[] data = downloadBinary.DownloadBinaryMethod(ref command, address);

                        if (data == null)
                        {
                            downloadedList.Add(address);
                            num += 1;
                            if (StoppingTest() == true)
                                break;
                            continue;
                        }
                        //ファイルの禁止文字を変換する
                        string fileName = GetFileString(address);

                        mutex.WaitOne();
                        //バイナリファイルの保存
                        File.WriteAllBytes(saveFolder + Path.DirectorySeparatorChar + fileName, data);
                        num += 1;
                        //ダウンロード済のリストに加える
                        downloadedList.Add(address);

                        progressText = string.Format("{0}/{1} 受信中です", num, max);
                        Const.form.mainForm.Invoke((Action)(() => progressBarForm.textLabel.Text = progressText));
                        Const.form.mainForm.Invoke((Action)(() => progressBarForm.progressBar.Value = num));
                        mutex.ReleaseMutex();

                        if (StoppingTest() == true)
                            break;
                    }
                }
                catch { ;}

                //DLしたリストのファイルを作る((((実際にダウンロードしたものだけを保存（中止によってDLされなかったものを含まない
                str = StrUtil.GetStrByLineList(downloadedList.ToArray());
                FileIO.SaveAddUnicode(saveFolderMini, "DownLoadList.txt", str);

                Const.form.mainForm.Invoke((Action)(() => progressBarForm.textLabel.Text = "終了しました"));
                Thread.Sleep(750);
                //プログレスバーを閉じる         
                progressBarForm.popUp.BeginInvoke((Action)(() => progressBarForm.Closing()));
            }
            Visible = false;
            FormGUI.OpenTargetFolder2(saveFolder);
        }

        public string GetFileString(string address)
        {
            string fileName = address;
            fileName = fileName.Replace(':', '_');
            fileName = fileName.Replace('/', '_');
            fileName = fileName.Replace('\\', '_');
            fileName = fileName.Replace('|', '_');
            fileName = fileName.Replace(';', '_');
            fileName = fileName.Replace('<', '_');
            fileName = fileName.Replace('>', '_');
            fileName = fileName.Replace('"', '_');
            fileName = fileName.Replace('\"', '_');
            fileName = fileName.Replace('?', '_');
            return fileName;
        }

        public void GetImageHtmlListFromDat(DatInfo dat)
        {
            Regex jpgRegex = new Regex( "t?tp://([-_.!~*\'()a-zA-Z0-9;/?:@&=+$$,%#]+jpg)");
            Regex jpegRegex = new Regex("t?tp://([-_.!~*\'()a-zA-Z0-9;/?:@&=+$$,%#]+jpeg)");
            Regex pngRegex = new Regex( "t?tp://([-_.!~*\'()a-zA-Z0-9;/?:@&=+$$,%#]+png)");
            Regex gifRegex = new Regex("t?tp://([-_.!~*\'()a-zA-Z0-9;/?:@&=+$$,%#]+gif)");
            Regex bmpRegex = new Regex("t?tp://([-_.!~*\'()a-zA-Z0-9;/?:@&=+$$,%#]+bmp)");

            foreach (Comment comment in dat.comments)
            {

                MatchCollection jpgMC = jpgRegex.Matches(comment.body);
                MatchCollection jpegMC = jpegRegex.Matches(comment.body);
                MatchCollection pngMC = pngRegex.Matches(comment.body);
                MatchCollection gifMC = gifRegex.Matches(comment.body);
                MatchCollection bmpMC = bmpRegex.Matches(comment.body);

                if ((jpgMC.Count > 0) && (Const.opt.otherOption.IsJpegImage.Equals("True") == true))
                {
                    for (int num = 0; jpgMC.Count > num; num++)
                    {
                        if (jpgMC[num].Success == true)
                            analysisImageList.Add(new AnalysisImageList("h" + jpgMC[num].Groups[0].Value, comment.num));
                    }
                }
                else if ((jpegMC.Count > 0) && (Const.opt.otherOption.IsJpegImage.Equals("True") == true))
                {
                    for (int num = 0; jpegMC.Count > num; num++)
                    {
                        if (jpegMC[num].Success == true)
                            analysisImageList.Add(new AnalysisImageList("h" + jpegMC[num].Groups[0].Value, comment.num));
                    }
                }
                else if ((pngMC.Count > 0) && (Const.opt.otherOption.IsPngImage.Equals("True") == true))
                {
                    for (int num = 0; pngMC.Count > num; num++)
                    {
                        if (pngMC[num].Success == true)
                            analysisImageList.Add(new AnalysisImageList("h" + pngMC[num].Groups[0].Value, comment.num));
                    }
                }
                else if ((gifMC.Count > 0) && (Const.opt.otherOption.IsGifImage.Equals("True") == true))
                {
                    for (int num = 0; gifMC.Count > num; num++)
                    {
                        if (gifMC[num].Success == true)
                            analysisImageList.Add(new AnalysisImageList("h" + gifMC[num].Groups[0].Value, comment.num));
                    }
                }
                else if ((bmpMC.Count > 0) && (Const.opt.otherOption.IsBmpImage.Equals("True") == true))
                {
                    for (int num = 0; bmpMC.Count > num; num++)
                    {
                        if (bmpMC[num].Success == true)
                            analysisImageList.Add(new AnalysisImageList("h" + bmpMC[num].Groups[0].Value, comment.num));
                    }
                }
            }
        }
        public string CapText(Match m)
        {
            return m.Value.ToString();
        }
        public void Cloose()
        {
            try
            {
                dat.comments.Clear();
                dat = null;
            }
            catch (System.Exception ex)
            {
                Const.debugForm.OutPutDebug("Analysis", ex);
            }

            try
            {
                this.analysisImageList.Clear();
            }
            catch (System.Exception ex)
            {
                Const.debugForm.OutPutDebug("Analysis", ex);
            }
            //Const.form.mainForm.Name = "mainForm";
            Visible = false;
        }
    }
}
