/*
 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#import <JavaNativeFoundation/JavaNativeFoundation.h>

#import "CMenuItem.h"
#import "CMenu.h"
#import "AWTEvent.h"
#import "ThreadUtilities.h"

#import "java_awt_Event.h"
#import "java_awt_event_KeyEvent.h"
#import "sun_lwawt_macosx_CMenuItem.h"

#define NOT_A_CHECKBOXMENU -2


@implementation CMenuItem

- (id) initWithPeer:(jobject)peer asSeparator: (NSNumber *) asSeparator{
AWT_ASSERT_APPKIT_THREAD;
    self = [super initWithPeer:peer];
    if (self) {
        if ([asSeparator boolValue]) {
            fMenuItem = (NSMenuItem*)[NSMenuItem separatorItem];
            [fMenuItem retain];
        } else {
            fMenuItem = [[NSMenuItem alloc] init];
            [fMenuItem setAction:@selector(handleAction:)];
            [fMenuItem setTarget:self];
        }
        fIsCheckbox = NO;
        fIsEnabled = YES;
    }
    return self;
}

// This is because NSApplication doesn't check the target's window when sending
// actions; they only check the target itself.  We always return YES,
// since we shouldn't even be installed unless our window is active.
- (BOOL) worksWhenModal {
    return YES;
}

// Events
- (void)handleAction:(NSMenuItem *)sender {
AWT_ASSERT_APPKIT_THREAD;
    JNIEnv *env = [ThreadUtilities getJNIEnv];
JNF_COCOA_ENTER(env);

    // If we are called as a result of user pressing a shortcut, do nothing,
    // because AVTView has already sent corresponding key event to the Java
    // layer from performKeyEquivalent.
    // There is an exception from the rule above, though: if a window with
    // a menu gets minimized by user and there are no other windows to take
    // focus, the window's menu won't be removed from the global menu bar.
    // However, the Java layer won't handle invocation by a shortcut coming
    // from this "frameless" menu, because there are no active windows. This
    // means we have to handle it here.
    NSEvent *currEvent = [[NSApplication sharedApplication] currentEvent];
    if ([currEvent type] == NSKeyDown) {
        NSString *menuKey = [sender keyEquivalent];
        NSString *eventKey = [currEvent charactersIgnoringModifiers];

        // Apple uses characters from private Unicode range for some of the
        // keys, so we need to do the same translation here that we do
        // for the regular key down events
        if ([eventKey length] == 1) {
            unichar origChar = [eventKey characterAtIndex:0];
            unichar newChar =  NsCharToJavaChar(origChar, 0);
            if (newChar == java_awt_event_KeyEvent_CHAR_UNDEFINED) {
                newChar = origChar;
            }

            eventKey = [NSString stringWithCharacters: &newChar length: 1];
        }

        NSWindow *keyWindow = [NSApp keyWindow];
        if ([menuKey isEqualToString:eventKey] && keyWindow != nil) {
            return;
        }
    }

    if (fIsCheckbox) {
        static JNF_CLASS_CACHE(jc_CCheckboxMenuItem, "sun/lwawt/macosx/CCheckboxMenuItem");
        static JNF_MEMBER_CACHE(jm_ckHandleAction, jc_CCheckboxMenuItem, "handleAction", "(Z)V");

        // Send the opposite of what's currently checked -- the action
        // indicates what state we're going to.
        NSInteger state = [sender state];
        jboolean newState = (state == NSOnState ? JNI_FALSE : JNI_TRUE);
        JNFCallVoidMethod(env, fPeer, jm_ckHandleAction, newState);
    } else {
        static JNF_CLASS_CACHE(jc_CMenuItem, "sun/lwawt/macosx/CMenuItem");
        static JNF_MEMBER_CACHE(jm_handleAction, jc_CMenuItem, "handleAction", "(JI)V"); // AWT_THREADING Safe (event)

        NSUInteger modifiers = [currEvent modifierFlags];
        jint javaModifiers = NsKeyModifiersToJavaModifiers(modifiers, NO);

        JNFCallVoidMethod(env, fPeer, jm_handleAction, UTC(currEvent), javaModifiers); // AWT_THREADING Safe (event)
    }
JNF_COCOA_EXIT(env);
}

- (void) setJavaLabel:(NSString *)theLabel shortcut:(NSString *)theKeyEquivalent modifierMask:(jint)modifiers {

    NSUInteger modifierMask = 0;

    if (![theKeyEquivalent isEqualToString:@""]) {
        // Force the key equivalent to lower case if not using the shift key.
        // Otherwise AppKit will draw a Shift glyph in the menu.
        if ((modifiers & java_awt_event_KeyEvent_SHIFT_MASK) == 0) {
            theKeyEquivalent = [theKeyEquivalent lowercaseString];
        }

        // Hack for the question mark -- SHIFT and / means use the question mark.
        if ((modifiers & java_awt_event_KeyEvent_SHIFT_MASK) != 0 &&
            [theKeyEquivalent isEqualToString:@"/"])
        {
            theKeyEquivalent = @"?";
            modifiers &= ~java_awt_event_KeyEvent_SHIFT_MASK;
        }

        modifierMask = JavaModifiersToNsKeyModifiers(modifiers, NO);
    }

    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
        [fMenuItem setKeyEquivalent:theKeyEquivalent];
        [fMenuItem setKeyEquivalentModifierMask:modifierMask];
        [fMenuItem setTitle:theLabel];
    }];
}

- (void) setJavaImage:(NSImage *)theImage {

    [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
        [fMenuItem setImage:theImage];
    }];
}

- (void) setJavaToolTipText:(NSString *)theText {

    [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
        [fMenuItem setToolTip:theText];
    }];
}


- (void)setJavaEnabled:(BOOL) enabled {

    [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
        @synchronized(self) {
            fIsEnabled = enabled;

            // Warning:  This won't work if the parent menu is disabled.
            // See [CMenu syncFromJava]. We still need to call it here so
            // the NSMenuItem itself gets properly updated.
            [fMenuItem setEnabled:fIsEnabled];
        }
    }];
}

- (BOOL)isEnabled {

    BOOL enabled = NO;
    @synchronized(self) {
        enabled = fIsEnabled;
    }
    return enabled;
}


- (void)setJavaState:(BOOL)newState {

    [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
        [fMenuItem setState:(newState ? NSOnState : NSOffState)];
    }];
}

- (void)cleanup {
    [fMenuItem setAction:NULL];
    [fMenuItem setTarget:nil];
}

- (void)dealloc {
    [fMenuItem release];
    fMenuItem = nil;

    [super dealloc];
}

- (void)addNSMenuItemToMenu:(NSMenu *)inMenu {
    [inMenu addItem:fMenuItem];
}

- (NSMenuItem *)menuItem {
    return [[fMenuItem retain] autorelease];
}

- (void)setIsCheckbox {
    fIsCheckbox = YES;
}

- (void) _createMenuItem_OnAppKitThread: (NSMutableArray *)argValue {
    jobject cPeerObjGlobal = (jobject)[[argValue objectAtIndex: 0] pointerValue];
    NSNumber * asSeparator = (NSNumber *)[argValue objectAtIndex: 1];
    CMenuItem *aCMenuItem = [self initWithPeer: cPeerObjGlobal asSeparator: asSeparator];
    [argValue removeAllObjects];
    [argValue addObject: aCMenuItem];
}

- (NSString *)description {
    return [NSString stringWithFormat:@"CMenuItem[ %@ ]", fMenuItem];
}

@end

/** Convert a Java keycode for SetMenuItemCmd */
static unichar AWTKeyToMacShortcut(jint awtKey, BOOL doShift) {
    unichar macKey = 0;

    if ((awtKey >= java_awt_event_KeyEvent_VK_0 && awtKey <= java_awt_event_KeyEvent_VK_9) ||
        (awtKey >= java_awt_event_KeyEvent_VK_A && awtKey <= java_awt_event_KeyEvent_VK_Z))
    {
        // These ranges are the same in ASCII
        macKey = awtKey;
    } else if (awtKey >= java_awt_event_KeyEvent_VK_F1 && awtKey <= java_awt_event_KeyEvent_VK_F12) {
        // Support for F1 - F12 has been around since Java 1.0 and fall into a lower range.
        macKey = awtKey - java_awt_event_KeyEvent_VK_F1 + NSF1FunctionKey;
    } else if (awtKey >= java_awt_event_KeyEvent_VK_F13 && awtKey <= java_awt_event_KeyEvent_VK_F24) {
        // Support for F13-F24 came in Java 1.2 and are at a different range.
        macKey = awtKey - java_awt_event_KeyEvent_VK_F13 + NSF13FunctionKey;
    } else {
        // Special characters
        switch (awtKey) {
        case java_awt_event_KeyEvent_VK_BACK_QUOTE      : macKey = '`'; break;
        case java_awt_event_KeyEvent_VK_QUOTE           : macKey = '\''; break;

        case java_awt_event_KeyEvent_VK_ESCAPE          : macKey = 0x1B; break;
//        case java_awt_event_KeyEvent_VK_SPACE           : macKey = kMenuSpaceGlyph; break;
        case java_awt_event_KeyEvent_VK_PAGE_UP         : macKey = NSPageUpFunctionKey; break;
        case java_awt_event_KeyEvent_VK_PAGE_DOWN       : macKey = NSPageDownFunctionKey; break;
        case java_awt_event_KeyEvent_VK_END             : macKey = NSEndFunctionKey; break;
        case java_awt_event_KeyEvent_VK_HOME            : macKey = NSHomeFunctionKey; break;

        case java_awt_event_KeyEvent_VK_LEFT            : macKey = NSLeftArrowFunctionKey; break;
        case java_awt_event_KeyEvent_VK_UP              : macKey = NSUpArrowFunctionKey; break;
        case java_awt_event_KeyEvent_VK_RIGHT           : macKey = NSRightArrowFunctionKey; break;
        case java_awt_event_KeyEvent_VK_DOWN            : macKey = NSDownArrowFunctionKey; break;

        case java_awt_event_KeyEvent_VK_COMMA           : macKey = ','; break;

        // Mac OS doesn't distinguish between the two '-' keys...
        case java_awt_event_KeyEvent_VK_MINUS           :
        case java_awt_event_KeyEvent_VK_SUBTRACT        : macKey = '-'; break;

        // or the two '.' keys...
        case java_awt_event_KeyEvent_VK_DECIMAL         :
        case java_awt_event_KeyEvent_VK_PERIOD          : macKey = '.'; break;

        // or the two '/' keys.
        case java_awt_event_KeyEvent_VK_DIVIDE          :
        case java_awt_event_KeyEvent_VK_SLASH           : macKey = '/'; break;

        case java_awt_event_KeyEvent_VK_SEMICOLON       : macKey = ';'; break;
        case java_awt_event_KeyEvent_VK_EQUALS          : macKey = '='; break;

        case java_awt_event_KeyEvent_VK_OPEN_BRACKET    : macKey = '['; break;
        case java_awt_event_KeyEvent_VK_BACK_SLASH      : macKey = '\\'; break;
        case java_awt_event_KeyEvent_VK_CLOSE_BRACKET   : macKey = ']'; break;

        case java_awt_event_KeyEvent_VK_MULTIPLY        : macKey = '*'; break;
        case java_awt_event_KeyEvent_VK_ADD             : macKey = '+'; break;

        case java_awt_event_KeyEvent_VK_HELP            : macKey = NSHelpFunctionKey; break;
        case java_awt_event_KeyEvent_VK_TAB             : macKey = NSTabCharacter; break;
        case java_awt_event_KeyEvent_VK_ENTER           : macKey = NSNewlineCharacter; break;
        case java_awt_event_KeyEvent_VK_BACK_SPACE      : macKey = NSBackspaceCharacter; break;
        case java_awt_event_KeyEvent_VK_DELETE          : macKey = NSDeleteCharacter; break;
        case java_awt_event_KeyEvent_VK_CLEAR           : macKey = NSClearDisplayFunctionKey; break;
        case java_awt_event_KeyEvent_VK_AMPERSAND       : macKey = '&'; break;
        case java_awt_event_KeyEvent_VK_ASTERISK        : macKey = '*'; break;
        case java_awt_event_KeyEvent_VK_QUOTEDBL        : macKey = '\"'; break;
        case java_awt_event_KeyEvent_VK_LESS            : macKey = '<'; break;
        case java_awt_event_KeyEvent_VK_GREATER         : macKey = '>'; break;
        case java_awt_event_KeyEvent_VK_BRACELEFT       : macKey = '{'; break;
        case java_awt_event_KeyEvent_VK_BRACERIGHT      : macKey = '}'; break;
        case java_awt_event_KeyEvent_VK_AT              : macKey = '@'; break;
        case java_awt_event_KeyEvent_VK_COLON           : macKey = ':'; break;
        case java_awt_event_KeyEvent_VK_CIRCUMFLEX      : macKey = '^'; break;
        case java_awt_event_KeyEvent_VK_DOLLAR          : macKey = '$'; break;
        case java_awt_event_KeyEvent_VK_EXCLAMATION_MARK : macKey = '!'; break;
        case java_awt_event_KeyEvent_VK_LEFT_PARENTHESIS : macKey = '('; break;
        case java_awt_event_KeyEvent_VK_NUMBER_SIGN     : macKey = '#'; break;
        case java_awt_event_KeyEvent_VK_PLUS            : macKey = '+'; break;
        case java_awt_event_KeyEvent_VK_RIGHT_PARENTHESIS: macKey = ')'; break;
        case java_awt_event_KeyEvent_VK_UNDERSCORE      : macKey = '_'; break;
        }
    }
    return macKey;
}

