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

using System.Diagnostics;
using System.Net;
using System.IO;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Threading;

using nispi.controlclass;

namespace nispi
{
    /// <summary>
    /// 最新の生存スレッドに関して整理して作成した画像を返す
    /// また、１日前のログに関しては変動しないと考えられるので作成した画像を保存し、
    /// 要求に合わせて画像を読み込んで返す
    /// </summary>
    ///
    class stringstring
    {
        public string data1;
        public string data2;

        public stringstring(string data1,string data2)
        {
            this.data1 = data1;
            this.data2 = data2;
        }
    }

    class GetScreeningIndex
    {
        string frontFile;
        Object thisLock = new Object();
        string fileName;

        PlusTime plusTime = null;
        string withInTime = "";
        string withInFileName = "";
        string withInInfoFileName = "";

        Dictionary<string, KokkaData> nameDic;
        Dictionary<string, KokkaData> colorDic;

        //時間抽出関係
        public int containKakoLog = 0;
        public int withInNum = 0;
        public string pinPointData = "";
        public string pinPointJPDate = "";

        public string str = "";

        public GetScreeningIndex(string frontFile, string fileName, Dictionary<string, KokkaData> nameDic, Dictionary<string, KokkaData> colorDic)
        {
            this.frontFile = frontFile;
            this.fileName = fileName;
            this.nameDic = nameDic;
            this.colorDic = colorDic;
        }

        //解析範囲を時間指定する場合のメソッド
        public void GetSurviveThreadIndex(int containKakoLog, PlusTime plusTime, string pinPointData)
        {

            this.containKakoLog = containKakoLog;
            this.plusTime = plusTime;
            this.pinPointData = pinPointData;

            if (this.plusTime != null)
            {
                //ファイルの基準でUnix時間を得る
                withInTime = UnixTime.GetUnixTimeByPlusTime(plusTime).ToString();

                //範囲から最大の日にちのファイル名を得る
                withInFileName = UnixTime.GetFileNameByPlusTime(plusTime);

                //インフォファイルを得る
                withInInfoFileName = UnixTime.GetInfoFileNameByPlusTime(plusTime);
            }
            else if (this.pinPointData.Length > 0)
            {
                withInFileName = this.pinPointData + ".txt";
                withInInfoFileName = this.pinPointData + ".info.txt";
            }

            Thread t = new Thread(new ThreadStart(Draw));
            t.IsBackground = true;
            t.Start();

            t.Join();
        }

        //全生存ファイルが解析対象の場合のメソッド
        public void GetSurviveThreadIndex()
        {
            Thread t = new Thread(new ThreadStart(Draw));
            t.IsBackground = true;
            t.Start();

            t.Join();
        }

        delegate void WriteBoardList_Delegate(TreeViewParts treeView, List<stringstring> strstrList);

