//ライセンス情報はAgeOnフォルダのLISENCEフォルダを参照してください
/*
# Copyright (c) 2008 Hideki Ikemoto
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*# Copyright (c) 2014 Naoki MAEDA
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
 * 
 * ダウンロード関連のメソッド
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.IO;

namespace nispi
{
    class Util
    {
        public const int TYPE_2CH = 0;
        public const int TYPE_MACHIBBS = 1;
        public const int TYPE_JBBS = 2;
        public const int TYPE_FAVORITE = 3;
        public const int TYPE_SCREENING = 4;
        public const int TYPE_2CHSC = 5;
        public const int TYPE_OPEN2CH = 6;
        public const int TYPE_NEXT2CH = 7;
        public const int TYPE_JIKKYO = 8;
        public const int TYPE_BLOGBAN = 9;
        public const int TYPE_SHIZU = 10;
        public const int TYPE_VIP2CH = 11;
        public const int TYPE_UNKNOWN = -1;
        public const int TYPE_REFIND2CH = 12;
        public Util()
        {
            ;
        }

        public static int BoardType(string url)
        {
            Regex url_www_2ch = new Regex("http://www\\.2ch\\.net/.*");
            Regex url_2ch = new Regex("http://.*\\.2ch\\.net/.*");
            Regex url_bbspink = new Regex("http://.*\\.bbspink\\.com/.*");
            Regex url_machibbs = new Regex("http://.*\\.machi\\.to/.*");
            Regex url_jbbs = new Regex("http://jbbs\\.shitaraba\\.net/.*");
            Regex url_2chsc = new Regex("http://.*\\.2ch\\.sc/.*");
            Regex url_open2ch = new Regex("http://.*\\.open2ch\\.net/.*");
            Regex url_open2ch_2 = new Regex("http://open2ch\\.net/.*");
            Regex url_next2ch = new Regex("http://next2ch\\.net/.*");
            Regex url_vip2ch = new Regex("http://.*\\.vip2ch\\.net/.*");
            Regex url_vip2ch_2 = new Regex("http://.*\\.vip2ch\\.com/.*");
            //http://kita.jikkyo.org/lnanmin/
            Regex url_jikkyo = new Regex("http://.*\\.jikkyo\\.org/.*");
            //http://rikach.usamimi.info/cgi-bin/lnanusmm/
            Regex url_jikkyo_2 = new Regex("http://rikach\\.usamimi\\.info/.*");
            //http://livech.sakura.ne.jp/livesalon/
            Regex url_jikkyo_3 = new Regex("http://livech\\.sakura\\.ne\\.jp/.*");
            Regex url_jikkyo_4 = new Regex("http://jikkyo\\.org/.*");

            //http://blogban.net/lic/
            Regex url_blogban = new Regex("http://blogban\\.net/.*");
            //http://shizu.0000.jp/chie/index2.html
            Regex url_shizu = new Regex("http://shizu\\.0000\\.jp/.*");

            Regex url_favorite = new Regex("local://favorite/.*");
            Regex url_screening = new Regex("local://screening/.*");

            Regex url_refind2ch = new Regex("http://refind2ch.org/");

            if (url == null)
                return TYPE_UNKNOWN;
            if (url.Length < 1)
                return TYPE_UNKNOWN;

            else if (url_vip2ch.Match(url).Success)
                return TYPE_VIP2CH;
            else if (url_vip2ch_2.Match(url).Success)
                return TYPE_VIP2CH;
            else if (url_2ch.Match(url).Success)
                return TYPE_2CH;
            else if (url_bbspink.Match(url).Success)
                return TYPE_2CH;
            else if (url_machibbs.Match(url).Success)
                return TYPE_MACHIBBS;
            else if (url_jbbs.Match(url).Success)
                return TYPE_JBBS;
            else if (url_favorite.Match(url).Success)
                return TYPE_FAVORITE;
            else if (url_screening.Match(url).Success)
                return TYPE_SCREENING;
            else if (url_2chsc.Match(url).Success)
                return TYPE_2CHSC;
            else if (url_open2ch.Match(url).Success)
                return TYPE_OPEN2CH;
            else if (url_open2ch_2.Match(url).Success)
                return TYPE_OPEN2CH;



            else if (url_jikkyo.Match(url).Success)
                return TYPE_JIKKYO;
            else if (url_jikkyo_2.Match(url).Success)
                return TYPE_JIKKYO;
            else if (url_jikkyo_3.Match(url).Success)
                return TYPE_JIKKYO;
            else if (url_jikkyo_4.Match(url).Success)
                return TYPE_JIKKYO;

            else if (url_blogban.Match(url).Success)
                return TYPE_BLOGBAN;
            else if (url_shizu.Match(url).Success)
                return TYPE_SHIZU;

            else if (url_next2ch.Match(url).Success)
                return TYPE_NEXT2CH;
            else if (url_refind2ch.Match(url).Success)
                return TYPE_REFIND2CH;


            else
                return TYPE_UNKNOWN;
        }
        public static string BoardUrlToBoardTypeName(string board_url)
        {
            switch (BoardType(board_url))
            {
                case TYPE_2CH:
                    return "2ch";
                case TYPE_MACHIBBS:
                    return "machibbs";
                case TYPE_JBBS:
                    return "jbbs";
                case TYPE_2CHSC:
                    return "2chsc";
                case TYPE_OPEN2CH:
                    return "open2ch";
                case TYPE_NEXT2CH:
                    return "next2ch";

                case TYPE_JIKKYO:
                    return "jikkyo";
                case TYPE_BLOGBAN:
                    return "blogban";
                case TYPE_SHIZU:
                    return "shizu";

                case TYPE_VIP2CH:
                    return "vip2ch";

                case TYPE_FAVORITE:
                    return "favorite";
                case TYPE_SCREENING:
                    return "screening";
                case TYPE_REFIND2CH:
                    return "refind2ch";
                case TYPE_UNKNOWN:
                    return "_";
            }
            return null;
        }

        public static bool BoardUrlCheck(string url)
        {
            Regex url_www_2ch = new Regex("http://www\\.2ch\\.net/.*");
            Regex url_2ch = new Regex("http://.*\\.2ch\\.net/.*");
            Regex url_bbspink = new Regex("http://.*\\.bbspink\\.com/.*");
            Regex url_machibbs = new Regex("http://.*\\.machi\\.to/.*");
            Regex url_jbbs = new Regex("http://jbbs\\.shitaraba\\.net/.*");
            Regex url_2chsc = new Regex("http://.*\\.2ch\\.sc/.*");
            Regex url_open2ch = new Regex("http://.*\\.open2ch\\.net/.*");
            Regex url_open2ch_2 = new Regex("http://open2ch\\.net/.*");
            Regex url_next2ch = new Regex("http://next2ch\\.net/.*");
            Regex url_vip2ch = new Regex("http://.*\\.vip2ch\\.net/.*");
            Regex url_vip2ch_2 = new Regex("http://.*\\.vip2ch\\.com/.*");

            //http://kita.jikkyo.org/lnanmin/
            Regex url_jikkyo = new Regex("http://.*\\.jikkyo\\.org/.*");
            //http://rikach.usamimi.info/cgi-bin/lnanusmm/
            Regex url_jikkyo_2 = new Regex("http://rikach\\.usamimi\\.info/.*");
            //http://livech.sakura.ne.jp/livesalon/
            Regex url_jikkyo_3 = new Regex("http://livech\\.sakura\\.ne\\.jp/.*");
            Regex url_jikkyo_4 = new Regex("http://jikkyo\\.org/.*");

            //http://blogban.net/lic/
            Regex url_blogban = new Regex("http://blogban\\.net/.*");
            //http://shizu.0000.jp/chie/index2.html
            Regex url_shizu = new Regex("http://shizu\\.0000\\.jp/.*");

            Regex url_favorite = new Regex("local://favorite/.*");
            Regex url_screening = new Regex("local://screening/.*");

            Uri u = new Uri(url);

            if (url.Length < 1)
                return false;
            else if (url_www_2ch.Match(url).Success)
                return false;
            else if ((url_2ch.Match(url).Success ||
                (url_bbspink.Match(url)).Success ||
                (url_2chsc.Match(url)).Success ||
                (url_open2ch.Match(url)).Success ||
                (url_next2ch.Match(url)).Success ||
                (url_machibbs.Match(url)).Success ||
                (url_jbbs.Match(url)).Success ||
                (url_jikkyo.Match(url)).Success ||
                (url_jikkyo_2.Match(url)).Success ||
                (url_jikkyo_3.Match(url)).Success ||
                (url_jikkyo_4.Match(url)).Success ||        
                
                (url_blogban.Match(url)).Success ||
                (url_shizu.Match(url)).Success ||
                
                (url_vip2ch.Match(url)).Success ||
                (url_vip2ch_2.Match(url)).Success ||   

                (url_screening.Match(url)).Success ||
                (url_favorite.Match(url)).Success))
                return true;
            else if (u.AbsolutePath.Length < 1)
                return false;
            else if (u.AbsolutePath.Split('/').Length != 3)
                return false;
            else
                return false;
        }

        /*public static bool ThreadUrlCheck(string url)
        {
            Uri u = new Uri(url);

            if (u.AbsolutePath.Split('/').Length == 5)
                return true;
            else
                return false;
        }*/

        public static string BoardUrlToBoardID(string url)
        {
            Uri u = new Uri(url);

            switch (BoardType(url))
            {
                case TYPE_2CH:
                case TYPE_MACHIBBS:
                case TYPE_2CHSC:
                case TYPE_OPEN2CH:
                case TYPE_NEXT2CH:
                //case TYPE_JIKKYO:
                case TYPE_BLOGBAN:
                case TYPE_SHIZU:
                case TYPE_VIP2CH:
                case TYPE_UNKNOWN:
                    return u.AbsolutePath.Split('/')[1];
                case TYPE_JIKKYO:
                    {
                        if (url.Contains("usamimi.info") == true)
                            return u.AbsolutePath.Split('/')[2];
                        else
                            return u.AbsolutePath.Split('/')[1];
                    }
                case TYPE_JBBS:
                    return u.AbsolutePath.Split('/')[1] + "/" + u.AbsolutePath.Split('/')[2];
                case TYPE_FAVORITE:
                case TYPE_SCREENING:
                    return u.AbsolutePath.Split('/')[1];
            }
            return null;
        }

        public static string BuildMACHIBBSPostStr(string name, string mail,
            string body, string board_id,
            string thread_id, string server_time, string session_id, string buttonText)
        {
            System.Text.Encoding enc = System.Text.Encoding.GetEncoding("shift_jis");
            string str = "";

            str += "subject=";
            str += "&NAME=" + System.Web.HttpUtility.UrlEncode(name, enc);//SJIS with JISX0201
            str += "&MAIL=" + System.Web.HttpUtility.UrlEncode(mail, enc);//SJIS with JISX0201
            str += "&MESSAGE=" + System.Web.HttpUtility.UrlEncode(body, enc);//SJIS with JISX0201
            str += "&BBS=" + System.Web.HttpUtility.UrlEncode(board_id, enc);
            str += "&TIME=" + System.Web.HttpUtility.UrlEncode(server_time.ToString(), enc);
            str += "&READ=" + "TRUE";
            str += "&KEY=" + System.Web.HttpUtility.UrlEncode(thread_id, enc);
            str += "&CC=" + System.Web.HttpUtility.UrlEncode("あ", enc);
            str += "&submit=" + System.Web.HttpUtility.UrlEncode(buttonText, enc);

            return str;
        }

        public static string BuildJbbsPostStr(string name, string mail,
            string body, string board_id,
            string thread_id, string server_time)
        {
            System.Text.Encoding enc = System.Text.Encoding.GetEncoding("euc-jp");
            string str = "";

            str += "subject=";
            str += "&BBS=" + board_id.Split('/')[1];
            str += "&KEY=" + thread_id;
            str += "&DIR=" + board_id.Split('/')[0];
            str += "&NAME=" + System.Web.HttpUtility.UrlEncode(name, enc);// UTF-8 -> SJIS with JISX0201
            str += "&MAIL=" + System.Web.HttpUtility.UrlEncode(mail, enc);// # UTF-8 -> SJIS with JISX0201
            str += "&MESSAGE=" + System.Web.HttpUtility.UrlEncode(body, enc);//UTF-8 -> SJIS with JISX0201
            str += "&TIME=" + server_time.ToString();
            str += "&submit=" + System.Web.HttpUtility.UrlEncode("書き込む", enc);
            return str;
        }



        public static string BuildPostStr(string name, string mail,
            string body, string board_id,
            string thread_id, string server_time, string session_id, string buttonText)
        {
            System.Text.Encoding enc = System.Text.Encoding.GetEncoding("shift_jis");
            string str = "";

            str += "subject=";
            str += "&FROM=" + System.Web.HttpUtility.UrlEncode(name, enc);//SJIS with JISX0201
            str += "&mail=" + System.Web.HttpUtility.UrlEncode(mail, enc);//SJIS with JISX0201
            str += "&MESSAGE=" + System.Web.HttpUtility.UrlEncode(body, enc);//SJIS with JISX0201
            str += "&bbs=" + board_id;
            str += "&time=" + server_time.ToString();
            str += "&key=" + thread_id;
            str += "&submit=" + System.Web.HttpUtility.UrlEncode(buttonText, enc);

            return str;
        }

        public static string BuildJbbsBoardPostStr(string threadName,string name, string mail,
            string body, string board_id,
            string thread_id, string server_time)
        {
            System.Text.Encoding enc = System.Text.Encoding.GetEncoding("euc-jp");
            string str = "";

            str += "SUBJECT=" + System.Web.HttpUtility.UrlEncode(threadName, enc);//SJIS with JISX0201
            str += "&BBS=" + board_id.Split('/')[1];
            str += "&DIR=" + board_id.Split('/')[0];
            str += "&NAME=" + System.Web.HttpUtility.UrlEncode(name, enc);// UTF-8 -> SJIS with JISX0201
            str += "&MAIL=" + System.Web.HttpUtility.UrlEncode(mail, enc);// # UTF-8 -> SJIS with JISX0201
            str += "&MESSAGE=" + System.Web.HttpUtility.UrlEncode(body, enc);//UTF-8 -> SJIS with JISX0201
            str += "&TIME=" + server_time.ToString();
            str += "&submit=" + System.Web.HttpUtility.UrlEncode("新規書き込み", enc);
            return str;
        }

        public static string BuildMACHIBBSBoardPostStr(string threadName, string name, string mail,
            string body, string board_id,
            string thread_id, string server_time)
        {
            System.Text.Encoding enc = System.Text.Encoding.GetEncoding("shift_jis");
            string str = "";

            str += "SUBJECT=" + System.Web.HttpUtility.UrlEncode(threadName, enc);//SJIS with JISX0201
            str += "&NAME=" + System.Web.HttpUtility.UrlEncode(name, enc);//SJIS with JISX0201
            str += "&MAIL=" + System.Web.HttpUtility.UrlEncode(mail, enc);//SJIS with JISX0201
            str += "&MESSAGE=" + System.Web.HttpUtility.UrlEncode(body, enc);//SJIS with JISX0201
            str += "&BBS=" + System.Web.HttpUtility.UrlEncode(board_id, enc);
            str += "&TIME=" + System.Web.HttpUtility.UrlEncode(server_time.ToString(), enc);
            str += "&READ=" + "TRUE";
            str += "&KEY=" + System.Web.HttpUtility.UrlEncode(thread_id, enc);
            str += "&CC=" + System.Web.HttpUtility.UrlEncode("あ", enc);
            str += "&submit=" + System.Web.HttpUtility.UrlEncode("新規書き込み", enc);

            return str;
        }

        public static string BuildPostBoardStr(string subject, string name, string mail,
            string body, string board_id, string server_time, string buttonText)
        {
            System.Text.Encoding enc = System.Text.Encoding.GetEncoding("shift_jis");
            string str = "";

            str += "subject=" + System.Web.HttpUtility.UrlEncode(subject, enc);//SJIS with JISX0201
            str += "&FROM=" + System.Web.HttpUtility.UrlEncode(name, enc);//SJIS with JISX0201
            str += "&mail=" + System.Web.HttpUtility.UrlEncode(mail, enc);//SJIS with JISX0201
            str += "&MESSAGE=" + System.Web.HttpUtility.UrlEncode(body, enc);//SJIS with JISX0201
            str += "&bbs=" + board_id;
            str += "&time=" + server_time.ToString();
            str += "&submit=" + System.Web.HttpUtility.UrlEncode(buttonText, enc);

            return str;
        }

        public static string DatUrlToDatFileName(string url)
        {
            Uri u = new Uri(url);

            switch (BoardType(url))
            {
                case TYPE_2CH:
                case TYPE_2CHSC:
                case TYPE_OPEN2CH:
                case TYPE_NEXT2CH:
                //case TYPE_JIKKYO:
                case TYPE_BLOGBAN:
                case TYPE_SHIZU:
                case TYPE_VIP2CH:
                case TYPE_UNKNOWN:
                    {
                        return u.AbsolutePath.Split('/')[3];
                    }
                case TYPE_MACHIBBS:
                    {
                        return u.AbsolutePath.Split('/')[4] + ".dat";
                    }
                case TYPE_JIKKYO:
                    {
                        if (url.Contains("usamimi.info") == true)
                            return u.AbsolutePath.Split('/')[4];
                        else
                            return u.AbsolutePath.Split('/')[3];
                    }
                case TYPE_JBBS:
                    {
                        return u.AbsolutePath.Split('/')[5];
                    }
            }
            return null;
        }

        public static string DatUrlToThreadID(string url)
        {
            string dat_file_name = "";

            dat_file_name = DatUrlToDatFileName(url);
            return dat_file_name.Split('.')[0];
        }

        public static string DatUrlToBoardID(string url)
        {
            try
            {
                Uri u = new Uri(url);

                switch (BoardType(url))
                {
                    case TYPE_2CH:
                    case TYPE_2CHSC:
                    case TYPE_OPEN2CH:
                    case TYPE_NEXT2CH:
                    //case TYPE_JIKKYO:
                    case TYPE_BLOGBAN:
                    case TYPE_SHIZU:
                    case TYPE_VIP2CH:
                    case TYPE_UNKNOWN:
                        {
                            return u.AbsolutePath.Split('/')[1];
                        }
                    case TYPE_MACHIBBS:
                        {
                            return u.AbsolutePath.Split('/')[3];
                        }
                    case TYPE_JIKKYO:
                        {
                            if (url.Contains("usamimi.info") == true)
                                return u.AbsolutePath.Split('/')[2];
                            else
                                return u.AbsolutePath.Split('/')[1];
                        }
                    case TYPE_JBBS:
                        {
                            return u.AbsolutePath.Split('/')[3] + "/" + u.AbsolutePath.Split('/')[4];
                        }
                }
                return null;
            }
            catch
            {
                return null;
            }
        }

        public static string DatUrlToMACHIBBSBoardID(string url)
        {
            return url.Split('/')[2].Split('.')[0];
        }
        public static string DatUrlToWriteUrl(string url)
        {
            Uri u = new Uri(url);
            string board_id;
            string thread_id;
            switch (BoardType(url))
            {
                case TYPE_2CH:
                case TYPE_UNKNOWN:
                case TYPE_NEXT2CH:
                case TYPE_2CHSC:
                //case TYPE_JIKKYO:
                case TYPE_BLOGBAN:
                case TYPE_SHIZU:
                case TYPE_VIP2CH:
                case TYPE_OPEN2CH:
                    {
                        return "http://" + u.Host.ToString() + "/test/bbs.cgi";
                    }
                case TYPE_JBBS:
                    {
                        board_id = DatUrlToBoardID(url);
                        thread_id = DatUrlToThreadID(url);
                        return "http://" + u.Host.ToString() + "/bbs/write.cgi/" + board_id + "/" + thread_id + "/";
                    }
                case TYPE_JIKKYO:
                    {
                        if (url.Contains("usamimi.info") == true)
                            return "http://" + u.Host.ToString() + "/cgi-bin/test/bbs.cgi";
                        else
                            return "http://" + u.Host.ToString() + "/test/bbs.cgi";
                    }
                case TYPE_MACHIBBS:
                    {
                        board_id = DatUrlToMACHIBBSBoardID(url);
                        return "http://" + board_id + ".machi.to/bbs/write.cgi?guid=ON";
                    }
            }
            return null;
        }
        public static string DatUrlToJbbsBoardWriteUrl(string url)
        {
            Uri u = new Uri(url);
            string boardID = BoardUrlToBoardID(url);
            return "http://" + u.Host.ToString() + "/bbs/write.cgi/" + boardID + "/" + "new/";
        }
        public static string BoardUrlToWriteUrl(string url)
        {
            Uri u = new Uri(url);
            string board_id;

            switch (BoardType(url))
            {
                case TYPE_2CH:
                case TYPE_UNKNOWN:
                //case TYPE_MACHIBBS:
                case TYPE_2CHSC:
                case TYPE_OPEN2CH:
                case TYPE_NEXT2CH:
                //case TYPE_JIKKYO:
                case TYPE_BLOGBAN:
                case TYPE_VIP2CH:
                case TYPE_SHIZU:
                    {
                        return "http://" + u.Host.ToString() + "/test/bbs.cgi";
                    }
                case TYPE_JIKKYO:
                    {
                        if (url.Contains("usamimi.info") == true)
                            return "http://" + u.Host.ToString() + "/cgi-bin/test/bbs.cgi";
                        else
                            return "http://" + u.Host.ToString() + "/test/bbs.cgi";
                    }
                case TYPE_JBBS:
                    {
                        board_id = BoardUrlToBoardID(url);
                        return "http://" + u.Host.ToString() + "/bbs/write.cgi/" + board_id + "/";
                    }
                case TYPE_MACHIBBS:
                    {
                        board_id = DatUrlToMACHIBBSBoardID(url);
                        return "http://" + board_id + ".machi.to/bbs/write.cgi?guid=ON";
                    }
            }
            return null;
        }

        public static string DatUrlToBoardUrl(string url)
        {
            Uri u = new Uri(url);
            string board_id;

            board_id = DatUrlToBoardID(url);
            return "http://" + u.Host.ToString() + "/" + board_id + "/";
        }

        //http://jbbs.livedoor.jp/bbs/rawmode.cgi/computer/18420/1103791337/
        //-> http://jbbs.livedoor.jp/bbs/read.cgi/computer/18420/1103791337/
        public static string DatUrlToThreadUrl(string url)
        {
            Uri u = new Uri(url);
            string board_id;
            string thread_id;

            switch (BoardType(url))
            {
                case TYPE_2CH:
                case TYPE_UNKNOWN:
                //case TYPE_MACHIBBS:
                case TYPE_2CHSC:
                case TYPE_OPEN2CH:
                //case TYPE_JIKKYO:
                case TYPE_BLOGBAN:
                case TYPE_SHIZU:
                case TYPE_VIP2CH:
                case TYPE_NEXT2CH:
                    {
                        board_id = DatUrlToBoardID(url);
                        thread_id = DatUrlToThreadID(url);
                        return string.Format("http://{0}/test/read.cgi/{1}/{2}/", u.Host.ToString(), board_id, thread_id);
                    }
                case TYPE_MACHIBBS:
                case TYPE_JBBS:
                    {
                        board_id = DatUrlToBoardID(url);
                        thread_id = DatUrlToThreadID(url);
                        return string.Format("http://{0}/bbs/read.cgi/{1}/{2}/", u.Host.ToString(), board_id, thread_id);
                    }
                case TYPE_JIKKYO:
                    {
                        u = new Uri(url);
                        board_id = DatUrlToBoardID(url);
                        thread_id = DatUrlToThreadID(url);

                        if (url.Contains("usamimi.info") == true)
                        {
                            //http://rikach.usamimi.info/cgi-bin/lnanusmm/dat/1388907250.dat
                            //↓
                            //http://rikach.usamimi.info/cgi-bin/test/read.cgi/lnanusmm/1403614483/
                            return string.Format("http://{0}/cgi-bin/test/read.cgi/{1}/{2}/", u.Host.ToString(), board_id, thread_id);
                        }
                        else
                            return string.Format("http://{0}/test/read.cgi/{1}/{2}/", u.Host.ToString(), board_id, thread_id);
                    }

            }
            return null;
        }

        //datからファイルパスに
        public static string DatUrlToDatPath(string dat_url)
        {
            string dir = "";
            string dat_file_name = "";

            dir = DatUrlToDatDirPath(dat_url);
            dat_file_name = DatUrlToDatFileName(dat_url);

            return dir + "/" + dat_file_name;

        }

        public static string DatUrlToDatDirPath(string dat_url)
        {
            string board_id = "";
            Uri u = new Uri(dat_url);

            string home_dir = Const.DataDir;

            board_id = DatUrlToBoardID(dat_url);

            switch (BoardType(dat_url))
            {
                case TYPE_2CH:
                case TYPE_UNKNOWN:
                    {
                        return home_dir + Path.DirectorySeparatorChar + ".ageon" + Path.DirectorySeparatorChar +
                        "cache" + Path.DirectorySeparatorChar + "2ch" + Path.DirectorySeparatorChar + board_id;
                    }
                case TYPE_MACHIBBS:
                    {
                        return home_dir + "/.ageon/cache/machibbs/" + board_id;
                    }
                case TYPE_JBBS:
                    {
                        home_dir = home_dir + string.Format("/.ageon/cache/{0}/", u.Host.ToString());
                        return home_dir + board_id.Replace('/', '_');
                    }
                case TYPE_2CHSC:
                    {
                        return home_dir + "/.ageon/cache/2chsc/" + board_id;
                    }
                case TYPE_OPEN2CH:
                    {
                        return home_dir + "/.ageon/cache/open2ch/" + board_id;
                    }
                case TYPE_NEXT2CH:
                    {
                        return home_dir + "/.ageon/cache/next2ch/" + board_id;
                    }
                case TYPE_JIKKYO:
                    {
                        return home_dir + "/.ageon/cache/jikkyo/" + board_id;
                    }
                case TYPE_BLOGBAN:
                    {
                        return home_dir + "/.ageon/cache/blogban/" + board_id;
                    }
                case TYPE_SHIZU:
                    {
                        return home_dir + "/.ageon/cache/shizu/" + board_id;
                    }
                case TYPE_VIP2CH:
                    {
                        return home_dir + "/.ageon/cache/vip2ch/" + board_id;
                    }
                case TYPE_SCREENING:
                    {
                        return home_dir + "/.ageon/cache/screening/" + board_id;
                    }
            }
            return null;
        }
        public static string DatUrlToDatDirPath2(string dat_url)
        {
            string board_id = "";
            Uri u = new Uri(dat_url);

            string home_dir = Const.DataDir;

            board_id = DatUrlToBoardID(dat_url);

            switch (BoardType(dat_url))
            {
                case TYPE_2CH:
                case TYPE_UNKNOWN:
                    {
                        return home_dir + Path.DirectorySeparatorChar + ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "2ch" + Path.DirectorySeparatorChar + board_id;
                    }
                case TYPE_2CHSC:
                    {
                        return home_dir + Path.DirectorySeparatorChar + ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "2chsc" + Path.DirectorySeparatorChar + board_id;
                    }
                case TYPE_OPEN2CH:
                    {
                        return home_dir + Path.DirectorySeparatorChar + ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "open2ch" + Path.DirectorySeparatorChar + board_id;
                    }
                case TYPE_NEXT2CH:
                    {
                        return home_dir + Path.DirectorySeparatorChar + ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "next2ch" + Path.DirectorySeparatorChar + board_id;
                    }
                case TYPE_JIKKYO:
                    {
                        return home_dir + Path.DirectorySeparatorChar + ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "jikkyo" + Path.DirectorySeparatorChar + board_id;
                    }
                case TYPE_BLOGBAN:
                    {
                        return home_dir + Path.DirectorySeparatorChar + ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "blogban" + Path.DirectorySeparatorChar + board_id;
                    }
                case TYPE_SHIZU:
                    {
                        return home_dir + Path.DirectorySeparatorChar + ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "shizu" + Path.DirectorySeparatorChar + board_id;
                    }
                case TYPE_VIP2CH:
                    {
                        return home_dir + Path.DirectorySeparatorChar + ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "vip2ch" + Path.DirectorySeparatorChar + board_id;
                    }
                case TYPE_MACHIBBS:
                    {
                        return home_dir + Path.DirectorySeparatorChar + ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "machibbs" + Path.DirectorySeparatorChar + board_id;
                    }
            }
            return null;
        }
        public static string DatUrlToDatDirRelativePath(string datUrl)
        {
            string boardID = "";
            Uri u = new Uri(datUrl);

            boardID = DatUrlToBoardID(datUrl);

            switch (BoardType(datUrl))
            {
                case TYPE_2CH:
                case TYPE_UNKNOWN:
                    {
                        return ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "2ch" + Path.DirectorySeparatorChar + boardID;
                    }
                case TYPE_2CHSC:
                    {
                        return ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "2chsc" + Path.DirectorySeparatorChar + boardID;
                    }
                case TYPE_OPEN2CH:
                    {
                        return ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "open2ch" + Path.DirectorySeparatorChar + boardID;
                    }
                case TYPE_NEXT2CH:
                    {
                        return ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "next2ch" + Path.DirectorySeparatorChar + boardID;
                    }
                case TYPE_JIKKYO:
                    {
                        return ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "jikkyo" + Path.DirectorySeparatorChar + boardID;
                    }
                case TYPE_BLOGBAN:
                    {
                        return ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "blogban" + Path.DirectorySeparatorChar + boardID;
                    }
                case TYPE_SHIZU:
                    {
                        return ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "shizu" + Path.DirectorySeparatorChar + boardID;
                    }
                case TYPE_VIP2CH:
                    {
                        return ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "vip2ch" + Path.DirectorySeparatorChar + boardID;
                    }
                case TYPE_MACHIBBS:
                    {
                        return ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "machibbs" + Path.DirectorySeparatorChar + boardID;
                    }
                case TYPE_JBBS:
                    {
                        string temp = ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + u.Host.ToString();
                        return Path.DirectorySeparatorChar + temp + boardID.Replace('/', '_');
                    }
                case TYPE_SCREENING:
                    {
                        return ".ageon" + Path.DirectorySeparatorChar + "cache" + Path.DirectorySeparatorChar + "screening" + Path.DirectorySeparatorChar + boardID;
                    }
            }
            return null;
        }

        public static string ThreadUrlToBoardName(string url)
        {
            Uri u = new Uri(url);

            return u.AbsolutePath.Split('/')[1];
        }

        public static string ThreadUrlToBoardID(string url)
        {
            Uri u = new Uri(url);
            switch (Util.BoardType(url))
            {
                case TYPE_2CH:
                case TYPE_UNKNOWN:
                case TYPE_2CHSC:
                case TYPE_OPEN2CH:
                case TYPE_NEXT2CH:
                //case TYPE_JIKKYO:
                case TYPE_BLOGBAN:
                case TYPE_VIP2CH:
                case TYPE_SHIZU:
                    return u.AbsolutePath.Split('/')[3];
                case TYPE_MACHIBBS:
                    return u.AbsolutePath.Split('/')[1];
                case TYPE_JIKKYO:
                    {
                        if (url.Contains("usamimi.info") == true)
                            return u.AbsolutePath.Split('/')[4];
                        else
                            return u.AbsolutePath.Split('/')[3];
                    }
                case TYPE_JBBS:
                    return u.AbsolutePath.Split('/')[2];

            }
            return "";
        }

        public static string ThreadUrlToThreadID(string url)
        {
            Uri u = new Uri(url);
            switch (Util.BoardType(url))
            {
                case TYPE_2CH:
                case TYPE_UNKNOWN:
                case TYPE_2CHSC:
                case TYPE_OPEN2CH:
                case TYPE_NEXT2CH:
                //case TYPE_JIKKYO:
                case TYPE_BLOGBAN:
                case TYPE_VIP2CH:
                case TYPE_SHIZU:
                    return u.AbsolutePath.Split('/')[4];
                case TYPE_MACHIBBS:
                    return u.AbsolutePath.Split('/')[1];
                case TYPE_JIKKYO:
                    {
                        if (url.Contains("usamimi.info") == true)
                            return u.AbsolutePath.Split('/')[5];
                        else
                            return u.AbsolutePath.Split('/')[4];
                    }
                case TYPE_JBBS:
                    return u.AbsolutePath.Split('/')[2];
            }
            return "";
        }

        public static string ThreadUrlToDatUrl(string url)
        {
            if ((url == null) || (url.Length == 0))
                return "";
            Uri u;

            if (BoardType(url) == TYPE_MACHIBBS)
            {
                u = new Uri(url);
                //http://www.machi.to/bbs/offlaw.cgi/tawara/1421293744/
                return string.Format("http://{0}/bbs/offlaw.cgi/{1}/{2}/", u.Host.ToString(), u.AbsolutePath.Split('/')[3], u.AbsolutePath.Split('/')[4]);
                //return string.Format("http://{0}/{1}/{2}.cgi", u.Host.ToString(), u.AbsolutePath.Split('/')[3], u.AbsolutePath.Split('/')[4]);
            }
            else if (BoardType(url) ==TYPE_JIKKYO)
            {
                u = new Uri(url);
                string board_id = ThreadUrlToBoardID(url);
                string thread_id = ThreadUrlToThreadID(url);
                
                if (url.Contains("usamimi.info") == true)
                {
                    //http://rikach.usamimi.info/cgi-bin/lnanusmm/dat/1388907250.dat
                    return string.Format("http://{0}/cgi-bin/{1}/dat/{2}.dat", u.Host.ToString(), board_id, thread_id);
                }
                else
                    return string.Format("http://{0}/{1}/dat/{2}.dat", u.Host.ToString(), board_id, thread_id);
            }
            else if (BoardType(url) == TYPE_JBBS)
            {
                u = new Uri(url);
                //http://jbbs.shitaraba.net/bbs/read.cgi/business/18638/1451680901/l50
                //http://jbbs.shitaraba.net/bbs/rawmode.cgi/business/18638/1451680855
                string[] item = u.AbsolutePath.Split('/');
                string boardName = item[3];
                string boardId = item[4];
                string threadId = item[5];

                string address = string.Format("http://{0}/bbs/rawmode.cgi/{1}/{2}/{3}", u.Host.ToString(), boardName,boardId, threadId);
                return address;
            
            }
            else if (BoardType(url) == TYPE_NEXT2CH)
            {
                u = new Uri(url);
                string[] item = u.AbsolutePath.Split('/');
                string boardId = item[1];
                string threadID = item[2];
                string address = string.Format("http://next2ch.net/{0}/dat/{1}.dat", boardId, threadID);
                return address;
            }
            else
            {
                u = new Uri(url);
                string board_id = ThreadUrlToBoardID(url);
                string thread_id = ThreadUrlToThreadID(url);

                return string.Format("http://{0}/{1}/dat/{2}.dat", u.Host.ToString(), board_id, thread_id);
            }
        }
        //http://[サーバー]/[板名]/kako/[スレッド番号（上4桁）]/[スレッド番号（上5桁）]/[スレッド番号].dat.gz
        //http://[サーバー]/[板名]/kako/[スレッド番号（上3桁）]/[スレッド番号].dat.gz
        public static string DatUrlToKakoLogUrl(string url)
        {
            Uri u = new Uri(url);
            string host = u.Host;
            string boardID = DatUrlToBoardID(url);
            string threadID = DatUrlToThreadID(url);

            if (threadID.Length == 10)
            {
                return string.Format("http://{0}/{1}/kako/{2}/{3}/{4}.dat.gz",
                    host,
                    boardID,
                    threadID.Substring(0, 4),
                    threadID.Substring(0, 5),
                    threadID);
            }
            else if (threadID.Length == 9)
            {
                return string.Format("http://{0}/{1}/kako/{2}/{3}.dat.gz",
                   host,
                   boardID,
                   threadID.Substring(0, 3),
                   threadID);
            }
            return "";
        }

        public static string DatUrlToOfflaw2Path(string datUrl)
        {
            Uri u = new Uri(datUrl);
            string board_id = DatUrlToBoardID(datUrl);
            string thread_id = DatUrlToThreadID(datUrl);

            int type = Util.BoardType(datUrl);

            if (type == Util.TYPE_2CH)
                return string.Format("http://{0}/test/offlaw2.so?shiro=kuma&sid=ERROR&bbs={1}&key={2}",
                    u.Host, board_id, thread_id);
            else if (type == Util.TYPE_2CHSC)
                return string.Format("http://{0}.2ch.sc/test/offlaw2.so?shiro=kuma&sid=ERROR&bbs={1}&key={2}",
                    u.Host, board_id, thread_id);
            else if (type == Util.TYPE_OPEN2CH)
                return string.Format("http://{0}.open2ch.net/test/offlaw2.so?shiro=kuma&sid=ERROR&bbs={1}&key={2}",
                    u.Host, board_id, thread_id);
            else if (type == Util.TYPE_NEXT2CH)
                return string.Format("http://{0}.next2ch.net/test/offlaw2.so?shiro=kuma&sid=ERROR&bbs={1}&key={2}",
                    u.Host, board_id, thread_id);

            else if (type == Util.TYPE_JIKKYO)
            {
                if (datUrl.Contains("usamimi.info") == true)
                {
                    return string.Format("http://{0}.usamimi.info/cgi-bin/test/offlaw2.so?shiro=kuma&sid=ERROR&bbs={1}&key={2}",
                        u.Host, board_id, thread_id);
                }
                else if (datUrl.Contains("sakura.ne.jp") == true)
                {
                    return string.Format("http://{0}.sakura.ne.jp/test/offlaw2.so?shiro=kuma&sid=ERROR&bbs={1}&key={2}",
                        u.Host, board_id, thread_id);
                }
                else
                    return string.Format("http://{0}.jikkyo.org/test/offlaw2.so?shiro=kuma&sid=ERROR&bbs={1}&key={2}",
                        u.Host, board_id, thread_id);
            }
            else if (type == Util.TYPE_BLOGBAN)
                return string.Format("http://{0}.blogban.net/test/offlaw2.so?shiro=kuma&sid=ERROR&bbs={1}&key={2}",
                    u.Host, board_id, thread_id);
            else if (type == Util.TYPE_SHIZU)
                return string.Format("http://{0}.shizu.0000.jp/test/offlaw2.so?shiro=kuma&sid=ERROR&bbs={1}&key={2}",
                    u.Host, board_id, thread_id);

            else if (type == Util.TYPE_VIP2CH)
                return string.Format("http://{0}.vip2ch.net/test/offlaw2.so?shiro=kuma&sid=ERROR&bbs={1}&key={2}",
                    u.Host, board_id, thread_id);
            else if (type == Util.TYPE_MACHIBBS)
                return string.Format("http://{0}.machi.to/test/offlaw2.so?shiro=kuma&sid=ERROR&bbs={1}&key={2}",
                    u.Host, board_id, thread_id);

            else
                return "";
        }

        public static string DatUrlToBoardTextUrl(string datUrl)
        {
            Uri u = new Uri(datUrl);
            string boardId = DatUrlToBoardID(datUrl);
            string threadId = DatUrlToThreadID(datUrl);

            int type = Util.BoardType(datUrl);

            if (type == Util.TYPE_JBBS)
            {
                return string.Format("http://jbbs.shitaraba.net/{0}/subject.txt", boardId);
            }
            else
            {
                foreach (KeyValuePair<string, string> dic in BoardDataBase.urlDic)
                {
                    if (Util.BoardType(dic.Value) == type)
                    {
                        if (Util.BoardUrlToBoardID(dic.Value).Equals(boardId) == true)
                        {
                            if (dic.Value[dic.Value.Length - 1] == '/')
                                return dic.Value + "subject.txt";
                            else
                                return dic.Value + "/subject.txt";
                        }
                    }
                }
                return "";
            }
        }
        public static string DatUrlToBoardBBSUrl(string datUrl)
        {
            Uri u = new Uri(datUrl);
            string boardId = DatUrlToBoardID(datUrl);
            string threadId = DatUrlToThreadID(datUrl);

            int type = Util.BoardType(datUrl);

            if (type == Util.TYPE_JBBS)
            {
                return string.Format("http://jbbs.shitaraba.net/{0}/", boardId);
            }
            else
            {
                foreach (KeyValuePair<string, string> dic in BoardDataBase.urlDic)
                {
                    if (Util.BoardType(dic.Value) == type)
                    {
                        if (Util.BoardUrlToBoardID(dic.Value).Equals(boardId) == true)
                        {
                            if (dic.Value[dic.Value.Length - 1] == '/')
                                return dic.Value + "";
                            else
                                return dic.Value + "/";
                        }
                    }
                }
                return "";
            }
        }
        public static string MakeDatUrl(string board_url, string dat_file_name)
        {
            Uri u = new Uri(board_url);

            switch (BoardType(board_url))
            {
                case TYPE_2CH:
                case TYPE_UNKNOWN:
                case TYPE_2CHSC:
                case TYPE_OPEN2CH:
                case TYPE_JIKKYO:
                case TYPE_BLOGBAN:
                case TYPE_SHIZU:
                case TYPE_VIP2CH:
                case TYPE_NEXT2CH:
                    {
                        return board_url + "dat/" + dat_file_name;
                    }
                case TYPE_MACHIBBS:
                    {
                        string board_id = ThreadUrlToBoardID(board_url);
                        string thread_id = dat_file_name.Split('.')[0];
                        return string.Format("http://{0}/bbs/offlaw.cgi/{1}/{2}/", u.Host.ToString(), board_id, thread_id);
                    }
                case TYPE_JBBS:
                    {
                        string board_name = ThreadUrlToBoardName(board_url);
                        string board_id = ThreadUrlToBoardID(board_url);
                        string thread_id = dat_file_name.Split('.')[0];
                        return string.Format("http://jbbs.shitaraba.net/bbs/rawmode.cgi/{0}/{1}/{2}", board_name, board_id, thread_id);
                    }
            }
            return null;
        }

        public static string MACHIBBSAddressToOfflaw(string url)
        {
            //http://[SERVER]/bbs/offlaw.cgi/[BBS]/
            string boardID = BoardUrlToBoardID(url);
            string host = ThreadUrlToThreadID(url);
            return string.Format("http://{0}.machi.to/bbs/offlaw.cgi/{1}/", host, boardID);
        }

        public static string TruncatStr(string str, int num)
        {
            int count = 0;
            string ret = "";

            foreach (char x in str.ToCharArray())
            {
                if (count >= num)
                    break;
                ret += x;
                count += 1;
            }

            if (str.Length != ret.Length)
                ret += "…";

            return ret;
        }
    }
}