/*
 * Class:     sun_lwawt_macosx_CMenuItem
 * Method:    nativeSetLabel
 * Signature: (JLjava/lang/String;CII)V
 */
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CMenuItem_nativeSetLabel
(JNIEnv *env, jobject peer,
     jlong menuItemObj, jstring label,
     jchar shortcutKey, jint shortcutKeyCode, jint mods)
{
JNF_COCOA_ENTER(env);
    NSString *theLabel = JNFJavaToNSString(env, label);
    NSString *theKeyEquivalent = nil;
    unichar macKey = shortcutKey;

    if (macKey == 0) {
        macKey = AWTKeyToMacShortcut(shortcutKeyCode, (mods & java_awt_event_KeyEvent_SHIFT_MASK) != 0);
    }

    if (macKey != 0) {
        unichar equivalent[1] = {macKey};
        theKeyEquivalent = [NSString stringWithCharacters:equivalent length:1];
    } else {
        theKeyEquivalent = @"";
    }

    [((CMenuItem *)jlong_to_ptr(menuItemObj)) setJavaLabel:theLabel shortcut:theKeyEquivalent modifierMask:mods];
JNF_COCOA_EXIT(env);
}

/*
 * Class:     sun_lwawt_macosx_CMenuItem
 * Method:    nativeSetTooltip
 * Signature: (JLjava/lang/String;)V
 */
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CMenuItem_nativeSetTooltip
(JNIEnv *env, jobject peer, jlong menuItemObj, jstring tooltip)
{
JNF_COCOA_ENTER(env);
    NSString *theTooltip = JNFJavaToNSString(env, tooltip);
    [((CMenuItem *)jlong_to_ptr(menuItemObj)) setJavaToolTipText:theTooltip];
JNF_COCOA_EXIT(env);
}

