using System;
using System.IO;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Xml;
using System.Collections;
using System.Diagnostics;

namespace カブラウザもどき
{
    /// <summary>
    /// 旧ヤフー掲示板から情報取得を受け持つクラス
    /// Form1クラスとはcontextクラスを介して情報の受け渡しを行う
    /// ヤフー掲示板の仕様に依存する実装を行う。
    /// このクラスはtextream以前のもの。
    /// 2013年3月末には廃止予定
    /// </summary>
    public class GetYahoo : AbstractGetYahoo
    {
        private static NonDispBrowser ndbLocal = null;  // 裏で動く非表示のブラウザ(ActiveX制御あり)
        private WebBrowserController ndbLocalControl = null;
        public int minTitleNo = 10000000;
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public GetYahoo()
        {
            return;
        }
        /// <summary>
        /// 通常はこちらを使用
        /// </summary>
        /// <param name="context"></param>
        /// <param name="console">左下ウィンドウ</param>
        /// <param name="console2">一番下ステータスウィンドウ</param>
        /// <param name="ndbControl"></param>
        /// <param name="edinetlist"></param>
        public GetYahoo(カブラウザもどき.CurrentContext context, TextBox console, StatusStrip console2, WebBrowserController ndbControl, Hashtable edinetlist)
        {
            this.context = context;
            this.console = console;
            this.console2 = console2;
            this.ndbControl = ndbControl;
            this.edinetlist = edinetlist;
            this.context.SetYahooInstance(this);
            ndbLocal = new NonDispBrowser(console2);
            ndbLocalControl = new WebBrowserController(ndbLocal);
        }
        public override string GetPostUrl()
        {
            if (context.GetCode() == "") return "";
            return "http://post.messages.yahoo.co.jp/bbs?mm=FN&action=r&board=" + GetBoard(context.GetCode()) + "&tid=" + GetTid(context.GetCode()) + "&sid=" + GetSid(context.GetCode()) ;
        }
        public override string GetReplyUrl(string mid)
        {
            if (context.GetCode() == "") return "";
            return "http://post.messages.yahoo.co.jp/bbs?mm=FN&action=r&board=" + GetBoard(context.GetCode()) + "&tid=" + GetTid(context.GetCode()) + "&sid=" + GetSid(context.GetCode()) + "&mid=" + mid;
        }
        public override string GetThreadUrl(string mid)
        {
            if (context.GetCode() == "") return "";
            return "http://post.messages.yahoo.co.jp/bbs?mm=FN&action=m&board=" + GetBoard(context.GetCode()) + "&tid=" + GetTid(context.GetCode()) + "&sid=" + GetSid(context.GetCode()) + "&mid=" + mid + "&thr=" + mid + "&cur=" + mid;
        }

        public override string GetHalfYearChartUrl()
        {
            if (context.GetCode() == "") return "";
            return "http://stocks.finance.yahoo.co.jp/stocks/chart/?code=" + context.GetCodeAndExchange() + "&ct=z&t=6m&q=c&l=off&z=m&p=m5,m25,s&a=v";
        }
        public override string GetNewsUrl()
        {
            if (context.GetCode() == "") return "";
            return "http://stocks.finance.yahoo.co.jp/stocks/news/?code=" + context.GetCode();
        }
        public override string GetColum()
        {
            if (context.GetCode() == "") return "";
            return "http://news.finance.yahoo.co.jp/search/?q=" + context.GetCode();
        }
        public override string GetCompanyInfo()
        {
            if (context.GetCode() == "") return "";
            return "http://stocks.finance.yahoo.co.jp/stocks/profile/?code=" + context.GetCode();
        }
        public override string GetDailyRankingUrl()
        {
            if (context.GetCode() == "") return "";
            return "http://messages.yahoo.co.jp/ranking/stocks/postranking_daily.html";
        }
        public override string GetWeeklyRankingUrl()
        {
            if (context.GetCode() == "") return "";
            return "http://messages.yahoo.co.jp/ranking/stocks/postranking_weekly.html";
        }
        public override string GetMonthlyRankingUrl()
        {
            if (context.GetCode() == "") return "";
            return "http://messages.yahoo.co.jp/ranking/stocks/postranking_monthly.html";
        }
        public override string GetBaseUrl()
        {
            if (context.GetCode() == "") return "";
            return "http://messages.yahoo.co.jp/bbs?action=topics&board=" + GetBoard(context.GetCode()) + "&tid=" + GetTid(context.GetCode()) + "&sid=" + GetSid(context.GetCode());
        }
        public override string GetMassageUrl(string mid)
        {
            if (context.GetCode() == "") return "";
            return "http://messages.yahoo.co.jp/bbs?.mm=FN&action=m&board=" + GetBoard(context.GetCode()) + "&tid=" + GetTid(context.GetCode()) + "&sid=" + GetSid(context.GetCode()) + "&mid=" + mid;
        }
        public override string GetMessageListFromUserId(string sender)
        {
            //like this http://search.messages.yahoo.co.jp/search/?p=ayakai0116 
            if (context.GetCode() == "") return "";
            return "http://search.messages.yahoo.co.jp/search/?p=" + sender;
        }
        public override string GetLoginUrl()
        {
            return "";
        }

        /// <summary>
        /// まとめよみURL取得
        /// </summary>
        /// <param name="mid"></param>
        /// <returns></returns>
        public string GetMatomeUrl(string mid)
        {
            //for example: http://messages.yahoo.co.jp/bbs?.mm=FN&action=5&board=1001720&tid=1720&sid=1001720&mid=1968
            return "http://messages.yahoo.co.jp/bbs?.mm=FN&action=5&board=" + GetBoard(context.GetCode()) + "&tid=" + GetTid(context.GetCode()) + "&sid=" + GetSid(context.GetCode()) + "&mid=" + mid;
        }

        /// <summary>
        /// 自分の投稿
        /// </summary>
        /// <returns></returns>
        public override string GetPostedSelf() {
            return "http://messages.yahoo.co.jp/my.html";
        }

