<commit_before>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using DesktopAnalytics;
using Glyssen.Controls;
using Glyssen.Shared;
using Glyssen.Utilities;
using GlyssenEngine;
using GlyssenEngine.Bundle;
using GlyssenEngine.Paratext;
using GlyssenEngine.Script;
using L10NSharp;
using L10NSharp.TMXUtils;
using L10NSharp.UI;
using SIL.DblBundle.Text;
using SIL.Reporting;
using SIL.Scripture;
using static System.String;

namespace Glyssen.Dialogs
{
	public partial class ScriptureRangeSelectionDlg : Form
	{
		private readonly Project m_project;
		private ParatextScrTextWrapper m_paratextScrTextWrapper;
		private readonly List<Book> m_availableOtBooks;
		private readonly List<Book> m_availableNtBooks;
		private readonly int m_bookCodeColumnIndex = 0;
		private readonly int m_vernacularColumnIndex = 1;
		private readonly int m_includeInScriptColumnIndex = 2;
		private readonly int m_multiVoiceColumnIndex = 3;
		private Dictionary<string, bool> m_includeInScript;
		private Dictionary<string, bool> m_multiVoice;
		private List<string> m_storedOtSelections;
		private List<string> m_storedNtSelections;

		private DialogResult m_userDecisionAboutUpdatedBookContent = DialogResult.None;

		internal ScriptureRangeSelectionDlg(Project project, ParatextScrTextWrapper paratextScrTextWrapper)
		{
			InitializeComponent();

			m_project = project;
			m_paratextScrTextWrapper = paratextScrTextWrapper;

			m_availableOtBooks = m_project.AvailableBooks.Where(b => BCVRef.BookToNumber(b.Code) <= 39).ToList();
			m_availableNtBooks = m_project.AvailableBooks.Where(b => BCVRef.BookToNumber(b.Code) > 39).ToList();

			Initialize();

			HandleStringsLocalized();
			LocalizeItemDlg<TMXDocument>.StringsLocalized += HandleStringsLocalized;
		}

		private void HandleStringsLocalized()
		{
			Debug.Assert(LocalizationManager.UILanguageId != "en" || Text == "Select Books - {0}",
				"Dev alert: the localized string and ID of this dialog's window title MUST be kept in sync with the version in Project.FoundUnacceptableChangesInAvailableBooks!");

			Text = Format(Text, m_project.Name);
		}

		private void ScriptureRangeSelectionDlg_Load(object sender, EventArgs e)
		{
			MainForm.SetChildFormLocation(this);
		}

		private void Initialize()
		{
			m_includeInScript = new Dictionary<string, bool>(m_project.AvailableBooks.Count);
			m_multiVoice = new Dictionary<string, bool>(m_project.AvailableBooks.Count);

			// First time in. For bundle-based projects, default to all included.
			// For Paratext projects, we don't do this because we've predetermined which books
			// are included based on checking status.
			if (m_project.IsBundleBasedProject && m_project.IncludedBooks.Count == 0)
				foreach (var availableBook in m_project.AvailableBooks)
					availableBook.IncludeInScript = true;

			m_otBooksGrid.RowCount = m_availableOtBooks.Count;
			m_ntBooksGrid.RowCount = m_availableNtBooks.Count;

			if (m_otBooksGrid.RowCount == 0)
				HideOtGrid();
			if (m_ntBooksGrid.RowCount == 0)
				HideNtGrid();

			InitializeGridData(m_otBooksGrid, m_availableOtBooks);
			InitializeGridData(m_ntBooksGrid, m_availableNtBooks);

			if (m_checkBoxOldTestament.Visible && !m_includeInScript.Any(p => p.Value && BCVRef.BookToNumber(p.Key) <= 39))
				m_checkBoxOldTestament.Checked = false;
			if (m_checkBoxNewTestament.Visible && !m_includeInScript.Any(p => p.Value && BCVRef.BookToNumber(p.Key) > 39))
				m_checkBoxNewTestament.Checked = false;

			SetupDropdownHeaderCells();
		}

