module FPPrac.Trees.LayoutTree 
        ( LayoutTree(..)
        , LayoutNodeContent(..)
        , LayoutLine(..)
        , TopConnect
        , BottomConnect
        , Radius
        , printTree
) where

import EventLoop.Output
import EventLoop.Output.Single
import EventLoop.CommonTypes

data LayoutTree = LBox Pos TopConnect BottomConnect [LayoutNodeContent] [(LayoutLine, LayoutTree)] deriving (Show)

data LayoutNodeContent = LayoutNodeText Color Pos String Dimension
                       | LayoutNode Color Pos Radius
                       deriving (Show)
                       
data LayoutLine = LayoutLine Color
                deriving (Show)

type TopConnect = Connect
type BottomConnect = Connect
type Connect = Pos
type Radius = Float
type Offset = Pos

marginLine = 3 :: Float
lineThickness = 2 :: Float
textFont = "Courier"
----------------------------------------------------------

absolutePos :: Pos -> Pos -> Pos
absolutePos (offsetx, offsety) (relx, rely) = (offsetx + relx, offsety + rely)

printTree :: LayoutTree -> GObject
printTree (LBox pos _ botConnect nodeContents childrenWithLines) = Container (gChildren ++ gLines ++ gContents)
                                                where
                                                    children = map snd childrenWithLines
                                                    gChildren = map printTree children
                                                    gContents = map (printNodeContent pos) nodeContents
                                                    gLines = map (printLine (botConnect')) childrenWithLines
                                                    botConnect' = absolutePos pos botConnect
                                                    

                                                    
printNodeContent :: Offset -> LayoutNodeContent -> GObject
printNodeContent (xOffset, yOffset) (LayoutNodeText color (x,y) str (_, height)) = GObject "nodetext" (Text color 1 color (x + xOffset, y + yOffset) height textFont str True) []
printNodeContent (xOffset, yOffset) (LayoutNode color (x,y) rad)                 = GObject "node" (Arc (0,0,0) 0 color (x + xOffset, y + yOffset) rad 0 360) []

printLine :: Pos -> (LayoutLine, LayoutTree) -> GObject
printLine startPos ((LayoutLine lineColor),(LBox pos topConnect _ _ _)) = GObject "line" (Line lineColor lineThickness [startMarg, endMarg]) []
                                                                        where
                                                                            startMarg = marginizePosition marginLine startPos endPos
                                                                            endMarg   = marginizePosition marginLine endPos startPos
                                                                            endPos    = absolutePos pos topConnect
         
marginizePosition :: Float -> Pos -> Pos -> Pos
marginizePosition margin (xStart, yStart) (xEnd, yEnd) = (xStart', yStart')
                            where
                                xStart'  = xStart + fraction * xSize
                                yStart'  = yStart + fraction * ySize
                                fraction = margin / size
                                size     = sqrt (xSize^2 + ySize^2)
                                xSize    = xEnd - xStart
                                ySize    = yEnd - yStart