open import FRP.JS.Bool using ( Bool ; true ; false ; not ; _∨_ )
open import FRP.JS.True using ( True )
open import FRP.JS.Maybe using ( Maybe ; just ; nothing )
open import FRP.JS.Primitive using (; String )

module FRP.JS.Float where

infixr 4 _≤_ _<_ _≟_ _≠_
infixl 6 _+_ _-_
infixl 7 _*_ _/_ _/?_

open import FRP.JS.Primitive public using ()

primitive
  primFloatPlus      :  ->  -> 
  primFloatMinus     :  ->  -> 
  primFloatTimes     :  ->  -> 
  primFloatDiv       :  ->  -> 
  primFloatLess      :  ->  -> Bool
  primFloor          :  -> 
  primCeiling        :  -> 
  primExp            :  -> 
  primLog            :  -> 
  primSin            :  -> 
  primShowFloat      :  -> String
  primShowInteger    :   String
  primIntegerToFloat :   

_+_   = primFloatPlus
_-_   = primFloatMinus
_*_   = primFloatTimes
_<_   = primFloatLess
⌊_⌋   = primFloor
⌈_⌉   = primCeiling
exp   = primExp
log   = primLog
sin   = primSin

{-# COMPILED_JS _+_   function(x) { return function(y) { return x + y; }; } #-}
{-# COMPILED_JS _-_   function(x) { return function(y) { return x - y; }; } #-}
{-# COMPILED_JS _*_   function(x) { return function(y) { return x * y; }; } #-}
{-# COMPILED_JS _<_   function(x) { return function(y) { return x < y; }; } #-}
{-# COMPILED_JS ⌊_⌋   Math.floor #-}
{-# COMPILED_JS ⌈_⌉   Math.ceil #-}
{-# COMPILED_JS exp   Math.exp #-}
{-# COMPILED_JS log   Math.log #-}
{-# COMPILED_JS sin   Math.sin #-}

-_ :   
- x = 0.0 - x

_≠_ :     Bool
(x  y) = (x < y)  (y < x)

_≟_ :     Bool
(x  y) = not (x  y)

_≤_ :     Bool
(x  y) = not (y < x)

-- Some hoop-jumping to avoid division by zero, so we don't end up with
-- Infinity, -Infinity or NaN.

_/_ : (x y : )  {y≠0 : True (y  0.0)}  
x / y = primFloatDiv x y

_/?_ :     Maybe 
x /? 0.0 = nothing
x /? y   = just (primFloatDiv x y)

show :   String
show x 
 with (x  primIntegerToFloat  x )
... | true  = primShowInteger  x 
... | false = primShowFloat x

{-# COMPILED_JS -_   function(x) { return -x; } #-}
{-# COMPILED_JS _≠_ function(x) { return function(y) { return x !== y; }; } #-}
{-# COMPILED_JS _≟_ function(x) { return function(y) { return x === y; }; } #-}
{-# COMPILED_JS _≤_  function(x) { return function(y) { return x <= y; }; } #-}
{-# COMPILED_JS _/_  function(x) { return function(y) { return function() { return x / y; }; }; } #-}
{-# COMPILED_JS _/?_  function(x) { return function(y) { if (y === 0) { return null; } else { return x / y; } }; } #-}
{-# COMPILED_JS show  function(x) { return x.toString(); } #-}