		private bool GetParatextScrTextWrapperIfNeeded(bool refreshBooksIfExisting = false)
		{<commit_msg>PG-1287: Added comment to GetParatextScrTextWrapperIfNeeded<commit_after>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using DesktopAnalytics;
using Glyssen.Controls;
using Glyssen.Shared;
using Glyssen.Utilities;
using GlyssenEngine;
using GlyssenEngine.Bundle;
using GlyssenEngine.Paratext;
using GlyssenEngine.Script;
using L10NSharp;
using L10NSharp.TMXUtils;
using L10NSharp.UI;
using SIL.DblBundle.Text;
using SIL.Reporting;
using SIL.Scripture;
using static System.String;

namespace Glyssen.Dialogs
{
	public partial class ScriptureRangeSelectionDlg : Form
	{
		private readonly Project m_project;
		private ParatextScrTextWrapper m_paratextScrTextWrapper;
		private readonly List<Book> m_availableOtBooks;
		private readonly List<Book> m_availableNtBooks;
		private readonly int m_bookCodeColumnIndex = 0;
		private readonly int m_vernacularColumnIndex = 1;
		private readonly int m_includeInScriptColumnIndex = 2;
		private readonly int m_multiVoiceColumnIndex = 3;
		private Dictionary<string, bool> m_includeInScript;
		private Dictionary<string, bool> m_multiVoice;
		private List<string> m_storedOtSelections;
		private List<string> m_storedNtSelections;

		private DialogResult m_userDecisionAboutUpdatedBookContent = DialogResult.None;

		internal ScriptureRangeSelectionDlg(Project project, ParatextScrTextWrapper paratextScrTextWrapper)
		{
			InitializeComponent();

			m_project = project;
			m_paratextScrTextWrapper = paratextScrTextWrapper;

			m_availableOtBooks = m_project.AvailableBooks.Where(b => BCVRef.BookToNumber(b.Code) <= 39).ToList();
			m_availableNtBooks = m_project.AvailableBooks.Where(b => BCVRef.BookToNumber(b.Code) > 39).ToList();

			Initialize();

			HandleStringsLocalized();
			LocalizeItemDlg<TMXDocument>.StringsLocalized += HandleStringsLocalized;
		}

		private void HandleStringsLocalized()
		{
			Debug.Assert(LocalizationManager.UILanguageId != "en" || Text == "Select Books - {0}",
				"Dev alert: the localized string and ID of this dialog's window title MUST be kept in sync with the version in Project.FoundUnacceptableChangesInAvailableBooks!");

			Text = Format(Text, m_project.Name);
		}

		private void ScriptureRangeSelectionDlg_Load(object sender, EventArgs e)
		{
			MainForm.SetChildFormLocation(this);
		}

		private void Initialize()
		{
			m_includeInScript = new Dictionary<string, bool>(m_project.AvailableBooks.Count);
			m_multiVoice = new Dictionary<string, bool>(m_project.AvailableBooks.Count);

			// First time in. For bundle-based projects, default to all included.
			// For Paratext projects, we don't do this because we've predetermined which books
			// are included based on checking status.
			if (m_project.IsBundleBasedProject && m_project.IncludedBooks.Count == 0)
				foreach (var availableBook in m_project.AvailableBooks)
					availableBook.IncludeInScript = true;

			m_otBooksGrid.RowCount = m_availableOtBooks.Count;
			m_ntBooksGrid.RowCount = m_availableNtBooks.Count;

			if (m_otBooksGrid.RowCount == 0)
				HideOtGrid();
			if (m_ntBooksGrid.RowCount == 0)
				HideNtGrid();

			InitializeGridData(m_otBooksGrid, m_availableOtBooks);
			InitializeGridData(m_ntBooksGrid, m_availableNtBooks);

			if (m_checkBoxOldTestament.Visible && !m_includeInScript.Any(p => p.Value && BCVRef.BookToNumber(p.Key) <= 39))
				m_checkBoxOldTestament.Checked = false;
			if (m_checkBoxNewTestament.Visible && !m_includeInScript.Any(p => p.Value && BCVRef.BookToNumber(p.Key) > 39))
				m_checkBoxNewTestament.Checked = false;

			SetupDropdownHeaderCells();
		}

		/// <summary>
		/// Attempts to set m_paratextScrTextWrapper (if not set) and optionally updates the information about available books
		/// and their current checking status. This can fail if the Paratext project cannot be found, so callers should check
		/// the return value rather than blindly assuming it succeeded. The focus of this dialog is not on getting updated
		/// content from Paratext, so we don't want to bother the user if that isn't possible. If it is possible, then we ask
		/// them about including the updated content (when appropriate) when the OK button is clicked. This method will generally
		/// not initiate interaction with the user, but there is at least one edge case where it might (when the Paratext
		/// project is found but has a different metadata ID).
		/// </summary>
		/// <param name="refreshBooksIfExisting">Flag indicating that GetUpdatedBookInfo should be called to update the checking
		/// status of books in Paratext when m_paratextScrTextWrapper is already set</param>
		/// <returns><c>true</c> if m_paratextScrTextWrapper is set; <c>false</c> if m_paratextScrTextWrapper is null</returns>
		private bool GetParatextScrTextWrapperIfNeeded(bool refreshBooksIfExisting = false)
		{
{'fraction_non_alphanumeric': 0.08422026839426192, 'fraction_numerical': 0.005552984729291994, 'mean_word_length': 5.255426917510854, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 43, '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': '6261968', 'n_tokens_mistral': 2982, 'n_tokens_neox': 2596, 'n_words': 673}