        public override bool IsValidYahooCode(string code)
        {
            bool ret = false;
            string chkUrl = "http://m.finance.yahoo.co.jp/stock/bbs?code=" + code;

            HtmlDocument doc = null;
            try {
                ndbLocal.NavigateAndWait(chkUrl);
                doc = ndbLocal.Document;

                // エラーチェック
                if (doc.Title.ToString() == "エラー - Y!ファイナンス") {

                    console.AppendText("( ・益・)ﾉ > そんなもんねぇよ。　 " + code + Form1.csCrLf);

                } else {

                    // 会社名を解析
                    string companyName = doc.Title.ToString();
                    context.comapnyName = companyName.Split('【')[0];
                    console.AppendText(doc.Title.ToString() + Form1.csCrLf);

                    string sLink = "";
                    HtmlElementCollection el = doc.GetElementsByTagName("A");
                    foreach (HtmlElement e in el) {
                        sLink = e.GetAttribute("href");
                        context.SetCode(code);
                        if (sLink.ToString() == "http://m.finance.yahoo.co.jp/stock?code=" + context.GetCode() + ".T" ||
                            sLink.ToString() == "http://m.finance.yahoo.co.jp/stock?code=" + context.GetCode() + ".O" ||
                            sLink.ToString() == "http://m.finance.yahoo.co.jp/stock?code=" + context.GetCode() + ".Q") {
                            context.SetCodeAndExchange(e.GetAttribute("href").Replace("http://m.finance.yahoo.co.jp/stock?code=", ""));
                        }
                    }

                    ret = true;
                }
            }
            finally {
                //何もしない
            }
            return ret;
        }

        /// <summary>
        /// TitleListに表示する件数
        /// （旧）Yahoo掲示板では40件
        /// </summary>
        /// <returns></returns>
        public override uint GetDisplayRows()
        {
            return 40;
        }

        /// <summary>
        /// チャートのhtmlを取得する
        /// </summary>
        /// <returns></returns>
        public override string GetChartHtml(WebBrowser webBrowser1)
        {
            string ret = "";
            if (webBrowser1.Version.Major > 6) {
                ret = "<style type='text/css'>TD.y_chart { font-size: 12px; background: #EEEEDD; border: 1px; }</style>";
                ret += "<br><table border='1' cellspacing='0'><tr>";
                ret += "<td class='y_chart'>日足</td><td class='y_chart'>1週間</td></tr><tr>";
                ret += "<td rowspan='3'><img src='http://rchart.yahoo.co.jp/z?s=" + context.GetCodeAndExchange() + "&t=6m&l=off&z=m&q=c&a=v&c=' width='400'></img>";
                ret += "</td><td rowspan='1'>";
                ret += "<img src='http://rchart.yahoo.co.jp/g?s=" + context.GetCodeAndExchange() + "&t=6m&l=off&z=m&q=c&a=v&c=' width='200'></img>";
                ret += "</tr><tr><td class='y_chart'>日中足</td></tr><tr><td rowspan='1'>";
                ret += "<img src='http://rchart.yahoo.co.jp/f?s=" + context.GetCodeAndExchange() + "&t=6m&l=off&z=m&q=c&a=v&c=' width='200'></img>";
                ret += "</td></tr></table>";
            } else  // IE6以下はアンチエイリアスが効かなくて汚い
            {
                ret = "<style type='text/css'>TD.y_chart { font-size: 12px; background: #EEEEDD; border: 1px; }</style>";
                ret += "<br><table border='1' cellspacing='0'><tr>";
                ret += "<td class='y_chart'>日足</td><td class='y_chart'>1週間</td></tr><tr>";
                ret += "<td rowspan='3'><img src='http://rchart.yahoo.co.jp/z?s=" + context.GetCodeAndExchange() + "&t=6m&l=off&z=m&q=c&a=v&c='></img>";
                ret += "</td><td rowspan='1'>";
                ret += "<img src='http://rchart.yahoo.co.jp/g?s=" + context.GetCodeAndExchange() + "&t=6m&l=off&z=m&q=c&a=v&c=' ></img>";
                ret += "</tr><tr><td class='y_chart'>日中足</td></tr><tr><td rowspan='1'>";
                ret += "<img src='http://rchart.yahoo.co.jp/f?s=" + context.GetCodeAndExchange() + "&t=6m&l=off&z=m&q=c&a=v&c=' ></img>";
                ret += "</td></tr></table>";
            }
            return ret;
        }


        /// <summary>
        ///  Yahoo掲示板のTopic ID (tid=部分)、最大TitleNo を取得する.取得値は状態変数に格納する
        ///  この値は変則で、単に銘柄コード(ex.2432)もあれば、ランダム？(8136 -> a55a5sa5jaaa) 
        ///  パターンもある。取得した値はコンテキストに格納する
        ///  セットする値(context):  Code, Tid , maxTilteNo
        /// </summary>
        /// <returns>0:正常 -1:異常</returns>
        public override string GetTid(string code)
        {
            string ret = "0";         // 戻り値
            // ローカルにコードが存在するならそのまま返す
            if (edinetlist.ContainsKey(code)) {
                ret = ((string)edinetlist[code]).Split(',')[3];
                return ret;
            } else {
                ret =  code;
            }
            return ret;
        }


        /// <summary>
        /// Yahoo掲示板からトピックIDを取得する。
        /// この関数はローカルedinetcodelistからTIDが取得できず、どうしてもTIDがほしい
        /// 時のみ呼び出すこと
        ///  ※引数docにはyahoo.GetBaseUrl()をnavigateした結果を渡して下さい
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="isCheckLock"></param>
        /// <returns></returns>
        public string GetTid(HtmlDocument doc, bool isCheckLock)
        {
            bool breakFlag = false;
            string ret = "";
            if (!IsValidUrl(doc)) {
                console.AppendText("( ｡・-・) ﾖｲﾖｲ...変な値が返ってるよ..." + Form1.csCrLf);
                console2.Items[0].Text = doc.Url.ToString();
                return "-1";
            }

            // object lcok
            if (isCheckLock) {
                if (!context.Lock()) { MessageBox.Show("銘柄コードは現在ロックされています\nしばらくお待ちください"); return "-1"; }
            }
            // object lock

            try {
                // Topic id取得
                foreach (HtmlElement e in doc.GetElementsByTagName("LINK")) {
                    string text = e.OuterHtml.Replace("&amp;", "&"); // リンク文字列
                    string[] aTmp;
                    if (text.IndexOf("rel=alternate") != -1) {
                        aTmp = text.Split('&');
                        int iCnt = 0;
                        foreach (string s in aTmp) {
                            if (s.Length > 3 && s.Substring(0, 3) == "tid") {
                                string regularTid = s.Split('=')[1];
                                regularTid = regularTid.Split('"')[0];
                                ret = regularTid;

                                // デバッグ用
                                System.Console.WriteLine(context.GetCode() + ": " + GetBaseUrl() + "&tid=" + context.GetTid());
                                using (StreamWriter sw = new StreamWriter(Form1.csDatDir + "TitleList.txt", true)) {
                                    sw.WriteLine(context.GetCode() + ": " + GetBaseUrl() + "&tid=" + context.GetTid());
                                    sw.Close();
                                }
                                breakFlag = true;
                            }
                            if (breakFlag) break;
                        }

                    }
                    if (breakFlag) break;

                }

            }
            finally {
                if (isCheckLock) {
                    context.UnLock();
                }
            }
            return ret;
        }

