using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Xml;
using System.Windows.Data;
using System.IO;
using System.Globalization;
using System.Web;
using Microsoft.VisualStudio.Shell.Interop;
using System.Windows.Controls.Primitives;
using System.Windows.Controls;
using Microsoft.Win32;
namespace MS.SDKMSDNKeywordIndex
{
public class HelpApiShim
{
private static string _baseOfflineUrlSession;
private const string baseOfflineUrl = "http://127.0.0.1:47873/help/";
private static string _locale;
public HelpApiShim()
{
_baseOfflineUrlSession = GetBaseHelpUrl(); // baseOfflineUrl + NativeMethods.GetSessionNumber().ToString() + "/ms.help?";
_locale = CultureInfo.CurrentUICulture.ToString();
}
private static string GetBaseHelpUrl()
{
string pid;
HelpUtility.StartHelpAgent();
System.Diagnostics.Process[] helpProcesses = System.Diagnostics.Process.GetProcessesByName("helplibagent");
pid = helpProcesses[0].Id.ToString();
_baseOfflineUrlSession = baseOfflineUrl + NativeMethods.GetSessionNumber().ToString() + "-" + pid + "/ms.help?";
return _baseOfflineUrlSession;
}
public List<TocNode> GetRootTocNodes()
{
TocNode rootNode = new TocNode("", "", "-1");
return GetTocNodes(rootNode);
}
public List<TocNode> GetTocNodes(TocNode tocNode)
{
List<TocNode> childNodes = new List<TocNode>();
if (tocNode == null)
return childNodes;
string tocURL = buildHelpUrl("children", tocNode.Id, "VS", "100", "xml");
Stream tocXmlStream = HelpUtility.GetHelpXmlAsStream(tocURL);
XmlTextReader tocReader = new XmlTextReader(tocXmlStream);
while (tocReader.Read())
{
switch (tocReader.NodeType)
{
case XmlNodeType.Element:
if (tocReader.Name.Equals("topic"))
{
TocNode node = new TocNode();
node.Id = tocReader.GetAttribute("id");
tocReader.ReadToDescendant("title");
node.Title = tocReader.ReadString();
tocReader.ReadToNextSibling("url");
node.Url = tocReader.ReadString();
node.hasChildren = nodeHasChildren(node);
childNodes.Add(node);
}
break;
}
}
return childNodes;
}
private static bool nodeHasChildren(TocNode node)
{
string tocURL = buildHelpUrl("children", node.Id, "VS", "100", "xml");
XmlDocument document = HelpUtility.GetHelpXmlAsXmlDocument(tocURL);
XmlNodeList topicNodes = document.SelectNodes("/children/topic");
if (topicNodes.Count > 0)
{ return true; }
else
{ return false; }
}
public List<kwdItem> GetKeywordItems(string keyword)
{
List<kwdItem> kwdList = new List<kwdItem>();
string helpUrl = buildHelpUrl("keywords", keyword, "VS", "100", "xml", "&pageSize=100000&pagenumber=1");
Stream keywordXmlStream = HelpUtility.GetHelpXmlAsStream(helpUrl);
if (keywordXmlStream == null)
return kwdList;
XmlTextReader keywordReader = new XmlTextReader(keywordXmlStream);
string currentKwd = "";
while (keywordReader.Read())
{
switch (keywordReader.NodeType)
{
case XmlNodeType.Element:
if (keywordReader.Name.Equals("keywords"))
{
//keywordCount = int.Parse(keywordReader.GetAttribute("totalKeywords"));
//currentKeywordCount += int.Parse(keywordReader.GetAttribute("returnedkeywords"));
}
else if (keywordReader.Name.Equals("keyword"))
{
currentKwd = keywordReader.GetAttribute("value");
kwdList.Add(new kwdItem(currentKwd, currentKwd));
}
else if (keywordReader.Name.Equals("subkey"))
{
string subKey = keywordReader.GetAttribute("display");
kwdList.Add(new kwdItem(" " + subKey, currentKwd + "," + subKey));
}
break;
}
}
return kwdList;
}
public void NavigateKeywordTopic(kwdItem kwd, string browser, bool embedTOC)
{
string helpUrl = createKwdItemUrl(kwd, embedTOC);
if (helpUrl != null)
{
launchHelp(helpUrl, browser);
}
}
public void NavigateKeywordTopic(XmlDocument keywordTopicXML, string browser, bool embedTOCparam)
{
string helpUrl = createKwdItemUrl(keywordTopicXML, embedTOCparam);
if (helpUrl != null)
{
launchHelp(helpUrl, browser);
}
}
public void NavigateTopicItem(TopicItem topic, string browser, bool embedTOCParam)
{
string helpUrl = createTopicItemUrl(topic, embedTOCParam);
if (helpUrl != null)
{
launchHelp(helpUrl, browser);
}
}
public void NavigateSearchTerm(string searchTerm, string browser, bool embedTOCParam)
{
string helpUrl = createSearchItemUrl(searchTerm, embedTOCParam);
if (helpUrl != null)
{
launchHelp(helpUrl, browser);
}
}
public XmlDocument GetTopicXMLForKeyword (kwdItem kwd)
{
string encodedKwdValue = HttpUtility.UrlEncode(kwd.Value.TrimStart());
string helpUrl = buildHelpUrl("keywords", encodedKwdValue, "VS", "100", "xml", "&category=topic");
XmlDocument topics = HelpUtility.GetHelpXmlAsXmlDocument(helpUrl);
return topics;
}
public void NavigateTocNode(TocNodeViewModel toc, string browser, bool embedTOCParam)
{
string helpUrl = buildHelpUrl("page", Uri.EscapeUriString(toc.Id.Replace("#", "%23")), "VS", "100", "xhtml", "&category=topic&embedded=" + embedTOCParam);
launchHelp(helpUrl, browser);
}
private static string buildHelpUrl(string method, string query, string product, string version, string returnFormat, string otherParams = "")
{
return _baseOfflineUrlSession + "method=" + method + getQueryName(method) + query + "&product=" + product + "&productversion=" + version + "&locale=" + _locale + "&format=" + returnFormat + otherParams;
}
private void launchHelp(string url ,string browser)
{
switch (browser)
{
case "IDE":
HelpUtility.LaunchIDEBrowserHelp(url);
break;
case "default":
HelpUtility.LaunchBrowserHelp(url);
break;
}
}
private string createKwdItemUrl(kwdItem kwd, bool embedTOCParam)
{
string encodedKwdValue = HttpUtility.UrlEncode(kwd.Value.TrimStart());
string helpUrl = buildHelpUrl("keywords", encodedKwdValue, "VS", "100", "xml", "&category=topic");
XmlDocument topics = HelpUtility.GetHelpXmlAsXmlDocument(helpUrl);
XmlNodeList topicNodes = topics.SelectNodes("/keywords/topic");
if (topicNodes.Count > 0)
{
helpUrl = buildHelpUrl("page", Uri.EscapeUriString(topicNodes[0].Attributes["id"].Value.Replace("#", "%23")), "VS", "100", "xhtml", "&embedded=" + embedTOCParam);
return helpUrl;
}
return null;
}
private string createKwdItemUrl(XmlDocument keywordTopicXML, bool embedTOCParam)
{
XmlNodeList topicNodes = keywordTopicXML.SelectNodes("/keywords/topic");
if (topicNodes.Count > 0)
{
return buildHelpUrl("page", Uri.EscapeUriString(topicNodes[0].Attributes["id"].Value.Replace("#", "%23")), "VS", "100", "xhtml", "&embedded=" + embedTOCParam);
}
return null;
}
private string createTopicItemUrl(TopicItem topic, bool embedTOCparam)
{
return buildHelpUrl("page", Uri.EscapeUriString(topic.Id.Replace("#", "%23")), "VS", "100", "xhtml","&topicversion=" + topic.Version + "embedded=" + embedTOCparam);
}
private string createSearchItemUrl(string searchTerm, bool embedTOCParam)
{
return buildHelpUrl("search", HttpUtility.UrlEncode(searchTerm.TrimStart()), "VS", "100", "xhtml");
}
public XmlDocument getTopicsForKeyword(kwdItem kwd)
{
string encodedKwdValue = HttpUtility.UrlEncode(kwd.Value.TrimStart());
string helpUrl = buildHelpUrl("keywords", encodedKwdValue, "VS", "100", "xml", "&category=topic");
XmlDocument topics = HelpUtility.GetHelpXmlAsXmlDocument(helpUrl);
return topics;
}
private static string getQueryName(string method)
{
string queryName = "";
switch (method)
{
case "page":
queryName = "&id=";
break;
case "children":
queryName = "&id=";
break;
default:
queryName = "&query=";
break;
}
return queryName;
}
}
}