コード例 #1
0
 public void GoPrevSlide()
 {
     if (currentSubIndex > 0)
     {
         GotoSlide(currentVerseNum, currentSubIndex - 1);
     }
     else
     {
         if (currentVerseNum > 1)
         {
             GotoSlide(currentVerseNum - 1, slideData[currentVerseNum - 1].MaxCount - 1);
         }
         else
         {
             // Try to navigate a chapter back
             BibleVerse bv = bibVerses[1];
             if (bv.RefChapter > 1)
             {
                 bv.RefChapter--;
                 bv.RefVerse = 1;
                 LoadBibDat(bv);
                 PrepareForDisplay();
                 GotoVerse(bibVerses.Count);
             }
         }
     }
 }
コード例 #2
0
 public void GoNextSlide()
 {
     // Try to step up the sub index
     if (currentSubIndex < slideData[currentVerseNum].MaxCount - 1)
     {
         GotoSlide(currentVerseNum, currentSubIndex + 1);
     }
     else
     {
         // Try to step up the verse count
         if (currentVerseNum < bibVerses.Count)
         {
             GotoSlide(currentVerseNum + 1, 0);
         }
         else
         {
             // Try to navigate a chapter forward
             BibleVerse bv        = bibVerses[1];
             int        chapCount = Program.BibleDS.BibleLookUp.FindByVersionIdMappingBook(bv.RefVersion, bv.RefBook).NumberOfChapters;
             if (bv.RefChapter < chapCount)
             {
                 bv.RefChapter++;
                 bv.RefVerse = 1;
                 LoadBibDat(bv);
                 PrepareForDisplay();
                 GotoVerse(1);
             }
         }
     }
 }
コード例 #3
0
 internal static void InternalDebugPrintVerses(List <BibleSearchResult> lResults)
 {
     foreach (BibleSearchResult r in lResults)
     {
         BibleVerse bv = r.bibVerse;
         System.Diagnostics.Trace.WriteLine(r.score + " " + bv.RefBook + " " + bv.RefChapter + ", " + bv.RefVerse + ": " + bv.Text);
     }
 }
コード例 #4
0
        public static List <BibleSearchResult> Search(List <string> searchTerms)
        {
            if (searchTerms.Count < 1)
            {
                throw (new ApplicationException("No search terms"));
            }

            // Double check sql
            string p = ",./<>?[]\\{}|!@#$%^&*()-=_+:;'\"";

            foreach (string str in searchTerms)
            {
                if (str.IndexOfAny(p.ToCharArray()) != -1)
                {
                    throw (new ApplicationException("Malformed sql passed to Search"));
                }
            }

            // Build the query
            string query = "SELECT \"VERSION\", \"REFBOOK\", \"REFCHAPTER\", \"REFVERSE\", \"DATA\", \"BOOK\", \"CHAPTER\", \"VERSE\" FROM \"BIBLEVERSES\" WHERE ";

            foreach (string s in searchTerms)
            {
                query += "(\"DATA\" LIKE '%" + s + "%') AND ";
            }
            query = query.Remove(query.Length - 4);

            // Query the database
            List <BibleSearchResult> lResults = new List <BibleSearchResult>();

            using (FBirdTask t = new FBirdTask())
            {
                t.CommandText = query;
                t.ExecuteReader();
                int cutoff = 250;

                while (t.DR.Read() && cutoff > 0)
                {
                    cutoff--;

                    BibleSearchResult r  = new BibleSearchResult();
                    BibleVerse        bv = new BibleVerse();
                    bv.RefVersion       = t.GetString(0);
                    bv.RefBook          = t.GetString(1);
                    bv.RefChapter       = t.GetInt32(2);
                    bv.RefVerse         = t.GetInt32(3);
                    bv.Text             = t.GetString(4);
                    bv.SecondaryBook    = t.GetString(5);
                    bv.SecondaryChapter = t.GetInt32(6);
                    bv.SecondaryVerse   = t.GetInt32(7);
                    r.bibVerse          = bv;
                    r.searchResult      = bv.Text;
                    lResults.Add(r);
                }
            }

            return(lResults);
        }
