using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Net;
using System.IO;
namespace Crosswords.WebHelper
{
public class HtmlParser
{
const string msgFormat = "table[{0}], tr[{1}], td[{2}], code: {3}";
const string table_pattern = "<table.*?>(.*?)</table>";
const string tr_pattern = "<tr>(.*?)</tr>";
const string td_pattern = "<td.*?>(.*?)</td>";
const string code_pattern = "<code>(.*?)</code>";
string html = string.Empty;
WebRequest request;
public HtmlParser(int size, Action<string> onSuccess, Action onFailure, Action<int> onProgressChanged
)
{
GetPuzzleHtml(size,
//onSucess
(html) =>
{
this.html = html;
onSuccess(html);
},
//onFailure
() =>
{
onFailure();
},
//onProgressChanged
(percentage) =>
{
onProgressChanged(percentage);
}
);
}
public HtmlParser(string html)
{
this.html = html;
}
private List<string> GetContents(string input, string pattern)
{
MatchCollection matches = Regex.Matches(input, pattern, RegexOptions.Singleline);
List<string> contents = new List<string>();
foreach (Match match in matches)
contents.Add(match.Value);
return contents;
}
public string Parse()
{
List<string> tableContents = GetContents(html, table_pattern);
StringBuilder ret = new StringBuilder();
int tableIndex = 0;
foreach (string tableContent in tableContents)
{
List<string> trContents = GetContents(tableContent, tr_pattern);
int trIndex = 0;
foreach (string trContent in trContents)
{
List<string> tdContents = GetContents(trContent, td_pattern);
int tdIndex = 0;
foreach (string tdContent in tdContents)
{
Match code_match = Regex.Match(tdContent, code_pattern);
string code_value = code_match.Groups[1].Value.Replace(" ", "");
if (string.IsNullOrEmpty(code_value))
code_value = " ";
ret.Append(code_value);
tdIndex++;
}
ret.Append("");
trIndex++;
}
tableIndex++;
}
var words = ret.ToString();
return words;
}
public void GetPuzzleHtml(int size, Action<string> onSuccess, Action onFailure, Action<int> onProgressChanged)
{
var ret = string.Empty;
var tileMap = string.Empty;
switch (size)
{
case 4:
tileMap = string.Concat(
"0000",
"0000",
"0000",
"0000");
break;
case 7:
tileMap = string.Concat(
"0000011",
"0000100",
"0000100",
"0110000",
"1000000",
"0000000",
"0000100");
break;
case 10:
tileMap = string.Concat(
"0000110001",
"0000100001",
"0000000000",
"0000000000",
"1110001000",
"1000000100",
"0001000011",
"0000100000",
"0000010000",
"1000000000");
break;
}
var queryString = GetRequestQueryStringBySize(size, tileMap);
var url = string.Format("http://pdos.csail.mit.edu/cgi-bin/theme-cword{0}", queryString.AppendFormat("&t={0}", DateTime.Now.Millisecond));
//if (request != null)
//{
// request.Abort();
//}
//request = WebRequest.Create(url);
//request.BeginGetResponse(r =>
//{
// var response = request.EndGetResponse(r);
// using (var sr = new StreamReader(response.GetResponseStream()))
// {
// endGetResponse(sr.ReadToEnd());
// }
//}, null);
DownloadString
(url,
//onSuccess
(html) =>
{
onSuccess(html);
},
//onFailure
() =>
{
onFailure();
},
//progress
(percentage) =>
{
onProgressChanged(percentage);
});
}
private void DownloadString(string url, Action<string> onDownloadCompleted, Action onConnectionFailed, Action<int> onProgressChanged)
{
try
{
var webClient = new WebClient();
webClient.DownloadStringCompleted += (sender, e) =>
{
try
{
onDownloadCompleted(e.Result);
}
catch (Exception exc)
{
onConnectionFailed();
}
};
webClient.DownloadProgressChanged += (sender, e) =>
{
onProgressChanged(e.ProgressPercentage);
};
webClient.AllowReadStreamBuffering = true;
webClient.DownloadStringAsync(new Uri(url), webClient);
}
catch (Exception exc)
{
onConnectionFailed();
}
}
private static StringBuilder GetRequestQueryStringBySize(int size, string tileMap)
{
var queryString = new StringBuilder();
for (var row = 0; row < size; row++)
{
for (var col = 0; col < size; col++)
{
var val = tileMap[row * size + col];
if (val == '0')
{
var prefix = "&";
if (string.IsNullOrEmpty(queryString.ToString()))
{
prefix = "?";
}
queryString.AppendFormat("{0}r{1}c{2}=", prefix, row, col);
}
}
}
return queryString;
}
}
}