using System;
using System.Collections.Generic;
using System.Globalization;
namespace JD.UserControls.QuickOpenDialogs
{
///
/// Allows to search using default search patterns (contains words in order, ...).
///
public class TextQuery
{
private readonly string m_text;
private readonly string[] m_words;
public TextQuery(string text)
{
m_text = text ?? string.Empty;
m_words = m_text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
}
///
/// Returns the length of the original search
///
public int TextLength
{
get { return m_text.Length; }
}
///
/// Returns the number of word in the query
///
public IReadOnlyList Words
{
get { return m_words; }
}
///
/// The original unformatted text of the query.
///
public string OriginalText
{
get { return m_text; }
}
///
/// Checks the text for a match.
///
public MatchResult Matches(string text)
{
if (string.IsNullOrEmpty(text))
{
return MatchResult.Invalid;
}
int index = 0;
int score = -1;
for (int i = 0; i < m_words.Length; ++i)
{
if (index >= text.Length)
{
return MatchResult.Invalid;
}
index = CultureInfo.InvariantCulture.CompareInfo.IndexOf(text, m_words[i], CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase);
if (index == -1)
{
return MatchResult.Invalid;
}
CheckPreviousSeparator(text, index, ref score);
index += m_words[i].Length;
CheckNextSeparator(text, index, ref score);
}
return new MatchResult(score);
}
private static void CheckPreviousSeparator(string text, int index, ref int score)
{
if (index == 0)
{
score -= 4;
}
else if (IsSeparator(text[index - 1]))
{
score -= 2;
}
}
private static void CheckNextSeparator(string text, int index, ref int score)
{
if (index >= text.Length || IsSeparator(text[index]))
{
score -= 1;
}
}
private static bool IsSeparator(char c)
{
return char.IsWhiteSpace(c) || c == '.' || c == '\\';
}
public struct MatchResult : IComparable
{
public static readonly MatchResult Invalid = new MatchResult();
private readonly int m_score;
public MatchResult(int score)
{
m_score = score;
}
public bool IsMatch
{
get { return m_score != 0; }
}
public int CompareTo(MatchResult other)
{
return m_score.CompareTo(other.m_score);
}
}
}
}