public AssignCharacterViewModel(Project project, BlocksToDisplay mode, BookBlockIndices startingIndices)
            : base(project, mode, startingIndices)
        {
            m_combinedCharacterVerseData = new CombinedCharacterVerseData(project);

            CurrentBlockMatchupChanged += OnCurrentBlockMatchupChanged;
        }
        public BlockNavigatorViewModel(Project project, BlocksToDisplay mode, BookBlockIndices startingIndices, ProjectSettingsViewModel settingsViewModel = null)
        {
            m_project = project;
            m_project.QuoteParseCompleted += HandleProjectQuoteParseCompleted;

            m_navigator = new BlockNavigator(m_project.IncludedBooks);

            m_includedBooks = project.IncludedBooks.Select(b => b.BookId);
            Versification   = project.Versification;

            if (settingsViewModel != null)
            {
                m_font = new FontProxy(settingsViewModel.WsModel.CurrentDefaultFontName,
                                       (int)settingsViewModel.WsModel.CurrentDefaultFontSize, settingsViewModel.WsModel.CurrentRightToLeftScript);
            }
            else
            {
                m_font = new FontProxy(project.FontFamily, project.FontSizeInPoints, project.RightToLeftScript);
            }
            CacheReferenceTextFonts(project.ReferenceText);

            FontSizeUiAdjustment = project.FontSizeUiAdjustment;

            Mode = mode;

            if (startingIndices != null && !startingIndices.IsUndefined)
            {
                SetBlock(startingIndices);
                m_currentBlockIndex = m_relevantBlocks.IndexOf(startingIndices);
                if (m_currentBlockIndex < 0)
                {
                    m_temporarilyIncludedBlock = startingIndices;
                }
            }
        }
        public AssignCharacterViewModel(Project project, BlocksToDisplay mode, BookBlockIndices startingIndices)
            : base(project, mode, startingIndices)
        {
            m_projectCharacterVerseData  = project.ProjectCharacterVerseData;
            m_combinedCharacterVerseData = new CombinedCharacterVerseData(project);

            CurrentBlockMatchupChanged += (sender, args) => { m_pendingCharacterVerseAdditions.Clear(); };
        }
 private void SetBlock(BookBlockIndices indices, bool clearBlockMatchup = true)
 {
     if (clearBlockMatchup)
     {
         ClearBlockMatchup();
     }
     m_navigator.SetIndices(indices);
     HandleCurrentBlockChanged();
 }
        public bool TryLoadBlock(VerseRef verseRef)
        {
            var indices = m_navigator.GetIndicesOfFirstBlockAtReference(verseRef);

            if (indices == null)
            {
                return(false);
            }
            m_currentBlockIndex        = m_relevantBlocks.IndexOf(indices);
            m_temporarilyIncludedBlock = m_currentBlockIndex < 0 ? indices : null;
            SetBlock(indices);
            return(true);
        }
        private void LoadClosestRelevantBlock(bool prev)
        {
            if (m_temporarilyIncludedBlock == null)
            {
                m_currentBlockIndex = 0;
            }
            else
            {
                m_currentBlockIndex        = GetIndexOfClosestRelevantBlock(m_relevantBlocks, m_temporarilyIncludedBlock, prev, 0, RelevantBlockCount - 1);
                m_temporarilyIncludedBlock = null;
            }

            if (m_currentBlockIndex < 0)
            {
                m_currentBlockIndex = 0;
            }

            SetBlock(m_relevantBlocks[m_currentBlockIndex]);
        }
        public void ClearBlockMatchup()
        {
            if (m_currentRefBlockMatchups == null)
            {
                return;
            }
            BlockGroupingStyle = BlockGroupingType.Quote;
            var relevant = IsCurrentBlockRelevant;

            m_currentRefBlockMatchups = null;
            if (!relevant)
            {
                m_temporarilyIncludedBlock = GetCurrentBlockIndices();
            }
            if (CurrentBlockMatchupChanged != null)
            {
                CurrentBlockMatchupChanged(this, new EventArgs());
            }
        }
        public BlockNavigatorViewModel(Project project, BlocksToDisplay mode, BookBlockIndices startingIndices, ProjectSettingsViewModel settingsViewModel = null)
        {
            m_project = project;
            m_project.QuoteParseCompleted += (s, e) =>
            {
                m_navigator = new BlockNavigator(m_project.IncludedBooks);
                ResetFilter(null);
            };

            m_navigator = new BlockNavigator(m_project.IncludedBooks);

            m_includedBooks = project.IncludedBooks.Select(b => b.BookId);
            Versification   = project.Versification;

            if (settingsViewModel != null)
            {
                m_fontFamily           = settingsViewModel.WsModel.CurrentDefaultFontName;
                m_baseFontSizeInPoints = (int)settingsViewModel.WsModel.CurrentDefaultFontSize;
                m_rightToLeftScript    = settingsViewModel.WsModel.CurrentRightToLeftScript;
            }
            else
            {
                m_fontFamily           = project.FontFamily;
                m_baseFontSizeInPoints = project.FontSizeInPoints;
                m_rightToLeftScript    = project.RightToLeftScript;
            }
            FontSizeUiAdjustment = project.FontSizeUiAdjustment;

            Mode = mode;

            if (startingIndices != null && !startingIndices.IsUndefined)
            {
                SetBlock(startingIndices);
                m_currentBlockIndex = m_relevantBlocks.IndexOf(startingIndices);
                if (m_currentBlockIndex < 0)
                {
                    m_temporarilyIncludedBlock = startingIndices;
                }
            }
        }
        private void ResetFilter(Block selectedBlock)
        {
            PopulateRelevantBlocks();

            if (IsRelevant(m_navigator.CurrentBlock))
            {
                m_currentBlockIndex        = 0;
                m_temporarilyIncludedBlock = null;
            }
            else
            {
                if (RelevantBlockCount > 0)
                {
                    m_currentBlockIndex = -1;
                    if (m_temporarilyIncludedBlock != null)
                    {
                        // Block that was temporarily included in previous filter might now match the new filter
                        var i = m_relevantBlocks.IndexOf(m_temporarilyIncludedBlock);
                        if (i >= 0)
                        {
                            m_currentBlockIndex        = i;
                            m_temporarilyIncludedBlock = null;
                            SetBlock(m_relevantBlocks[m_currentBlockIndex]);
                            return;
                        }
                    }
                    LoadNextRelevantBlock();
                }
                else if (selectedBlock != null)
                {
                    m_temporarilyIncludedBlock = m_navigator.GetIndicesOfSpecificBlock(selectedBlock);
                    m_navigator.SetIndices(m_temporarilyIncludedBlock);
                }
                else
                {
                    m_temporarilyIncludedBlock = m_navigator.GetIndices();
                }
            }
        }
        public static int GetIndexOfClosestRelevantBlock(List <BookBlockIndices> list, BookBlockIndices key, bool prev,
                                                         int min, int max)
        {
            if (min > max)
            {
                if (prev)
                {
                    return((max >= 0 && max < list.Count && s_bookBlockComparer.Compare(key, list[max]) > 0) ? max : -1);
                }

                return((min >= 0 && min < list.Count && s_bookBlockComparer.Compare(key, list[min]) < 0) ? min : -1);
            }
            int mid = (min + max) / 2;

            int comparison = s_bookBlockComparer.Compare(key, list[mid]);

            if (comparison == 0)
            {
                throw new ArgumentException("Block not expected to be in existing list", "key");
            }

            if (comparison < 0)
            {
                return(GetIndexOfClosestRelevantBlock(list, key, prev, min, mid - 1));
            }

            return(GetIndexOfClosestRelevantBlock(list, key, prev, mid + 1, max));
        }
 private void SetBlock(BookBlockIndices indices)
 {
     m_navigator.SetIndices(indices);
     HandleCurrentBlockChanged();
 }
 public AssignCharacterViewModel(Project project, BlocksToDisplay mode, BookBlockIndices startingIndices)
     : base(project, mode, startingIndices)
 {
     m_projectCharacterVerseData  = project.ProjectCharacterVerseData;
     m_combinedCharacterVerseData = new CombinedCharacterVerseData(project);
 }