```{-# LANGUAGE DeriveDataTypeable #-}
{- |
Copyright   :  (c) Claude Heiland-Allen 2011

Maintainer  :  claudiusmaximus@goto10.org
Stability   :  unstable
Portability :  portable

Simple substitution tiling with each square divided into four quadrants
(with no rotation).
-}
, module Data.Tiling.Class
) where

import Data.Data (Data)
import Data.Typeable (Typeable)
import Data.Bits (bit, shiftL, shiftR, testBit, (.|.))
import Data.List (unfoldr)
import Data.Ratio ((%))

import Data.Tiling.Class

-- | A square tile.
deriving (Read, Show, Eq, Ord, Data, Typeable)

-- | Substitution tiling for square tiles.
root = Quad 0 0 0
parent q = snd `fmap` quadParent q
exterior (Quad l x y) =
let d = bit l
in  rectangle (x % d) ((x + 1) % d) (y % d) ((y + 1) % d)
interior = exterior
inside   q r = exterior q `insideR` r
encloses q r = r `insideR` interior q
outside  q r = exterior q `outsideR` r
overlaps q r = exterior q `overlapsR` r

data Quadrant = NorthWest | NorthEast | SouthWest | SouthEast
deriving (Read, Show, Eq, Ord, Enum, Bounded, Data, Typeable)

isNorth, isSouth, isWest, isEast :: Quadrant -> Bool
isEast c = fromEnum c `testBit` 0
isSouth c = fromEnum c `testBit` 1
isNorth = not . isSouth
isWest = not . isEast

-- | The child tile at a given quadrant.
{ quadLevel = l + 1
, quadWest  = x `shiftL` 1 .|. (fromIntegral . fromEnum . isEast ) c
, quadNorth = y `shiftL` 1 .|. (fromIntegral . fromEnum . isSouth) c
}

-- | The parent with quadrant information for the tile.  Satisfies:
--
| l > 0  = Just
( toEnum (fromEnum (y `testBit` 0) `shiftL` 1 .|. fromEnum (x `testBit` 0))
)
| otherwise = Nothing

-- | The path from this tile to the root.  Satisfies:
--

-- | Suggested file system location for data pertaining to a 'Quad'.