        /**
         * 引数docにはyahoo.GetBaseUrl()をnavigateした結果を渡すこと
         * */
        public override int GetMaxTitleNo(HtmlDocument doc, bool isCheckLock)
        {
            int iMaxTitleNo = -1;
            string sComp = "";

            if (!IsValidUrl(doc)) {
                console.AppendText("( ｡・-・) ﾖｲﾖｲ...変な値が返ってるよ..." + Form1.csCrLf);
                console2.Items[0].Text = doc.Url.ToString();
                return -1;
            }

            // object lcok
            if (isCheckLock) {
                if (!context.Lock()) { MessageBox.Show("銘柄コードは現在ロックされています\nしばらくお待ちください"); return -1; }
            }
            // object lock

            try {
                // 最大TitleNo取得
                foreach (HtmlElement e in doc.GetElementsByTagName("A")) {
                    string sLink = e.GetAttribute("href");

                    if (sLink.Length > 33 && sLink.Substring(0, 33) == "http://post.messages.yahoo.co.jp/") {
                        context.postUrl = sLink.ToString();
                    }

                    if ((sLink.Length > 50 && sLink.Substring(0, 47) == "http://messages.yahoo.co.jp/bbs?.mm=FN&action=m") ||
                        (sLink.Length > 50 && sLink.Substring(0, 47) == "http://messages.yahoo.co.jp/bbs?.mm=FN&action=5")) {
                        string[] de = { "mid=", "\">" };
                        string[] tmp = e.OuterHtml.Split(de, StringSplitOptions.None);
                        if (tmp.Length > 1) {
                            sComp = tmp[1];
                            int test = 0;
                            if (int.TryParse(sComp, out test)) {
                                if (iMaxTitleNo < test) {
                                    iMaxTitleNo = test;
                                }
                            }
                        }
                    }
                }
                context.maxTilteNo = iMaxTitleNo.ToString();
            }
            catch (Exception e) {
                console.AppendText(e.ToString());
            }

            finally {
                if (isCheckLock) {
                    context.UnLock();
                }
            }
            return iMaxTitleNo;
        }
        /// <summary>
        ///  Yahoo掲示板のその他の情報を取得する
        ///  セットする値(context):  codeAndExchange, comapnyName
        ///  セットする値(yahoo):  &DATE, &CLOSE, &CHANGE 
        /// </summary>
        public override void GetOtherInfo(string code, HtmlDocument doc)
        {

            try {

                // IMG用の市場コードを含んだ銘柄コード
                foreach (HtmlElement e in doc.GetElementsByTagName("IMG")) {
                    string sLink = e.GetAttribute("src");
                    try {
                        if (sLink.Length >= 36 && (sLink.Substring(0, 30) == "http://rchart.yahoo.co.jp/t?s=" || 
                                                   sLink.Substring(0, 30) == "http://gchart.yahoo.co.jp/t?s=")) {
                            string tmp = sLink.ToString().Substring(30, sLink.Length - 30);
                            context.SetCodeAndExchange(tmp.Split('&')[0]);
                            break;
                        }
                    }
                    catch (NullReferenceException exp) {
                        context.SetCodeAndExchange("");
                    }
                }

                //終値と前日比
                int itemCnt = 0;
                foreach (HtmlElement e in doc.GetElementsByTagName("DIV")) {

                    if (itemCnt == 4) break;
                    switch (e.GetAttribute("className")) {
                        case "kabu_meigara":
                            context.title = e.InnerText;
                            if (e.GetElementsByTagName("A").Count > 0) {
                                context.comapnyName = e.GetElementsByTagName("A")[0].InnerText;
                                itemCnt++;
                            }
                            break;
                        case "kabu_date":
                            context.GetSkin().set("&DATE", e.InnerHtml);
                            itemCnt++;
                            break;
                        case "kabu_number_price":
                            context.GetSkin().set("&CLOSE", e.InnerHtml);
                            context.close = e.InnerText;
                            itemCnt++;
                            break;
                        case "kabu_number_change":
                            context.GetSkin().set("&CHANGE", e.InnerHtml);
                            context.change = e.InnerText;
                            itemCnt++;
                            break;
                        default:
                            break;

                    }
                }

            }
            catch (IndexOutOfRangeException e) {
                console.AppendText(e.ToString() + Form1.csCrLf);
            }
            catch (NullReferenceException e) {
                console.AppendText(e.ToString() + Form1.csCrLf);
            }
            return ;
        }
        
        public override string GetSid(string code)
        {
            string ret = "-1";
            if (edinetlist.ContainsKey(code)) {
                ret = ((string)edinetlist[code]).Split(',')[2];
            } else {
                ret = "100" + code;
            }
            return ret;
        }

        public override string GetBoard(string code)
        {
            string ret = "-1";
            if (edinetlist.ContainsKey(code)) {
                ret = ((string)edinetlist[code]).Split(',')[1];
            } else {
                ret = "100" + code;
            }
            return ret;
        }

