module Graphics.PS.Query ( startPt, endPt
                         , mkValid
                         , approx, close ) where

import Graphics.PS.Pt
import Graphics.PS.Bezier
import Graphics.PS.Path

-- | Locate the starting point of the path.
startPt :: Path -> Maybe Pt
startPt (MoveTo p) = Just p
startPt (Join p _) = startPt p
startPt _ = Nothing

startPt' :: Path -> Maybe Pt
startPt' (MoveTo p) = Just p
startPt' (LineTo p) = Just p
startPt' (CurveTo p _ _) = Just p
startPt' (Join p _) = startPt' p
startPt' _ = Nothing

-- | Ensure path begins with a MoveTo.
mkValid :: Path -> Path
mkValid p = f (startPt' p)
    where f (Just q) = MoveTo q +++ p
          f Nothing = p

-- | Locate the end point of the path.
endPt :: Path -> Maybe Pt
endPt (MoveTo p) = Just p
endPt (LineTo p) = Just p
endPt (CurveTo _ _ p) = Just p
endPt (Join _ p) = endPt p
endPt _ = Nothing

-- | Add a LineTo the start point of path.
close :: Path -> Path
close p = f (startPt p)
    where f (Just q) = p +++ LineTo q
          f Nothing = p

-- | Approximate curves as straight lines.
approx :: Double -> Path -> Path
approx n (Join a (CurveTo p q r)) = 
    let is = [0, (1.0/n) .. 1.0]
        f (Just p1) p2 p3 p4 = map (bezier4 p1 p2 p3 p4) is
        f Nothing _ _ _ = []
    in a +++ line (f (endPt a) p q r)
approx _ p = p

{--

data BBox = BBox Pt Pt
            deriving (Eq, Show)

import Graphics.PS.Transform

bboxSum :: BBox -> BBox -> BBox
bboxSum (BBox a b) (BBox c d) = BBox (ptMin a c) (ptMax b d)

bbox :: Path -> BBox
bbox (MoveTo p)     = BBox p p
bbox (LineTo p)     = BBox p p
bbox (Join a b)     = bbox a `bboxSum` bbox b
bbox _              = error "illegal Query"

join :: Path -> Path -> Path
join a b = a +++ translate x y b
    where (Pt x y) = endPt a

link :: Path -> Path -> Path
link a b = a +++ LineTo (startPt b) +++ b

relMoveTo :: Path -> Pt -> Path
relMoveTo path (Pt dx dy) = path +++ MoveTo (Pt (x + dx) (y + dy))
    where (Pt x y) = endPt path

relLineTo :: Path -> Pt -> Path
relLineTo path (Pt dx dy) = path +++ LineTo (Pt (x + dx) (y + dy))
    where (Pt x y) = endPt path

hasText :: Path -> Bool
hasText (Join p1 p2) = hasText p1 || hasText p2
hasText (Text _ _) = True
hasText _ = False

--}