using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using Microsoft.Phone.Controls;
namespace TranslatorByMoth //TODO replace with your namespace, so App can be resolved
{
public static class RTL
{
///
/// Calling code can determine whether to use this class or not for the text.
///
/// two letter ISO code for the language, e.g. "he" or "ar"
/// true for RTL languages supported
public static bool RequiresRTL(string lang)
{
return (lang == "he" || lang == "ar");
}
private static int MaxCharactersPerLine
{
get
{
#if WINDOWS_PHONE
if (((Application.Current as App).RootFrame.Orientation & PageOrientation.Portrait) != 0)
return 37;
else // Landscape
#endif
return 50;
}
}
///
/// Accepts a string (multi-line, line breaks, whatever) of the supported RTL languages and reverses it.
///
/// text that needs reversing
/// whether to break the returned text into lines of MaxCharactersPerLine length
/// Arabic is treated specially, due to characters having different appearence dependent on what comes before/after them
/// true if the returned string is sent to a service. false if it is to be displayed to the user
/// the reversed string ready to be displayed to the user or sent to a service
public static string ReverseLengthyMultilineText(string translatedRtlThatIsLtr, bool breakInLines, bool isArabic, bool isFromRTL)
{
if (translatedRtlThatIsLtr.Trim().Length < 2) //if null, let it throw
return translatedRtlThatIsLtr;
string[] words = translatedRtlThatIsLtr.Split(new char[] { ' ', Convert.ToChar(160), '\n' }, StringSplitOptions.RemoveEmptyEntries);
StringBuilder result = new StringBuilder();
int charCount = -1;
List line = new List();
int charsPerLine = breakInLines ? RTL.MaxCharactersPerLine : Int32.MaxValue;
foreach (string w in words)
{
// for spaces between words.
charCount++;
charCount += w.Length;
// if adding this word exceeds the chars per line then add a new line here
// and this word will go to the next line.
if (breakInLines && charCount > charsPerLine)
{
result.AppendLine(RTL.ReverseLine(line, isArabic, isFromRTL));
// start a new line...
line.Clear();
charCount = w.Length;
}
line.Add(w);
}
result.Append(RTL.ReverseLine(line, isArabic, isFromRTL));
return result.ToString();
}
private static string ReverseLine(List words, bool isArabic, bool isFromRTL)
{
List reversedWords = new List(words.Count);
for (int i = words.Count - 1; i > -1; i--)
reversedWords.Add(RTL.ReverseWord(words[i], isArabic, isFromRTL));
return String.Join(" ", reversedWords.ToArray());
}
///
/// Reverses a string that has no spaces or line breaks, taking into account to preserve order of numbers and English strings.
///
/// the text to reverse
/// Arabic is treated specially, due to characters having different appearence dependent on what comes before/after them
/// true if the returned string is sent to a service. false if it is to displayed to the user
/// the reversed string ready to be displayed to the user or sent to a service
public static string ReverseWord(string word, bool isArabic, bool isFromRTL)
{
if (word.Length < 2) //if null let it throw
return word;
Match m = Regex.Match(word, "[a-zA-Z0-9]+.*[a-zA-Z0-9]+");
if (m.Success)
{
// English or numbers translation
// isolate punctuation prefix and suffix. These should be reversed. The English word shouldn't be reversed.
string prefix = word.Substring(0, m.Index);
string actualWord = m.Value;
string suffix = word.Substring(m.Length + m.Index);
return RTL.ReverseWord(suffix, isArabic, isFromRTL) + actualWord + ReverseWord(prefix, isArabic, isFromRTL);
}
else
// normal RTL translation
if (!isArabic) // regardless of TO or FROM, simple reversing works for Hebrew
return new string(
System.Linq.Enumerable.ToArray(
System.Linq.Enumerable.Reverse(word.ToCharArray())));
else
// Arabic
if (!isFromRTL)
return new string(
System.Linq.Enumerable.ToArray(
System.Linq.Enumerable.Reverse(new Arabic.Utils.SuperString(word).DisplayText.ToCharArray())));
//Arabic.Utils.SuperString comes from http://arabic4wp7.codeplex.com/
else
// TODO nothing here works. Can't get Arabic string and send it to Bing service and get back English :-(
return "Sorry, not supported yet";
// get DisplayText - doesn't work
//return new Arabic.Utils.SuperString(word).DisplayText;
// get Text - doesn't work
//return new Arabic.Utils.SuperString(word).Text;
// reverse first, then Text - doesn't work
//return new Arabic.Utils.SuperString(new string(
// System.Linq.Enumerable.ToArray(
// System.Linq.Enumerable.Reverse(word.ToCharArray())))).Text;
// reverse first, then DisplayText - doesn't work
//return new Arabic.Utils.SuperString(new string(
// System.Linq.Enumerable.ToArray(
// System.Linq.Enumerable.Reverse(word.ToCharArray())))).DisplayText;
// get Text then reverse - doesn't work
//return new string(
// System.Linq.Enumerable.ToArray(
// System.Linq.Enumerable.Reverse(new Arabic.Utils.SuperString(word).Text.ToCharArray())));
// get DisplayText then reverse - doesn't work
//return new string(
// System.Linq.Enumerable.ToArray(
// System.Linq.Enumerable.Reverse(new Arabic.Utils.SuperString(word).DisplayText.ToCharArray())));
// just reverse - doesn't work
//return new string(
// System.Linq.Enumerable.ToArray(
// System.Linq.Enumerable.Reverse(word.ToCharArray())));
}
}
}