        /// <summary>
        /// 該当銘柄コードのTitle一覧の取得を行う
        /// 投稿タイトル一覧を取得して配列に格納する
        /// </summary>
        /// <param name="pageNo">ぺジー番号 0:最新 -1:前の40件 1:次の40件</param>
        public override void GetTitleLists(string longCode, int pageNo)
        {
            string url = "";
            int ret = 0;
            NonDispBrowser ndb = (NonDispBrowser)ndbControl.GetBrowser();

            switch (pageNo) {
                case 1:
                    if (context.nextPage == null || context.nextPage == "") {
                        ret = -1;
                    } else {
                        url = context.nextPage;
                        context.ClearTitleList();
                    }
                    break;
                case -1:
                    if (context.prevPage == null || context.prevPage == "") {
                        ret = -1;
                    } else {
                        context.ClearTitleList();
                        url = context.prevPage;
                    }
                    break;
                case 0:
                default:
                    url = GetBaseUrl();
                    GetTid(context.GetCode());
                    break;
            }

            ComConstants now = ndbControl.DlControl;

            if (ret == 0) {
                if (!context.Lock()) { MessageBox.Show("銘柄コードは現在ロックされています\nしばらくお待ちください"); return ; }
                try {
                    ComConstants filter = ComConstants.DLCTL_NO_JAVA
                                        | ComConstants.DLCTL_NO_SCRIPTS
                                        | ComConstants.DLCTL_NO_DLACTIVEXCTLS
                                        | ComConstants.DLCTL_NO_RUNACTIVEXCTLS
                                        | ComConstants.DLCTL_DLIMAGES;
                    ndbControl.DlControl = filter;

                    // URLパターン
                    // Page1: http://messages.yahoo.co.jp/bbs?.mm=FN&action=l&board=1006758&sid=1006758&tid=a5bda5ka1bc&start=281236
                    // Page2: http://messages.yahoo.co.jp/bbs?.mm=FN&action=l&board=1006758&sid=1006758&tid=a5bda5ka1bc&start=281196
                    //  ※tidあり、tidを入れたら、startは必須？
                    //または、
                    // Page(最新): http://messages.yahoo.co.jp/bbs?.mm=FN&action=topic&board=1006758&sid=1006758

                    //Stopwatch sw = new Stopwatch();
                    //sw.Start();
                    if (!ndb.NavigateAndWait(url)) {
                        console.AppendText("( ｡・-・) 失敗ｼﾀﾖｳﾀﾞ...もう一回やって！" + Form1.csCrLf);
                    }
                    //sw.Stop();
                    //this.textBox2.AppendText("DL時間：" + sw.ElapsedMilliseconds + csCrLf);
                    console.AppendText("( ･∀･)ﾉ > げっと！　 " + context.GetCode() + Form1.csCrLf);
                    HtmlDocument doc = ndb.Document;
                    if (! IsValidUrl(doc)) {
                        console.AppendText("( ｡・-・) ﾖｲﾖｲ...変な値が返ってるよ..." + Form1.csCrLf);
                        console2.Items[0].Text = url;
                        return;
                    }

                    // テーブル内の文字列を構造体に格納する
                    // タイトル一覧はHTMLの四重にネストされたテーブル配下にある.
                    int tblCnt = 0;
                    int rowCnt = 0;
                    foreach (HtmlElement e in doc.GetElementsByTagName("TABLE")) {
                        if (e.InnerText != null && e.InnerText.IndexOf("投稿時間") != -1) {
                            tblCnt++;
                            if (tblCnt == 4) {
                                HtmlElementCollection rows = e.GetElementsByTagName("TR");
                                foreach (HtmlElement row in rows) {
                                    HtmlElementCollection cols = row.GetElementsByTagName("TD");
                                    int chkelm = 0;
                                    bool bChk = int.TryParse(cols[0].InnerText, out chkelm);
                                    if (cols.Count == 9 && bChk && chkelm > 1 ) {
                                        context.t[rowCnt].titleNo = chkelm.ToString();
                                        context.t[rowCnt].title = cols[1].InnerText;
                                        context.t[rowCnt].sender = cols[4].InnerText;
                                        context.t[rowCnt].emotion = cols[5].InnerText;
                                        context.t[rowCnt].sendTime = cols[8].InnerText;
                                        rowCnt++;
                                    }
                                }
                            }
                        }
                    }

                    foreach (HtmlElement e in doc.GetElementsByTagName("A")) {
                        string href = e.GetAttribute("href"); // HREF属性の値
                        string text = e.InnerText; // リンク文字列

                        if (e.InnerText == "前の40件") context.prevPage = e.GetAttribute("href");
                        if (e.InnerText == "次の40件") context.nextPage = e.GetAttribute("href");

                    }

                    // yahoo掲示板その他の情報の取得
                    if (context.comapnyName == "") {
                        GetOtherInfo(context.GetCode(), doc);
                    }
                }
                finally {
                    context.UnLock();
                    ndbControl.DlControl = now;
                }
            } else // GetTid() の戻り値 not 0 
            {
                console.AppendText("( ・益・)　ﾉ > ﾖｲﾖｲわかんねぇよ。" + Form1.csCrLf);
            }
            return ;
        }

        /// <summary>
        /// 引数のURLのメッセージコンテンツを取得する 
        /// URL例) http://messages.yahoo.co.jp/bbs?.mm=FN&action=m&board=1005214&tid=ffckdcee5a4bekbbr&sid=1005214&mid=10331
        /// </summary>
        /// <returns></returns>
        public override string GetContents(string mid)
        {
            string content = "";
            // 画像、ActiveXのダウンロードを抑止
            //WebBrowserController ctl = new WebBrowserController(this.webBrowser1);
            ComConstants now = ndbLocalControl.DlControl;
            ComConstants filter = ComConstants.DLCTL_NO_DLACTIVEXCTLS
                                | ComConstants.DLCTL_NO_JAVA
                                | ComConstants.DLCTL_NO_SCRIPTS
                                | ComConstants.DLCTL_NO_DLACTIVEXCTLS
                                | ComConstants.DLCTL_NO_RUNACTIVEXCTLS
                                & ~ComConstants.DLCTL_DLIMAGES;
            ndbLocalControl.DlControl = filter;
            NonDispBrowser ndbLocal = (NonDispBrowser)ndbLocalControl.GetBrowser();

            try {
                // メッセージ内容はhtmlの中から"class=s130"をキーとして取得する
                string pad = "";
                string url = GetMassageUrl(mid);
                console2.Items[0].Text = url;

                //DL時間計測
                //Stopwatch watch = new Stopwatch();
                //watch.Start();
                if (!ndbLocal.NavigateAndWait(url)) {
                    console.AppendText("( ｡・-・) 失敗ｼﾀﾖｳﾀﾞ...もう一回やって！" + Form1.csCrLf);
                    return "Navigate 失敗";
                }
                HtmlDocument doc = ndbLocal.Document;
                if (doc.Title == "Yahoo!掲示板 - エラー") {
                    return doc.Title;
                }
                context.title = doc.Title;
                //watch.Stop();
                //console.AppendText("計測時間: " + watch.ElapsedMilliseconds + Form1.csCrLf);


                // コンテンツの取得方法１ (skin利用時はこれを採用)
                HtmlElementCollection all = doc.All;
                HtmlElementCollection ec = doc.GetElementsByTagName("TD");
                YahooSkin skin = context.GetSkin();
                skin.ContextToSkin(context);
                bool findflag = false;
                foreach (HtmlElement e in ec) {
                    switch (e.GetAttribute("className")) {
                        case "s130":
                            content = e.InnerHtml.Replace(Form1.csCrLf, "<BR>");
                            findflag = true;
                            /*
                            //skinファイルに内容を格納
                            skin.set("&MESSAGE", e.InnerHtml);
                            skin.set("&RESURL", GetReplyUrl(mid));
                            // titlelistからskin変数格納
                            foreach ( TitleLists item in context.t ) {
                                if (mid == item.titleNo) {
                                    skin.set("&NUMBER", item.titleNo);
                                    skin.set("&TITLE", item.title);
                                    skin.set("&NAME", item.sender);
                                    skin.set("&FEELINGS", item.emotion);
                                    skin.set("&DATE", item.sendTime);
                                    findflag = true;
                                    break;
                                }
                            }
                             * */
                            break;
                        default:
                            break;

                    }
                    if (findflag) break;
                }

                // コンテンツの取得方法２　早いが失敗する可能性あり
                /*  skin対応前はこれを使用する */
                /*
                string retHtml = "";
                if (doc.GetElementsByTagName("TABLE").Count >= 25) {
                    HtmlElement eRet = doc.GetElementsByTagName("TABLE")[25];
                    retHtml = eRet.OuterHtml;
                    eRet = null;
                    doc = null;
                } else retHtml = "contents get error!";
                return retHtml;
                 */

                /**
                 * 今はコメント
                 * 投稿者のメッセージ一覧用IURL取得
                ec = doc.GetElementsByTagName("A");
                foreach (HtmlElement e in ec) {
                    switch (e.GetAttribute("className")) {

                        case "findMessage":
                            //like this http://search.messages.yahoo.co.jp/search/?p=ayakai0116 
                            skin.set("&M_FINDMSG", e.GetAttribute("HREF"));
                            skin.set("&M_NICKNAME", e.GetAttribute("HREF").Replace("http://search.messages.yahoo.co.jp/search/?p=", ""));
                            break;
                        default:
                            break;

                    }
                }
                **/
            }
            catch (NullReferenceException e) {
                console.AppendText(e.ToString() + Form1.csCrLf);
                return "contents get error!";
            }
            finally {
                //ndbControl.DlControl = now;
                //ndbLocal.Dispose();
                //ndbLocal = null;
            }

            return content;
        }


