1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Xml.Linq;
5: using System.IO;
6: using System.Reflection;
7: using System.Web;
8: using System.Text.RegularExpressions;
9:
10: namespace Ia.TentPlay.Cl.Model.Memorise
11: {
12: ////////////////////////////////////////////////////////////////////////////
13:
14: /// <summary publish="true">
15: /// ApplicationInformation Support class for TentPlay Memorise model
16: /// </summary>
17: ///
18: /// <remarks>
19: /// Copyright © 2006-2018 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
20: ///
21: /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
22: /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
23: ///
24: /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
25: /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
26: ///
27: /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
28: ///
29: /// Copyright notice: This notice may not be removed or altered from any source distribution.
30: /// </remarks>
31: public class ApplicationInformation
32: {
33: private static XDocument xDocument;
34: private static List<Application> applicationList;
35: private static List<Translation> translationList;
36:
37: ////////////////////////////////////////////////////////////////////////////
38:
39: /// <summary>
40: ///
41: /// </summary>
42: public ApplicationInformation() { }
43:
44: ////////////////////////////////////////////////////////////////////////////
45: ////////////////////////////////////////////////////////////////////////////
46:
47: /// <summary>
48: ///
49: /// </summary>
50: public class Application
51: {
52: /// <summary/>
53: public Application() { }
54:
55: /// <summary/>
56: public string Id { get; set; }
57: /// <summary/>
58: public Ia.TentPlay.Cl.Model.Memorise.Test.TestTopic TestTopic { get; set; }
59: /// <summary/>
60: public string Name { get; set; }
61: /// <summary/>
62: public Dictionary<string, string> NameDictionary { get; set; }
63: /// <summary/>
64: public string ManifestPackagePrefix { get; set; }
65:
66: /// <summary/>
67: public string WhatsNew { get; set; }
68: /// <summary/>
69: public string VersionName { get; set; }
70: /// <summary/>
71: public string CopyrightYear { get; set; }
72: /// <summary/>
73: public string ManifestPackage { get; set; }
74:
75: /// <summary/>
76: public string ApplicationDownloadLink { get; set; }
77:
78: /// <summary/>
79: public string GoogleAdMobAdUnitDebugId { get; set; }
80: /// <summary/>
81: public string GoogleAdMobAppId { get; set; }
82: /// <summary/>
83: public string GoogleAdMobAdUnitProductionId { get; set; }
84:
85: /// <summary/>
86: public DateTime Published { get; set; }
87:
88: /// <summary/>
89: public int Count { get; set; }
90: /// <summary/>
91: /// <summary/>
92: public string ColorPrimary { get; set; }
93: /// <summary/>
94: public string ColorPrimaryDark { get; set; }
95: /// <summary/>
96: public string ColorAccent { get; set; }
97:
98: /// <summary/>
99: public bool LanguageListMatchesTranslationList
100: {
101: get
102: {
103: bool b;
104:
105: if (Languages != null && Translations != null)
106: {
107: b = Languages.All(u => Translations.Any(y => y.Iso6391 == u.Iso6391)) && Translations.All(u => Languages.Any(y => y.Iso6391 == u.Iso6391)) && Languages.Count == Translations.Count;
108: }
109: else b = false;
110:
111: return b;
112: }
113: }
114: /// <summary/>
115: public virtual List<Image> NavigationHeaderImages { get; set; }
116: /// <summary/>
117: public virtual List<Ia.Cl.Model.Language> Languages { get; set; }
118: /// <summary/>
119: public virtual ICollection<Translation> Translations
120: {
121: get
122: {
123: if (translationList == null || translationList.Count == 0)
124: {
125: translationList = TranslationList; // (this);
126: }
127:
128: return translationList;
129: }
130: }
131: }
132:
133: ////////////////////////////////////////////////////////////////////////////
134:
135: public class Image
136: {
137: /// <summary/>
138: //public string Caption { get; set; }
139: /// <summary/>
140: //public string Photographer { get; set; }
141: /// <summary/>
142: //public string Source { get; set; }
143: /// <summary/>
144: public string AndroidFileName { get; set; }
145: /// <summary/>
146: public string FileName { get; set; }
147: }
148:
149: ////////////////////////////////////////////////////////////////////////////
150:
151: public class Translation
152: {
153: /// <summary/>
154: public Translation() { }
155:
156: /// <summary/>
157: public string Iso6391 { get; set; }
158: /// <summary/>
159: public string SiteName { get; set; }
160: /// <summary/>
161: public string CompanyName { get; set; }
162: /// <summary/>
163: public string ShortDescription { get; set; }
164: /// <summary/>
165: public string LongDescription { get; set; }
166:
167: /// <summary/>
168: public string About { get; set; }
169: /// <summary/>
170: public string AboutTitle { get; set; }
171: /// <summary/>
172: public string SearchSearchHint { get; set; }
173: /// <summary/>
174: public string Statistic { get; set; }
175: /// <summary/>
176: public string StatisticTitle { get; set; }
177: /// <summary/>
178: public string Setting { get; set; }
179: /// <summary/>
180: public string SettingTitle { get; set; }
181:
182: /// <summary/>
183: public string ShareTitle { get; set; }
184: /// <summary/>
185: public string ShareApplication { get; set; }
186: /// <summary/>
187: public string ShareTrek { get; set; }
188: /// <summary/>
189: public string ShareNoEmailClientInstalled { get; set; }
190: /// <summary/>
191: public string ShareContactUs { get; set; }
192:
193: /// <summary/>
194: public string HelpFeedbackTitle { get; set; }
195: /// <summary/>
196: public string Help { get; set; }
197: /// <summary/>
198: public string HelpTitle { get; set; }
199: /// <summary/>
200: public string HelpMagnifiyingGlass { get; set; }
201: /// <summary/>
202: public string HelpMainListOrder { get; set; }
203: /// <summary/>
204: public string Feedback { get; set; }
205: /// <summary/>
206: public string FeedbackTitle { get; set; }
207: /// <summary/>
208: public string FeedbackEmailSubject { get; set; }
209:
210: /// <summary/>
211: public string Legal { get; set; }
212: /// <summary/>
213: public string LegalTitle { get; set; }
214: }
215:
216: ////////////////////////////////////////////////////////////////////////////
217:
218: /// <summary>
219: ///
220: /// </summary>
221: public static List<Ia.TentPlay.Cl.Model.Memorise.ApplicationInformation.Application> ApplicationList
222: {
223: get
224: {
225: if (applicationList == null || applicationList.Count == 0)
226: {
227: if (HttpContext.Current != null && HttpContext.Current.Application["applicationList"] != null)
228: {
229: applicationList = (List<Application>)HttpContext.Current.Application["applicationList"];
230: }
231: else
232: {
233: applicationList = Ia.TentPlay.Cl.Model.Memorise.ApplicationInformation._ApplicationList;
234:
235: if (HttpContext.Current != null) HttpContext.Current.Application["applicationList"] = applicationList;
236: }
237: }
238:
239: return applicationList;
240: }
241: }
242:
243: ////////////////////////////////////////////////////////////////////////////
244:
245: /// <summary>
246: ///
247: /// </summary>
248: private static List<Ia.TentPlay.Cl.Model.Memorise.ApplicationInformation.Application> _ApplicationList
249: {
250: get
251: {
252: if (applicationList == null || applicationList.Count == 0)
253: {
254: Application application;
255:
256: applicationList = new List<Application>(100);
257:
258: foreach (XElement x in XDocument.Element("applicationInformation").Element("applicationList").Elements("application"))
259: {
260: application = new Application();
261: application.Id = x.Attribute("id").Value;
262:
263: // public enum TestTopic { MorseCode = 0, German = 1, Math = 2, Kanji = 3, Russian = 4, Kana = 5, PhoneticAlphabet = 6 };
264: switch(application.Id)
265: {
266: case "morsecode": application.TestTopic = Ia.TentPlay.Cl.Model.Memorise.Test.TestTopic.MorseCode; break;
267: case "german": application.TestTopic = Ia.TentPlay.Cl.Model.Memorise.Test.TestTopic.German; break;
268: case "math": application.TestTopic = Ia.TentPlay.Cl.Model.Memorise.Test.TestTopic.Math; break;
269: case "kanji": application.TestTopic = Ia.TentPlay.Cl.Model.Memorise.Test.TestTopic.Kanji; break;
270: case "russian": application.TestTopic = Ia.TentPlay.Cl.Model.Memorise.Test.TestTopic.Russian; break;
271: case "kana": application.TestTopic = Ia.TentPlay.Cl.Model.Memorise.Test.TestTopic.Kana; break;
272: case "phoneticAlphabet": application.TestTopic = Ia.TentPlay.Cl.Model.Memorise.Test.TestTopic.PhoneticAlphabet; break;
273: default: application.TestTopic = 0; break;
274: }
275:
276: application.Name = x.Element("name").Attribute("en").Value;
277: application.NameDictionary = ApplicationNameDictionary(x);
278:
279: application.ManifestPackagePrefix = x.Parent.Parent.Element("manifestPackagePrefix").Value;
280:
281: application.GoogleAdMobAdUnitDebugId = x.Parent.Parent.Element("googleAdMobAdUnitDebugId").Value;
282:
283: application.WhatsNew = Regex.Replace(x.Parent.Parent.Element("googleStoreWhatsNew").Value.Trim(), @"\n[ ]+", "\n");
284:
285: application.VersionName = x.Element("version").Attribute("name").Value;
286: application.CopyrightYear = x.Element("version").Attribute("copyrightYear").Value;
287: application.Published = (x.Attribute("published") != null) ? DateTime.Parse(x.Attribute("published").Value) : DateTime.MinValue;
288:
289: application.ManifestPackage = x.Element("manifestPackage").Value;
290:
291: application.ApplicationDownloadLink = ReplaceNameVariableWithName(Ia.TentPlay.Cl.Model.Data.CompanyInformation.ApplicationDownloadLink, application);
292:
293: application.GoogleAdMobAppId = x.Element("googleAdMobAppId").Value;
294: application.GoogleAdMobAdUnitProductionId = x.Element("googleAdMobAdUnitId").Value;
295:
296: application.ColorPrimary = (from e in x.Element("colorTheme").Elements("color") where e.Attribute("name").Value == "colorPrimary" select e.Attribute("value").Value).SingleOrDefault();
297: application.ColorPrimaryDark = (from e in x.Element("colorTheme").Elements("color") where e.Attribute("name").Value == "colorPrimaryDark" select e.Attribute("value").Value).SingleOrDefault();
298: application.ColorAccent = (from e in x.Element("colorTheme").Elements("color") where e.Attribute("name").Value == "colorAccent" select e.Attribute("value").Value).SingleOrDefault();
299:
300: application.NavigationHeaderImages = ApplicationImageList(x.Element("navigationHeader").Element("imageList"));
301:
302: application.Languages = ApplicationLanguageList(application.Id);
303:
304: applicationList.Add(application);
305: }
306: }
307:
308: return applicationList.ToList();
309: }
310: }
311:
312: ////////////////////////////////////////////////////////////////////////////
313:
314: /// <summary>
315: ///
316: /// </summary>
317: private static List<Ia.Cl.Model.Language> ApplicationLanguageList(string fileCountry)
318: {
319: List<Ia.Cl.Model.Language> list, countrySpokenLanguageList, featureDesignationLanguageList;
320:
321: list = new List<Ia.Cl.Model.Language>();
322:
323: if (fileCountry == "uk") fileCountry = "gb";
324:
325: countrySpokenLanguageList = (from c in Ia.Cl.Model.Country.List where c.Iso2 == fileCountry.ToUpper() select c.SpokenLanguageList).SingleOrDefault();
326:
327: featureDesignationLanguageList = Ia.TentPlay.Cl.Model.Data.Trek.FeatureDesignation.LanguageList;
328:
329: // I will only support English
330: //list = (from c in countrySpokenLanguageList join n in featureDesignationLanguageList on c.Symbol equals n.Symbol select c).ToList();
331:
332: // below: add English to all language lists for all countries
333: if (list.Find(u => u.Symbol == "en") == null) list.Add(Ia.Cl.Model.Language.List.Single(u => u.Symbol == "en"));
334:
335: return list;
336: }
337:
338: ////////////////////////////////////////////////////////////////////////////
339:
340: /// <summary>
341: ///
342: /// </summary>
343: private static List<Image> ApplicationImageList(XElement imageList)
344: {
345: Image image;
346: List<Image> list;
347:
348: list = new List<Image>();
349:
350: foreach (XElement x in imageList.Elements("image"))
351: {
352: image = new Image();
353:
354: // Attribute
355: //image.Caption = x.Attribute("caption").Value;
356: //image.Photographer = x.Attribute("photographer").Value.Replace(" ", "").ToLower();
357: //image.Source = x.Attribute("source").Value.ToLower();
358: image.FileName = x.Attribute("fileName").Value;
359: image.AndroidFileName = x.Attribute("fileName").Value.Replace("-", "_");
360:
361: list.Add(image);
362: }
363:
364: return list;
365: }
366:
367: ////////////////////////////////////////////////////////////////////////////
368:
369: /// <summary>
370: ///
371: /// </summary>
372: public static void Statistic(ref Ia.TentPlay.Cl.Model.Memorise.ApplicationInformation.Application application)
373: {
374: int featureCount, administrative, populated, vegetation, locality, undersea, street, hypsographic, hydrographic, spot;
375: Ia.Cl.Model.Result result;
376:
377: //Ia.TentPlay.Cl.Model.Data.Trek.Feature.Statistic(application.Iso2, out featureCount, out administrative, out populated, out vegetation, out locality, out undersea, out street, out hypsographic, out hydrographic, out spot, out result);
378:
379: application.Count = 0; // featureCount;
380: }
381:
382: ////////////////////////////////////////////////////////////////////////////
383:
384: /// <summary>
385: ///
386: /// </summary>
387: private static Dictionary<string, string> ApplicationNameDictionary(XElement xElement)
388: {
389: XElement xe;
390: IEnumerable<XAttribute> list;
391: Dictionary<string, string> dictionary;
392:
393: dictionary = new Dictionary<string, string>();
394:
395: xe = xElement.Element("name");
396:
397: if (xe.HasAttributes)
398: {
399: list = xe.Attributes();
400:
401: foreach (XAttribute xa in list)
402: {
403: dictionary.Add(xa.Name.LocalName, xa.Value);
404: }
405: }
406:
407: return dictionary;
408: }
409:
410: ////////////////////////////////////////////////////////////////////////////
411: ////////////////////////////////////////////////////////////////////////////
412:
413: /// <summary>
414: ///
415: /// </summary>
416: public static List<Ia.TentPlay.Cl.Model.Memorise.ApplicationInformation.Translation> TranslationList
417: {
418: get
419: {
420: if (translationList == null || translationList.Count == 0)
421: {
422: if (HttpContext.Current != null && HttpContext.Current.Application["translationList"] != null)
423: {
424: translationList = (List<Translation>)HttpContext.Current.Application["translationList"];
425: }
426: else
427: {
428: translationList = Ia.TentPlay.Cl.Model.Memorise.ApplicationInformation._TranslationList;
429:
430: if (HttpContext.Current != null) HttpContext.Current.Application["translationList"] = translationList;
431: }
432: }
433:
434: return translationList;
435: }
436: }
437:
438: ////////////////////////////////////////////////////////////////////////////
439:
440: /// <summary>
441: ///
442: /// </summary>
443: private static List<Ia.TentPlay.Cl.Model.Memorise.ApplicationInformation.Translation> _TranslationList
444: {
445: get
446: {
447: if (translationList == null || translationList.Count == 0)
448: {
449: Translation translation;
450:
451: translationList = new List<Translation>(100);
452:
453: foreach (XElement x in XDocument.Element("applicationInformation").Element("translationList").Elements("translation"))
454: {
455: translation = new Translation();
456: translation.Iso6391 = x.Attribute("id").Value;
457: translation.SiteName = x.Element("siteName").Value;
458: translation.CompanyName = x.Element("companyName").Value;
459: translation.About = x.Element("about").Value.Trim();
460: translation.AboutTitle = x.Element("about").Attribute("title").Value;
461: translation.Statistic = x.Element("statistic").Value.Trim();
462: translation.StatisticTitle = x.Element("statistic").Attribute("title").Value;
463: translation.Setting = x.Element("setting").Value.Trim();
464: translation.SettingTitle = x.Element("setting").Attribute("title").Value;
465:
466: translation.ShareTitle = x.Element("share").Attribute("title").Value;
467: translation.ShareApplication = x.Element("share").Element("application").Value.Trim();
468: translation.ShareTrek = x.Element("share").Element("trek").Value.Trim();
469: translation.ShareNoEmailClientInstalled = x.Element("share").Attribute("noEmailClientInstalled").Value;
470: translation.ShareContactUs = x.Element("share").Attribute("contactUs").Value;
471:
472: translation.HelpFeedbackTitle = x.Element("help_feedback").Attribute("title").Value;
473: translation.Help = x.Element("help_feedback").Element("help").Value.Trim();
474: translation.HelpTitle = x.Element("help_feedback").Element("help").Attribute("title").Value;
475: translation.HelpMainListOrder = x.Element("help_feedback").Element("help").Attribute("mainListOrder").Value;
476: translation.HelpMagnifiyingGlass = x.Element("help_feedback").Element("help").Attribute("magnifiyingGlass").Value;
477: translation.Feedback = x.Element("help_feedback").Element("feedback").Value.Trim();
478: translation.FeedbackTitle = x.Element("help_feedback").Element("feedback").Attribute("title").Value;
479: translation.FeedbackEmailSubject = x.Element("help_feedback").Element("feedback").Attribute("feedbackEmailSubject").Value;
480:
481: translation.Legal = x.Element("legal").Value.Trim();
482: translation.LegalTitle = x.Element("legal").Attribute("title").Value;
483:
484:
485: translationList.Add(translation);
486: }
487: }
488:
489: return translationList.ToList();
490: }
491: }
492:
493: ////////////////////////////////////////////////////////////////////////////
494:
495: /// <summary>
496: ///
497: /// </summary>
498: private static string ReplaceNameVariableWithName(string line, Ia.TentPlay.Cl.Model.Memorise.ApplicationInformation.Application application)
499: {
500: return ReplaceNameVariableWithName(line, application, null);
501: }
502:
503: ////////////////////////////////////////////////////////////////////////////
504:
505: /// <summary>
506: ///
507: /// </summary>
508: private static string ReplaceNameVariableWithName(string line, Ia.TentPlay.Cl.Model.Memorise.ApplicationInformation.Application application, string iso6391)
509: {
510: string s;
511:
512: s = line;
513:
514: // this must be before $manifestPackage
515: s = Replace(s, "$applicationDownloadLink", application.ApplicationDownloadLink);
516:
517: if (!string.IsNullOrEmpty(iso6391))
518: {
519: s = Replace(s, "$applicationName", application.NameDictionary[iso6391]);
520: // s = Replace(s, "$countryName", application.NameDictionary[iso6391]);
521: }
522:
523: //s = Replace(s, "$countryIso2", application.Iso2);
524: s = Replace(s, "$version", application.VersionName);
525: s = Replace(s, "$manifestPackagePrefix", application.ManifestPackagePrefix);
526: s = Replace(s, "$manifestPackage", application.ManifestPackage);
527: s = Replace(s, "$copyrightYear", application.CopyrightYear);
528: s = Replace(s, "$featureCount", application.Count.ToString());
529:
530: s = Replace(s, "$companyName", Ia.TentPlay.Cl.Model.Data.CompanyInformation.CompanyName);
531: s = Replace(s, "$companyEmail", Ia.TentPlay.Cl.Model.Data.CompanyInformation.CompanyEmail);
532: s = Replace(s, "$companyUrl", Ia.TentPlay.Cl.Model.Data.CompanyInformation.CompanyUrl);
533:
534: s = Replace(s, "$applicationCompanyName", Ia.TentPlay.Cl.Model.Data.CompanyInformation.ApplicationCompanyName);
535: s = Replace(s, "$applicationCompanyEmail", Ia.TentPlay.Cl.Model.Data.CompanyInformation.ApplicationCompanyEmail);
536: s = Replace(s, "$applicationCompanyUrl", Ia.TentPlay.Cl.Model.Data.CompanyInformation.ApplicationCompanyUrl);
537:
538: return s;
539: }
540:
541: ////////////////////////////////////////////////////////////////////////////
542:
543: /// <summary>
544: ///
545: /// </summary>
546: private static string Replace(string content, string term, string replacementTerm)
547: {
548: return content.Replace(term, replacementTerm);
549: }
550:
551: ////////////////////////////////////////////////////////////////////////////
552: ////////////////////////////////////////////////////////////////////////////
553:
554: /// <summary>
555: ///
556: /// How to embed and access resources by using Visual C# http://support.microsoft.com/kb/319292/en-us
557: ///
558: /// 1. Change the "Build Action" property of your XML file from "Content" to "Embedded Resource".
559: /// 2. Add "using System.Reflection".
560: /// 3. Manifest resource stream will start with the project namespace, the location of XML file.
561: ///
562: /// </summary>
563:
564: private static XDocument XDocument
565: {
566: get
567: {
568: Assembly _assembly;
569: StreamReader streamReader;
570:
571: if (xDocument == null)
572: {
573: _assembly = Assembly.GetExecutingAssembly();
574: streamReader = new StreamReader(_assembly.GetManifestResourceStream("Ia.TentPlay.Cl.model.data.memorise.application-information.xml"));
575:
576: try
577: {
578: if (streamReader.Peek() != -1) xDocument = System.Xml.Linq.XDocument.Load(streamReader);
579: }
580: catch (Exception)
581: {
582: }
583: finally
584: {
585: }
586: }
587:
588: return xDocument;
589: }
590: }
591:
592: ////////////////////////////////////////////////////////////////////////////
593: ////////////////////////////////////////////////////////////////////////////
594: }
595: }