コード例 #5
0
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (scrolling)
            {
                int yDiff         = e.Y - scrollMDownY;
                int scrollerRange = this.Height - scrollerHeight; // Remember that we are measuring from the center of the scroller
                this.scrollerPos = (scrollPosAtMDown + ((double)yDiff / scrollerRange));

                // Bounds check
                if (scrollerPos < 0)
                {
                    scrollerPos = 0;
                }
                if (scrollerPos > 1)
                {
                    scrollerPos = 1;
                }

                this.Refresh();
            }

            // Update cursor
            Rectangle scrollerRect = new Rectangle(0, ScrollerY, 16, scrollerHeight);

            if (e.X > 16)
            {
                this.Cursor = Cursors.Hand;
            }
            else
            {
                if (scrollerRect.Contains(e.Location))
                {
                    this.Cursor = Cursors.Hand;
                }
                else
                {
                    this.Cursor = Cursors.Default;
                }
            }

            // Update the mouse states
            foreach (Rectangle r in hitMapping.Keys)
            {
                Rectangle r2 = r;
                r2.Y -= HitAdjust;
                if (r2.Contains(e.Location))
                {
                    highlightedVerse = hitMapping[r];
                    this.Refresh();
                    return;
                }
            }
            highlightedVerse = null;
            this.Refresh();
        }
コード例 #6
0
        private void CalculateItems()
        {
            /// Function summary:
            /// We need to get the rectangles for each verse and store them for hit detection
            /// and easy painting.

            hitMapping.Clear();
            verseRectMapping.Clear();
            if (proj == null || proj.bibVerses.Count == 0 || proj.currentVerseNum == -1)
            {
                return;
            }

            // Init
            Bitmap   b           = new Bitmap(1, 1);
            Graphics g           = Graphics.FromImage(b);
            int      spacing     = 1;
            int      indent      = 16;
            int      textPadding = 4;
            int      textWidth   = this.Width - spacing - indent;

            // Tile downward
            int cy        = spacing;
            int ixCurrent = 1;

            while (ixCurrent <= proj.bibVerses.Count)
            {
                BibleVerse bv = proj.bibVerses[ixCurrent];
                currentChapter = bv.RefChapter;
                int       itemH = (int)g.MeasureString(bv.RefVerse + ". " + bv.Text, this.Font, textWidth).Height + textPadding;
                Rectangle r     = new Rectangle(indent, cy, this.Width - indent, itemH);
                hitMapping.Add(r, bv);
                verseRectMapping.Add(ixCurrent, r);
                cy += itemH + spacing;
                ixCurrent++;
            }

            // Calculate scroller ratio
            Rectangle lastVerse = verseRectMapping[proj.bibVerses.Count];

            totalVerseHeight = lastVerse.Y + lastVerse.Height;
            double sr = (double)Height / totalVerseHeight;

            if (sr < 1)
            {
                scrollerRatio  = sr;
                scrollerHeight = (int)(Height * sr);
            }
            else
            {
                scrollerRatio = 1;
            }

            CenterToCurrentVerse();
        }
コード例 #7
0
        //////////////////////////////////////////////////////////////////////////////
        public BibleProject(BibleVerse verse)
        {
            Program.ConfigHelper.BibleFormatChanged += delegate { RefreshData(); };

            this.name = verse.ToString();

            // Data
            currentVerseNum = verse.RefVerse;
            LoadBibDat(verse); // Load the bible data from the database
            PrepareForDisplay();
        }
コード例 #8
0
ファイル: BibleSearchPnl.cs プロジェクト: radtek/epresenter
        private void StartProject(bool activate)
        {
#if DEMO
            searchExpired = true;
#endif

            if (this.lbBibleBook.SelectedIndex == -1 ||
                this.lbBibleChapter.SelectedIndex == -1 ||
                this.lbBibleVerse.SelectedIndex == -1)
            {
                return;
            }

            // Build start verse
            BibleVerse bv = new BibleVerse();
            bv.RefBook    = ((BookData)this.lbBibleBook.SelectedItem).mappingName;
            bv.RefChapter = this.lbBibleChapter.SelectedIndex + 1;
            bv.RefVerse   = ((VerseData)this.lbBibleVerse.SelectedItem).num;

            #if !DEMO
            // Get selection range
            int       startR        = -1;
            int       endR          = -1;
            bool      validSelction = false;
            ParseData pd            = ParseVerse(txtBibleLocation.Text, false);
            if (pd.verse != "" && pd.endVerse != "" &&
                int.TryParse(pd.verse, out startR) && int.TryParse(pd.endVerse, out endR) &&
                endR >= startR)
            {
                validSelction = true;
            }
            #endif

            // Create & activate project
            BibleProject bp = new BibleProject(bv);
            #if !DEMO
            if (validSelction)
            {
                bp.selectionRangeStartVerse = startR;
                bp.selectionRangeEndVerse   = endR;
            }
            #endif
            Program.Presenter.AddProject(bp);
            if (activate)
            {
                bp.Activate();
            }

            // Clear ui
            this.Deactivate();
        }