        /// <summary>
        /// 引数のURLのメッセージコンテンツをYahooモバイルから取得する 
        /// 例) http://m.finance.yahoo.co.jp/stock/bbs?code=6255
        /// </summary>
        /// <param name="mid"></param>
        /// <returns></returns>
        private string GetContentsFromMobileSite(string mid)
        {
            NonDispBrowser ndb = (NonDispBrowser)ndbControl.GetBrowser();

            try {
                // メッセージ内容はhtmlの中から"class=s130"をキーとして取得する
                string url = "http://m.finance.yahoo.co.jp/stock/bbs?code=" + context.GetCode();
                // toolStripStatusLabel1.Text = url;
                ndb.NavigateAndWait(url);

                bool bThisMessage = false;

                HtmlDocument doc = ndb.Document;
                HtmlElementCollection all = doc.All;
                HtmlElementCollection articles = doc.GetElementsByTagName("article");
                HtmlElementCollection titles = doc.GetElementsByTagName("h3");
                HtmlElementCollection texts = doc.GetElementsByTagName("p");

                Console.WriteLine("message id: " + mid);

                for (int i = 0; i < all.Count; i++) {
                    if (all[i].GetAttribute("classname") == "title" && (all[i].InnerText.IndexOf(mid) != -1)) {
                        for (int j = 0; j < 10; j++) {
                            Console.WriteLine(all[i + j].InnerText);
                            if (all[i + j].GetAttribute("classname") == "text") {
                                return all[i + j].InnerText;
                            }
                        }
                    }
                }

                for (int i = 0; i < titles.Count; i++) {
                    if (titles[i].InnerText.IndexOf(mid) != -1) {
                        return articles[i].InnerHtml;
                    }
                }

                // 引数のmidのメッセージを探し出して戻す
                foreach (HtmlElement article in articles) {
                    //                foreach (HtmlElement e in article)
                    //                {
                    HtmlElement e = article;
                    if (e.GetAttribute("className") == "title") {
                        if (e.InnerText.IndexOf(mid) != -1) {
                            bThisMessage = true;
                        };
                    }
                    if (e.GetAttribute("className") == "text" && bThisMessage == true) {
                        if (e.InnerText.IndexOf(mid) != -1) {
                            return e.InnerHtml;
                        };
                    }
                    //                }
                }
            }
            finally {
            }
            return "contents get error!";
        }


