/*
 * Functions to translate keys on the Mac intel OS X platform
 *
 * Copyright 2008 CodeWeavers, Aric Stewart
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 */
/* Modified by MikuInstaller project on 2008-06-27. */

#ifdef __APPLE__

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

/* Wine Includes */
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wingdi.h"
#include "winnls.h"
#include "imm.h"
#include "ddk/imm.h"
#include "keysym2ucs.h"
#include "wine/debug.h"

#include "osxime_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(mac_ime);

/* These tables are from Events.h  
 * But i want to avoid bringing Mac headers into this file as it causes 
 * conflicts with the wine headers.
 */
enum {
  kNullCharCode                 = 0,
  kHomeCharCode                 = 1,
  kEnterCharCode                = 3,
  kEndCharCode                  = 4,
  kHelpCharCode                 = 5,
  kBellCharCode                 = 7,
  kBackspaceCharCode            = 8,
  kTabCharCode                  = 9,
  kLineFeedCharCode             = 10,
  kVerticalTabCharCode          = 11,
  kPageUpCharCode               = 11,
  kFormFeedCharCode             = 12,
  kPageDownCharCode             = 12,
  kReturnCharCode               = 13,
  kFunctionKeyCharCode          = 16,
  kCommandCharCode              = 17,   /* glyph available only in system fonts*/
  kCheckCharCode                = 18,   /* glyph available only in system fonts*/
  kDiamondCharCode              = 19,   /* glyph available only in system fonts*/
  kAppleLogoCharCode            = 20,   /* glyph available only in system fonts*/
  kEscapeCharCode               = 27,
  kClearCharCode                = 27,
  kLeftArrowCharCode            = 28,
  kRightArrowCharCode           = 29,
  kUpArrowCharCode              = 30,
  kDownArrowCharCode            = 31,
  kSpaceCharCode                = 32,
  kDeleteCharCode               = 127,
  kBulletCharCode               = 165,
  kNonBreakingSpaceCharCode     = 202
};

enum {
                                        /* modifiers */
  activeFlagBit                 = 0,    /* activate? (activateEvt and mouseDown)*/
  btnStateBit                   = 7,    /* state of button?*/
  cmdKeyBit                     = 8,    /* command key down?*/
  shiftKeyBit                   = 9,    /* shift key down?*/
  alphaLockBit                  = 10,   /* alpha lock down?*/
  optionKeyBit                  = 11,   /* option key down?*/
  controlKeyBit                 = 12,   /* control key down?*/
  rightShiftKeyBit              = 13,   /* right shift key down? Not supported on Mac OS X.*/
  rightOptionKeyBit             = 14,   /* right Option key down? Not supported on Mac OS X.*/
  rightControlKeyBit            = 15    /* right Control key down? Not supported on Mac OS X.*/
};

enum {
  activeFlag                    = 1 << activeFlagBit,
  btnState                      = 1 << btnStateBit,
  cmdKey                        = 1 << cmdKeyBit,
  shiftKey                      = 1 << shiftKeyBit,
  alphaLock                     = 1 << alphaLockBit,
  optionKey                     = 1 << optionKeyBit,
  controlKey                    = 1 << controlKeyBit,
  rightShiftKey                 = 1 << rightShiftKeyBit, /* Not supported on Mac OS X.*/
  rightOptionKey                = 1 << rightOptionKeyBit, /* Not supported on Mac OS X.*/
  rightControlKey               = 1 << rightControlKeyBit /* Not supported on Mac OS X.*/
};

/* End copy from Events.h */

extern TSMHandle gHandle;

#define XtoMacKeycode_KnownUnused -1

