﻿<%@ Page Language="C#" EnableViewState="False" %>

<script runat="server">
//===============================================================================================================
// System  : Sandcastle Help File Builder
// File    : SearchHelp.aspx
// Author  : Eric Woodruff  (Eric@EWoodruff.us)
// Updated : 04/09/2014
// Note    : Copyright 2007-2014, Eric Woodruff, All rights reserved
// Compiler: Microsoft C#
//
// This file contains the code used to search for keywords within the help topics using the full-text index
// files created by the help file builder.
//
// This code is published under the Microsoft Public License (Ms-PL).  A copy of the license should be
// distributed with the code.  It can also be found at the project website: https://GitHub.com/EWSoftware/SHFB.  This
// notice, the author's name, and all copyright notices must remain intact in all applications, documentation,
// and source files.
//
//    Date     Who  Comments
// ==============================================================================================================
// 06/24/2007  EFW  Created the code
// 02/17/2012  EFW  Switched to JSON serialization to support websites that use something other than ASP.NET
//                  such as PHP.
//===============================================================================================================

/// <summary>
/// This class is used to track the results and their rankings
/// </summary>
private class Ranking
{
    public string Filename, PageTitle;
    public int Rank;

    public Ranking(string file, string title, int rank)
    {
        Filename = file;
        PageTitle = title;
        Rank = rank;
    }
}

/// <summary>
/// Render the search results
/// </summary>
/// <param name="writer">The writer to which the results are written</param>
protected override void Render(HtmlTextWriter writer)
{
    JavaScriptSerializer jss = new JavaScriptSerializer();
    string searchText, ftiFile;
    char letter;
    bool sortByTitle = false;

    jss.MaxJsonLength = Int32.MaxValue;

    // The keywords for which to search should be passed in the query string
    searchText = this.Request.QueryString["Keywords"];

    if(String.IsNullOrEmpty(searchText))
    {
        writer.Write("<b class=\"PaddedText\">Nothing found</b>");
        return;
    }

    // An optional SortByTitle option can also be specified
    if(this.Request.QueryString["SortByTitle"] != null)
        sortByTitle = Convert.ToBoolean(this.Request.QueryString["SortByTitle"]);

    List<string> keywords = this.ParseKeywords(searchText);
    List<char> letters = new List<char>();
    List<string> fileList;
    Dictionary<string, List<long>> ftiWords, wordDictionary =
        new Dictionary<string,List<long>>();

    // Load the file index
    using(StreamReader sr = new StreamReader(Server.MapPath("fti/FTI_Files.json")))
    {
        fileList = jss.Deserialize<List<string>>(sr.ReadToEnd());
    }

    // Load the required word index files
    foreach(string word in keywords)
    {
        letter = word[0];

        if(!letters.Contains(letter))
        {
            letters.Add(letter);
            ftiFile = Server.MapPath(String.Format(CultureInfo.InvariantCulture,
                "fti/FTI_{0}.json", (int)letter));

            if(File.Exists(ftiFile))
            {
                using(StreamReader sr = new StreamReader(ftiFile))
                {
                    ftiWords = jss.Deserialize<Dictionary<string, List<long>>>(sr.ReadToEnd());
                }

                foreach(string ftiWord in ftiWords.Keys)
                    wordDictionary.Add(ftiWord, ftiWords[ftiWord]);
            }
        }
    }

    // Perform the search and return the results as a block of HTML
    writer.Write(this.Search(keywords, fileList, wordDictionary, sortByTitle));
}

/// <summary>
/// Split the search text up into keywords
/// </summary>
/// <param name="keywords">The keywords to parse</param>
/// <returns>A list containing the words for which to search</returns>
private List<string> ParseKeywords(string keywords)
{
    List<string> keywordList = new List<string>();
    string checkWord;
    string[] words = Regex.Split(keywords, @"\W+");

    foreach(string word in words)
    {
        checkWord = word.ToLower(CultureInfo.InvariantCulture);
        
        if(checkWord.Length > 2 && !Char.IsDigit(checkWord[0]) &&
          !keywordList.Contains(checkWord))
            keywordList.Add(checkWord);
    }

    return keywordList;
}