        ///<summary>
        /// HTMLから投稿タイトル一覧を全部取得してファイルに保存する
        /// 最新titleIDからmaxRow分はTitleListsクラスに格納する
        /// ※1メッセージごとに取得するが、遅い。
        /// このため、SaveAllTitleListを使用することに変更
        ///</summary>
        public void SaveAllTitleList2(string code)
        {
            int maxTitleNo = 0;

            if (code == "" || code == null) { return; }
            
            NonDispBrowser ndb = (NonDispBrowser)ndbControl.GetBrowser();
            bool bReadExitFlag = false; // キャッシュされた最新まで達したので読込み終了する

            if ((MessageBox.Show("この処理を行うとタイトルによる「全文検索」が可能となりますが、\n処理は５分から１０分程度の時間がかかります。続行しますか？", "ダウンロード確認",
                    MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.No)) { return ; }

            if (File.Exists(Form1.csDatDir + code + ".dat")) {
                string line = "";
                using (StreamReader sr = new StreamReader(Form1.csDatDir + code + ".dat")) {
                    line = sr.ReadLine();
                    if (line != null && line.Split(Form1.delimiter).Length > 1) {
                        maxTitleNo = int.Parse(line.Split(Form1.delimiter)[0]);
                        MessageBox.Show(maxTitleNo + "以降を取得して保存します。");
                    }
                }
            }

            if (!context.Lock()) { MessageBox.Show("銘柄コードは現在ロックされています\nしばらくお待ちください"); return ; }
            context.Lock();
            try {

                string tid = GetTid(code);

                TitleLists data = new TitleLists();

                // 最新の一覧
                ndb.NavigateAndWait(GetBaseUrl());
                string path = Form1.csDatDir + code + ".dat";

                //if (File.Exists(path))
                //{
                //    SortUniqTitleList(path);
                //}
                StreamWriter sw = new StreamWriter(path, true);
                sw.WriteLine("0" + Form1.delimiter + context.GetTid() + Form1.delimiter + context.GetCodeAndExchange() + Form1.delimiter + context.comapnyName);

                context.maxTilteNo = GetMaxTitleNo(ndb.Document, false).ToString();

                for (int i = 0; i <= (context.GetMaxTitleNo() / 40); i++) {

                    console2.Items[0].Text = ndb.Url.ToString();
                    HtmlDocument doc = ndb.Document;

                    context.prevPage = "";
                    foreach (HtmlElement e in doc.GetElementsByTagName("A")) {
                        if (e.InnerText == "前の40件") {
                            context.prevPage = e.GetAttribute("href");
                            break;
                        }
                    }
                        
                    // 前の40件リンクを辿ってyahoo掲示板をクロール
                    // タイトル一覧はHTMLの四重にネストされたテーブル配下にある.
                    int tblCnt = 0;
                    int flushCnt = 0;
                    foreach (HtmlElement e in doc.GetElementsByTagName("TABLE")) {
                        if (e.InnerText != null && e.InnerText.IndexOf("投稿時間") != -1) {
                            tblCnt++;
                            if (tblCnt == 4) {
                                HtmlElementCollection rows = e.GetElementsByTagName("TR");
                                foreach (HtmlElement row in rows) {
                                    HtmlElementCollection cols = row.GetElementsByTagName("TD");
                                    int chkelm = 0;
                                    bool bChk = false;
                                    if ( cols.Count > 0 )
                                        bChk = int.TryParse(cols[0].InnerText, out chkelm);
                                    if (cols.Count == 9 && bChk && chkelm > 1 && chkelm <= context.GetMaxTitleNo()) {
                                        data.titleNo = chkelm.ToString();
                                        data.title = cols[1].InnerText;
                                        data.sender = cols[4].InnerText;
                                        data.emotion = cols[5].InnerText;
                                        data.sendTime = cols[8].InnerText;
                                        data.content = GetContents(data.titleNo);
                                        data.WriteLine2(sw);
                                        flushCnt++;
                                        if (flushCnt % 100 == 0) {
                                            sw.Flush();
                                        }
                                        /*
                                        if (chkelm <= maxTitleNo) {
                                            bReadExitFlag = true;
                                            break;
                                        }
                                            * */
                                    }
                                }
                            }
                        }
                        if (bReadExitFlag) break;
                    }
                    if (bReadExitFlag) break;
                    console.AppendText(context.prevPage + Form1.csCrLf);

                    if (context.prevPage != "") {
                        ndb.NavigateAndWait(context.prevPage);
                    } else {
                        break;
                    }
                } // 読込みループ終了
                sw.Close();
                sw = null;
                Utils.SortUniqTitleList(path);
            }
            finally {
                context.UnLock();
            }
            MessageBox.Show("ダウンロード完了！");
            return ;
        }


        ///<summary>
        /// HTMLから投稿タイトル一覧を全部取得してファイルに保存する
        /// 最新titleIDからmaxRow分はTitleListsクラスに格納する
        ///</summary>
        public override void SaveAllTitleList(string code)
        {
            string path = "";
            string url = "";

            if (code == "" || code == null) { return; }


            // 画像、ActiveXのダウンロードを抑止
            //WebBrowserController ctl = new WebBrowserController(this.webBrowser1);
            ComConstants now = ndbLocalControl.DlControl;
            ComConstants filter = ComConstants.DLCTL_NO_DLACTIVEXCTLS
                                | ComConstants.DLCTL_NO_JAVA
                                | ComConstants.DLCTL_NO_SCRIPTS
                                | ComConstants.DLCTL_NO_DLACTIVEXCTLS
                                | ComConstants.DLCTL_NO_RUNACTIVEXCTLS
                                & ~ComConstants.DLCTL_DLIMAGES;
            ndbLocalControl.DlControl = filter;
            NonDispBrowser ndbLocal = (NonDispBrowser)ndbLocalControl.GetBrowser();

//            NonDispBrowser ndb = (NonDispBrowser)ndbControl.GetBrowser();
            path = Form1.csDatDir + code + ".dat";


            context.Lock();
            console2.Items[0].Text = code + " " + context.GetMaxTitleNo() ;
            bool jumpFlag = false;
            bool firstLine = false;
            StreamWriter sw = null;
            try {

                if (File.Exists(Form1.csDatDir + code + ".dat") && MinCodes[code] != null) {
                    // 最後のめっせーじIDを検索
                    int minMid = int.Parse(MinCodes[code].ToString());
                    if (minMid == 1 || minMid == 0 || minMid == 2) {
                        // このファイルは飛ばす
                        jumpFlag = true;

                    } else {
                        //再度確認
                        int chkMinMid = -1;
                        int ChkMaxMid = -1;
                        GetMinimumMid(code, out chkMinMid, out ChkMaxMid);

                        if (chkMinMid == 1 || chkMinMid == 0 || chkMinMid == 2 || chkMinMid == 3 || chkMinMid == 4) {
                            // このファイルは飛ばす
                            jumpFlag = true;
                        } else {
                            context.maxTilteNo = chkMinMid.ToString();
                            url = GetMatomeUrl(chkMinMid.ToString());
                        }
                    }

                } else {
                    if (context.GetCode() == "") context.SetCode(code);
                    url = GetBaseUrl();
                    ndbLocal.NavigateAndWait(url);
                    if (!IsValidUrl(ndbLocal.Document)) {
                        console2.Items[0].Text = url;
                        return;
                    }

                    context.maxTilteNo = GetMaxTitleNo(ndbLocal.Document, false).ToString();
                    // 最初のまとめ
                    url = GetMatomeUrl(context.maxTilteNo);
                    firstLine = true;
                }

                if (!jumpFlag) {

                    // ヒント：まとめよみを表示するURLパターンは2種類存在するようである
                    ndbLocal.NavigateAndWait(url);
                    if (!IsValidUrl(ndbLocal.Document)) {
                        url = url.Replace("&action=5", "&action=m");
                        ndbLocal.NavigateAndWait(url);
                    }

                    // StreamWriterインスタンス　＆　最初の１行
                    FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.None);
                    //StreamWriter sw = new StreamWriter(path, true);
                    sw = new StreamWriter(fs);

                    Hashtable history = new Hashtable();
                    history.Clear();

                    if (firstLine) {
                        sw.WriteLine("0" + Form1.delimiter + context.GetTid() + Form1.delimiter + context.GetCodeAndExchange() + Form1.delimiter + context.comapnyName);
                    }

                    // ヒント：リンク切れ対策
                    // リンクが切れている場合は表示できた「まとめよみ」の最小msgから10引いたmidを前のリンクとする
                    //this.minTitleNo = 10000000;
                    this.minTitleNo = context.GetMaxTitleNo();

                    for (int i = 0; i <= (context.GetMaxTitleNo() / 5); i++) {

                        HtmlDocument doc = ndbLocal.Document;

                        // まとめよみしたメッセージを保存
                        SaveMessage(doc, sw, history);

                        console.AppendText(context.prevPage + Form1.csCrLf);

                        if (context.prevPage != "") {

                            //一度取得したURLは二回ナビゲートすることは無い
                            if (!history.Contains(context.prevPage)) {
                                history.Add(context.prevPage, context.prevPage);
                                ndbLocal.NavigateAndWait(context.prevPage);

                                // ヒント：まとめよみを表示するURLパターンは2種類存在するようである
                                if (! IsValidUrl(ndbLocal.Document)) {
                                    context.prevPage = context.prevPage.Replace("&action=5", "&action=m");
                                    ndbLocal.NavigateAndWait(context.prevPage);
                                }

                            } else {
                                // 
                                // ヒント：同一リンク循環対策
                                if (this.minTitleNo > 4) {
                                    string[] tmp = doc.Url.ToString().Split('=');
                                    string makeUrl = tmp[0];
                                    for (int j = 1; j < tmp.Length - 1; j++) {
                                        makeUrl += '=' + tmp[j];
                                    }
                                    // メッセージを10個ほど飛ばす
                                    this.minTitleNo = this.minTitleNo - 10;
                                    makeUrl += '=' + this.minTitleNo.ToString();
                                    context.prevPage = makeUrl;
                                    ndbLocal.NavigateAndWait(context.prevPage);
                                } else {
                                    sw.Flush();
                                    sw.Close();
                                    return;
                                }
                            }
                        } else {
                            break;
                        }
                    }  // 読込みループ終了
                    sw.Close();
                    sw = null;
                    Utils.SortUniqTitleList(path);
                }
            }
            catch (IOException e) {
                console.AppendText(path + "のopenに失敗しました");
            }
            finally {
                context.UnLock();
                //ndbControl.DlControl = now;
                //ndbLocal.Dispose();
                //ndbLocal = null;
            }
            //            MessageBox.Show("ダウンロード完了！");
            return;
        }

