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

namespace nispi
{
    class DownloadSubject
    {
        public string httpResData;
        private ManualResetEvent allDone;
        private int type;

        const int BUFFER_SIZE = 4096;
        public DownloadSubject()
        {
            httpResData = "";
        }

        public bool DownloadSubjectText(string url)
        {
            this.type = Util.BoardType(url);

            allDone = new ManualResetEvent(false);

            Uri u = new Uri(url);

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(u);
            req.KeepAlive = false;
            req.ProtocolVersion = HttpVersion.Version11;
            req.Method = "GET";

            //ユーザーエージェント
            if (Const.opt.otherOption.UserAgent.Length > 0)
                req.UserAgent = Const.opt.otherOption.UserAgent;
            else
                req.UserAgent = Const.USER_AGENT;

            req.AutomaticDecompression = DecompressionMethods.GZip;
            req.Timeout = 10000;

            //プロクシ
            if ((Const.opt.otherOption.IsProxyUse.Equals("True") == true) &&
                (Const.opt.otherOption.ProxyAddress.Equals("none") == false) &&
                (Const.opt.otherOption.ProxyAddress.Length > 0))
            {
                WebProxy proxy = new WebProxy(
                    "http://" + Const.opt.otherOption.ProxyAddress + ":" +
                    Const.opt.otherOption.ProxyPort);
                req.Proxy = proxy;
            }
            else
                req.Proxy = null;

            RequestState myRequestState = new RequestState();
            myRequestState.request = req;


            // Start the asynchronous request.
            IAsyncResult result =
              (IAsyncResult)req.BeginGetResponse(new AsyncCallback(RespCallback), myRequestState);

            allDone.WaitOne();

            if (myRequestState.response.StatusCode == HttpStatusCode.OK)
            {
                ;
            }
            else if (myRequestState.response.StatusCode == HttpStatusCode.Redirect)
                return false;
            else
                return false;

            myRequestState.response.Close();

            string dir;
            string boardName;

            if (Util.TYPE_JBBS == type)
            {
                boardName = u.AbsolutePath.Split('/')[1] + "_" + u.AbsolutePath.Split('/')[2];
                string hostName = u.Host.ToString();
                dir = Const.DataDir + Path.DirectorySeparatorChar + ".ageon" + Path.DirectorySeparatorChar + 
                    "cache" + Path.DirectorySeparatorChar + hostName + Path.DirectorySeparatorChar + boardName;
            }
            else if (Util.TYPE_JIKKYO == type)
            {
                boardName = u.AbsolutePath.Split('/')[2];
                dir = Const.DataDir + Path.DirectorySeparatorChar + ".ageon" + Path.DirectorySeparatorChar + "cache" +
                Path.DirectorySeparatorChar + Util.BoardUrlToBoardTypeName(url) + Path.DirectorySeparatorChar + boardName;
            }
            else
            {
                boardName = u.AbsolutePath.Split('/')[1];
                dir = Const.DataDir + Path.DirectorySeparatorChar + ".ageon" + Path.DirectorySeparatorChar + "cache" +
                Path.DirectorySeparatorChar + Util.BoardUrlToBoardTypeName(url) + Path.DirectorySeparatorChar + boardName;
            }

            Downloader.save(dir, "subject.txt", this.httpResData);
            return true;
        }


        private void RespCallback(IAsyncResult asynchronousResult)
        {
            try
            {
                RequestState myRequestState = (RequestState)asynchronousResult.AsyncState;
                HttpWebRequest myHttpWebRequest = myRequestState.request;
                myRequestState.response = (HttpWebResponse)myHttpWebRequest.EndGetResponse(asynchronousResult);

                Stream responseStream = myRequestState.response.GetResponseStream();
                myRequestState.streamResponse = responseStream;


                try
                {
                    //読み込んでしまった本文を読み込む
                    Stream st = myRequestState.streamResponse;
                    StreamReader sr;

                    if (Util.TYPE_JBBS == type)
                    {
                        sr = new StreamReader(st, System.Text.Encoding.GetEncoding("EUC-JP"));
                    }
                    /*else if (Util.TYPE_OPEN2CH == type)
                    {
                        sr = new StreamReader(st, System.Text.Encoding.UTF8);
                    }*/
                    else
                    {
                        sr = new StreamReader(st, System.Text.Encoding.GetEncoding("shift-jis"));
                    }
                    string str;

                    str = sr.ReadToEnd();
                    myRequestState.responseData.Append(str);
                }
                catch { ;}

                //---//
                IAsyncResult asynchronousInputRead = responseStream.BeginRead(myRequestState.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), myRequestState);
                return;
            }
            catch
            { ;}
        }

        private void ReadCallBack(IAsyncResult asyncResult)
        {
            RequestState myRequestState = (RequestState)asyncResult.AsyncState;
            Stream st = myRequestState.streamResponse;
            StreamReader sr;

            if (Util.TYPE_JBBS == type)
            {
                 sr = new StreamReader(st, System.Text.Encoding.GetEncoding("EUC-JP"));
            }
            /*else if (Util.TYPE_OPEN2CH == type)
            {
                sr = new StreamReader(st, System.Text.Encoding.UTF8);
            }*/
            else
            {
                sr = new StreamReader(st, System.Text.Encoding.GetEncoding("shift-jis"));
            }
            
            string str;
            try
            {
                str = sr.ReadToEnd();

                if (str.Length > 0)
                {
                    myRequestState.responseData.Append(str);
                    try
                    {
                        IAsyncResult asynchronousResult = st.BeginRead(myRequestState.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), myRequestState);
                        sr.Close();
                        st.Close();
                        return;
                    }
                    catch
                    {
                    }
                }
                else
                {
                }
            }
            catch { ;}

            if (myRequestState.responseData.Length > 1)
            {
                this.httpResData = myRequestState.responseData.ToString();
            }

            myRequestState.streamResponse.Close();
            //myRequestState.response.Close();
            sr.Close();
            st.Close();

            allDone.Set();
        }
    }
}
