local ffi = require( "ffi" )
local dll = ffi.load( 'curses' )
local shl = bit.lshift

ffi.cdef[[
      typedef void* WINDOW;
      typedef unsigned chtype;
      int endwin();
      int beep();
      int echo(); int noecho();
      int nl();   int nonl();
      int raw();  int noraw();
      int COLS;   int LINES;
      WINDOW* initscr();
      WINDOW* stdscr;
      int waddch(WINDOW*,const chtype ch);
      int wgetch(WINDOW*);
      int wmove(WINDOW*,int,int);
      int wclear(WINDOW*);
      int wrefresh(WINDOW*);
      int wattrset(WINDOW*,int);
      int wclrtoeol(WINDOW*);
      int meta(WINDOW*w,bool);
      int intrflush(WINDOW*w,bool);
      int keypad(WINDOW*w,bool);
      void wtimeout(WINDOW*w,int);
]]

local stdscr = {
   move      = function(self,y,x) return dll.wmove(     self.window, y, x ) end,
   keypad    = function(self,a)   return dll.keypad(    self.window, a    ) end,
   meta      = function(self,a)   return dll.meta(      self.window, a    ) end,
   intrflush = function(self,a)   return dll.intrflush( self.window, a    ) end,
   addch     = function(self,c)   return dll.waddch(    self.window, c    ) end,
   getch     = function(self)     return dll.wgetch(    self.window       ) end,
   clear     = function(self)     return dll.wclear(    self.window       ) end,
   refresh   = function(self)     return dll.wrefresh(  self.window       ) end,
   attrset   = function(self,a)   return dll.wattrset(  self.window, a    ) end,
   clrtoeol  = function(self)     return dll.wclrtoeol( self.window       ) end,
   timeout   = function(self,a)          dll.wtimeout(  self.window, a    ) end,
}

