//ライセンス情報は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.WriteToThread
{
    class SendPostData
    {
        public string httpResData;
        //public int httpResDataLength;

        public MemoryStream httpResRawData;
        public int httpResRawDataLength;

        private ManualResetEvent allDone;
        private int type;
        //private string datUrl;
        private string boardUrl;
        private string writeUrl;
        public string cookieString;

        const int BUFFER_SIZE = 4096;
        public SendPostData()
        {
            httpResData = "";
            httpResRawData = new MemoryStream();
        }

        public bool Send(string boardUrl, string writeUrl, string postData)
        {
            this.type = Util.BoardType(boardUrl);
            this.boardUrl = boardUrl;
            this.writeUrl = writeUrl;

            byte[] postDataBytes = Encoding.ASCII.GetBytes(postData);

            allDone = new ManualResetEvent(false);

            Uri u = new Uri(this.writeUrl);

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(u);

            req.KeepAlive = false;
            req.ProtocolVersion = HttpVersion.Version11;
            req.Method = "POST";
            req.UserAgent = Const.USER_AGENT;
            req.AutomaticDecompression = DecompressionMethods.GZip;
            req.Timeout = 10000;
            req.Proxy = null;
            req.ContentType = "application/x-www-form-urlencoded";
            req.Referer = this.boardUrl;
            req.Accept = "*/*";
            req.Headers[HttpRequestHeader.AcceptLanguage] = "ja";
            req.Expect = "";

            //クッキーを設定
            req.CookieContainer = new CookieContainer();
            req.CookieContainer.Add(Const.cookieCollection);

            if (((Const.beState == true) && (boardUrl.Contains(".2ch.net/test/read.cgi/") == true)) ||
                ((Const.beSCState == true) && (boardUrl.Contains(".2ch.sc/test/read.cgi/") == true)))
            {
                //{
                //Beの時にはさらに加える
                //    if ((boardUrl.Contains("/test/read.cgi/argue/") == true) ||
                //         (boardUrl.Contains("/test/read.cgi/nandemo/") == true) ||
                //        (boardUrl.Contains("/test/read.cgi/be/") == true))
                //    {
                req.CookieContainer.Add(Const.beCookieCollection);
                //    }
                //}
            }
            Stream postStream = req.GetRequestStream();
            postStream.Write(postDataBytes, 0, postDataBytes.Length);

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

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

            allDone.WaitOne();

            //--レスポンスを見る
            //過去ログ落ち、人大杉//DownloadDatの受信のメソッドでnullのまま返すようにしてある
            if (myRequestState.response == null)
            {
                this.httpResData = "false1";
                return false;
            }
            else if (myRequestState.response.StatusCode == HttpStatusCode.OK)
            {
                ;
            }
            else if (myRequestState.response.StatusCode == HttpStatusCode.Redirect)
                return false;
            else
                return false;

            //クッキーを得る
            Const.cookieCollection.Add(myRequestState.response.Cookies);

            //--受信したデータを見る
            if ((httpResData == null) || (httpResData.Length < 1))
                return false;

            if (httpResData.StartsWith("-ERR もう　つかえません"))
            {
                httpResData = "false2";
                return false;
            }
            
            foreach(Cookie cookie in myRequestState.response.Cookies)
                cookieString += cookie.Value.ToString();

            myRequestState.response.Close();
            return true;
        }


        private void RespCallback(IAsyncResult asynchronousResult)
        {
            try
            {
                RequestState myRequestState = (RequestState)asynchronousResult.AsyncState;
                HttpWebRequest myHttpWebRequest = myRequestState.request;
                //人大杉の時の処理
                if (true == myHttpWebRequest.Address.AbsoluteUri.Equals("http://www2.2ch.net/live.html"))
                {
                    allDone.Set();
                    return;
                }
                try
                {
                    myRequestState.response = (HttpWebResponse)myHttpWebRequest.EndGetResponse(asynchronousResult);
                }
                catch
                {
                    //新規データが無い時にエラーが帰ることがある
                    allDone.Set();
                    return;
                }
                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
                    {
                        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
            {
                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();

                if (Util.TYPE_JBBS == type)
                {
                    Encoding eucEnc = Encoding.GetEncoding("EUC-JP");
                    this.httpResRawDataLength = eucEnc.GetByteCount(this.httpResData);
                }
                else
                {
                    Encoding sjisEnc = Encoding.GetEncoding("Shift_JIS");
                    this.httpResRawDataLength = sjisEnc.GetByteCount(this.httpResData);
                }
            }


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

            allDone.Set();
        }
    }
}
