/*
 *  KCemu -- The emulator for the KC85 homecomputer series and much more.
 *  Copyright (C) 1997-2010 Torsten Paul
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <iostream>
#include <iomanip>

#include "kc/system.h"

#include "kc/z80.h"
#include "kc/keys.h"
//#include "kc/muglerpc/keydef.h"
#include "kc/muglerpc/keyboard.h"

#include "libdbg/dbg.h"

KeyboardMuglerPC::KeyboardMuglerPC(void)
{
  init();
  z80->register_ic(this);
}


KeyboardMuglerPC::~KeyboardMuglerPC(void)
{
  z80->unregister_ic(this);
}

void
KeyboardMuglerPC::init(void)
{
  int a;

  for (a = 0;a < MAX_KEYS;a++)
    {
      _keybuf[a].sym = -1;
      _keybuf[a].code = -1;
    }
}

int
KeyboardMuglerPC::decode_key(int keysym, bool press)
{
  return keysym;
}

void
KeyboardMuglerPC::keyPressed(int keysym, int keycode)
{
  int k;

  /*
   *  ignore repeated key press events (e.g. generated by
   *  GTK that reports key repeat as keypress/keypress/keypress/...
   *  without the possibility to switch that off :-( )
   */
  for (int a = 0;a < MAX_KEYS;a++)
    if (_keybuf[a].code == keycode)
      return;

  k = decode_key(keysym, true);
  if (k == -1)
    return;

  DBG(2, form("KCemu/keyboard/muglerpc/key_press",
	      "##### Keyboard: keyPressed  [%03x/%02x] ",
	      keysym, k));

  for (int a = 0;a < MAX_KEYS;a++)
    {
      if (_keybuf[a].code == -1)
	{
	  _keybuf[a].sym = k;
	  _keybuf[a].code = keycode;
	  break;
	}
    }

  for (int a = 0;a < MAX_KEYS;a++)
    if (_keybuf[a].code != -1)
      DBG(2, form("KCemu/keyboard/muglerpc/key_press",
		  " {%02d:%02x:%02x}", a, _keybuf[a].sym, _keybuf[a].code));
  
  DBG(2, form("KCemu/keyboard/muglerpc/key_press",
	      "\n"));
}

void
KeyboardMuglerPC::keyReleased(int keysym, int keycode)
{
  if (keysym == -1)
    {
      for (int a = 0;a < MAX_KEYS;a++)
        _keybuf[a].code = -1;
      return;
    }
                                                                                
  /*
   *  remove (maybe multiple) entries from keyboard buffer
   */
  for (int a = 0;a < MAX_KEYS;a++)
    if (_keybuf[a].code == keycode)
      _keybuf[a].code = -1;
                                                                                
  DBG(2, form("KCemu/keyboard/muglerpc/key_release",
	      "##### Keyboard: keyPressed  [%03x/%02x] ",
	      keysym, keycode));

  for (int a = 0;a < MAX_KEYS;a++)
    if (_keybuf[a].code != -1)
      DBG(2, form("KCemu/keyboard/muglerpc/key_press",
		  " {%02d:%02x:%02x}", a, _keybuf[a].sym, _keybuf[a].code));

  DBG(2, form("KCemu/keyboard/muglerpc/key_release",
              "\n"));
}

void
KeyboardMuglerPC::replayString(const char *text)
{
}

void
KeyboardMuglerPC::callback(void *data)
{
}

int
KeyboardMuglerPC::callback_A_in(void)
{
  for (int a = 0;a < MAX_KEYS;a++)
    {
      if (_keybuf[a].code == -1)
	continue;

      if (_keybuf[a].sym == KC_KEY_SHIFT)
	continue;

      if (_keybuf[a].sym == KC_KEY_CONTROL)
	continue;

      return _keybuf[a].sym | 0x80;
    }

  return 0;
}

void
KeyboardMuglerPC::callback_A_out(byte_t val)
{
}

int
KeyboardMuglerPC::callback_B_in(void)
{
  return -1;
}

void
KeyboardMuglerPC::callback_B_out(byte_t val)
{
}

void
KeyboardMuglerPC::reset(bool power_on)
{
  init();
}

void
KeyboardMuglerPC::reti(void)
{
}