/*
 * Class:     sun_lwawt_macosx_CMenuItem
 * Method:    nativeSetImage
 * Signature: (JJ)V
 */
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CMenuItem_nativeSetImage
(JNIEnv *env, jobject peer, jlong menuItemObj, jlong image)
{
JNF_COCOA_ENTER(env);
    [((CMenuItem *)jlong_to_ptr(menuItemObj)) setJavaImage:(NSImage*)jlong_to_ptr(image)];
JNF_COCOA_EXIT(env);
}

/*
 * Class:     sun_lwawt_macosx_CMenuItem
 * Method:    nativeCreate
 * Signature: (JZ)J
 */
JNIEXPORT jlong JNICALL
Java_sun_lwawt_macosx_CMenuItem_nativeCreate
    (JNIEnv *env, jobject peer, jlong parentCMenuObj, jboolean isSeparator)
{

    CMenuItem *aCMenuItem = nil;
    CMenu *parentCMenu = (CMenu *)jlong_to_ptr(parentCMenuObj);
JNF_COCOA_ENTER(env);

    jobject cPeerObjGlobal = (*env)->NewGlobalRef(env, peer);

    NSMutableArray *args = nil;

    // Create a new item....
    if (isSeparator == JNI_TRUE) {
        args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:YES],  nil];
    } else {
        args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:NO],  nil];
    }

    [ThreadUtilities performOnMainThread:@selector(_createMenuItem_OnAppKitThread:) on:[CMenuItem alloc] withObject:args waitUntilDone:YES];

    aCMenuItem = (CMenuItem *)[args objectAtIndex: 0];

    if (aCMenuItem == nil) {
        return 0L;
    }

    // and add it to the parent item.
    [parentCMenu addJavaMenuItem: aCMenuItem];

    // setLabel will be called after creation completes.

    if (aCMenuItem) {
        CFRetain(aCMenuItem); // GC
        [aCMenuItem release];
    }

