------------------------------------------------------------------
-- |
-- Module      :  Data.JSRef
-- Copyright   :  (c) Dmitry Golubovsky, 2009
-- License     :  BSD-style
-- 
-- Maintainer  :  golubovsky@gmail.com
-- Stability   :  experimental
-- Portability :  portable
-- 
--
--
-- Mutable Javascript reference objects
------------------------------------------------------------------

module Data.JSRef (
  JSRef
 ,newJSRef
 ,readJSRef
 ,writeJSRef
) where

import Language.JSMW.Monad
import Data.DOM
import BrownPLT.JavaScript

-- | An opaque data type parameterized by the type of the stored value.

data JSRef a = JSRef a

-- | Create a mutable Javascript reference object and initialize it.

newJSRef :: Expression a -> JSMW e (Expression (JSRef a))

newJSRef x = do
  let et = JSRef (exprType x)
      obj = ObjectLit et [(PropId et (Id et "_val"), x /\ et)]
  return obj >>= once

-- | Store a value in a mutable Javascript reference object.

writeJSRef :: Expression (JSRef a) -> Expression a -> JSMW e (Expression (JSRef a))

writeJSRef r v = once =<< setjsProperty "_val" v r

-- | Retrieve a value from a mutable Javascript reference object.

readJSRef :: Expression (JSRef a) -> JSMW e (Expression a)

readJSRef r = do
  let et = undefined :: a
      v = DotRef et (r /\ et) (Id et "_val")
  return v