{-# LANGUAGE ForeignFunctionInterface #-}
 
module Language.ObjectiveC.Luka.API where

import Foreign hiding (void)
import Foreign.C.Types
import Foreign.C.String

import Prelude ()
import Air.Env
import Control.Monad ((>=>))

import Language.ObjectiveC.Luka.RunTime

import Foreign.LibFFI



get_i :: String -> ID -> IO ID
get_i ivar_name obj = do
    object_getInstanceVariable obj ivar_name >>= object_getIvar obj
      

from_ns_string :: ID -> IO String
from_ns_string = msg_cstring "UTF8String" [] >=> peekCString



with_pool :: IO a -> IO ()
with_pool _io = do
  pool <- class_named "NSAutoreleasePool" >>= msg_obj "alloc" [] >>= msg_obj "init" []
  
  _io
  
  pool .msg "release" []


msg         :: String -> [Arg] -> ID -> IO ()
msg         methodName args obj = sel_named methodName >>= \sel -> objc_msgSend_void    obj sel args

msg_ptr     :: String -> [Arg] -> ID -> IO (Ptr ())                                         
msg_ptr     methodName args obj = sel_named methodName >>= \sel -> objc_msgSend_ptr     obj sel args
                                                                                       
msg_obj     :: String -> [Arg] -> ID -> IO ID                                           
msg_obj     methodName args obj = sel_named methodName >>= \sel -> objc_msgSend_obj     obj sel args
                                                                                        
msg_cint    :: String -> [Arg] -> ID -> IO CInt                                         
msg_cint    methodName args obj = sel_named methodName >>= \sel -> objc_msgSend_cint    obj sel args
                                                                                        
msg_cuint   :: String -> [Arg] -> ID -> IO CUInt                                        
msg_cuint   methodName args obj = sel_named methodName >>= \sel -> objc_msgSend_cuint   obj sel args
                                                                                        
msg_clong   :: String -> [Arg] -> ID -> IO CLong                                        
msg_clong   methodName args obj = sel_named methodName >>= \sel -> objc_msgSend_clong   obj sel args
                                                                                        
msg_culong  :: String -> [Arg] -> ID -> IO CULong                                       
msg_culong  methodName args obj = sel_named methodName >>= \sel -> objc_msgSend_culong  obj sel args
                                                                                        
msg_cfloat  :: String -> [Arg] -> ID -> IO CFloat                                       
msg_cfloat  methodName args obj = sel_named methodName >>= \sel -> objc_msgSend_cfloat  obj sel args
                                                                                        
msg_cdouble :: String -> [Arg] -> ID -> IO CDouble                                      
msg_cdouble methodName args obj = sel_named methodName >>= \sel -> objc_msgSend_cdouble obj sel args
                                                                                        
msg_cchar   :: String -> [Arg] -> ID -> IO CChar                                        
msg_cchar   methodName args obj = sel_named methodName >>= \sel -> objc_msgSend_cchar   obj sel args
                                                                                        
msg_uchar   :: String -> [Arg] -> ID -> IO CUChar                                       
msg_uchar   methodName args obj = sel_named methodName >>= \sel -> objc_msgSend_cuchar  obj sel args

msg_cstring :: String -> [Arg] -> ID -> IO CString                                       
msg_cstring methodName args obj = sel_named methodName >>= \sel -> objc_msgSend_cstring obj sel args
                                                                                            


sel_named :: String -> IO SEL
sel_named = sel_getUid


ns_string :: String -> IO ID
ns_string x = do
  class_named "NSString" >>= msg_obj "stringWithUTF8String:" [argString x]


class_named :: String -> IO ID
class_named = objc_getClass

ns_puts :: String -> [Arg] -> IO ()
ns_puts x args = do
  ns_msg <- ns_string x
  ns_log - argPtr ns_msg : args

set_method :: String -> String -> FunPtr a -> IO (FunPtr ())
set_method class_name sel_name method_implementation = do
  class_pointer <- class_named class_name
  cmd <- sel_named sel_name
  
  method <- class_getInstanceMethod class_pointer cmd
  
  method_setImplementation method method_implementation