        private void SaveMessage(HtmlDocument doc, StreamWriter sw, Hashtable history)
        {
            int maxTitleNo = 0;  // 最新MID

            try {

                // 最初のページは最大MIDを自動取得
                if (context.maxTilteNo == "") {
                    context.maxTilteNo = GetMaxTitleNo(doc, false).ToString();
                }

                if (! IsValidUrl(doc)) {
                    return;
                }

                context.prevPage = "";
                foreach (HtmlElement e in doc.GetElementsByTagName("A")) {
                    if (e.InnerText == "前の5件") {
                        context.prevPage = e.GetAttribute("href");
                        break;
                    }
                }

                // 前の5件リンクを辿ってyahoo掲示板をクロール
                int flushCnt = 0;
                //int minTitleNo = 10000000;

                TitleLists data = new TitleLists();
                HtmlElement elm5 = Utils.GetElementByClassName(doc, "s130", "TD", 5);
                if (elm5 != null) {
                    HtmlElement parent5 = elm5.Parent.Parent.Parent.Parent.Parent.Parent;
                    HtmlElement title5 = parent5.GetElementsByTagName("TR")[0];
                    HtmlElement sender5 = Utils.GetElementByClassName(parent5, "nameId");
                    if (sender5 != null) {
                        data.sender = sender5.GetElementsByTagName("A")[0].InnerText.Trim();
                    }

                    HtmlElement emotion5 = Utils.GetEmotionElement(parent5);
                    if (emotion5 != null) {
                        data.emotion = emotion5.InnerText.Replace("投稿時の気持ち: ", "").Trim();
                    }
                    data.title = title5.GetElementsByTagName("TD")[1].InnerText.Trim();

                    string[] t5 = Utils.ParseTile(title5.GetElementsByTagName("TD")[2].InnerText);
                    data.sendTime = t5[0];
                    maxTitleNo = int.Parse(t5[1]);
                    data.titleNo = t5[2];
                    data.content = elm5.InnerHtml.Replace(Form1.csCrLf, "<BR>");
                    data.WriteLine2(sw);
                    emotion5 = null;
                    parent5 = null;
                    sender5 = null;
                    title5 = null;
                    elm5 = null;
                    flushCnt++;

                    if (int.Parse(data.titleNo) < this.minTitleNo) {
                        this.minTitleNo = int.Parse(data.titleNo);
                    }
                }

                data = new TitleLists();
                HtmlElement elm4 = Utils.GetElementByClassName(doc, "s130", "TD", 4);
                if (elm4 != null) {
                    HtmlElement parent4 = elm4.Parent.Parent.Parent.Parent.Parent.Parent;
                    HtmlElement title4 = parent4.GetElementsByTagName("TR")[0];
                    HtmlElement sender4 = Utils.GetElementByClassName(parent4, "nameId");
                    if (sender4 != null) {
                        data.sender = sender4.GetElementsByTagName("A")[0].InnerText.Trim();
                    }

                    HtmlElement emotion4 = Utils.GetEmotionElement(parent4);
                    if (emotion4 != null) {
                        data.emotion = emotion4.InnerText.Replace("投稿時の気持ち: ", "").Trim();
                    }
                    data.title = title4.GetElementsByTagName("TD")[1].InnerText.Trim();

                    string[] t4 = Utils.ParseTile(title4.GetElementsByTagName("TD")[2].InnerText);
                    data.sendTime = t4[0];
                    maxTitleNo = int.Parse(t4[1]);
                    data.titleNo = t4[2];
                    data.content = elm4.InnerHtml.Replace(Form1.csCrLf, "<BR>");
                    data.WriteLine2(sw);
                    emotion4 = null;
                    parent4 = null;
                    sender4 = null;
                    title4 = null;
                    elm4 = null;
                    flushCnt++;
                    if (int.Parse(data.titleNo) < this.minTitleNo) {
                        this.minTitleNo = int.Parse(data.titleNo);
                    }
                }

                data = new TitleLists();
                HtmlElement elm3 = Utils.GetElementByClassName(doc, "s130", "TD", 3);
                if (elm3 != null) {
                    HtmlElement parent3 = elm3.Parent.Parent.Parent.Parent.Parent.Parent;
                    HtmlElement title3 = parent3.GetElementsByTagName("TR")[0];
                    HtmlElement sender3 = Utils.GetElementByClassName(parent3, "nameId");
                    if (sender3 != null) {
                        data.sender = sender3.GetElementsByTagName("A")[0].InnerText.Trim();
                    }

                    HtmlElement emotion3 = Utils.GetEmotionElement(parent3);
                    if (emotion3 != null) {
                        data.emotion = emotion3.InnerText.Replace("投稿時の気持ち: ", "").Trim();
                    }
                    data.title = title3.GetElementsByTagName("TD")[1].InnerText;

                    string[] t3 = Utils.ParseTile(title3.GetElementsByTagName("TD")[2].InnerText);
                    data.sendTime = t3[0];
                    maxTitleNo = int.Parse(t3[1]);
                    data.titleNo = t3[2];
                    data.content = elm3.InnerHtml.Replace(Form1.csCrLf, "<BR>");
                    data.WriteLine2(sw);
                    parent3 = null;
                    sender3 = null;
                    emotion3 = null;
                    title3 = null;
                    elm3 = null;
                    flushCnt++;
                    if (int.Parse(data.titleNo) < this.minTitleNo) {
                        this.minTitleNo = int.Parse(data.titleNo);
                    }
                }

                data = new TitleLists();
                HtmlElement elm2 = Utils.GetElementByClassName(doc, "s130", "TD", 2);
                if (elm2 != null) {
                    HtmlElement parent2 = elm2.Parent.Parent.Parent.Parent.Parent.Parent;
                    HtmlElement title2 = parent2.GetElementsByTagName("TR")[0];
                    HtmlElement sender2 = Utils.GetElementByClassName(parent2, "nameId");
                    if (sender2 != null) {
                        data.sender = sender2.GetElementsByTagName("A")[0].InnerText.Trim();
                    }

                    HtmlElement emotion2 = Utils.GetEmotionElement(parent2);
                    if (emotion2 != null) {
                        data.emotion = emotion2.InnerText.Replace("投稿時の気持ち: ", "").Trim();
                    }
                    data.title = title2.GetElementsByTagName("TD")[1].InnerText.Trim();

                    string[] t2 = Utils.ParseTile(title2.GetElementsByTagName("TD")[2].InnerText);
                    data.sendTime = t2[0];
                    maxTitleNo = int.Parse(t2[1]);
                    data.titleNo = t2[2];
                    data.content = elm2.InnerHtml.Replace(Form1.csCrLf, "<BR>");
                    data.WriteLine2(sw);
                    emotion2 = null;
                    parent2 = null;
                    sender2 = null;
                    title2 = null;
                    elm2 = null;
                    flushCnt++;
                    if (int.Parse(data.titleNo) < minTitleNo) {
                        minTitleNo = int.Parse(data.titleNo);
                    }
                }

                data = new TitleLists();
                HtmlElement elm1 = Utils.GetElementByClassName(doc, "s130", "TD", 1);
                if (elm1 != null) {
                    HtmlElement parent1 = elm1.Parent.Parent.Parent.Parent.Parent.Parent;
                    HtmlElement title1 = parent1.GetElementsByTagName("TR")[0];
                    HtmlElement sender1 = Utils.GetElementByClassName(parent1, "nameId");
                    if (sender1 != null) {
                        data.sender = sender1.GetElementsByTagName("A")[0].InnerText.Trim();
                    }

                    HtmlElement emotion1 = Utils.GetEmotionElement(parent1);
                    if (emotion1 != null) {
                        data.emotion = emotion1.InnerText.Replace("投稿時の気持ち: ", "").Trim();
                    }
                    data.title = title1.GetElementsByTagName("TD")[1].InnerText.Trim();

                    string[] t1 = Utils.ParseTile(title1.GetElementsByTagName("TD")[2].InnerText);
                    data.sendTime = t1[0];
                    maxTitleNo = int.Parse(t1[1]);
                    data.titleNo = t1[2];
                    data.content = elm1.InnerHtml.Replace(Form1.csCrLf, "<BR>");
                    data.WriteLine2(sw);
                    parent1 = null;
                    emotion1 = null;
                    sender1 = null;
                    title1 = null;
                    elm1 = null;
                    flushCnt++;
                    if (int.Parse(data.titleNo) < this.minTitleNo) {
                        this.minTitleNo = int.Parse(data.titleNo);
                    }
                }
                if (flushCnt % 100 == 0) {
                    sw.Flush();
                }

                // 「前の5件」リンク切れ対策
                if (this.minTitleNo > 4 && context.prevPage == "") {
                    string[] tmp = doc.Url.ToString().Split('=');
                    string makeUrl = tmp[0];
                    for (int i = 1; i < tmp.Length - 1; i++) {
                        makeUrl += '=' +tmp[i];
                    }
                    // メッセージを10個ほど飛ばす
                    this.minTitleNo = this.minTitleNo - 10;
                    makeUrl += '=' + this.minTitleNo.ToString();
                    context.prevPage = makeUrl;
                }
            }
            catch (NullReferenceException e) {
                // 何もしない
            }

        }

