<commit_before>﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Glyssen.Shared;
using Glyssen.Shared.Bundle;
using Glyssen.Utilities;
using GlyssenEngine;
using GlyssenEngine.Bundle;
using GlyssenEngine.Paratext;
using GlyssenEngine.Script;
using GlyssenEngine.Utilities;
using GlyssenEngine.ViewModels;
using GlyssenFileBasedPersistence;
using L10NSharp;
using L10NSharp.XLiffUtils;
using L10NSharp.UI;
using SIL.IO;
using SIL.Reporting;
using SIL.Windows.Forms.WritingSystems;
using Analytics = DesktopAnalytics.Analytics;
using BlockNavigatorViewModel = GlyssenEngine.ViewModels.BlockNavigatorViewModel<System.Drawing.Font>;

namespace Glyssen.Dialogs
{
	public partial class ProjectSettingsDlg : FormWithPersistedSettings
	{
		private ProjectSettingsViewModel m_model;
		private WritingSystemSetupModel m_wsViewModel;

		private class ChapterAnnouncementItem
		{
			public string UiString { get; private set; }
			public ChapterAnnouncement ChapterAnnouncement { get; private set; }

			public ChapterAnnouncementItem(string uiString, ChapterAnnouncement chapterAnnouncement)
			{
				UiString = uiString;
				ChapterAnnouncement = chapterAnnouncement;
			}

			public override string ToString()
			{
				return UiString;
			}
		}

		public ProjectSettingsDlg(ProjectSettingsViewModel model, WritingSystemSetupModel wsViewModel)
		{
			InitializeComponent();

			m_txtRecordingProjectName.MaxLength = model.Project.MaxProjectNameLength;

			for (int i = 0; i < m_cboBookMarker.Items.Count; i++)
			{
				var chapterAnnouncement = (ChapterAnnouncement)i;
				m_cboBookMarker.Items[i] = new ChapterAnnouncementItem(LocalizationManager.GetDynamicString(GlyssenInfo.ApplicationId,
					"DialogBoxes.ProjectSettingsDlg.ChapterAnnouncementTab.BookMarkerComboBox.Items." + chapterAnnouncement,
					m_cboBookMarker.Items[i].ToString()), chapterAnnouncement);
			}

			IReadOnlyList<BookScript> books = model.Project.IncludedBooks.Any() ? model.Project.IncludedBooks : model.Project.Books;
			if (books.All(book => string.IsNullOrEmpty(book.PageHeader)))
				RemoveItemFromBookMarkerCombo(ChapterAnnouncement.PageHeader);
			if (books.All(book => string.IsNullOrEmpty(book.MainTitle)))
				RemoveItemFromBookMarkerCombo(ChapterAnnouncement.MainTitle1);

			LocalizeItemDlg<XLiffDocument>.StringsLocalized += HandleStringsLocalized;
			SetViewModel(model, wsViewModel);
			HandleStringsLocalized();
		}

		private void HandleStringsLocalized()
		{
			LoadReferenceTextOptions();
			LoadProjectDramatizationOptions();
			UpdateQuotePageDisplay();

			var fmt = m_linkLblChangeOmittedChapterAnnouncements.Text;
			var linkStartPos = fmt.IndexOf("{0}");
			m_linkLblChangeOmittedChapterAnnouncements.Text = String.Format(fmt, m_tabPageScriptOptions.Text);
			if (linkStartPos >= 0 && m_tabPageScriptOptions.Text.Length > 0)
				m_linkLblChangeOmittedChapterAnnouncements.LinkArea = new LinkArea(linkStartPos, m_tabPageScriptOptions.Text.Length);
			else
				m_linkLblChangeOmittedChapterAnnouncements.LinkArea = default(LinkArea);
			if (m_model.IsLiveParatextProject)
				m_lblOriginalSource.Text = String.Format(LocalizationManager.GetString(
					"DialogBoxes.ProjectSettingsDlg.SourceLabelForParatextProject", "{0} project:", "\"Paratext\" (product name)"),
					ParatextScrTextWrapper.kParatextProgramName);
		}

