module Eventloop.Module.DrawTrees.DrawTrees

    ( setupDrawTreesModuleConfiguration

    , drawTreesModuleIdentifier

    , drawTreesPostProcessor

    , showGeneralTreeList

    , rbExampleTree

    , roseExampleTree

    ) where



import Eventloop.Module.DrawTrees.Types

import Eventloop.Utility.Trees.LayoutTree

import Eventloop.Utility.Trees.GeneralTree

import Eventloop.Module.BasicShapes.Types

import Eventloop.Types.Common

import Eventloop.Types.Events

import Eventloop.Types.System





setupDrawTreesModuleConfiguration :: EventloopSetupModuleConfiguration

setupDrawTreesModuleConfiguration = ( EventloopSetupModuleConfiguration 

                                         drawTreesModuleIdentifier

                                         Nothing

                                         Nothing

                                         Nothing

                                         (Just drawTreesPostProcessor)

                                         Nothing

                                         Nothing

                                      )



drawTreesModuleIdentifier :: EventloopModuleIdentifier

drawTreesModuleIdentifier = "parseTree"





drawTreesPostProcessor :: PostProcessor

drawTreesPostProcessor sharedConst sharedIOT ioConst ioStateT (OutDrawTrees (DrawTrees canvasId trees))

    = return [OutBasicShapes $ DrawShapes canvasId [shapeTrees]]

    where

        (shapeTrees, _, _) = showGeneralTreeList trees

        

drawTreesPostProcessor sharedConst sharedIOT ioConst ioStateT out

    = return [out]





maxWidth :: Int

maxWidth = 1024



showGeneralTreeList :: [GeneralTree] -> (Shape, RightOffset, BottomOffset)

showGeneralTreeList list = showGeneralTreeList' 0 0 0 0 list



showGeneralTreeList' :: LeftOffset -> TopOffset -> Float -> Int -> [GeneralTree] -> (Shape, RightOffset, BottomOffset)

showGeneralTreeList' _ _ _ _ [] = (CompositeShape [] Nothing Nothing, 0, 0)

showGeneralTreeList' left top maxBottom i (x:xs) | right <= 1024 || width > 1024 = (CompositeShape (treeShapes ++ gtrees) Nothing Nothing, rightOff', botOff')

                                                 | otherwise = showGeneralTreeList' 0 maxBottom' maxBottom' i (x:xs)

                                               where

                                                   maxBottom' = max maxBottom bottom

                                                   (CompositeShape treeShapes _ _, right, bottom) = showGeneralTree left top i x

                                                   (CompositeShape gtrees _ _, rightOff, botOff) = showGeneralTreeList' (right + marginBetweenTrees) top maxBottom' i' xs

                                                   i' = i + 1

                                                   width = right - left

                                                   rightOff' = max rightOff right

                                                   botOff'   = max bottom botOff



       

showGeneralTree :: LeftOffset -> TopOffset -> Int -> GeneralTree -> (Shape, RightOffset, BottomOffset)

showGeneralTree left top i tree =  (CompositeShape [treeIndexShape, treeShape] Nothing Nothing, right, bottom)

                                where

                                    (ltree, right, bottom) = layoutGeneralTree left' top tree

                                    treeShape = printTree ltree

                                    (treeIndexShape, left') = treeIndex i (left, top)



instance GeneralizeTree RBTree where

    generalizeTree (RBNode col _ []) = GeneralTreeBox content []

                                    where

                                        content = [GeneralNode (nodeColorToFillColor col) 5]

                                                

    generalizeTree (RBNode col str children) = GeneralTreeBox content children'WithLines

                                            where

                                                content = [GeneralNode (nodeColorToFillColor col) 20, GeneralNodeText (0,0,0, 255) str]

                                                children' = map generalizeTree children

                                                line = GeneralLine (0,0,0, 255)

                                                children'WithLines = zip (repeat line) children'



nodeColorToFillColor :: NodeColor -> FillColor

nodeColorToFillColor NodeRed   = (255, 0, 0, 255)

nodeColorToFillColor NodeBlack = (0, 0, 0, 255)

nodeColorToFillColor NodeGrey  = (125, 125, 125, 255)

                  

                 

instance GeneralizeTree RoseTree where

    generalizeTree (RoseNode str children) = GeneralTreeBox content children'WithLines

                                            where

                                                content = [GeneralNodeText (0,0,0, 255) str]

                                                children'WithLines = zip (repeat line) (map generalizeTree children)

                                                line = GeneralLine (0,0,0, 255)   

                        

rbExampleTree = RBNode NodeBlack "12"

                        [ RBNode NodeRed "10"

                                    [ RBNode NodeBlack "9"

                                                [ RBNode NodeBlack "" [],

                                                  RBNode NodeBlack "" []

                                                ],

                                      RBNode NodeBlack "11"

                                                [RBNode NodeBlack "" [],

                                                 RBNode NodeBlack "" []

                                                ]

                                    ],

                          RBNode NodeRed "13"

                                    [RBNode NodeBlack "36" [],

                                     RBNode NodeBlack "42"

                                               [RBNode NodeRed "36"

                                                          [RBNode NodeBlack "" [],

                                                           RBNode NodeBlack "" []

                                                          ],

                                                RBNode NodeBlack "" []

                                               ]

                                    ]

                        ]

                        

roseExampleTree = RoseNode "z"

                        [ RoseNode "aaa"

                                    [ RoseNode "bbb"

                                                [ RoseNode "ccc" [],

                                                  RoseNode "ddd" []

                                                ],

                                      RoseNode ""

                                                [RoseNode "fff" [],

                                                 RoseNode "ggg" [],

                                                 RoseNode "hhh" []

                                                ],

                                      RoseNode "iii"

                                                [RoseNode "" []

                                                ]

                                    ],

                          RoseNode "kkk"

                                    [RoseNode "lll" [],

                                     RoseNode "mmm"

                                               [RoseNode "nnn"

                                                          [RoseNode "q" [],

                                                           RoseNode "r" []

                                                          ],

                                                RoseNode "ooo" [],

                                                RoseNode "ppp" []

                                               ]

                                    ]

                        ]