using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Threading;

using System.Windows.Forms;

namespace nispi.Controls.UsefulAddress
{
    class ThreadData
    {
        public double lastAccessTime;
        public int viewCount;
        public double viewProbability;
        public int ThreadType;
        public string title;
        public string address;

        public ThreadData(int ThreadType, string title, string address)
        {
            this.ThreadType = ThreadType;
            this.title = title;
            this.address = address;
        }

        public ThreadData(string[] item)
        {
            this.ThreadType = Int32.Parse(item[0]);
            this.title = item[1];
            this.address = item[2];
            this.lastAccessTime = Double.Parse(item[3]);
            this.viewCount = Int32.Parse(item[4]);
            this.viewProbability = Double.Parse(item[5]);
        }
        public void CountUp()
        {
            viewCount += 1;
            DateTime dt = DateTime.UtcNow;
            lastAccessTime = UnixTime.GetUnixTime(dt);
            viewProbability = viewCount * lastAccessTime;
        }
        public void CountDown()
        {
            viewCount -= 1;

            DateTime dt = DateTime.UtcNow;
            lastAccessTime = UnixTime.GetUnixTime(dt);
            viewProbability = viewCount * lastAccessTime;
        }
    }

    class UsefulThread
    {
        public static List<ThreadData> threadDataList = new List<ThreadData>();
        public static Mutex mutex = new Mutex(false, "UsefulThread");

        public static void Add(int threadType, string title, string address)
        {
            mutex.WaitOne();

            try
            {
                int num = threadDataList.FindIndex(a => a.address.Equals(address));
                if (0 > num)
                {
                    ThreadData ThreadData = new ThreadData(threadType, title, address);
                    ThreadData.CountUp();
                    threadDataList.Insert(0,ThreadData);

                }
                else
                {
                    threadDataList[num].CountUp();
                }
            }
            catch
            {
                ThreadData ThreadData = new ThreadData(threadType, title, address);
                ThreadData.CountUp();
                threadDataList.Insert(0, ThreadData);
            }

            threadDataList = threadDataList.OrderByDescending(a => a.lastAccessTime).ToList();

            threadDataList = Get().ToList();

            SaveFile();

            mutex.ReleaseMutex();
        }

        private static ThreadData[] Get()
        {
            mutex.WaitOne();

            ThreadData[] threadDataClone = new ThreadData[threadDataList.Count];
            
            threadDataList.CopyTo(threadDataClone);

            threadDataList.Clear();

            int count = threadDataClone.Length;
            int count30 = 30;
            if (count < 30)
                count30 = count;
            
            mutex.ReleaseMutex();

            return threadDataClone.Take(count30).ToArray();
        }

        private static void SaveFile()
        {
            StringBuilder sb = new StringBuilder();
            foreach (ThreadData td in threadDataList)
            {
                sb.Append(string.Format("{0}<>{1}<>{2}<>{3}<>{4}<>{5}\r\n",
                    td.ThreadType, td.title, td.address, td.lastAccessTime, td.viewCount, td.viewProbability));
            }
            FileIO.SaveUnicode("setting", "usefulthread.txt", sb.ToString());
        }
        public static void ReadFile()
        {
            string[] stringSeparators = new string[] { "<>" };
            string[] stringSeparators2 = new string[] { "\r\n" };

            string data = FileIO.ReadUnicode("setting", "usefulthread.txt");
            string[] lines = data.Split(stringSeparators2, StringSplitOptions.RemoveEmptyEntries);
            
            foreach (string line in lines)
            {
                string[] item = line.Split(stringSeparators, StringSplitOptions.RemoveEmptyEntries);
                ThreadData temp = new ThreadData(item);
                threadDataList.Add(temp);
            }
        }
    }
}