all repos — bibel @ d229be0e52779e06632c53ce0a1115b2c2249c25

Unnamed repository; edit this file 'description' to name the repository.

internal/dateprogression.go (view raw)

  1package bible
  2
  3import (
  4	"fmt"
  5	"time"
  6)
  7
  8// DateProgression handles calculating Bible position based on date
  9type DateProgression struct {
 10	bible *Bible
 11}
 12
 13// NewDateProgression creates a new date progression calculator
 14func NewDateProgression(bible *Bible) *DateProgression {
 15	return &DateProgression{bible: bible}
 16}
 17
 18// GetPositionForDate calculates the verse range for a given date
 19func (dp *DateProgression) GetPositionForDate(date time.Time) (*Bookmark, error) {
 20	// Calculate day of year (1-366)
 21	dayOfYear := date.YearDay()
 22
 23	// Each day shows 12 verses
 24	targetVerseOffset := (dayOfYear - 1) * 12 // Zero-indexed
 25
 26	// Walk through Gospels to find the position
 27	return dp.findPositionForOffset(targetVerseOffset)
 28}
 29
 30// findPositionForOffset finds the bookmark for a given cumulative verse offset
 31func (dp *DateProgression) findPositionForOffset(offset int) (*Bookmark, error) {
 32	// Iterate through books 40-43 (Matthew, Mark, Luke, John)
 33	for book := 40; book <= 43; book++ {
 34		// Find last chapter in this book
 35		maxChapter := 0
 36		for chapter := 1; ; chapter++ {
 37			if dp.bible.CountVersesInChapter(book, chapter) == 0 {
 38				maxChapter = chapter - 1
 39				break
 40			}
 41		}
 42
 43		// Iterate through chapters
 44		for chapter := 1; chapter <= maxChapter; chapter++ {
 45			versesInChapter := dp.bible.CountVersesInChapter(book, chapter)
 46
 47			// Check if offset falls within this chapter
 48			if offset < versesInChapter {
 49				// Offset is within this chapter
 50				firstVerse := offset + 1 // Convert from 0-indexed to 1-indexed
 51
 52				// Create initial bookmark (like AdvanceBookmark does)
 53				secondVerse := min(firstVerse+11, versesInChapter)
 54				bookmark := &Bookmark{
 55					Book:        BookIndex(book),
 56					Chapter:     chapter,
 57					FirstVerse:  firstVerse,
 58					SecondVerse: secondVerse,
 59				}
 60
 61				// Apply lookahead rule (like AdjustForLookahead)
 62				return dp.applyLookahead(bookmark), nil
 63			}
 64
 65			// Move to next chapter, subtracting this chapter's verses
 66			offset -= versesInChapter
 67		}
 68	}
 69
 70	// If we've gone through all Gospels and offset is still positive, wrap
 71	// around to beginning (start over) Calculate modulo offset within total
 72	// Gospel verses
 73	totalVerses := dp.GetTotalGospelVerses()
 74	if offset >= 0 {
 75		adjustedOffset := offset % totalVerses
 76		// Recursively find position for adjusted offset
 77		return dp.findPositionForOffset(adjustedOffset)
 78	}
 79
 80	return nil, fmt.Errorf("could not find position for offset %d", offset)
 81}
 82
 83// applyLookahead applies the lookahead rule (same as BookmarkManager.AdjustForLookahead)
 84func (dp *DateProgression) applyLookahead(bookmark *Bookmark) *Bookmark {
 85	versesInChapter := dp.bible.CountVersesInChapter(int(bookmark.Book), bookmark.Chapter)
 86	versesRemaining := versesInChapter - bookmark.SecondVerse
 87
 88	// If we're not at the end of the chapter and less than 12 verses remain for NEXT snippet
 89	if versesRemaining > 0 && versesRemaining < 12 {
 90		return &Bookmark{
 91			Book:        bookmark.Book,
 92			Chapter:     bookmark.Chapter,
 93			FirstVerse:  bookmark.FirstVerse,
 94			SecondVerse: versesInChapter,
 95		}
 96	}
 97
 98	// Otherwise return the original bookmark
 99	return bookmark
100}
101
102// GetTotalGospelVerses returns the total number of verses in all four Gospels
103func (dp *DateProgression) GetTotalGospelVerses() int {
104	total := 0
105	for book := 40; book <= 43; book++ {
106		for chapter := 1; ; chapter++ {
107			verses := dp.bible.CountVersesInChapter(book, chapter)
108			if verses == 0 {
109				break
110			}
111			total += verses
112		}
113	}
114	return total
115}
116