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 BoardData
    {
        public double lastAccessTime;
        public int viewCount;
        public double viewProbability;
        public int boardType;
        public string title;
        public string address;

        public BoardData(int boardType, string title, string address)
        {
            this.boardType = boardType;
            this.title = title;
            this.address = address;
        }
        public BoardData(string[] item)
        {
            this.boardType = 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;
        }
    }

    class UsefulBoard
    {
        public static List<BoardData> boardDataList = new List<BoardData>();
        public static Mutex mutex = new Mutex(false, "UsefulBoard");

        public static void Add(int boardType,string title, string address)
        {
            if (boardType == Util.TYPE_FAVORITE)
                return;

            mutex.WaitOne();

            try
            {
                int num = boardDataList.FindIndex(a => a.address.Equals(address));
                if (0 > num)
                {
                    BoardData boardData = new BoardData(boardType, title, address);
                    boardData.CountUp();
                    boardDataList.Insert(0, boardData);

                }
                else
                {
                    boardDataList[num].CountUp();
                }
            }
            catch
            {
                BoardData boardData = new BoardData(boardType, title, address);
                boardData.CountUp();
                boardDataList.Insert(0, boardData);
            }

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

            boardDataList = Get().ToList();

            SaveFile();

            mutex.ReleaseMutex();
        }

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

            BoardData[] boardDataClone = new BoardData[boardDataList.Count];

            boardDataList.CopyTo(boardDataClone);
            
            boardDataList.Clear();
            
            int count = boardDataClone.Length;
            int count30 = 30;
            if (count < 30)
                count30 = count;

            mutex.ReleaseMutex();

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

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

            string data = FileIO.ReadUnicode("setting", "usefulboard.txt");
            string[] lines = data.Split(stringSeparators2, StringSplitOptions.RemoveEmptyEntries);

            foreach (string line in lines)
            {
                string[] item = line.Split(stringSeparators, StringSplitOptions.None);
                BoardData temp = new BoardData(item);
                boardDataList.Add(temp);
            }
        }
    }
}