int xToMacKeycodeMap[] = {
    /*   0 -> */ XtoMacKeycode_KnownUnused,
    /*   1 -> */  53,
    /*   2 -> */  18,
    /*   3 -> */  19,
    /*   4 -> */  20,
    /*   5 -> */  21,
    /*   6 -> */  23,
    /*   7 -> */  22,
    /*   8 -> */  26,
    /*   9 -> */  28,
    /*  10 -> */  25,
    /*  11 -> */  29,
    /*  12 -> */  27,
    /*  13 -> */  24,
    /*  14 -> */  51,
    /*  15 -> */  48,
    /*  16 -> */  12,
    /*  17 -> */  13,
    /*  18 -> */  14,
    /*  19 -> */  15,
    /*  20 -> */  17,
    /*  21 -> */  16,
    /*  22 -> */  32,
    /*  23 -> */  34,
    /*  24 -> */  31,
    /*  25 -> */  35,
    /*  26 -> */  33,
    /*  27 -> */  30,
    /*  28 -> */  36,
    /*  29 -> */  59,
    /*  30 -> */   0,
    /*  31 -> */   1,
    /*  32 -> */   2,
    /*  33 -> */   3,
    /*  34 -> */   5,
    /*  35 -> */   4,
    /*  36 -> */  38,
    /*  37 -> */  40,
    /*  38 -> */  37,
    /*  39 -> */  41,
    /*  40 -> */  39,
    /*  41 -> */  50,
    /*  42 -> */  56,
    /*  43 -> */  42,
    /*  44 -> */   6,
    /*  45 -> */   7,
    /*  46 -> */   8,
    /*  47 -> */   9,
    /*  48 -> */  11,
    /*  49 -> */  45,
    /*  50 -> */  46,
    /*  51 -> */  43,
    /*  52 -> */  47,
    /*  53 -> */  44,
    /*  54 -> */  60,
    /*  55 -> */  67,
    /*  56 -> */  58,
    /*  57 -> */  49,
    /*  58 -> */  57,
    /*  59 -> */ 122,
    /*  60 -> */ 120,
    /*  61 -> */  99,
    /*  62 -> */ 118,
    /*  63 -> */  96,
    /*  64 -> */  97,
    /*  65 -> */  98,
    /*  66 -> */ 100,
    /*  67 -> */ 101,
    /*  68 -> */ 109,
    /*  69 -> */  71,
    /*  70 -> */ XtoMacKeycode_KnownUnused,
    /*  71 -> */  89,
    /*  72 -> */  91,
    /*  73 -> */  92,
    /*  74 -> */  78,
    /*  75 -> */  86,
    /*  76 -> */  87,
    /*  77 -> */  88,
    /*  78 -> */  69,
    /*  79 -> */  83,
    /*  80 -> */  84,
    /*  81 -> */  85,
    /*  82 -> */  82,
    /*  83 -> */ XtoMacKeycode_KnownUnused,
    /*  84 -> */ XtoMacKeycode_KnownUnused,
    /*  85 -> */ XtoMacKeycode_KnownUnused,
    /*  86 -> */  10,
    /*  87 -> */ 103,
    /*  88 -> */ 111,
    /*  89 -> */ 115,
    /*  90 -> */ 126,
    /*  91 -> */ 116,
    /*  92 -> */ 123,
    /*  93 -> */ XtoMacKeycode_KnownUnused,
    /*  94 -> */ 124,
    /*  95 -> */ 119,
    /*  96 -> */ 125,
    /*  97 -> */ 121,
    /*  98 -> */ 114,
    /*  99 -> */ 117,
    /* 100 -> */  76,
    /* 101 -> */  62,
    /* 102 -> */ XtoMacKeycode_KnownUnused,
    /* 103 -> */ XtoMacKeycode_KnownUnused,
    /* 104 -> */  75,
    /* 105 -> */  61,
    /* 106 -> */ XtoMacKeycode_KnownUnused,
    /* 107 -> */  55,
    /* 108 -> */  63,
    /* 109 -> */ XtoMacKeycode_KnownUnused,
    /* 110 -> */ 105, /* From /usr/X11R6/lib/X11/xkb/keycodes/xfree86: FK13.*/
    /* 111 -> */ 107, /* From /usr/X11R6/lib/X11/xkb/keycodes/xfree86: FK14.*/
    /* 112 -> */ 113, /* From /usr/X11R6/lib/X11/xkb/keycodes/xfree86: FK15.*/
    /* 113 -> */ 106, /* From /usr/X11R6/lib/X11/xkb/keycodes/xfree86: FK16.*/
    /* 114 -> */ XtoMacKeycode_KnownUnused,
    /* 115 -> */  65, /* From /usr/X11R6/lib/X11/xkb/keycodes/xfree86: KPDC.*/
    /* 116 -> */ XtoMacKeycode_KnownUnused,
    /* 117 -> */ XtoMacKeycode_KnownUnused,
    /* 118 -> */  81,
    /* 119 -> */ XtoMacKeycode_KnownUnused,
    /* 120 -> */ XtoMacKeycode_KnownUnused,
    /* 121 -> */ 102, /* From /usr/X11R6/lib/X11/xkb/keycodes/xfree86: XFER.  This is a bit of a guess.  The Mac mappings do nothing but exit dead key states for JIS keyboards.  I'm assuming that's because they're about to switch states, which I'm guessing is what these keys do.*/
    /* 122 -> */ XtoMacKeycode_KnownUnused,
    /* 123 -> */ XtoMacKeycode_KnownUnused,
    /* 124 -> */ XtoMacKeycode_KnownUnused,
    /* 125 -> */  93, /* Only maps for JIS keyboards; maps to yen/pipe/backslash across many keyboard layouts.  From /usr/X11R6/lib/X11/xkb/keycodes/xfree86: AE13.  That definition is labeled as "Yen".  Also, the position of the Yen key on JIS keyboards is to the right of AE12.*/
    /* 126 -> */ XtoMacKeycode_KnownUnused,
    /* 127 -> */ XtoMacKeycode_KnownUnused,
    /* 128 -> */ XtoMacKeycode_KnownUnused,
    /* 129 -> */ XtoMacKeycode_KnownUnused,
    /* 130 -> */ XtoMacKeycode_KnownUnused,
    /* 131 -> */ XtoMacKeycode_KnownUnused,
    /* 132 -> */ XtoMacKeycode_KnownUnused,
    /* 133 -> */ XtoMacKeycode_KnownUnused,
    /* 134 -> */ XtoMacKeycode_KnownUnused,
    /* 135 -> */ XtoMacKeycode_KnownUnused,
    /* 136 -> */ XtoMacKeycode_KnownUnused,
    /* 137 -> */ XtoMacKeycode_KnownUnused,
    /* 138 -> */ XtoMacKeycode_KnownUnused,
    /* 139 -> */ XtoMacKeycode_KnownUnused,
    /* 140 -> */ XtoMacKeycode_KnownUnused,
    /* 141 -> */ XtoMacKeycode_KnownUnused,
    /* 142 -> */ XtoMacKeycode_KnownUnused,
    /* 143 -> */ XtoMacKeycode_KnownUnused,
    /* 144 -> */ XtoMacKeycode_KnownUnused,
    /* 145 -> */ XtoMacKeycode_KnownUnused,
    /* 146 -> */ XtoMacKeycode_KnownUnused,
    /* 147 -> */ XtoMacKeycode_KnownUnused,
    /* 148 -> */ XtoMacKeycode_KnownUnused,
    /* 149 -> */ XtoMacKeycode_KnownUnused,
    /* 150 -> */ XtoMacKeycode_KnownUnused,
    /* 151 -> */ XtoMacKeycode_KnownUnused,
    /* 152 -> */ XtoMacKeycode_KnownUnused,
    /* 153 -> */ XtoMacKeycode_KnownUnused,
    /* 154 -> */ XtoMacKeycode_KnownUnused,
    /* 155 -> */ XtoMacKeycode_KnownUnused,
    /* 156 -> */ XtoMacKeycode_KnownUnused,
    /* 157 -> */ XtoMacKeycode_KnownUnused,
    /* 158 -> */ XtoMacKeycode_KnownUnused,
    /* 159 -> */ XtoMacKeycode_KnownUnused,
    /* 160 -> */ XtoMacKeycode_KnownUnused,
    /* 161 -> */ XtoMacKeycode_KnownUnused,
    /* 162 -> */ XtoMacKeycode_KnownUnused,
    /* 163 -> */ XtoMacKeycode_KnownUnused,
    /* 164 -> */ XtoMacKeycode_KnownUnused,
    /* 165 -> */ XtoMacKeycode_KnownUnused,
    /* 166 -> */ XtoMacKeycode_KnownUnused,
    /* 167 -> */ XtoMacKeycode_KnownUnused,
    /* 168 -> */ XtoMacKeycode_KnownUnused,
    /* 169 -> */ XtoMacKeycode_KnownUnused,
    /* 170 -> */ XtoMacKeycode_KnownUnused,
    /* 171 -> */ XtoMacKeycode_KnownUnused,
    /* 172 -> */ XtoMacKeycode_KnownUnused,
    /* 173 -> */ XtoMacKeycode_KnownUnused,
    /* 174 -> */ XtoMacKeycode_KnownUnused,
    /* 175 -> */ XtoMacKeycode_KnownUnused,
    /* 176 -> */ XtoMacKeycode_KnownUnused,
    /* 177 -> */ XtoMacKeycode_KnownUnused,
    /* 178 -> */ XtoMacKeycode_KnownUnused,
    /* 179 -> */ XtoMacKeycode_KnownUnused,
    /* 180 -> */ XtoMacKeycode_KnownUnused,
    /* 181 -> */ XtoMacKeycode_KnownUnused,
    /* 182 -> */ XtoMacKeycode_KnownUnused,
    /* 183 -> */ XtoMacKeycode_KnownUnused,
    /* 184 -> */ XtoMacKeycode_KnownUnused,
    /* 185 -> */ XtoMacKeycode_KnownUnused,
    /* 186 -> */ XtoMacKeycode_KnownUnused,
    /* 187 -> */ XtoMacKeycode_KnownUnused,
    /* 188 -> */ XtoMacKeycode_KnownUnused,
    /* 189 -> */ XtoMacKeycode_KnownUnused,
    /* 190 -> */ XtoMacKeycode_KnownUnused,
    /* 191 -> */ XtoMacKeycode_KnownUnused,
    /* 192 -> */ XtoMacKeycode_KnownUnused,
    /* 193 -> */ XtoMacKeycode_KnownUnused,
    /* 194 -> */ XtoMacKeycode_KnownUnused,
    /* 195 -> */ XtoMacKeycode_KnownUnused,
    /* 196 -> */ XtoMacKeycode_KnownUnused,
    /* 197 -> */ XtoMacKeycode_KnownUnused,
    /* 198 -> */ XtoMacKeycode_KnownUnused,
    /* 199 -> */ XtoMacKeycode_KnownUnused,
    /* 200 -> */  104, /* From /usr/X11R6/lib/X11/xkb/keycodes/xfree86: HKTG. In Leopard's Events.h, this keycode is documented as kVK_JIS_Kana, which I'm 
 assuming matches XKB's "Hiragana_Katakana toggle". */
    /* 201 -> */ XtoMacKeycode_KnownUnused,
    /* 202 -> */ XtoMacKeycode_KnownUnused,
    /* 203 -> */  94, /* Only maps for JIS keyboards; maps to underscore/grave/combining-grave across many keyboard layouts.  From /usr/X11R6/lib/X11/xkb/keycodes/xfree86: AB11.  This is a bit of a guess.  That definition is labeled as "backslash/underscore".  Only the "underscore" part matches this key's mapping.*/
    /* No X keycode maps to these Mac keycodes:
       XXX ->     52, // This maps to the Enter character code in all keyboard layouts.  Is this some alternate Enter key?  See 76.
       XXX ->     54,
       XXX ->     64,
       XXX ->     66,
       XXX ->     68,
       XXX ->     70,
       XXX ->     72,
       XXX ->     73,
       XXX ->     74,
       XXX ->     77,
       XXX ->     79,
       XXX ->     80,
       XXX ->     90,
       XXX ->     95, // Only maps for JIS keyboards; maps to comma for all modifier combinations across many keyboard layouts.  It seems unlikely that any such key exists.
       XXX ->    108,
       XXX ->    110,
       XXX ->    112,
       XXX ->    127,
    */
};