コード例 #9
0
            public void PrepFontFit(GfxContext ctx, Dictionary <int, BibleVerse> verses, int startVerse, PresenterFont font)
            {
                Size nativeSize = DisplayEngine.NativeResolution.Size;

                //////////////////////////////////////////////////////////////////
                // Format data
                BibleVerse bv1      = verses[1];
                string     bookname = Program.BibleDS.BibleLookUp.FindByVersionIdMappingBook(bv1.RefVersion, bv1.RefBook).DisplayBook;
                string     title    = bookname + " " + bv1.RefChapter;
                string     data     = "";

                for (int i = startVerse; i <= verses.Count; i++)
                {
                    data += verses[i].RefVerse + ". " + verses[i].Text + "\r\n";
                }

                //////////////////////////////////////////////////////////////////
                // Measure
                StringFormat sf           = GetStringFormat();
                int          insideHeight = nativeSize.Height - paddingPixels * 2;
                int          insideWidth  = nativeSize.Width - paddingPixels * 2;
                int          titleHeight  = font.SizeInPoints * 2;
                RectangleF   rTitle       = new RectangleF(paddingPixels, paddingPixels, insideWidth, titleHeight);
                RectangleF   rText        = new RectangleF(paddingPixels, paddingPixels + titleHeight,
                                                           insideWidth, insideHeight - titleHeight);

                //////////////////////////////////////////////////////////////////
                // Build context
                ctx.destSize = DisplayEngine.NativeResolution.Size;
                ctx.textRegions.Clear();

                // Title text
                GfxTextRegion trTitle = new GfxTextRegion();

                ctx.textRegions.Add(trTitle);
                trTitle.font = (PresenterFont)font.Clone();
                trTitle.font.SizeInPoints = (int)(trTitle.font.SizeInPoints * 1.5);
                trTitle.message           = title;
                trTitle.bounds            = rTitle;

                // Data
                GfxTextRegion trData = new GfxTextRegion();

                ctx.textRegions.Add(trData);
                trData.font = (PresenterFont)font.Clone();
                trData.font.VerticalAlignment   = VerticalAlignment.Top;
                trData.font.HorizontalAlignment = HorizontalAlignment.Left;
                trData.fontClip = true;
                trData.message  = data;
                trData.bounds   = rText;
            }
コード例 #10
0
        public void DetachProject()
        {
            if (proj != null && ehRefresh != null)
            {
                proj.Refresh -= ehRefresh;
            }
            this.proj = null;
            ehRefresh = null;

            // Reset variables
            hitMapping.Clear();
            verseRectMapping.Clear();
            highlightedVerse = null;
            scrollerPos      = 0;
            scrollerRatio    = 1;
            scrollerHeight   = 0;
            searchTerms.Clear();
        }
コード例 #11
0
ファイル: BibleSearchPnl.cs プロジェクト: radtek/epresenter
        internal BibleVerse CopyCurrentVerse()
        {
            if (this.lbBibleBook.SelectedIndex == -1 ||
                this.lbBibleChapter.SelectedIndex == -1 ||
                this.lbBibleVerse.SelectedIndex == -1)
            {
                return(null);
            }

            // Build start verse
            BibleVerse bv = new BibleVerse();

            bv.RefBook    = ((BookData)this.lbBibleBook.SelectedItem).mappingName;
            bv.RefChapter = this.lbBibleChapter.SelectedIndex + 1;
            bv.RefVerse   = ((VerseData)this.lbBibleVerse.SelectedItem).num;
            bv.Text       = ((VerseData)this.lbBibleVerse.SelectedItem).text;
            return(bv);
        }