/// <summary>
/// Search for the specified keywords and return the results as a block of
/// HTML.
/// </summary>
/// <param name="keywords">The keywords for which to search</param>
/// <param name="fileInfo">The file list</param>
/// <param name="wordDictionary">The dictionary used to find the words</param>
/// <param name="sortByTitle">True to sort by title, false to sort by
/// ranking</param>
/// <returns>A block of HTML representing the search results.</returns>
private string Search(List<string> keywords, List<string> fileInfo,
    Dictionary<string, List<long>> wordDictionary, bool sortByTitle)
{
    StringBuilder sb = new StringBuilder(10240);
    Dictionary<string, List<long>> matches = new Dictionary<string, List<long>>();
    List<long> occurrences;
    List<int> matchingFileIndices = new List<int>(),
        occurrenceIndices = new List<int>();
    List<Ranking> rankings = new List<Ranking>();

    string filename, title;
    string[] fileIndex;
    bool isFirst = true;
    int idx, wordCount, matchCount;

    foreach(string word in keywords)
    {
        if(!wordDictionary.TryGetValue(word, out occurrences))
            return "<b class=\"PaddedText\">Nothing found</b>";

        matches.Add(word, occurrences);
        occurrenceIndices.Clear();

        // Get a list of the file indices for this match
        foreach(long entry in occurrences)
            occurrenceIndices.Add((int)(entry >> 16));
            
        if(isFirst)
        {
            isFirst = false;
            matchingFileIndices.AddRange(occurrenceIndices);
        }
        else
        {
            // After the first match, remove files that do not appear for
            // all found keywords.
            for(idx = 0; idx < matchingFileIndices.Count; idx++)
                if(!occurrenceIndices.Contains(matchingFileIndices[idx]))
                {
                    matchingFileIndices.RemoveAt(idx);
                    idx--;
                }
        }
    }

    if(matchingFileIndices.Count == 0)
        return "<b class=\"PaddedText\">Nothing found</b>";

    // Rank the files based on the number of times the words occurs
    foreach(int index in matchingFileIndices)
    {
        // Split out the title, filename, and word count
        fileIndex = fileInfo[index].Split('\x0');

        title = fileIndex[0];
        filename = fileIndex[1];
        wordCount = Convert.ToInt32(fileIndex[2]);
        matchCount = 0;
        
        foreach(string word in keywords)
        {
            occurrences = matches[word];

            foreach(long entry in occurrences)
                if((int)(entry >> 16) == index)
                    matchCount += (int)(entry & 0xFFFF);
        }

        rankings.Add(new Ranking(filename, title, matchCount * 1000 / wordCount));
    }

    // Sort by rank in descending order or by page title in ascending order
    rankings.Sort(delegate (Ranking x, Ranking y)
    {
        if(!sortByTitle)
            return y.Rank - x.Rank;

        return x.PageTitle.CompareTo(y.PageTitle);
    });

    // Format the file list and return the results
    foreach(Ranking r in rankings)
        sb.AppendFormat("<div class=\"TreeItem\">\r\n<img src=\"Item.gif\"/>" +
            "<a class=\"UnselectedNode\" target=\"TopicContent\" " +
            "href=\"{0}\" onclick=\"javascript: SelectSearchNode(this);\">" +
            "{1}</a>\r\n</div>\r\n", r.Filename, r.PageTitle);

    // Return the keywords used as well in a hidden span
    sb.AppendFormat("<span id=\"SearchKeywords\" style=\"display: none\">{0}</span>",
        String.Join(" ", keywords.ToArray()));

    return sb.ToString();
}

</script>