curses = {
   beep         = dll.beep,
   endwin       = dll.endwin,
   initscr      = function() stdscr.window = dll.initscr() end,
   stdscr       = function() return stdscr end,
   cols         = function() return dll.COLS end,
   lines        = function() return dll.LINES - 10 end,
   echo         = function(on) if on then dll.echo() else dll.noecho() end end,
   nl           = function(on) if on then dll.nl()   else dll.nonl()   end end,
   raw          = function(on) if on then dll.raw()  else dll.noraw()  end end,

   ERR = -(1),
   OK = 0,
   _SUBWIN = 0x01,
   _ENDLINE = 0x02,
   _FULLWIN = 0x04,
   _SCROLLWIN = 0x08,
   _ISPAD = 0x10,
   _HASMOVED = 0x20,
   _WRAPPED = 0x40,
   _NOCHANGE = -(1),
   _NEWINDEX = -(1),

   COLOR_BLACK = 0,
   COLOR_RED = 1,
   COLOR_GREEN = 2,
   COLOR_YELLOW = 3,
   COLOR_BLUE = 4,
   COLOR_MAGENTA = 5,
   COLOR_CYAN = 6,
   COLOR_WHITE = 7,

   A_NORMAL     = 0,
   A_ATTRIBUTES = 0xFFFFFF00,
   A_CHARTEXT   = shl( 1,  0 + 8) - 1,
   A_COLOR      = shl( shl( 1,  8 ) - 1, 8 ),
   A_STANDOUT   = shl( 1,  8 + 8 ),
   A_UNDERLINE  = shl( 1,  9 + 8 ),
   A_REVERSE    = shl( 1, 10 + 8 ),
   A_BLINK      = shl( 1, 11 + 8 ),
   A_DIM        = shl( 1, 12 + 8 ),
   A_BOLD       = shl( 1, 13 + 8 ),
   A_ALTCHARSET = shl( 1, 14 + 8 ),
   A_INVIS      = shl( 1, 15 + 8 ),
   A_PROTECT    = shl( 1, 16 + 8 ),
   A_HORIZONTAL = shl( 1, 17 + 8 ),
   A_LEFT       = shl( 1, 18 + 8 ),
   A_LOW        = shl( 1, 19 + 8 ),
   A_RIGHT      = shl( 1, 20 + 8 ),
   A_TOP        = shl( 1, 21 + 8 ),
   A_VERTICAL   = shl( 1, 22 + 8 ),

   KEY_CODE_YES = 256,
   KEY_MIN = 257,     
   KEY_BREAK = 257,   
   KEY_DOWN = 258,    
   KEY_UP = 259,      
   KEY_LEFT = 260,    
   KEY_RIGHT = 261,   
   KEY_HOME = 262,    
   KEY_BACKSPACE = 263,
   KEY_F0 = 264,      
   KEY_F1 = 265,
   KEY_F2 = 266,
   KEY_F3 = 267,
   KEY_F4 = 268,
   KEY_F5 = 269,
   KEY_F6 = 270,
   KEY_F7 = 271,
   KEY_F8 = 272,
   KEY_F9 = 273,
   KEY_F10 = 274,
   KEY_F11 = 275,
   KEY_F12 = 276,
   KEY_DL = 328,        
   KEY_IL = 329,        
   KEY_DC = 330,        
   KEY_IC = 331,            
   KEY_EIC = 332,           
   KEY_CLEAR = 333,         
   KEY_EOS = 334,           
   KEY_EOL = 335,           
   KEY_SF = 336,            
   KEY_SR = 337,            
   KEY_NPAGE = 338,         
   KEY_PPAGE = 339,         
   KEY_STAB = 340,          
   KEY_CTAB = 341,          
   KEY_CATAB = 342,         
   KEY_ENTER = 343,         
   KEY_SRESET = 344,        
   KEY_RESET = 345,         
   KEY_PRINT = 346,         
   KEY_LL = 347,            
   KEY_A1 = 348,            
   KEY_A3 = 349,            
   KEY_B2 = 350,            
   KEY_C1 = 351,            
   KEY_C3 = 352,            
   KEY_BTAB = 353,          
   KEY_BEG = 354,           
   KEY_CANCEL = 355,        
   KEY_CLOSE = 356,         
   KEY_COMMAND = 357,       
   KEY_COPY = 358,          
   KEY_CREATE = 359,        
   KEY_END = 360,           
   KEY_EXIT = 361,          
   KEY_FIND = 362,          
   KEY_HELP = 363,          
   KEY_MARK = 364,          
   KEY_MESSAGE = 365,       
   KEY_MOVE = 366,          
   KEY_NEXT = 367,          
   KEY_OPEN = 368,          
   KEY_OPTIONS = 369,       
   KEY_PREVIOUS = 370,      
   KEY_REDO = 371,          
   KEY_REFERENCE = 372,     
   KEY_REFRESH = 373,       
   KEY_REPLACE = 374,       
   KEY_RESTART = 375,       
   KEY_RESUME = 376,        
   KEY_SAVE = 377,          
   KEY_SBEG = 378,          
   KEY_SCANCEL = 379,       
   KEY_SCOMMAND = 380,      
   KEY_SCOPY = 381,         
   KEY_SCREATE = 382,       
   KEY_SDC = 383,           
   KEY_SDL = 384,           
   KEY_SELECT = 385,        
   KEY_SEND = 386,          
   KEY_SEOL = 387,          
   KEY_SEXIT = 388,         
   KEY_SFIND = 389,         
   KEY_SHELP = 390,         
   KEY_SHOME = 391,         
   KEY_SIC = 392,           
   KEY_SLEFT = 393,         
   KEY_SMESSAGE = 394,      
   KEY_SMOVE = 395,         
   KEY_SNEXT = 396,         
   KEY_SOPTIONS = 397,      
   KEY_SPREVIOUS = 398,     
   KEY_SPRINT = 399,        
   KEY_SREDO = 400,         
   KEY_SREPLACE = 401,      
   KEY_SRIGHT = 402,        
   KEY_SRSUME = 403,        
   KEY_SSAVE = 404,         
   KEY_SSUSPEND = 405,      
   KEY_SUNDO = 406,         
   KEY_SUSPEND = 407,       
   KEY_UNDO = 408,          
   KEY_MOUSE = 409,         
   KEY_RESIZE = 410,        
   KEY_MAX = 511,           
}