        private void Draw()
        {
            try
            {
                foreach (stringstring temp in BasicMapData.kokkaList)
                {
                    int num = temp.data1.IndexOf('(');
                    if (num > 0)
                        temp.data1 = temp.data1.Substring(0, num);
                }
                foreach (stringstring temp in BasicMapData.kenList)
                {
                    int num = temp.data1.IndexOf('(');
                    if (num > 0)
                        temp.data1 = temp.data1.Substring(0, num);
                }

                KokkaData kokkaData;

                string[] subFolders = Directory.GetDirectories(
                    Const.DataDir + Path.DirectorySeparatorChar +
                    ".ageon" + Path.DirectorySeparatorChar +
                    "cache" + Path.DirectorySeparatorChar +
                    "screening", "*", SearchOption.TopDirectoryOnly);

                List<string> folList = subFolders.ToList();

                folList = folList.Select(a => Path.GetFileNameWithoutExtension(a)).ToList();

                foreach (string yomi in folList)
                {
                    //マークする点の座標を得る

                    if (nameDic.ContainsKey(yomi) == false)
                        continue;
                    kokkaData = nameDic[yomi];

                    //色の強さを得る
                    int powerNum = 0;
                    //全生存スレが対象
                    if ((withInFileName == null) || (withInFileName.Length == 0))
                        powerNum = GetPower(yomi, fileName + ".info.txt");
                    else
                        //時間の範囲が指定されている場合
                        powerNum = GetPowerByWithInTime(yomi);

                    //値を代入。他から参照するため。
                    kokkaData.power = powerNum;

                    foreach (stringstring temp in BasicMapData.kokkaList)
                    {
                        if (temp.data2.Equals(yomi))
                        {
                            temp.data1 += string.Format("({0})", powerNum.ToString());
                        }
                    }
                    foreach (stringstring temp in BasicMapData.kenList)
                    {                        
                        if (temp.data2.Equals(yomi))
                        {
                            temp.data1 += string.Format("({0})", powerNum.ToString());
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                //Const.debugForm.OutPutDebug("Map", ex);
            }

           Const.form.mainForm.BeginInvoke(
                new WriteBoardList_Delegate(
                    MapMainFormConst.countryIndexTabMain.countryIndexView.countryIndexControls.treeViewParts.WriteScreeningCountryBoardList),
                    MapMainFormConst.countryIndexTabMain.countryIndexView.countryIndexControls.treeViewParts, BasicMapData.kokkaList);

           Const.form.mainForm.BeginInvoke(
                new WriteBoardList_Delegate(
                    MapMainFormConst.countryIndexTabMain.japanIndexView.countryIndexControls.treeViewParts.WriteScreeningCountryBoardList),
                    MapMainFormConst.countryIndexTabMain.japanIndexView.countryIndexControls.treeViewParts, BasicMapData.kenList);
        }

        public int GetPower(string yomi, string fileName)
        {
            string str = FileIO.ReadUnicode(".ageon/cache/screening/" + yomi, fileName);

            if ((str != null) && (str.Length > 0))
            {
                string[] rows = str.Split(new char[] { '\r', '\n' });

                rows = rows.Where(a => a.Length > 0).ToArray();
                return Int32.Parse(rows[0]);
            }
            else
                return 0;
        }

        //ルートメソッド
        public int GetPowerByWithInTime(string yomi)
        {
            try
            {
                List<string> files = new List<string>();
                files = GetFileList(yomi);
                if ((files == null) || (files.Count == 0)) return 0;


                if (this.pinPointData.Length == 0)
                    return GetWithInPower(yomi, files);
                else
                    return GetPinPointPower(yomi, files);
            }
            catch (System.Exception ex)
            {
                Const.debugForm.OutPutDebug("Map", ex);
                return 0;
            }
        }

        //フォルダ内のinfo.txtファイルのリストを得る
        public List<string> GetFileList(string yomi)
        {

            string dir = Const.DataDir + Path.DirectorySeparatorChar +
                ".ageon" + Path.DirectorySeparatorChar +
                "cache" + Path.DirectorySeparatorChar +
                "screening" + Path.DirectorySeparatorChar +
                yomi;

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

            string[] fileList = Directory.GetFiles(dir, "*", SearchOption.TopDirectoryOnly);

            if (fileList.Length == 0)
                return null;

            //時間指定されているinfoファイルを得る。
            List<string> fileList2 = fileList.Where(a => ((a.Contains("subject") == false) && (a.EndsWith("info.txt") == true))).ToList().Select(a => Path.GetFileName(a)).ToList();
            //ファイルを時間順に並び替える
            fileList2.Sort(BoadListSort.CompareString);
            return fileList2;
        }

        //スレッドの数を得る
        public int GetWithInPower(string yomi, List<string> fileList)
        {
            int powerNum = 0;

            //時間の範囲内のデータを得る
            foreach (string file in fileList)
            {
                //フォルダの日にちの方が大きいならば＝読み込む
                if (String.Compare(file, withInInfoFileName) == 1)
                {
                    powerNum += GetPowerInsider(yomi, file);
                }
                //フォルダと範囲の日にちが等しい
                else if (String.Compare(file, withInInfoFileName) == 0)
                {
                    string logFile = file.Substring(0, file.Length - 8) + "txt";
                    string temp = ReadLogStringByTime(yomi, logFile);
                    if (temp.Length > 0)
                    {
                        ThreadInfo lastThreadInfo = SubjectUtil.ParseSubjectInfoLines(temp, file);
                        //時間で絞り込む
                        lastThreadInfo.threadDataList = lastThreadInfo.threadDataList.Where(a => String.Compare(a.openTime, withInTime) > 0).ToList();
                        powerNum += lastThreadInfo.threadDataList.Count;
                        break;
                    }
                }
                //フォルダの日にちの方が小さいならば＝読み込まない
                else
                {
                    break;
                }
            }
            return powerNum;
        }
        //スレッドの数を得る
        public int GetPinPointPower(string yomi, List<string> fileList)
        {
            int powerNum = 0;

            //時間の範囲内のデータを得る
            foreach (string file in fileList)
            {
                if (String.Compare(file, withInInfoFileName) == 0)
                {
                    powerNum += GetPowerInsider(yomi, file);
                    break;
                }
                //フォルダの日にちの方が小さいならば＝読み込まない
                else
                {
                    break;
                }
            }
            return powerNum;
        }

        public int GetPowerInsider(string yomi, string fileName)
        {
            try
            {
                string str = FileIO.ReadUnicode(".ageon/cache/screening/" + yomi, fileName);

                if ((str != null) && (str.Length > 0))
                {
                    string[] rows = str.Split(new char[] { '\r', '\n' });

                    return Int32.Parse(rows[0]);
                }
                else
                    return 0;
            }
            catch (System.Exception ex)
            {
                Const.debugForm.OutPutDebug("Map", ex);
                return 0;
            }
        }
        
        public string ReadLogStringByTime(string yomi, string fileName)
        {

            string dir = ".ageon" + Path.DirectorySeparatorChar + "cache" +
                Path.DirectorySeparatorChar + "screening" + Path.DirectorySeparatorChar + yomi;

            string data = FileIO.ReadUnicode(dir, fileName);
            return data;
        }

        /*public string xeadLogStringByTime(string yomi, string fileName)
        {

            string dir = Const.DataDir + Path.DirectorySeparatorChar + ".ageon" + Path.DirectorySeparatorChar + "cache" +
                Path.DirectorySeparatorChar + "screening" + Path.DirectorySeparatorChar + yomi;

            string data = "";

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

            if (System.IO.File.Exists(dir + Path.DirectorySeparatorChar + fileName) == false)
                return "";

            FileStream fsr = new FileStream(dir + Path.DirectorySeparatorChar + fileName, FileMode.Open);
            StreamReader sr = new StreamReader(fsr, System.Text.Encoding.Unicode);
            data = sr.ReadToEnd();
            sr.Close();
            fsr.Close();
            return data;
        }*/
    }
}