/*
* input.h
* DIN Is Noise is copyright (c) 2006-2024 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/


#ifndef __input
#define __input

#include "chrono.h"
#include "log.h"

#include <SDL/SDL.h>

struct keyboard {

    int nkeys; // number of keys
    Uint8* now; // key state now (1 - down, 0 - up)
    Uint8* last; // last state of keys

		unsigned int size;

    double* tstamp;
    double* repeat;

    keyboard () {

      SDL_GetKeyState (&nkeys);

			size = nkeys * sizeof (Uint8);

      last = new Uint8 [nkeys];
      memset (last, 0, size);

      tstamp = new double [nkeys];
      repeat = new double [nkeys];

			dlog << "+++ initialised computer keyboard input +++" << endl;

    }

    void read () {
      now = SDL_GetKeyState (0);
    }

    void save () {
			memcpy (last, now, size);
    }

    ~keyboard () {
      delete[] last;
      delete[] tstamp;
      delete[] repeat;
			dlog << "--- destroyed computer keyboard input ---" << endl;
    }

};

extern keyboard keybd;

struct pressedt {
  int g;
  pressedt () : g(0) {}
};
extern pressedt elsewhere;
extern pressedt& pressed;

inline int nkeys () {
  return keybd.nkeys;
}

inline int keydown (unsigned int k) {
  return keybd.now[k];
}

inline int keyup (unsigned int k) {
  int wkd = keybd.last[k];
  int kd = keybd.now[k];
  return (!kd && wkd);
}

inline int waskeydown (unsigned int k) {
  return keybd.last[k];
}

inline int keypressed (unsigned int k) {
  int wkd = waskeydown (k), kd = keydown (k);
  if (kd && !wkd) return 1; else return 0;
}

inline int keypressedd (unsigned int k, double firstt = 1./3, double constt = 1./20) {
  /* keypressed with key repeat */
  int wkd = waskeydown(k), kd = keydown(k);
  if (kd) {
    if (!wkd) {
      keybd.repeat[k] = firstt + ui_clk();
      return 1;
    } else {
			if (ui_clk() > keybd.repeat[k]) {
        keybd.repeat[k] = constt + ui_clk();
        return 1;
      }
    }
  } 
  return 0;
}

inline int shift_down () {
  return (keydown (SDLK_LSHIFT) || keydown (SDLK_RSHIFT));
}

inline int ctrl_down () {
  return (keydown (SDLK_LCTRL) || keydown (SDLK_RCTRL)); 
} 

inline int alt_down () {
	return (keydown (SDLK_LALT) || keydown (SDLK_RALT));
}

extern int lmb, rmb, mmb;
extern int mousex, mousey, mouseyy;
extern int wheel;
extern int SHIFT, CTRL, ALT;
#endif