JNF_COCOA_EXIT(env);
    return ptr_to_jlong(aCMenuItem);
}

/*
 * Class:     sun_lwawt_macosx_CMenuItem
 * Method:    nativeSetEnabled
 * Signature: (JZ)V
 */
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CMenuItem_nativeSetEnabled
(JNIEnv *env, jobject peer, jlong menuItemObj, jboolean enable)
{
JNF_COCOA_ENTER(env);
    CMenuItem *item = (CMenuItem *)jlong_to_ptr(menuItemObj);
    [item setJavaEnabled: (enable == JNI_TRUE)];
JNF_COCOA_EXIT(env);
}

/*
 * Class:     sun_lwawt_macosx_CCheckboxMenuItem
 * Method:    nativeSetState
 * Signature: (IZ)V
 */
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CCheckboxMenuItem_nativeSetState
(JNIEnv *env, jobject peer, jlong menuItemObj, jboolean state)
{
JNF_COCOA_ENTER(env);
    CMenuItem *item = (CMenuItem *)jlong_to_ptr(menuItemObj);
    [item setJavaState: (state == JNI_TRUE)];
JNF_COCOA_EXIT(env);
}

/*
 * Class:     sun_lwawt_macosx_CCheckboxMenuItem
 * Method:    nativeSetState
 * Signature: (IZ)V
 */
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CCheckboxMenuItem_nativeSetIsCheckbox
(JNIEnv *env, jobject peer, jlong menuItemObj)
{
JNF_COCOA_ENTER(env);
    CMenuItem *item = (CMenuItem *)jlong_to_ptr(menuItemObj);
    [item setIsCheckbox];
JNF_COCOA_EXIT(env);
}
