using DNTPersianUtils.Core;
using RMuseum.Models.Divan;
using RMuseum.Models.Divan.ViewModels;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace RMuseum.Services.Implementation
{
///
/// Language Utilitis
///
public static class LanguageUtils
{
///
/// Persian Alphabet
///
public const string PersianAlphabet = "آابپتثجچحخدذرزژسشصضطظعغفقکگلمنوهیئؤء";
///
/// English Alphabet
///
public const string EnglishLowerCaseAlphabet = "abcdefghijklmnopqrstuvwxyz";
///
/// Check to see if input Contains Only Specific Characters
///
///
///
///
///
public static string GetFirstNotMatchingCharacter(string input, string specfics, string additional = "")
{
string all = specfics + additional;
foreach (char c in input)
if (all.IndexOf(c) == -1)
return (c + "");
return "";
}
///
/// make text searchable
///
///
///
public static string MakeTextSearchable(string text)
{
return text.Replace("", " ")//replace zwnj with space
.Replace("ّ", "")//tashdid
.Replace("َ", "")//a
.Replace("ِ", "")//e
.Replace("ُ", "")//o
.Replace("ً", "")//an
.Replace("ٍ", "")//en
.Replace("ٌ", "")//on
.Replace(".", "")//dot
.Replace("،", "")//virgool
.Replace("!", "")
.Replace("؟", "")
.Replace("ٔ", "")//ye
.Replace(":", "")
.Replace("ئ", "ی")
.Replace("؛", "")
.Replace(";", "")
.Replace("*", "")
.Replace(")", "")
.Replace("(", "")
.Replace("[", "")
.Replace("]", "")
.Replace("\"", "")
.Replace("'", "")
.Replace("«", "")
.Replace("»", "")
.Replace("ْ", "")//sokoon
// divan: Urdu normalisation (same rules apply to stored text and search terms)
.Replace("\u064A", "\u06CC")//arabic yeh -> farsi/urdu yeh
.Replace("\u0649", "\u06CC")//alef maksura -> yeh
.Replace("\u0643", "\u06A9")//arabic kaf -> keheh
.Replace("\u06C2", "\u06C1")//heh goal with hamza -> heh goal
.Replace("\u0647", "\u06C1")//arabic heh -> heh goal (do-chashmi heh U+06BE stays distinct)
.Replace("\u06D3", "\u06D2")//yeh barree with hamza -> yeh barree
.Replace("\u0623", "\u0627").Replace("\u0625", "\u0627")//alef with hamza -> alef
.Replace("\u06D4", "")//urdu full stop
.Replace("\u0670", "").Replace("\u0657", "").Replace("\u0658", "").Replace("\u0615", "")//urdu diacritics
.Replace("\u200D", "").Replace("\u200F", "").Replace("\u200E", "")//zwj, rtl/ltr marks
;
}
///
/// divan: SQL LIKE patterns for a search term (replaces SQL Server full-text CONTAINS, which the
/// Linux SQL Server image does not ship). "quoted phrase" -> one pattern; otherwise one pattern per
/// word, all of which must match. Terms are normalised like stored PlainText.
///
public static string[] SearchLikePatterns(string term)
{
if (string.IsNullOrWhiteSpace(term))
return Array.Empty();
term = term.Trim();
bool phrase = term.Length > 1 && term.StartsWith("\"") && term.EndsWith("\"");
string normalised = MakeTextSearchable(term.ApplyCorrectYeKe().Replace("\"", "").Replace("'", ""));
string[] parts = phrase ? new[] { normalised.Trim() } : normalised.Split(' ', StringSplitOptions.RemoveEmptyEntries);
return parts.Where(p => p.Length > 0)
.Select(p => "%" + p.Replace("[", "[[]").Replace("%", "[%]").Replace("_", "[_]") + "%")
.ToArray();
}
public static string CleanTextForTransileration(string text)
{
if (string.IsNullOrEmpty(text)) return text;
return text.Replace("", " ")//replace zwnj with space
.Replace("ّ", "")//tashdid
.Replace("َ", "")//a
.Replace("ِ", "")//e
.Replace("ُ", "")//o
.Replace("ً", "")//an
.Replace("ٍ", "")//en
.Replace("ٌ", "")//on
.Replace("ٔ", "")//ye
.Replace("ْ", "")//sokoon
;
}
public static string SameSoundLetters(string text)
{
return text.Replace("آ", "ا").Replace("ث", "س").Replace("ح", "ه").Replace("ذ", "ز").Replace("ص", "س").Replace("ض", "ز").Replace("ط", "ت").Replace("ظ", "ز").Replace("غ", "ق");
}
private static string PrepareTextForFindingRhyme(string text)
{
return MakeTextSearchable(text)
.Replace("لله", "للاه")
.Replace("آ", "ا")
.Replace("", "")
.Replace("", "")
.Replace("", "")
.Replace(" ", "")
.Trim();
}
///
/// find rhyme
///
///
///
///
///
///
public static DivanRhymeAnalysisResult FindRhyme(List verses, bool secondPhase = false, bool bandCouplets = false, bool tryWholeVerses = false)
{
try
{
List verseTextList = verses.Count == 2 || tryWholeVerses ? verses.Select(v => v.Text).ToList()
: bandCouplets ?
verses.Where(v => v.VersePosition == VersePosition.CenteredVerse2).Select(v => v.Text).ToList()
: verses.Where(v => v.VersePosition == VersePosition.Left).Select(v => v.Text).ToList();
if (verseTextList.Count > 1)
{
string rhyme = PrepareTextForFindingRhyme(verseTextList[0]);
if (string.IsNullOrEmpty(rhyme))
{
return new DivanRhymeAnalysisResult()
{
Rhyme = "",
FailVerse = verseTextList[0]
};
}
if (secondPhase)
{
if (rhyme.Length > 0 && rhyme[rhyme.Length - 1] == 'ی')
rhyme = rhyme.Remove(rhyme.Length - 1);
}
for (int j = 1; j < verseTextList.Count; j++)
{
string verseText = PrepareTextForFindingRhyme(verseTextList[j]);
if (secondPhase)
{
if (verseText.Length > 0 && verseText[verseText.Length - 1] == 'ی')
{
verseText = verseText.Remove(verseText.Length - 1);
}
}
string oldRhyme = rhyme;
rhyme = "";
int i = oldRhyme.Length - 1;
while (
(oldRhyme[i] == verseText[verseText.Length - oldRhyme.Length + i])
||
(
(oldRhyme[i] == 'ذ')
&&
(verseText[verseText.Length - oldRhyme.Length + i] == 'د')
)
||
(
(oldRhyme[i] == 'د')
&&
(verseText[verseText.Length - oldRhyme.Length + i] == 'ذ')
)
||
(
(oldRhyme[i] == 'ی')
&&
(verseText[verseText.Length - oldRhyme.Length + i] == 'ا')
)
||
(
(oldRhyme[i] == 'ا')
&&
(verseText[verseText.Length - oldRhyme.Length + i] == 'ی')
)
||
(oldRhyme[i] == verseText[verseText.Length - oldRhyme.Length + i])
||
(
(oldRhyme[i] == 'پ')
&&
(verseText[verseText.Length - oldRhyme.Length + i] == 'ب')
)
||
(
(oldRhyme[i] == 'ب')
&&
(verseText[verseText.Length - oldRhyme.Length + i] == 'پ')
)
||
(oldRhyme[i] == 'ة')
&&
(verseText[verseText.Length - oldRhyme.Length + i] == 'ت')
||
(oldRhyme[i] == 'ت')
&&
(verseText[verseText.Length - oldRhyme.Length + i] == 'ة')
)
{
rhyme = oldRhyme[i] + rhyme;
i--;
if (i == -1)
break;
}
if (rhyme.Length == 0)
{
if (verses.Count == 2 && verseTextList.Count == 2)
{
rhyme = PrepareTextForFindingRhyme(verseTextList[1]);
if(rhyme.Length > 50)
{
rhyme = "";
}
return new DivanRhymeAnalysisResult()
{
Rhyme = rhyme, //rhyme.Length > 50 condition check removed to search using prosody meters
FailVerse = "",
};
}
return new DivanRhymeAnalysisResult()
{
Rhyme = "",
FailVerse = verseText
};
}
}
if (!secondPhase)
{
if (string.IsNullOrEmpty(rhyme))
{
return FindRhyme(verses, true);
}
}
////rhyme.Length > 50 condition check removed to search using prosody meters
/*if (rhyme.Length > 50)
{
return new DivanRhymeAnalysisResult()
{
Rhyme = "",
FailVerse = "",
};
}*/
if (rhyme.Length > 50)
{
rhyme = "";
}
return new DivanRhymeAnalysisResult()
{
Rhyme = rhyme,
FailVerse = ""
};
}
}
catch
{
}
return new DivanRhymeAnalysisResult() { Rhyme = "", FailVerse = "" };
}
///
/// format money
///
///
///
public static string FormatMoney(decimal amount)
{
return amount.ToString("N0", new CultureInfo("ur-PK")).ToPersianNumbers();
}
///
/// format datetime
///
///
///
public static string FormatDate(DateTime dateTime)
{
return $"{dateTime.ToPersianYearMonthDay().Day.ToPersianNumbers()}م {PersianCulture.GetPersianMonthName(dateTime.ToPersianYearMonthDay().Month)} {dateTime.ToPersianYearMonthDay().Year.ToPersianNumbers()}";
}
///
/// short date
///
///
///
public static string FormatInShortDate(DateTime dateTime)
{
return dateTime.Year < 623 ? "" : $"{dateTime.ToPersianYearMonthDay().Year.ToPersianNumbers()}/{dateTime.ToPersianYearMonthDay().Month.ToString().PadLeft(2, '0').ToPersianNumbers()}/{dateTime.ToPersianYearMonthDay().Day.ToString().PadLeft(2, '0').ToPersianNumbers()}";
}
}
}