		protected override void OnVisibleChanged(EventArgs e)
		{
			base.OnVisibleChanged(e);
			var project = m_model.Project;
			if (IsHandleCreated && Visible && m_model.IsLiveParatextProject &&
				(project.QuoteSystemStatus & QuoteSystemStatus.ParseReady) != 0)
			{
				var paratextProj = project.GetParatextScrTextWrapper();
				if (paratextProj != null &&
					!project.WritingSystem.QuotationMarks.SequenceEqual(project.GetQuotationMarksWithFullySpecifiedContinuers(paratextProj.QuotationMarks)))
				{
					string msg = string.Format(LocalizationManager.GetString("Project.ParatextQuoteSystemChanged",
							"The quotation mark settings in {0} project {1} no longer match the settings in this {2} project. To update " +
							"this project to match the {0} project settings (and get the latest versions of the text), click {3}.",
							"Param 0: \"Paratext\" (product name); " +
							"Param 1: Paratext project short name (unique project identifier); " +
							"Param 2: \"Glyssen\" (product name); " +
							"Param 3: localized name of the \"Update\" button"),
						ParatextScrTextWrapper.kParatextProgramName,
						m_model.ParatextProjectName,
						GlyssenInfo.Product,
						LocalizedUpdateButtonName);
					MessageBox.Show(msg, Text, MessageBoxButtons.OK);
				}
			}
		}

		private void LoadProjectDramatizationOptions()
		{
			var optionList = new List<KeyValuePair<ExtraBiblicalMaterialSpeakerOption, string>>
			{
				new KeyValuePair<ExtraBiblicalMaterialSpeakerOption, string>(ExtraBiblicalMaterialSpeakerOption.Narrator,
					LocalizationManager.GetString("DialogBoxes.ProjectSettingsDlg.ExtraBiblicalSpeakerOption.Narrator", "Narrator")),
				new KeyValuePair<ExtraBiblicalMaterialSpeakerOption, string>(ExtraBiblicalMaterialSpeakerOption.MaleActor,
					LocalizationManager.GetString("DialogBoxes.ProjectSettingsDlg.ExtraBiblicalSpeakerOption.MaleActor", "Male Actor")),
				new KeyValuePair<ExtraBiblicalMaterialSpeakerOption, string>(ExtraBiblicalMaterialSpeakerOption.FemaleActor,
					LocalizationManager.GetString("DialogBoxes.ProjectSettingsDlg.ExtraBiblicalSpeakerOption.FemaleActor", "Female Actor")),
				new KeyValuePair<ExtraBiblicalMaterialSpeakerOption, string>(ExtraBiblicalMaterialSpeakerOption.ActorOfEitherGender,
					LocalizationManager.GetString("DialogBoxes.ProjectSettingsDlg.ExtraBiblicalSpeakerOption.EitherGender", "Either Gender")),
				new KeyValuePair<ExtraBiblicalMaterialSpeakerOption, string>(ExtraBiblicalMaterialSpeakerOption.Omitted,
					LocalizationManager.GetString("DialogBoxes.ProjectSettingsDlg.ExtraBiblicalSpeakerOption.Omitted", "Omitted"))
			};

			m_bookIntro.DataSource = new BindingSource(optionList, null);
			m_bookIntro.DisplayMember = "Value";
			m_bookIntro.ValueMember = "Key";

			m_sectionHeadings.DataSource = new BindingSource(optionList, null);
			m_sectionHeadings.DisplayMember = "Value";
			m_sectionHeadings.ValueMember = "Key";

			m_titleChapters.DataSource = new BindingSource(optionList, null);
			m_titleChapters.DisplayMember = "Value";
			m_titleChapters.ValueMember = "Key";
		}