        private void GetMinimumMid(string code, out int minVal, out int maxVal)
        {
            string tmp = "";
            int min = 10000000 ;
            int max = 0;
            int lines = 0;
            string line = "";
            string path = Form1.csDatDir + code + ".dat";

            // StreamWriterインスタンス　＆　最初の１行
            try {
                using (StreamReader sr = new StreamReader(path)) {
                    while ((line = sr.ReadLine()) != null) {
                        lines++;
                        tmp = line.Split(Form1.delimiter)[0];
                        try {
                            if (min > int.Parse(tmp) && int.Parse(tmp) != 0) {
                                min = int.Parse(tmp);
                            }
                            if (max < int.Parse(tmp)) {
                                max = int.Parse(tmp);
                            }
                        }
                        catch (Exception e) {
                            minVal = -1;
                            maxVal = -1;
                            return;
                        }
                    }
                    sr.Close();
                    sr.Dispose();
                    
                }
            }
            catch (FileNotFoundException e) {
                min = -1;
                max = -1;
            }
            catch (IOException e) {
                min = 0;
                max = 0;
            }

            if (lines == 0 || lines == 1) {
                min = 0;
                max = 0;
            }
            minVal = min;
            maxVal = max;
            return ;
        }

        public override bool IsValidUrl(HtmlDocument doc)
        {
            bool ret = true;
            if (doc.Title.ToString().Equals("Yahoo!掲示板 - エラー")) {
                ret = false;
            }
            return ret;
        }

        public override void AutoLogin(DispBrowser browser)
        {
            return;
        }

        Hashtable MinCodes = new Hashtable();
    }

}
