local base = require("packages.base")

local package = pl.class(base)
package._name = "pagebuilder-bestfit"

local MAX_PAGES = 5

function package:_init ()
   base._init(self)
   SILE.typesetter.buildPage = function (typesetter, independent)
      -- Find last penalty
      local q = typesetter.state.outputQueue
      local lastpenalty = -1
      local cHeight = SILE.types.length()
      for j = #q, 1, -1 do
         if q[j].is_penalty and lastpenalty == -1 then
            lastpenalty = q[j].penalty
         end
         cHeight = cHeight + q[j].height
      end
      if not (cHeight > typesetter.frame:height() * MAX_PAGES) and not independent and lastpenalty > -10000 then
         return false
      end
      SU.debug("pagebuilder", "Finally running pagebuilder")
      repeat
         q = typesetter.state.outputQueue
         local breaks = SILE.linebreak:doBreak(q, typesetter.frame:height(), true)
         --Height is variable! therefore only the first break is believable
         local point = breaks[1]
         if point.position == 0 then
            return false
         end
         local linestart = 1
         local slice = {}
         local newslice = {}
         for j = linestart, #typesetter.state.outputQueue do
            if j <= point.position then
               slice[#slice + 1] = q[j]
            else
               newslice[#newslice + 1] = q[j]
            end
         end
         typesetter:setVerticalGlue(slice, typesetter.frame:height())
         typesetter:outputLinesToPage(slice)
         typesetter.state.outputQueue = newslice
         if #typesetter.state.outputQueue == 0 then
            return false
         end
         typesetter:initNextFrame() -- This causes a tail call if there is more stuff waiting
      -- If not, we keep going if we are being asked to ship out a page now now now.
      until lastpenalty > -10000
      return false -- because we have already dealt with initializing the next frame
   end
end

package.documentation = [[
\begin{document}
Many of SILE’s core algorithms are borrowed from TeX, including the page builder.
While TeX’s \em{paragraph} builder uses the “best-fit” algorithm, trying multiple different paragraphing options to find the best justification, the page builder takes a more simple “first-fit” approach, shipping out a page as soon as the page target is met.
This experimental package uses the \em{paragraph} builder to build \em{pages}, applying the best-fit method to the set of vertical boxes and the vertical target instead of a set of horizontal boxes and a horizontal target.
\end{document}
]]

return package
