module Model.GridHeader (Header,new,addDependent,deleteDependent ,dependents,allDependents,index,setLabel ,insertLabelBefore,delete,label) where import Control.Applicative ((<$>)) import Control.Monad (forM) import qualified Data.List as List import Data.Ix (range) import Util.DynArray (DynArray) import qualified Util.DynArray as Dyn import CellCoordinate (CellCoord) type Label = String type Info = (Label,[CellCoord]) type Header = DynArray Int Info new :: IO Header new = Dyn.newLinearArray 0 ("",[]) setLabel :: Label -> Int -> Header -> IO () setLabel label to = Dyn.update to (\(_,deps) -> (label,deps)) insertLabelBefore :: Label -> Int -> Int -> Header -> IO () insertLabelBefore label i maxLabelIndex header = do Dyn.insertEmptyIntoLinearArrayBefore i maxLabelIndex header setLabel label i header addDependent :: CellCoord -> Int -> Header -> IO () addDependent dep to = Dyn.update to (\(l,deps) -> (l,dep:deps)) deleteDependent :: CellCoord -> Int -> Header -> IO () deleteDependent dep from = Dyn.update from (\(l,deps) -> (l,List.delete dep deps)) label :: Int -> Header -> IO Label label i header = fst <$> Dyn.read i header dependents :: Int -> Header -> IO [CellCoord] dependents i header = snd <$> Dyn.read i header allDependents :: Header -> IO [CellCoord] allDependents header = do b <- Dyn.bounds header concat <$> (forM (range b) $ \i -> dependents i header) index :: String -> Header -> IO (Maybe Int) index label = Dyn.indexBy (\(l,_) -> label == l) delete :: [Int] -> Header -> IO () delete = Dyn.deleteInLinearArray