{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}

module DeepCopy where

import qualified Data.Vector as V
import Control.Monad.State.Strict
import Control.Applicative
import Prelude

import Types

class DeepCopy a where
	deepCopy :: a -> M a

instance DeepCopy S where
	deepCopy s = S
		<$> deepCopy (world s)
		<*> deepCopy (flipSide s)
		<*> pure (player s)
		<*> deepCopy (bottomBuffer s)
		<*> pure (topBuffer s)
		<*> pure (peruser s)
		<*> pure (randSource s)
		<*> pure (helpShown s)
		<*> pure (messages s)
		<*> pure (spells s)
		<*> pure (poisons s)
		<*> pure (windows s)

instance DeepCopy (World, World) where
	deepCopy (w1, w2) = (,)
		<$> deepCopy w1
		<*> deepCopy w2

instance DeepCopy World where
	deepCopy w = lift $ V.unsafeThaw =<< V.mapM copyline =<< V.freeze w
	  where
		copyline v = V.freeze v >>= V.unsafeThaw