DrawCompiledGraphics1

module DrawCompiledGraphics1(drawK',drawChangesK',GCId) where
--import Fudget
import Xtypes
import XDraw(DrawCommand(FillRectangle),clearArea,draw,drawMany,Drawable(..))
import Geometry(growrect,(=.>),Rect(rectsize))
--import Message
--import NullF(putsK,putK)
import Utils(number)
--import EitherUtils(mapfilter)
import Data.Maybe(mapMaybe)
import CompiledGraphics
--import Rects
--import Maptrace(ctrace) -- debug
--import Io(echoK) -- debug
import FudgetIO(putLow)

--tr x = seq x $ ctrace "drawtrace" x x
--trLow = Low . tr
--trLow = tr . Low
--maptrLow = map trLow
--debugK = echoK

--drawK = drawK' MyWindow
drawK' d (higc,hiR) clip cg =
    case draw cg [] of
      [] -> id
      cmds -> putLow $ drawMany d cmds
  where
    draw (CGMark cg) = draw cg
    draw (CGraphics r cur cmds gs) =
      (if cur
       then ((higc,[FillRectangle cr | hr<-hiR r,cr<-clip hr]):)
       else id).
      (cmds++) .
      draws gs
    draws [] = id
    draws (g:gs) = draw g . draws gs

drawChangesK' d beQuick higc  (CGMark cg) (CGMark ocg) changes =
    --debugK (show [ ps | ps<-changes, take 1 ps/=[0]]) .
    drawChangesK' d beQuick higc cg ocg (mapMaybe drop0 changes)
  where drop0 [] = Just []
        drop0 (0:ps) = Just ps
	drop0 _ = Nothing

drawChangesK' d beQuick higc  cg@(CGraphics r  _ cmds cgs )
                          ocg@(CGraphics or _ ocmds ocgs) changes =
    --debugK (unwords ["Changes:",show changes,"or",show or,"nr",show r]) .
    if r/=or || [] `elem` changes
       -- Hack for overlapping parts:
       || not (null changes || null cmds && null ocmds)
    then --debugK "Drawing" .
         -- !! test if scrolling is enough
	 eraseOldK d r or .
         reDrawK' d beQuick higc cg
    else if null changes
         then --debugK "Pruning" .
	      id
	 else --debugK "Descending" .
	      let changes' i= [ p | i':p <- changes, i'==i]
	      in foldr (.) id [drawChangesK' d beQuick higc cg ocg (changes' i) |
				(i,(cg,ocg))<-number 1 (zip cgs ocgs)]
drawChangesK' d beQuick higc  cg ogc _ =
    --debugK "drawNewK" .
    drawNewK cg
  where
    drawNewK (CGMark cg) = drawNewK cg
    drawNewK cg@(CGraphics r _ _ _) =
      eraseOldK d r (cgrect ogc) .
      reDrawK' d beQuick higc cg

eraseOldK Nothing newrect oldrect =
  -- It's enough to clear the part of oldrect that is outside newrect.
  ifK (newrect/=oldrect)
      (putLow $ clearArea (growrect oldrect 1) False)
eraseOldK (Just (d,cleargc)) newrect oldrect =
  ifK (newrect/=oldrect)
      (putLow $ draw d cleargc (FillRectangle (growrect oldrect 1)))

reDrawK' d beQuick higc (CGMark cg) = reDrawK' d beQuick higc cg
reDrawK' Nothing beQuick higc cg@(CGraphics r _ _ _) =
  -- When drawing directly in a window:
  if (not beQuick || rectsize r =.> 400) -- heuristic
  then -- for big areas: wait for exposure event and draw only the
       -- visible part
       putLow (clearArea r True)
  else -- for small areas: draw everything immediately (reduced flicker)
       putLow (clearArea r False) . drawK' MyWindow higc (:[]) cg
reDrawK' (Just (d,cleargc)) beQuick higc cg@(CGraphics r _ _ _) =
       -- For drawing in a back buffer or a pixmap (assumes d/=MyWindow):
       putLow (draw d cleargc (FillRectangle r)) .
       drawK' d higc (:[]) cg

ifK b k = if b then k else id