//
// keyboard.cpp
//
// keyboard subsystem
//
//
// Author: Tomi Belan <tomi.belan@gmail.com>, (C) 2006
//
// Copyright: See COPYING file that comes with this distribution
//
//

#include <SDL.h>

#include "keyboard.h"

/**
* an array of keys, similar to 'key' from Allegro. Released keys have value 0,
* pressed keys have 1 and keys that wait for releasing have 2.
* Note: I know I could use SDL key-states, but when the user both presses and
* releases the key while one iteration of event loop is running, the program
* doesn't notice it. This implementation takes another approach - when user
* releases a key, it just notes it was released, but it actually updates the
* array only at end of the event loop.
*/
static int pressed[SDLK_LAST];
/**
* Currently pressed key. This will be returned by readkey(). Can be used, for
* example, to read input for an editbox widget. (Don't use this if it isn't
* needed; isPressed() and SDL key events are preferred.)
*/
static SDL_keysym pressedKey;

namespace Keyboard {
  /**
  * This is called from the event loop when a key is pressed.
  */
  void keyPress(SDL_Event* e)
  {
    if(!pressed[e->key.keysym.sym])
      pressed[e->key.keysym.sym] = 1;
    pressedKey = e->key.keysym;
  }
  /**
  * This is called from the event loop when a key is released. See description
  * of 'pressed' array above.
  */
  void keyRelease(SDL_Event* e)
  {
    pressed[e->key.keysym.sym] = 2;
  }
  /**
  * This actually marks key that are 'waiting for releasing' released. It is
  * called at end of event loop.
  */
  void releaseKeys()
  {
    for(register unsigned int i = 0; i < SDLK_LAST; i++)
      if(pressed[i] == 2)
        pressed[i] = 0;
  }
  
  /**
  * Returns true if key with code 'sdlk' is currently pressed.
  */
  bool isPressed(int sdlk)
  {
    return !!pressed[sdlk];
  }
  /**
  * Returns currently pressed key. See also description of 'pressedKey'.
  */
  SDL_keysym readkey()
  {
    return pressedKey;
  }
}