コード例 #12
0
ファイル: BibIndexer.cs プロジェクト: radtek/epresenter
        public List <BibleVerse> VersesFromIds(List <int> ids)
        {
            List <BibleVerse> bl = new List <BibleVerse>();

            // Convert to BibleVerse
            foreach (int ikey in ids)
            {
                byte[] bytes = BitConverter.GetBytes(ikey);

                BibleVerse bv = new BibleVerse();
                bv.RefVersion = bytes[3] == 1 ? "RST" : "KJV";
                bv.RefBook    = BookFromId((int)bytes[2]);
                bv.RefChapter = bytes[1];
                bv.RefVerse   = bytes[0];
                bl.Add(bv);
            }

            return(bl);
        }
コード例 #13
0
 private void proj_refresh(object sender, EventArgs e)
 {
     // Check translation changes && chapter changes
     if (hitMapping != null && hitMapping.Count > 0) // Update only if init
     {
         BibleVerse bv = hitMapping[verseRectMapping[1]];
         if (bv.RefVersion != Program.ConfigHelper.BiblePrimaryTranslation ||
             currentChapter != proj.bibVerses[1].RefChapter)
         {
             CalculateItems();
             this.Refresh();
         }
         else
         {
             CenterToCurrentVerse();
             this.Refresh();
         }
     }
 }
コード例 #14
0
        protected override void OnMouseDoubleClick(MouseEventArgs e)
        {
            base.OnMouseDoubleClick(e);

            BibleVerse bv = null;

            foreach (Rectangle r in hitMapping.Keys)
            {
                Rectangle r2 = r;
                r2.Y -= HitAdjust;
                if (r2.Contains(e.Location))
                {
                    bv = hitMapping[r];
                }
            }
            if (bv != null)
            {
                proj.GotoVerse(bv.RefVerse); // This will trigger this control to refresh
                proj.Activate();
            }
        }
コード例 #15
0
        public int Compare(BibleSearchResult a, BibleSearchResult b)
        {
            BibleVerse x   = a.bibVerse;
            BibleVerse y   = b.bibVerse;
            int        ixa = Program.BibleDS.BibleLookUp.FindByVersionIdMappingBook(x.RefVersion, x.RefBook).OrderNum;
            int        ixb = Program.BibleDS.BibleLookUp.FindByVersionIdMappingBook(x.RefVersion, y.RefBook).OrderNum;

            if (ixa == ixb)
            {
                if (x.RefChapter == y.RefChapter)
                {
                    return(x.RefVerse.CompareTo(y.RefVerse));
                }
                else
                {
                    return(x.RefChapter.CompareTo(y.RefChapter));
                }
            }
            else
            {
                return(ixa.CompareTo(ixb));
            }
        }
コード例 #16
0
        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
            {
                return; // Swallow non left clicks
            }
            base.OnMouseDown(e);
            Rectangle scrollerRect = new Rectangle(0, ScrollerY, 16, scrollerHeight);

            // Update cursor
            if (e.X <= 16)
            {
                if (scrollerRect.Contains(e.Location))
                {
                    this.scrolling   = true;
                    scrollMDownY     = e.Y;
                    scrollPosAtMDown = scrollerPos;
                }
            }

            BibleVerse bv = null;

            foreach (Rectangle r in hitMapping.Keys)
            {
                Rectangle r2 = r;
                r2.Y -= HitAdjust;
                if (r2.Contains(e.Location))
                {
                    bv = hitMapping[r];
                }
            }
            if (bv != null)
            {
                proj.GotoVerse(bv.RefVerse); // This will trigger this control to refresh
            }
        }
コード例 #17
0
 protected override void OnMouseLeave(EventArgs e)
 {
     base.OnMouseLeave(e);
     highlightedVerse = null;
     this.Refresh();
 }