		private void LoadReferenceTextOptions()
		{
			var currentSelection = SelectedReferenceText;
			var dataSource = new Dictionary<string, ReferenceTextProxy>();
			foreach (var refTextId in ReferenceTextProxy.AllAvailable)
			{
				string key;
				if (refTextId.Type == ReferenceTextType.Custom)
				{
					var fmt = (refTextId.Missing) ?
						LocalizationManager.GetString("DialogBoxes.ProjectSettingsDlg.MissingReferenceText", "Missing: {0}") :
						LocalizationManager.GetString("DialogBoxes.ProjectSettingsDlg.CustomReferenceText", "Custom: {0}");
					key = String.Format(fmt, refTextId.CustomIdentifier);
				}<commit_msg>PG-1376: Added comment to explain saving and restoring currentSelection<commit_after>﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Glyssen.Shared;
using Glyssen.Shared.Bundle;
using Glyssen.Utilities;
using GlyssenEngine;
using GlyssenEngine.Bundle;
using GlyssenEngine.Paratext;
using GlyssenEngine.Script;
using GlyssenEngine.Utilities;
using GlyssenEngine.ViewModels;
using GlyssenFileBasedPersistence;
using L10NSharp;
using L10NSharp.XLiffUtils;
using L10NSharp.UI;
using SIL.IO;
using SIL.Reporting;
using SIL.Windows.Forms.WritingSystems;
using Analytics = DesktopAnalytics.Analytics;
using BlockNavigatorViewModel = GlyssenEngine.ViewModels.BlockNavigatorViewModel<System.Drawing.Font>;

namespace Glyssen.Dialogs
{
	public partial class ProjectSettingsDlg : FormWithPersistedSettings
	{
		private ProjectSettingsViewModel m_model;
		private WritingSystemSetupModel m_wsViewModel;

		private class ChapterAnnouncementItem
		{
			public string UiString { get; private set; }
			public ChapterAnnouncement ChapterAnnouncement { get; private set; }

			public ChapterAnnouncementItem(string uiString, ChapterAnnouncement chapterAnnouncement)
			{
				UiString = uiString;
				ChapterAnnouncement = chapterAnnouncement;
			}

			public override string ToString()
			{
				return UiString;
			}
		}

		public ProjectSettingsDlg(ProjectSettingsViewModel model, WritingSystemSetupModel wsViewModel)
		{
			InitializeComponent();

			m_txtRecordingProjectName.MaxLength = model.Project.MaxProjectNameLength;

			for (int i = 0; i < m_cboBookMarker.Items.Count; i++)
			{
				var chapterAnnouncement = (ChapterAnnouncement)i;
				m_cboBookMarker.Items[i] = new ChapterAnnouncementItem(LocalizationManager.GetDynamicString(GlyssenInfo.ApplicationId,
					"DialogBoxes.ProjectSettingsDlg.ChapterAnnouncementTab.BookMarkerComboBox.Items." + chapterAnnouncement,
					m_cboBookMarker.Items[i].ToString()), chapterAnnouncement);
			}

			IReadOnlyList<BookScript> books = model.Project.IncludedBooks.Any() ? model.Project.IncludedBooks : model.Project.Books;
			if (books.All(book => string.IsNullOrEmpty(book.PageHeader)))
				RemoveItemFromBookMarkerCombo(ChapterAnnouncement.PageHeader);
			if (books.All(book => string.IsNullOrEmpty(book.MainTitle)))
				RemoveItemFromBookMarkerCombo(ChapterAnnouncement.MainTitle1);

			LocalizeItemDlg<XLiffDocument>.StringsLocalized += HandleStringsLocalized;
			SetViewModel(model, wsViewModel);
			HandleStringsLocalized();
		}

		private void HandleStringsLocalized()
		{
			LoadReferenceTextOptions();
			LoadProjectDramatizationOptions();
			UpdateQuotePageDisplay();

			var fmt = m_linkLblChangeOmittedChapterAnnouncements.Text;
			var linkStartPos = fmt.IndexOf("{0}");
			m_linkLblChangeOmittedChapterAnnouncements.Text = String.Format(fmt, m_tabPageScriptOptions.Text);
			if (linkStartPos >= 0 && m_tabPageScriptOptions.Text.Length > 0)
				m_linkLblChangeOmittedChapterAnnouncements.LinkArea = new LinkArea(linkStartPos, m_tabPageScriptOptions.Text.Length);
			else
				m_linkLblChangeOmittedChapterAnnouncements.LinkArea = default(LinkArea);
			if (m_model.IsLiveParatextProject)
				m_lblOriginalSource.Text = String.Format(LocalizationManager.GetString(
					"DialogBoxes.ProjectSettingsDlg.SourceLabelForParatextProject", "{0} project:", "\"Paratext\" (product name)"),
					ParatextScrTextWrapper.kParatextProgramName);
		}

		protected override void OnVisibleChanged(EventArgs e)
		{
			base.OnVisibleChanged(e);
			var project = m_model.Project;
			if (IsHandleCreated && Visible && m_model.IsLiveParatextProject &&
				(project.QuoteSystemStatus & QuoteSystemStatus.ParseReady) != 0)
			{
				var paratextProj = project.GetParatextScrTextWrapper();
				if (paratextProj != null &&
					!project.WritingSystem.QuotationMarks.SequenceEqual(project.GetQuotationMarksWithFullySpecifiedContinuers(paratextProj.QuotationMarks)))
				{
					string msg = string.Format(LocalizationManager.GetString("Project.ParatextQuoteSystemChanged",
							"The quotation mark settings in {0} project {1} no longer match the settings in this {2} project. To update " +
							"this project to match the {0} project settings (and get the latest versions of the text), click {3}.",
							"Param 0: \"Paratext\" (product name); " +
							"Param 1: Paratext project short name (unique project identifier); " +
							"Param 2: \"Glyssen\" (product name); " +
							"Param 3: localized name of the \"Update\" button"),
						ParatextScrTextWrapper.kParatextProgramName,
						m_model.ParatextProjectName,
						GlyssenInfo.Product,
						LocalizedUpdateButtonName);
					MessageBox.Show(msg, Text, MessageBoxButtons.OK);
				}
			}
		}

		private void LoadProjectDramatizationOptions()
		{
			var optionList = new List<KeyValuePair<ExtraBiblicalMaterialSpeakerOption, string>>
			{
				new KeyValuePair<ExtraBiblicalMaterialSpeakerOption, string>(ExtraBiblicalMaterialSpeakerOption.Narrator,
					LocalizationManager.GetString("DialogBoxes.ProjectSettingsDlg.ExtraBiblicalSpeakerOption.Narrator", "Narrator")),
				new KeyValuePair<ExtraBiblicalMaterialSpeakerOption, string>(ExtraBiblicalMaterialSpeakerOption.MaleActor,
					LocalizationManager.GetString("DialogBoxes.ProjectSettingsDlg.ExtraBiblicalSpeakerOption.MaleActor", "Male Actor")),
				new KeyValuePair<ExtraBiblicalMaterialSpeakerOption, string>(ExtraBiblicalMaterialSpeakerOption.FemaleActor,
					LocalizationManager.GetString("DialogBoxes.ProjectSettingsDlg.ExtraBiblicalSpeakerOption.FemaleActor", "Female Actor")),
				new KeyValuePair<ExtraBiblicalMaterialSpeakerOption, string>(ExtraBiblicalMaterialSpeakerOption.ActorOfEitherGender,
					LocalizationManager.GetString("DialogBoxes.ProjectSettingsDlg.ExtraBiblicalSpeakerOption.EitherGender", "Either Gender")),
				new KeyValuePair<ExtraBiblicalMaterialSpeakerOption, string>(ExtraBiblicalMaterialSpeakerOption.Omitted,
					LocalizationManager.GetString("DialogBoxes.ProjectSettingsDlg.ExtraBiblicalSpeakerOption.Omitted", "Omitted"))
			};

			m_bookIntro.DataSource = new BindingSource(optionList, null);
			m_bookIntro.DisplayMember = "Value";
			m_bookIntro.ValueMember = "Key";

			m_sectionHeadings.DataSource = new BindingSource(optionList, null);
			m_sectionHeadings.DisplayMember = "Value";
			m_sectionHeadings.ValueMember = "Key";

			m_titleChapters.DataSource = new BindingSource(optionList, null);
			m_titleChapters.DisplayMember = "Value";
			m_titleChapters.ValueMember = "Key";
		}

		private void LoadReferenceTextOptions()
		{
			// Saving the selection (if any) here is required to deal with the (rare) case where
			// the user does on-the-fly localization. When there is an existing selection that
			// differs from the one that was set when we came into this dialog and we reset the
			// data source, the selection gets lost. So we need to remember which one was selected
			// and restore it below.
			var currentSelection = SelectedReferenceText;
			var dataSource = new Dictionary<string, ReferenceTextProxy>();
			foreach (var refTextId in ReferenceTextProxy.AllAvailable)
			{
				string key;
				if (refTextId.Type == ReferenceTextType.Custom)
				{
					var fmt = (refTextId.Missing) ?
						LocalizationManager.GetString("DialogBoxes.ProjectSettingsDlg.MissingReferenceText", "Missing: {0}") :
						LocalizationManager.GetString("DialogBoxes.ProjectSettingsDlg.CustomReferenceText", "Custom: {0}");
					key = String.Format(fmt, refTextId.CustomIdentifier);
				}
{'fraction_non_alphanumeric': 0.08988610789060901, 'fraction_numerical': 0.00354634113073723, 'mean_word_length': 5.5994599459945995, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4107405', 'n_tokens_mistral': 5046, 'n_tokens_neox': 4264, 'n_words': 799}