using System;
using System.Linq;

namespace Valg.EVA.Skanning.UserInterfaceElements.FilterControls
{
    public static class TextSearch
    {
        public static bool IsCaseInsensitiveMatch(string searchParam, string text)
        {

            var searchParams = searchParam.ToLowerInvariant().Split(' ', '*');

            var searchText = RemovePartyInformation(text.ToLowerInvariant());
            if (searchParams.All(searchText.Contains))
            {
                return true;
            }
            else
            {
                return IsFuzzyMatch(searchParam.ToLowerInvariant(), searchText);
            }
        }

        private static string RemovePartyInformation(string text)
        {
            var indexPartyInfoStart = text.IndexOf("(", StringComparison.Ordinal);
            if (indexPartyInfoStart > 0)
            {
                return text.Substring(0, indexPartyInfoStart);
            }
            else
            {
                return text;
            }
        }

        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        public static int LevenshteinDistance(string src, string dest)
        {
            int[,] d = new int[src.Length + 1, dest.Length + 1];
            int i, j, cost;
            char[] str1 = src.ToCharArray();
            char[] str2 = dest.ToCharArray();

            for (i = 0; i <= str1.Length; i++)
            {
                d[i, 0] = i;
            }
            for (j = 0; j <= str2.Length; j++)
            {
                d[0, j] = j;
            }
            for (i = 1; i <= str1.Length; i++)
            {
                for (j = 1; j <= str2.Length; j++)
                {
                    if (str1[i - 1] == str2[j - 1])
                        cost = 0;
                    else
                        cost = 1;

                    d[i, j] =
                        Math.Min(
                            d[i - 1, j] + 1,					
                            Math.Min(
                                d[i, j - 1] + 1,				
                                d[i - 1, j - 1] + cost));		

                    if ((i > 1) && (j > 1) && (str1[i - 1] == str2[j - 2]) && (str1[i - 2] == str2[j - 1]))
                    {
                        d[i, j] = Math.Min(d[i, j], d[i - 2, j - 2] + cost);
                    }
                }
            }

            return d[str1.Length, str2.Length];
        }

        private static bool IsFuzzyMatch(string searchParam, string text)
        {                        

            
            double fuzzyness = 0.60;

            
            int levenshteinDistance = LevenshteinDistance(searchParam, text);

            
            int length = Math.Max(searchParam.Length, text.Length);

            
            double score = 1.0 - (double)levenshteinDistance / length;

            
            if (score > fuzzyness)
            {                
                return true;
            }
            else
            {                
                return false;
            }
        }
    }
}