コード例 #18
0
        protected override void OnPaint(PaintEventArgs e)
        {
            /// Function summary:
            /// - Items are layed out based on scroll position
            /// - Items that are closer to the current verse number are painted in a darker color
            /// - Scroll bar is painted based on scrollpos

            if (hitMapping == null || proj == null || proj.bibVerses.Count == 0 || proj.currentVerseNum == -1)
            {
                return;
            }

            int   spacing   = 1;
            int   indent    = 16;
            int   textwidth = this.Width - spacing - indent;
            Color lightBlue = Color.FromArgb(201, 215, 233);
            Color blue      = Color.FromArgb(164, 186, 217);

            // Paint items
            int adjust = HitAdjust;

            for (int i = 1; i <= proj.bibVerses.Count; i++)
            {
                BibleVerse bv        = proj.bibVerses[i];
                string     paintText = bv.RefVerse + ". " + bv.Text;
                Rectangle  r         = verseRectMapping[i];
                r.Y -= adjust;
                Rectangle rText = new Rectangle(spacing + indent, r.Y + 2, textwidth, r.Height);

                // Search term support
                StringFormat sf = new StringFormat();
                sf.SetMeasurableCharacterRanges(SearchHelper.FindCharacterRanges(paintText, searchTerms));

                // Paint highlight for highlighted verse
                if (bv == highlightedVerse)
                {
                    e.Graphics.FillRectangle(Brushes.LightGray, r);
                }

                // Paint for verse selection range
                if (bv.RefVerse >= proj.selectionRangeStartVerse && bv.RefVerse <= proj.selectionRangeEndVerse)
                {
                    e.Graphics.FillRectangle(new SolidBrush(lightBlue), r);
                }

                // Paint background for the selected verse
                if (i == proj.currentVerseNum)
                {
                    e.Graphics.FillRectangle(new SolidBrush(blue), r);
                }

                // Fill in the highlights
                foreach (Region rg in e.Graphics.MeasureCharacterRanges(paintText, this.Font, rText, sf))
                {
                    e.Graphics.FillRegion(new SolidBrush(Color.FromArgb(100, Color.Orange)), rg);
                }

                // Calculate text color
                int    proximity  = Math.Abs(i - proj.currentVerseNum);
                double percentage = (double)proximity / 3; // range of the color fade is 3
                if (percentage > 1)
                {
                    percentage = 1;                            // Cut off at 3
                }
                int        grayValue = (int)(percentage * 90); // 0 is black ... after 3 all is at 90/255 gray
                Color      gray      = Color.FromArgb(grayValue, grayValue, grayValue);
                SolidBrush sb        = new SolidBrush(gray);

                // Text
                e.Graphics.DrawString(paintText, this.Font, sb, rText); // Verse text
            }

            // Paint the scrollbar
            if (scrollerRatio < 1)
            {
                if (scrollerHeight < 42)
                {
                    scrollerHeight = 42;
                }
                int       scrollery  = ScrollerY;
                Image     srollerimg = global::EmpowerPresenter.Properties.Resources.scrollslider;
                Rectangle st         = new Rectangle(0, 0, srollerimg.Width, srollerimg.Width);
                Rectangle sm         = new Rectangle(0, srollerimg.Width, srollerimg.Width, srollerimg.Height - 2 * srollerimg.Width);
                Rectangle sb         = new Rectangle(0, srollerimg.Height - srollerimg.Width, srollerimg.Width, srollerimg.Width);
                e.Graphics.DrawImage(srollerimg, new Rectangle(0, scrollery, 16, srollerimg.Width), st, GraphicsUnit.Pixel);
                e.Graphics.DrawImage(srollerimg, new Rectangle(0, scrollery + srollerimg.Width, 16, scrollerHeight - 2 * srollerimg.Width), sm, GraphicsUnit.Pixel);
                e.Graphics.DrawImage(srollerimg, new Rectangle(0, scrollery + scrollerHeight - srollerimg.Width, 16, srollerimg.Width), sb, GraphicsUnit.Pixel);
                Image dotsimg = global::EmpowerPresenter.Properties.Resources.scrollerdots;
                int   dotspos = (int)((scrollerHeight - dotsimg.Height) / 2);
                e.Graphics.DrawImage(dotsimg, new Rectangle(4, dotspos + scrollery, dotsimg.Width, dotsimg.Height),
                                     new Rectangle(0, 0, dotsimg.Width, dotsimg.Height), GraphicsUnit.Pixel);
            }
        }