int MacToAscii(UINT uVKey, UINT keysym, UINT keycode, CONST LPBYTE lpbKeyState,
    LPDWORD lpdwTransKey)
{
	char theChar;
    WCHAR unichar;
	unsigned long theCode;
	unsigned long modifiers;

    modifiers = 0x00;

/* modifiers  */

  if (lpbKeyState[VK_SHIFT] & 0x80)
    modifiers |= shiftKey;
  if (lpbKeyState[VK_NUMLOCK] & 0x80)
    modifiers |= alphaLock;
  if (lpbKeyState[VK_CONTROL] & 0x80)
    modifiers |= controlKey;
  if (lpbKeyState[VK_MENU] & 0x80)
    modifiers |= cmdKey;
  if (lpbKeyState[VK_MENU] & 0x80)
    modifiers |= optionKey;

      switch(uVKey) {
      case VK_LEFT:
        theChar = kLeftArrowCharCode;
        break;
      case VK_UP:
        theChar = kUpArrowCharCode;
        break;
      case VK_RIGHT:
        theChar = kRightArrowCharCode;
        break;
      case VK_DOWN:
        theChar = kDownArrowCharCode;
        break;
      case VK_DELETE:
        theChar = kBackspaceCharCode;
        break;
      case VK_F1:
      case VK_F2:
      case VK_F3:
      case VK_F4:
      case VK_F5:
      case VK_F6:
      case VK_F7:
      case VK_F8:
      case VK_F9:
      case VK_F10:
      case VK_F11:
      case VK_F12:
        theChar = kFunctionKeyCharCode;
        break;
      default:
        theChar = keysym & 0x00FF;
        break;
      }

    //theCode = xToMacKeycodeMap[keycode];
    theCode = keycode;
    MacActivateTSMDocument(gHandle);
    unichar = keysym2ucs(keysym);

    return MacTSMEventCFS(gHandle,theChar,theCode,modifiers,unichar);
}
#endif
