protected virtual PageOnScreen GetInitialPage(ref PositionInBook position, Size screenSize)
 {
     // Find physical page at position
     PageOnScreen curPage = NewPage(position.PageNum, screenSize);
     curPage.TopOnScreen = position.GetTopOnScreen(curPage.Layout.Bounds.Height);
     return curPage;
 }
        /// <summary>
        /// Assemble screen -- return a list of pages for the screen with TopOnScreen set
        /// </summary>
        /// <param name="position"></param>
        /// <param name="screenSize"></param>
        /// <returns></returns>
        public List<PageOnScreen> AssembleScreen(ref PositionInBook position, Size screenSize) 
        {
            ArgCheck.NotNull(position, "newPosition");
            if (!CanApply(position, screenSize)) { throw new InvalidOperationException("Cannot apply at: " + position); }

            // Get the initial page. 
            // Does not necessarily return page at position -- in case of next, will advance it by one page.
            PageOnScreen curPage = GetInitialPage(ref position, screenSize);

            // Stack the pages
            List<PageOnScreen> pageContents = new List<PageOnScreen>();
            while (true)
            {
                pageContents.Add(curPage);

                if (ScreenFull(curPage, screenSize)) { break; }

                AdvancePage(ref curPage, screenSize);
            }

            // Update position based on the topmost page (with lowest page num)
            int minPageNum = pageContents.Min(x => x.PageNum);
            PageOnScreen topPage = pageContents.Find(x => x.PageNum == minPageNum);
            position = PositionInBook.FromPhysicalPage(topPage.PageNum, PageCount,
                topPage.TopOnScreen, topPage.Layout.Bounds.Height);

            return pageContents;
        }
 /// <summary>
 /// True if algorithm can be applied in the given state.
 /// (e.g. if moving back, it would apply to all positions except the start).
 /// </summary>
 /// <param name="position"></param>
 /// <param name="screenSize"></param>
 /// <returns></returns>
 public abstract bool CanApply(PositionInBook position, Size screenSize);
        protected override PageOnScreen GetInitialPage(ref PositionInBook position, Size screenSize)
        {
            PageOnScreen curPage = base.GetInitialPage(ref position, screenSize);
            curPage.TopOnScreen += screenSize.Height;

            // Edge case: if page is exactly below the screen, take the next one
            if (curPage.TopOnScreen == screenSize.Height)
            {
                AdvancePage(ref curPage, screenSize);
            }

            // Adjust position
            position = PositionInBook.FromPhysicalPage(curPage.PageNum, PageCount,
                curPage.TopOnScreen, curPage.Layout.Bounds.Height);

            return curPage;
        }
 public override bool CanApply(PositionInBook position, Size screenSize)
 {
     PageOnScreen firstPage = base.GetInitialPage(ref position, screenSize);
     
     return firstPage.PageNum > 1 ||
         // If first page in book, it must overflow above current screen
         firstPage.TopOnScreen < 0;
 }
        protected override PageOnScreen GetInitialPage(ref PositionInBook position, Size screenSize)
        {
            // Assemble current screen
            PageOnScreen curPage = _assembleCurrent.AssembleScreen(ref position, screenSize).Last();

            // Move the last page of current screen up by one screen
            curPage.TopOnScreen -= screenSize.Height;

            // Edge case: if page is exactly above the screen, take the next one
            if (curPage.TopOnScreen == -curPage.Layout.Bounds.Height)
            {
                AdvancePage(ref curPage, screenSize);
            }

            return curPage;
        }
        public override bool CanApply(PositionInBook position, Size screenSize)
        {
            // Get last page of current screen
            // Current screen render won't mess up position
            var pages = _assembleCurrent.AssembleScreen(ref position, screenSize);

            PageOnScreen lastPage = pages.Last();
            return lastPage.PageNum < PageCount ||
                // If last page in book, it must overflow the screen
                lastPage.BottomOnScreen > screenSize.Height;
        }
 public override bool CanApply(PositionInBook position, Size screenSize)
 {
     // Re-rendering current screen always possible
     // Position bounds are guarented already
     return true;
 }