コード例 #19
0
            public bool PrepSlideDoubleVerse(GfxContext ctx, Dictionary <int, BibleVerse> bibVerses, int currentVerseNum, PresenterFont font)
            {
                #region Format data
                BibleVerse bva        = bibVerses[currentVerseNum];
                BibleVerse bvb        = bibVerses[currentVerseNum + 1];
                string     firstText  = bva.RefVerse + ". " + bva.Text;
                string     secondText = bvb.RefVerse + ". " + bvb.Text;
                string     reference  = bva.ToString() + "-" + bvb.RefVerse;
                #endregion

                Size nativeSize = DisplayEngine.NativeResolution.Size;

                #region Measure
                StringFormat sf           = GetStringFormat();
                int          insideHeight = nativeSize.Height - paddingPixels * 2;
                int          insideWidth  = nativeSize.Width - paddingPixels * 2;
                Point        anchorTop    = new Point(paddingPixels, paddingPixels);
                Point        anchorBottom = new Point(paddingPixels, paddingPixels + (int)((double)insideHeight / 2));

                // Measure the reference blocks
                int refemSize      = (int)(font.SizeInPoints * .9); // actual drawing size is smaller than usual
                int refBlockHeight = (int)(font.SizeInPoints * 1.2);

                // Determine top of rectangle
                // Measure both strings
                RectangleF r = new RectangleF(paddingPixels, 0, insideWidth,
                                              InternalMeasureString(firstText, font, insideWidth, sf).Height);
                int h1      = (int)r.Height; // Get the size of the verse so we can fix the reference at the bottom
                int h2      = (int)InternalMeasureString(secondText, font, insideWidth, sf).Height;
                int offsetY = (int)(((double)insideHeight - h1 - h2 - refBlockHeight) / 2);
                if (font.VerticalAlignment == VerticalAlignment.Top)
                {
                    r.Y = paddingPixels;
                }
                else if (font.VerticalAlignment == VerticalAlignment.Middle)
                {
                    r.Y = offsetY;
                }
                else
                {
                    r.Y = nativeSize.Height - paddingPixels * 2 - h1 - h2 - refBlockHeight;
                }

                // Size check
                int standardMax = (int)((double)insideHeight / 2);
                if (h1 + h2 + refBlockHeight > standardMax)
                {
                    return(false);
                }
                #endregion

                #region Build context

                ctx.destSize = DisplayEngine.NativeResolution.Size;
                ctx.textRegions.Clear();

                // Draw the first part
                GfxTextRegion rVerse = new GfxTextRegion();
                ctx.textRegions.Add(rVerse);
                rVerse.font = font;
                rVerse.font.HorizontalAlignment = HorizontalAlignment.Left;
                rVerse.message = firstText;
                rVerse.bounds  = r;

                GfxTextRegion rVerse2 = new GfxTextRegion();
                ctx.textRegions.Add(rVerse2);
                rVerse2.font    = font;
                rVerse2.message = secondText;
                r.Y            += h1 + refemSize;
                r.Height        = h2;
                rVerse2.bounds  = r;

                // Reference
                GfxTextRegion rRef = new GfxTextRegion();
                ctx.textRegions.Add(rRef);
                rRef.font = (PresenterFont)font.Clone();
                SetRefFont(rRef.font);
                rRef.message       = reference;
                r.Y               += h2 + refBlockHeight - refemSize; // Move to the bottom of the rectangle
                rRef.bounds        = r;
                rRef.bounds.Height = refBlockHeight;

                #endregion

                return(true);
            }
