A group for use in PileArrays (PileArray.lhs).

\begin{code}
module Group where
import IOExts
import FranCore
import Monad
import List
import Maybe
import Ix
import Identify
import PlacePos
\end{code}

the unique eltname for elements of a pilearray
\begin{code}
newtype EltName = EltName Int
 deriving (Eq,Ord,Ix)

toElt :: Int -> EltName
fromElt :: EltName -> Int
toElt = EltName
fromElt (EltName a) = a

instance Show EltName where
 showsPrec d n = showString $ "toElt" ++ (show $ fromElt n)

instance Read EltName where
 readsPrec d ('t':'o':'E':'l':'t':xs) = 
   case readsPrec d xs of
     [(n,xs')] -> [(toElt n,xs')]
\end{code}

A groupref is mutable object, with a unique name, some members, and 
a pointer set, pointing to the top element, bottom element and visible
top and bottom elements of the group.
\begin{code}

type GroupRef = IORef GroupData

data GroupData = GroupData {posPointers :: PosPointers,
			    groupMembers :: [EltName],
			    groupName :: Ident}


data PosPointers = PosPointers {topName :: Maybe EltName,
			        bottomName :: Maybe EltName,
				visTopName :: Maybe EltName,
				visBottomName :: Maybe EltName}

initPosPointers :: PosPointers
initPosPointers = PosPointers Nothing Nothing Nothing Nothing
 
initGroupData :: Ident -> GroupData
initGroupData n = GroupData initPosPointers [] n
\end{code}

There are operations to make a group, insert an elemetn in a group,
and delete an element from the group. Note that code in the PileArray
module handles updating the pospointers of a group when an element 
is deleted. Therefore only use mkGroupRef yourself.

\begin{code}

mkGroupRef :: Ident -> IO GroupRef
mkGroupRef n = newIORef $ initGroupData n

insertInGroup :: GroupRef -> EltName -> IO ()
insertInGroup gr e = do
 gd <- readIORef gr
 writeIORef gr $ gd {groupMembers = e:groupMembers gd}

deleteFromGroup :: GroupRef -> EltName -> IO ()
deleteFromGroup gr e = do
 gd <- readIORef gr
 writeIORef gr $ gd {groupMembers = delete e $ groupMembers gd}

\end{code}
