using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace NewsCrawler
{
	public class Crawler
	{
		NewsForm m_Listener = null;
		DateTime m_Today = DateTime.Now;
		int m_iDartAPIRetry = 5;

		public Crawler(NewsForm Listener)
		{
			m_Listener = Listener;

			Test();
		}


		class REQUEST_STATUS
		{
			public HttpWebRequest m_HTTPReq = null;
			public bool m_bInitial = false;
			public Stopwatch m_Timer = new Stopwatch();

			public string m_strCodeName = "";
			public string m_strAuthKey = "";
		};

		void Test()
		{
			if(Util.IsDebugging() == false)
				return;

			ReadSupplyContract(false, "강스템바이오텍", "http://m.dart.fss.or.kr/viewer/main.st?rcpNo=20170111900149");
			ReadRevenue(false, "제일기획", "http://m.dart.fss.or.kr/viewer/main.st?rcpNo=20170126800508");
			ReadRevenue(false, "LS산전", "http://m.dart.fss.or.kr/viewer/main.st?rcpNo=20170126800581");
			ReadRightsIssue(false, "옴니텔", "http://m.dart.fss.or.kr/viewer/main.st?rcpNo=20170126000525");
			ReadPatent(false, "인트론바이오", "http://m.dart.fss.or.kr/viewer/main.st?rcpNo=20170125900080");
		}

		void ResponseAsiaE(IAsyncResult result)
		{
			REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState;
			HttpWebRequest HttpReq = State.m_HTTPReq;
			bool bInitial = State.m_bInitial;
			State.m_Timer.Stop();

			try
			{
				string strServerURL = "http://www.asiae.co.kr";
				using(HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse())
				{
					using(Stream dataStream = response.GetResponseStream())
					{
						using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("EUC-KR")))
						{
							string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd());
							responseFromServer = responseFromServer.Replace("\"\"", "\"");

							HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
							doc.LoadHtml(responseFromServer);
							string strXPath = "//div[contains(@class, 'txtform')]/ul/li";
							var lists = doc.DocumentNode.SelectNodes(strXPath);
							foreach(var item in lists)
							{
								string strTitle1 = item.SelectSingleNode(".//a").GetAttributeValue("title", "");
								string strTitle2 = item.SelectSingleNode(".//a").FirstChild.InnerText;
								string strTitle = (strTitle1.Length > strTitle2.Length ? strTitle1 : strTitle2);
								string strTime = item.SelectSingleNode(".//span").InnerText;
								string strURL = strServerURL+item.SelectSingleNode(".//a").GetAttributeValue("href", "");


								if(Regex.IsMatch(strTime, @"\d+/\d+")==true)
								{
									//Console.WriteLine("어제 기사 : " + item.InnerHtml);
									continue;
								}

								m_Listener.InsertItem(strTitle, "", "",
									DateTime.ParseExact(strTime, "HH:mm", CultureInfo.CurrentCulture),
									DateTime.Now,
									strURL, "아시아경제", State.m_Timer.Elapsed.TotalMilliseconds, bInitial);
							}

						}
					}
				}

				HttpReq.EndGetResponse(result);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		public void ReadAsiaE(bool bInitial = false)
		{
			try
			{
				HttpWebRequest HttpReq = WebRequest.Create("http://www.asiae.co.kr/news/sokbo/sokbo_left.htm") as HttpWebRequest;
				HttpReq.Credentials = CredentialCache.DefaultCredentials;
				HttpReq.Timeout = 2000;

				REQUEST_STATUS State = new REQUEST_STATUS();
				State.m_HTTPReq = HttpReq;
				State.m_bInitial = bInitial;
				State.m_Timer.Start();

				HttpReq.BeginGetResponse(new AsyncCallback(ResponseAsiaE), State);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}


		void ResponseEtoday(IAsyncResult result)
		{
			REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState;
			HttpWebRequest HttpReq = State.m_HTTPReq;
			bool bInitial = State.m_bInitial;
			State.m_Timer.Stop();

			try
			{
				using(HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse())
				{
					using(Stream dataStream = response.GetResponseStream())
					{
						using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("utf-8")))
						{
							string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd());

							HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
							doc.LoadHtml(responseFromServer);
							string strXPath = "//div[contains(@class, 'flash_tab_lst')]/ul/li";
							var lists = doc.DocumentNode.SelectNodes(strXPath);
							foreach(var item in lists)
							{
								string strTitle = item.SelectSingleNode(".//a").InnerText;
								string strTime = item.SelectSingleNode(".//span[contains(@class, 'flash_press')]").InnerText;
								string strURL = item.SelectSingleNode(".//a").GetAttributeValue("href", "");
								strURL="http://www.etoday.co.kr/news/section/newsview.php?idxno="+Regex.Replace(strURL, @"\D", "");

								if(Regex.IsMatch(strTime, @"\d+/\d+")==true)
								{
									//Console.WriteLine("어제 기사 : " + item.InnerHtml);
									continue;
								}

								m_Listener.InsertItem(strTitle, "", "",
									DateTime.ParseExact(strTime, "HH:mm", CultureInfo.CurrentCulture),
									DateTime.Now,
									strURL, "이투데이", State.m_Timer.Elapsed.TotalMilliseconds, bInitial);
							}
						}
					}
				}

				HttpReq.EndGetResponse(result);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		public void ReadEtoday(bool bInitial = false)
		{
			try
			{
				HttpWebRequest HttpReq = WebRequest.Create("http://www.etoday.co.kr/news/flash/flash_list.php?tab=1") as HttpWebRequest;
				HttpReq.Credentials = CredentialCache.DefaultCredentials;
				HttpReq.Timeout = 2000;

				REQUEST_STATUS State = new REQUEST_STATUS();
				State.m_HTTPReq = HttpReq;
				State.m_bInitial = bInitial;
				State.m_Timer.Start();

				HttpReq.BeginGetResponse(new AsyncCallback(ResponseEtoday), State);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}


		void ResponseEtoday2(IAsyncResult result)
		{
			REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState;
			HttpWebRequest HttpReq = State.m_HTTPReq;
			bool bInitial = State.m_bInitial;
			State.m_Timer.Stop();

			try
			{
				WebRequest request = WebRequest.Create("http://rss.etoday.co.kr/etoday/etoday_news_all.xml");
				request.Credentials=CredentialCache.DefaultCredentials;
				request.Timeout=2000;
				int iCDATALen = "<![CDATA[".Length;

				using(HttpWebResponse response = (HttpWebResponse)request.GetResponse())
				{
					using(Stream dataStream = response.GetResponseStream())
					{
						using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("utf-8")))
						{
							string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd());

							HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
							doc.LoadHtml(responseFromServer);

							string strXPath = "//item";
							var lists = doc.DocumentNode.SelectNodes(strXPath);
							if(lists == null)
								return;

							foreach(var item in lists)
							{
								string strTitle = item.SelectSingleNode(".//title").InnerText;
								strTitle = strTitle.Substring(iCDATALen, strTitle.Length-iCDATALen-3);
								string strTime = item.ChildNodes["pubDate"].InnerText;
								DateTime time = Convert.ToDateTime(strTime);
								strTime = time.ToString("HH:mm:ss");
								string strURL = "[rss] " + item.ChildNodes["link"].NextSibling.InnerText;

								if(time.Day != m_Today.Day)
								{
									//Console.WriteLine("어제 기사 : " + item.InnerHtml);
									continue;
								}

								m_Listener.InsertItem(strTitle, "", "",
									DateTime.ParseExact(strTime, "HH:mm:ss", CultureInfo.CurrentCulture),
									DateTime.Now,
									strURL, "이투데이 rss", State.m_Timer.Elapsed.TotalMilliseconds, bInitial);
							}
						}
					}
				}

				HttpReq.EndGetResponse(result);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		public void ReadEtoday2(bool bInitial = false)
		{
			try
			{
				HttpWebRequest HttpReq = WebRequest.Create("http://rss.etoday.co.kr/etoday/etoday_news_all.xml") as HttpWebRequest;
				HttpReq.Credentials = CredentialCache.DefaultCredentials;
				HttpReq.Timeout = 2000;

				REQUEST_STATUS State = new REQUEST_STATUS();
				State.m_HTTPReq = HttpReq;
				State.m_bInitial = bInitial;
				State.m_Timer.Start();

				HttpReq.BeginGetResponse(new AsyncCallback(ResponseEtoday2), State);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		void ResponseDart(IAsyncResult result)
		{
			REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState;
			HttpWebRequest HttpReq = State.m_HTTPReq;
			bool bInitial = State.m_bInitial;
			State.m_Timer.Stop();

			try
			{
				string strServerURL = "https://dart.fss.or.kr";

				using(HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse())
				{
					using(Stream dataStream = response.GetResponseStream())
					{
						using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("utf-8")))
						{
							string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd());

							HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
							doc.LoadHtml(responseFromServer);

							string strXPath = "//div[@id='listContents']/div[contains(@class, 'table_list')]/table/tr";
							var lists = doc.DocumentNode.SelectNodes(strXPath);
							foreach(var item in lists)
							{
								var rows = item.SelectNodes(".//td");
								if(rows.Count < 3)
									continue;

								string strTitle = rows[2].InnerText;
								strTitle=strTitle.Trim();
								string strTime = item.SelectSingleNode(".//td[contains(@class, 'cen_txt')]").InnerText;
								strTime=strTime.Trim();
								string strURL = rows[2].SelectSingleNode(".//a").GetAttributeValue("href", "");
								strURL=strURL.Trim();
								strURL =strServerURL+strURL;

								if(Regex.IsMatch(strTime, @"\d+/\d+")==true)
								{
									//Console.WriteLine("어제 기사 : " + item.InnerHtml);
									continue;
								}

								m_Listener.InsertItem(strTitle, "", "",
									DateTime.ParseExact(strTime, "HH:mm", CultureInfo.CurrentCulture),
									DateTime.Now,
									strURL, "DART", State.m_Timer.Elapsed.TotalMilliseconds, bInitial);
							}
						}
					}
				}

				HttpReq.EndGetResponse(result);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		public void ReadDart(bool bInitial = false)
		{
			try
			{
				HttpWebRequest HttpReq = WebRequest.Create("https://dart.fss.or.kr/dsac001/mainAll.do") as HttpWebRequest;
				HttpReq.Credentials = CredentialCache.DefaultCredentials;
				HttpReq.Timeout = 2000;

				REQUEST_STATUS State = new REQUEST_STATUS();
				State.m_HTTPReq = HttpReq;
				State.m_bInitial = bInitial;
				State.m_Timer.Start();

				HttpReq.BeginGetResponse(new AsyncCallback(ResponseDart), State);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		void ResponseSupplyContract(IAsyncResult result)
		{
			REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState;
			HttpWebRequest HttpReq = State.m_HTTPReq;
			bool bInitial = State.m_bInitial;
			State.m_Timer.Stop();

			try
			{
				using(HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse())
				{
					using(Stream dataStream = response.GetResponseStream())
					{
						using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("utf-8")))
						{
							string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd());

							dynamic jObj = Newtonsoft.Json.JsonConvert.DeserializeObject(responseFromServer);
							string strBody = jObj["reportBody"];
							strBody = strBody.Replace("\\\"", "\"");
							strBody = strBody.Replace("\r\n", "");
							HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
							doc.LoadHtml(strBody);

							string strXPath = "//tr";
							var lists = doc.DocumentNode.SelectNodes(strXPath);
							foreach(var item in lists)
							{
								var cols = item.SelectNodes(".//td");
								foreach(var col in cols)
								{
									if(col.InnerText.Contains("매출액 대비") == true)
									{
										string strRate = cols[cols.Count-1].InnerText;
										float fRate;
										float.TryParse(strRate, out fRate);
										m_Listener.OnReceivedSupplyContract(State.m_strCodeName, fRate);
										return;
									}
								}
							}
						}
					}
				}

				HttpReq.EndGetResponse(result);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		private void ReadSupplyContract(bool bInitial, string strCodeName, string strURL)
		{
			try
			{
				HttpWebRequest HttpReq = WebRequest.Create(strURL) as HttpWebRequest;
				HttpReq.Credentials = CredentialCache.DefaultCredentials;
				HttpReq.Timeout = 2000;

				REQUEST_STATUS State = new REQUEST_STATUS();
				State.m_HTTPReq = HttpReq;
				State.m_bInitial = bInitial;
				State.m_Timer.Start();
				State.m_strCodeName = strCodeName;

				HttpReq.BeginGetResponse(new AsyncCallback(ResponseSupplyContract), State);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		void ResponseRevenue(IAsyncResult result)
		{
			REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState;
			HttpWebRequest HttpReq = State.m_HTTPReq;
			bool bInitial = State.m_bInitial;
			State.m_Timer.Stop();

			try
			{
				using (HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse())
				{
					using (Stream dataStream = response.GetResponseStream())
					{
						using (StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("utf-8")))
						{
							string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd());

							dynamic jObj = Newtonsoft.Json.JsonConvert.DeserializeObject(responseFromServer);
							string strBody = jObj["reportBody"];
							strBody = strBody.Replace("\\\"", "\"");
							strBody = strBody.Replace("\r\n", "");
							HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
							doc.LoadHtml(strBody);

							string strXPath = "//tr";
							var lists = doc.DocumentNode.SelectNodes(strXPath);
							foreach (var item in lists)
							{
								var cols = item.SelectNodes(".//td");
								foreach (var col in cols)
								{
									if (col.InnerText.Contains("당기순이익") == true)
									{
										string strRate = cols[cols.Count - 1].InnerText;
										strRate = strRate.Replace("%", "");
										strRate = strRate.Replace(" ", "");
										float fRate;
										float.TryParse(strRate, NumberStyles.Float, CultureInfo.InvariantCulture, out fRate);
										m_Listener.OnReceivedRevenue(State.m_strCodeName, fRate);
										return;
									}
								}
							}
						}
					}
				}

				HttpReq.EndGetResponse(result);
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		private void ReadRevenue(bool bInitial, string strCodeName, string strURL)
		{
			try
			{
				HttpWebRequest HttpReq = WebRequest.Create(strURL) as HttpWebRequest;
				HttpReq.Credentials = CredentialCache.DefaultCredentials;
				HttpReq.Timeout = 2000;

				REQUEST_STATUS State = new REQUEST_STATUS();
				State.m_HTTPReq = HttpReq;
				State.m_bInitial = bInitial;
				State.m_Timer.Start();
				State.m_strCodeName = strCodeName;

				HttpReq.BeginGetResponse(new AsyncCallback(ResponseRevenue), State);
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		void ResponseRightsIssue(IAsyncResult result)
		{
			REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState;
			HttpWebRequest HttpReq = State.m_HTTPReq;
			bool bInitial = State.m_bInitial;
			State.m_Timer.Stop();

			try
			{
				using (HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse())
				{
					using (Stream dataStream = response.GetResponseStream())
					{
						using (StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("utf-8")))
						{
							string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd());

							dynamic jObj = Newtonsoft.Json.JsonConvert.DeserializeObject(responseFromServer);
							string strBody = jObj["reportBody"];
							strBody = strBody.Replace("\\\"", "\"");
							strBody = strBody.Replace("\r\n", "");
							HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
							doc.LoadHtml(strBody);

							string strXPath = "//tr";
							var lists = doc.DocumentNode.SelectNodes(strXPath);
							foreach (var item in lists)
							{
								var cols = item.SelectNodes(".//td");
								for(int i=0; i<cols.Count-1; i++)
								{
									if(cols[i].InnerText.Contains("증자방식") && cols[i+1].InnerText.Contains("제3자배정증자"))
									{
										m_Listener.OnReceivedRightsIssue(State.m_strCodeName);
										return;
									}
								}
							}
						}
					}
				}

				HttpReq.EndGetResponse(result);
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		private void ReadRightsIssue(bool bInitial, string strCodeName, string strURL)
		{
			try
			{
				HttpWebRequest HttpReq = WebRequest.Create(strURL) as HttpWebRequest;
				HttpReq.Credentials = CredentialCache.DefaultCredentials;
				HttpReq.Timeout = 2000;

				REQUEST_STATUS State = new REQUEST_STATUS();
				State.m_HTTPReq = HttpReq;
				State.m_bInitial = bInitial;
				State.m_Timer.Start();
				State.m_strCodeName = strCodeName;

				HttpReq.BeginGetResponse(new AsyncCallback(ResponseRightsIssue), State);
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		void ResponsePatent(IAsyncResult result)
		{
			REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState;
			HttpWebRequest HttpReq = State.m_HTTPReq;
			bool bInitial = State.m_bInitial;
			State.m_Timer.Stop();

			try
			{
				using(HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse())
				{
					using(Stream dataStream = response.GetResponseStream())
					{
						using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("utf-8")))
						{
							string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd());

							dynamic jObj = Newtonsoft.Json.JsonConvert.DeserializeObject(responseFromServer);
							string strBody = jObj["reportBody"];
							strBody = strBody.Replace("\\\"", "\"");
							strBody = strBody.Replace("\r\n", "");
							HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
							doc.LoadHtml(strBody);

							string strXPath = "//tr";
							var lists = doc.DocumentNode.SelectNodes(strXPath);
							foreach(var item in lists)
							{
								var cols = item.SelectNodes(".//td");
								for(int i = 0; i<cols.Count-1; i++)
								{
									if(cols[i].InnerText.Contains("기타 투자판단에 참고할 사항") && 
										Config.GetPatentSearchString().IsMatch(cols[i+1].InnerText))
									{
										m_Listener.OnReceivedPatent(State.m_strCodeName);
										return;
									}
								}
							}
						}
					}
				}

				HttpReq.EndGetResponse(result);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		private void ReadPatent(bool bInitial, string strCodeName, string strURL)
		{
			try
			{
				HttpWebRequest HttpReq = WebRequest.Create(strURL) as HttpWebRequest;
				HttpReq.Credentials = CredentialCache.DefaultCredentials;
				HttpReq.Timeout = 2000;

				REQUEST_STATUS State = new REQUEST_STATUS();
				State.m_HTTPReq = HttpReq;
				State.m_bInitial = bInitial;
				State.m_Timer.Start();
				State.m_strCodeName = strCodeName;

				HttpReq.BeginGetResponse(new AsyncCallback(ResponsePatent), State);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		void ResponseDartAPI(IAsyncResult result)
		{
			REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState;
			HttpWebRequest HttpReq = State.m_HTTPReq;
			bool bInitial = State.m_bInitial;
			State.m_Timer.Stop();

			try
			{
				using(HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse())
				{
					using(Stream dataStream = response.GetResponseStream())
					{
						using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("utf-8")))
						{
							string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd());

							dynamic jObj = Newtonsoft.Json.JsonConvert.DeserializeObject(responseFromServer);
							string strErrCode = jObj["err_code"];
							if(strErrCode == "020")
							{
								Config.SetDartAPIKeyLimit(State.m_strAuthKey);
								Util.Log(Util.LOG_TYPE.ERROR, string.Format("[DartAPI] {0} (key:{1}, retry:{2})", jObj["err_msg"], State.m_strAuthKey, m_iDartAPIRetry));
								return;
							}
							else if(strErrCode != "000")
							{
								Util.Log(Util.LOG_TYPE.ERROR, string.Format("[DartAPI] {0} (key:{1}, retry:{2})", jObj["err_msg"], State.m_strAuthKey, m_iDartAPIRetry));
								m_iDartAPIRetry--;
								return;
							}

							foreach(var data in jObj["list"])
							{
								string strTime = "00:00";
								string strTitle = data["rpt_nm"];
								string strCodeName = data["crp_nm"];
								string strURL = "http://m.dart.fss.or.kr/html_mdart/MD1007.html?rcpNo=" + data["rcp_no"];
								string strViewURL = "http://m.dart.fss.or.kr/viewer/main.st?rcpNo=" + data["rcp_no"];

								if (Config.CheckSupplyContract() &&  strCodeName != "" && strTitle.Contains("공급계약체결") && m_Listener.IsDuplicatedURL(strURL) == false)
									ReadSupplyContract(bInitial, strCodeName, strViewURL);
								else if(Config.CheckRevenue() && strCodeName != "" && strTitle.Contains("영업(잠정)실적(공정공시)") && m_Listener.IsDuplicatedURL(strURL) == false)
									ReadRevenue(bInitial, strCodeName, strViewURL);
								else if(Config.CheckRightsIssue() && strCodeName != "" && strTitle.Contains("유상증자결정") && m_Listener.IsDuplicatedURL(strURL) == false)
									ReadRightsIssue(bInitial, strCodeName, strViewURL);
								else if(Config.CheckPatent() && strCodeName != "" && strTitle.Contains("특허권취득") && m_Listener.IsDuplicatedURL(strURL) == false)
									ReadPatent(bInitial, strCodeName, strViewURL);

								m_Listener.InsertItem(strTitle, strCodeName, "",
									DateTime.ParseExact(strTime, "HH:mm", CultureInfo.CurrentCulture),
									DateTime.Now,
									strURL, "DartAPI", State.m_Timer.Elapsed.TotalMilliseconds, bInitial);
							}
						}
					}
				}

				HttpReq.EndGetResponse(result);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		public void ReadDartAPI(bool bInitial = false)
		{
			if (Util.IsDebugging() == true)
				return;

			if(m_iDartAPIRetry <= 0)
				return;

			try
			{
				string strAuthKey = Config.GetDartAPIKey();
				string strURL = "http://dart.fss.or.kr/api/search.json?auth="+strAuthKey+"&end_dt="+m_Today.ToString("yyyyMMdd");
				HttpWebRequest HttpReq = WebRequest.Create(strURL) as HttpWebRequest;
				HttpReq.Credentials = CredentialCache.DefaultCredentials;
				HttpReq.Timeout = 2000;

				REQUEST_STATUS State = new REQUEST_STATUS();
				State.m_HTTPReq = HttpReq;
				State.m_bInitial = bInitial;
				State.m_Timer.Start();
				State.m_strAuthKey = strAuthKey;

				HttpReq.BeginGetResponse(new AsyncCallback(ResponseDartAPI), State);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}


		void ResponseKIND(IAsyncResult result)
		{
			REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState;
			HttpWebRequest HttpReq = State.m_HTTPReq;
			bool bInitial = State.m_bInitial;
			State.m_Timer.Stop();

			try
			{
				//string strServerURL = "https://dart.fss.or.kr";
				int iCDATALen = "<![CDATA[".Length;

				using(HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse())
				{
					using(Stream dataStream = response.GetResponseStream())
					{
						using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("utf-8")))
						{
							string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd());

							HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
							doc.LoadHtml(responseFromServer);

							string strXPath = "//item";
							var lists = doc.DocumentNode.SelectNodes(strXPath);
							if(lists == null)
								return;

							foreach(var item in lists)
							{
								string strTitle = item.SelectSingleNode(".//title").InnerText;
								strTitle = strTitle.Substring(iCDATALen, strTitle.Length-iCDATALen-3);
								string strTime = item.ChildNodes["pubDate"].InnerText;
								DateTime time = Convert.ToDateTime(strTime);
								strTime = time.ToString("HH:mm:ss");
								string strURL = item.ChildNodes["link"].NextSibling.InnerText;
								strURL = strURL.Substring(iCDATALen, strURL.Length-iCDATALen-3);

								if(Regex.IsMatch(strTime, @"\d+/\d+")==true)
								{
									//Console.WriteLine("어제 기사 : " + item.InnerHtml);
									continue;
								}

								m_Listener.InsertItem(strTitle, "", "",
									DateTime.ParseExact(strTime, "HH:mm:ss", CultureInfo.CurrentCulture),
									DateTime.Now,
									strURL, "KIND", State.m_Timer.Elapsed.TotalMilliseconds, bInitial);
							}
						}
					}
				}

				HttpReq.EndGetResponse(result);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		public void ReadKIND(bool bInitial = false)
		{
			try
			{
				HttpWebRequest HttpReq = WebRequest.Create("http://kind.krx.co.kr/disclosure/rsstodaydistribute.do?method=searchRssTodayDistribute&repIsuSrtCd=&mktTpCd=0&searchCorpName=&currentPageSize=1000") as HttpWebRequest;
				HttpReq.Credentials = CredentialCache.DefaultCredentials;
				HttpReq.Timeout = 2000;

				REQUEST_STATUS State = new REQUEST_STATUS();
				State.m_HTTPReq = HttpReq;
				State.m_bInitial = bInitial;
				State.m_Timer.Start();

				HttpReq.BeginGetResponse(new AsyncCallback(ResponseKIND), State);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}


		void ResponseEdaily(IAsyncResult result)
		{
			REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState;
			HttpWebRequest HttpReq = State.m_HTTPReq;
			bool bInitial = State.m_bInitial;
			State.m_Timer.Stop();

			try
			{
				string strServerURL = "http://www.edaily.co.kr/news/realtime/realtime_NewsRead.asp";

				DateTime PrevTime = DateTime.Now;

				using(HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse())
				{
					using(Stream dataStream = response.GetResponseStream())
					{
						using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("EUC-KR")))
						{
							string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd());

							HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
							doc.LoadHtml(responseFromServer);
							string strXPath = "//li[contains(@id, 'NewsIcon')]";
							var lists = doc.DocumentNode.SelectNodes(strXPath);
							foreach(var item in lists)
							{
								string strTitle = item.SelectSingleNode(".//a").GetAttributeValue("title", "");
								string strTime = item.SelectSingleNode(".//span").InnerText;

								string strID = item.GetAttributeValue("id", "");
								strID = strID.Substring("NewsIcon_".Length);
								string strURL = strServerURL+"?newsid="+strID;

								DateTime Time;
								DateTime.TryParseExact(strTime, "HH:mm", CultureInfo.CurrentCulture, DateTimeStyles.None, out Time);
								if(Time > PrevTime)
									break;
								PrevTime = Time;

								m_Listener.InsertItem(strTitle, "", "", Time, DateTime.Now, strURL, "이데일리", State.m_Timer.Elapsed.TotalMilliseconds, bInitial);
							}
						}
					}
				}

				HttpReq.EndGetResponse(result);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		public void ReadEdaily(bool bInitial = false)
		{
			try
			{
				HttpWebRequest HttpReq = WebRequest.Create("http://www.edaily.co.kr/news/realtime/realtime_NewsList_1.asp") as HttpWebRequest;
				HttpReq.Credentials = CredentialCache.DefaultCredentials;
				HttpReq.Timeout = 2000;

				REQUEST_STATUS State = new REQUEST_STATUS();
				State.m_HTTPReq = HttpReq;
				State.m_bInitial = bInitial;
				State.m_Timer.Start();

				HttpReq.BeginGetResponse(new AsyncCallback(ResponseEdaily), State);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}


		void ResponseMoneyToday(IAsyncResult result)
		{
			REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState;
			HttpWebRequest HttpReq = State.m_HTTPReq;
			bool bInitial = State.m_bInitial;
			State.m_Timer.Stop();

			try
			{
				string strServerURL = "http://news.mt.co.kr/mtview.php?no=";

				DateTime PrevTime = DateTime.Now;

				using(HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse())
				{
					using(Stream dataStream = response.GetResponseStream())
					{
						using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("EUC-KR")))
						{
							string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd());

							HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
							doc.LoadHtml(responseFromServer);
							string strXPath = "//div[@id='articleList']//li[@class='bundle']";

							var lists = doc.DocumentNode.SelectNodes(strXPath);
							foreach(var item in lists)
							{
								string strTitle = item.SelectSingleNode(".//a").InnerText;
								string strTime = item.SelectSingleNode(".//span").InnerText;

								string strID = item.SelectSingleNode(".//a").GetAttributeValue("href", "");
								int iStart = strID.IndexOf('\'', 0);
								iStart = strID.IndexOf('\'', iStart+1);
								iStart = strID.IndexOf('\'', iStart+1);
								int iEnd = strID.IndexOf('\'', iStart+1);
								strID = strID.Substring(iStart+1, iEnd-iStart+1);
								string strURL = strServerURL+strID;

								DateTime Time;
								DateTime.TryParseExact(strTime, "HH:mm", CultureInfo.CurrentCulture, DateTimeStyles.None, out Time);
								if(Time > PrevTime)
									break;
								PrevTime = Time;

								m_Listener.InsertItem(strTitle, "", "", Time, DateTime.Now, strURL, "머니투데이", State.m_Timer.Elapsed.TotalMilliseconds, bInitial);
							}
						}
					}
				}

				HttpReq.EndGetResponse(result);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		public void ReadMoneyToday(bool bInitial = false)
		{
			try
			{
				HttpWebRequest HttpReq = WebRequest.Create("http://news.mt.co.kr/newsflash/newsflash.html") as HttpWebRequest;
				HttpReq.Credentials = CredentialCache.DefaultCredentials;
				HttpReq.Timeout = 2000;

				REQUEST_STATUS State = new REQUEST_STATUS();
				State.m_HTTPReq = HttpReq;
				State.m_bInitial = bInitial;
				State.m_Timer.Start();

				HttpReq.BeginGetResponse(new AsyncCallback(ResponseMoneyToday), State);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}


		void ResponseFinancialNewsJson(IAsyncResult result)
		{
			REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState;
			HttpWebRequest HttpReq = State.m_HTTPReq;
			bool bInitial = State.m_bInitial;
			State.m_Timer.Stop();

			try
			{
				string strServerURL = "http://www.fnnews.com/news/";

				using(HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse())
				{
					using(Stream dataStream = response.GetResponseStream())
					{
						using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("UTF-8")))
						{
							string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd());

							dynamic jObj = Newtonsoft.Json.JsonConvert.DeserializeObject(responseFromServer);
							foreach(var data in jObj)
							{
								string strTitle = data["title"];
								string strTime = data["date"];
								DateTime Time;
								DateTime.TryParseExact(strTime, "yyyy.MM.dd HH:mm", CultureInfo.CurrentCulture, DateTimeStyles.None, out Time);

								string strCode = data["code"];
								string strURL = strServerURL+strCode;

								if(Time.DayOfYear == m_Today.DayOfYear)
									m_Listener.InsertItem(strTitle, "", "", Time, DateTime.Now, strURL, "파이낸셜뉴스", State.m_Timer.Elapsed.TotalMilliseconds, bInitial);
							}
						}
					}
				}

				HttpReq.EndGetResponse(result);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		public void ReadFinancialNewsJson(bool bInitial = false)
		{
			try
			{
				HttpWebRequest HttpReq = WebRequest.Create("http://www.fnnews.com/newsflash/today/data?type=json") as HttpWebRequest;
				HttpReq.Credentials = CredentialCache.DefaultCredentials;
				HttpReq.Timeout = 2000;

				REQUEST_STATUS State = new REQUEST_STATUS();
				State.m_HTTPReq = HttpReq;
				State.m_bInitial = bInitial;
				State.m_Timer.Start();

				HttpReq.BeginGetResponse(new AsyncCallback(ResponseFinancialNewsJson), State);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}


		void ResponseFinancialNews(IAsyncResult result)
		{
			REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState;
			HttpWebRequest HttpReq = State.m_HTTPReq;
			bool bInitial = State.m_bInitial;
			State.m_Timer.Stop();

			try
			{
				string strServerURL = "http://www.fnnews.com";

				DateTime Today = DateTime.Now;

				using(HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse())
				{
					using(Stream dataStream = response.GetResponseStream())
					{
						using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("UTF-8")))
						{
							string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd());

							HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
							doc.LoadHtml(responseFromServer);
							string strXPath = "//div[@class='categoryList']//li";

							var lists = doc.DocumentNode.SelectNodes(strXPath);
							try
							{
								foreach(var item in lists)
								{
									string strTitle = item.SelectNodes(".//a")[1].InnerText;
									string strDateTime = item.SelectSingleNode(".//span[@class='category_date']").InnerText;
									string strURL = strServerURL+item.SelectNodes(".//a")[1].GetAttributeValue("href", "");

									DateTime Time;
									DateTime.TryParseExact(strDateTime, "yyyy.MM.dd HH:mm", CultureInfo.CurrentCulture, DateTimeStyles.None, out Time);
									if(Time.DayOfYear < m_Today.DayOfYear)
										break;

									m_Listener.InsertItem(strTitle, "", "", Time, DateTime.Now, strURL, "파이낸셜뉴스", State.m_Timer.Elapsed.TotalMilliseconds, bInitial);
								}
							}
							catch(Exception ex)
							{
								Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
							}
						}
					}
				}

				HttpReq.EndGetResponse(result);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}

		public void ReadFinancialNews(bool bInitial = false)
		{
			try
			{
				HttpWebRequest HttpReq = WebRequest.Create("http://www.fnnews.com/newsflash") as HttpWebRequest;
				HttpReq.Credentials = CredentialCache.DefaultCredentials;
				HttpReq.Timeout = 2000;

				REQUEST_STATUS State = new REQUEST_STATUS();
				State.m_HTTPReq = HttpReq;
				State.m_bInitial = bInitial;
				State.m_Timer.Start();

				HttpReq.BeginGetResponse(new AsyncCallback(ResponseFinancialNews), State);
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
			}
		}
	}
}