コード例 #20
0
        private void LoadBibDat(BibleVerse verse)
        {
            // Understanding the databse
            // SELECT FIRST 10 * FROM BIBLEVERSES
            // SELECT DISTINCT VERSION FROM BIBLEVERSES
            // SELECT DISTINCT BOOK FROM BIBLEVERSES

            // Verses are queried in the number scheme of the primary translation
            // KJV Psalms 23 == RST Psalms 22
            // SELECT FIRST 10 * FROM BIBLEVERSES AS PRI WHERE PRI.VERSION = 'RST' AND PRI.BOOK = 'Psalms'

            // Old implementation of the Bibleverse table
            // KJV | Ref book = original KJV numbering | Book = RST equivalent numbering
            // RST | Ref book = original RST numbering | Book = KJV equivalent numbering
            // One advantage of the old method is that ability to preload all the version of a chapter relative to the primary translation

            // PENDING: This code needs to be refactored to use a universal numbering scheme
            // https://www.biblegateway.com/passage/?search=Psalm+23&version=RUSV
            // KJV | Ref book = KJV numbering | Book = KJV numbering
            // RST | Ref book = KJV numbering | Book = RST numbering

            List <string>     translations = TranslationList();
            List <BibleVerse> verses       = new List <BibleVerse>();

            bibVerses.Clear();
            currentVerseNum = verse.RefVerse;
            using (FBirdTask t = new FBirdTask())
            {
                string select = "SELECT ";
                for (int tnum = 1; tnum <= translations.Count; tnum++)
                {
                    if (tnum > 1)
                    {
                        select += ", ";
                    }
                    select += string.Format("T{0}.REFBOOK, T{0}.REFCHAPTER, T{0}.REFVERSE, T{0}.DATA", tnum);
                }
                string from = " FROM BIBLEVERSES AS T1";
                for (int transIx = 1; transIx < translations.Count; transIx++)
                {
                    bool doMaping = translations[0] == "KJV" || translations[transIx] == "KJV";
                    if (doMaping)
                    {
                        from += string.Format(" LEFT JOIN BIBLEVERSES AS T{0} ON T1.BOOK = T{0}.REFBOOK AND T1.CHAPTER = T{0}.REFCHAPTER AND T1.VERSE = T{0}.REFVERSE", (transIx + 1));
                    }
                    else
                    {
                        from += string.Format(" LEFT JOIN BIBLEVERSES AS T{0} ON T1.REFBOOK = T{0}.REFBOOK AND T1.REFCHAPTER = T{0}.REFCHAPTER AND T1.REFVERSE = T{0}.REFVERSE", (transIx + 1));
                    }
                }
                string where = " WHERE T1.VERSION = @Version1 AND T1.REFBOOK = @Book AND T1.REFCHAPTER = @Chapter";
                for (int transIx = 1; transIx < translations.Count; transIx++)
                {
                    where += string.Format(" AND T{0}.VERSION = @Version{0}", (transIx + 1));
                }
                string order = " ORDER BY T1.REFBOOK, T1.REFCHAPTER, T1.REFVERSE, T1.VERSE";

                t.CommandText = select + from + where + order;
                t.Command.Parameters.Add("@Book", FbDbType.VarChar, 50).Value = verse.RefBook;
                t.Command.Parameters.Add("@Chapter", FbDbType.Integer).Value  = verse.RefChapter;
                for (int tnum = 1; tnum <= translations.Count; tnum++)
                {
                    t.Command.Parameters.Add("@Version" + tnum, FbDbType.VarChar, 10).Value = translations[tnum - 1];
                }
                t.ExecuteReader();

                while (t.DR.Read())
                {
                    int        ix     = 0;
                    BibleVerse bVerse = new BibleVerse();
                    bVerse.RefVersion = translations[0];
                    bVerse.RefBook    = t.GetString(ix++);
                    bVerse.RefChapter = t.GetInt32(ix++);
                    bVerse.RefVerse   = t.GetInt32(ix++);
                    bVerse.Text       = t.GetString(ix++);
                    if (translations.Count > 1)
                    {
                        bVerse.SecondaryVersion = translations[1];
                        bVerse.SecondaryBook    = t.GetString(ix++);
                        bVerse.SecondaryChapter = t.GetInt32(ix++);
                        bVerse.SecondaryVerse   = t.GetInt32(ix++);
                        bVerse.SecondaryText    = t.GetString(ix++);
                    }
                    if (translations.Count > 2)
                    {
                        bVerse.TertiaryVersion = translations[2];
                        bVerse.TertiaryBook    = t.GetString(ix++);
                        bVerse.TertiaryChapter = t.GetInt32(ix++);
                        bVerse.TertiaryVerse   = t.GetInt32(ix++);
                        bVerse.TertiaryText    = t.GetString(ix++);
                    }
                    verses.Add(bVerse);
                }
            }
            verses.ForEach(v => bibVerses.Add(v.RefVerse, v));
        }