///////////////////////////////////////////////////////////////////////////////
// Name:        src/osx/iphone/menuitem.mm
// Purpose:     wxMenuItem implementation
// Author:      Stefan Csomor
// Created:     1998-01-01
// Copyright:   (c) Stefan Csomor
// Licence:     wxWindows licence
///////////////////////////////////////////////////////////////////////////////

#include "wx/wxprec.h"

#include "wx/menuitem.h"
#include "wx/stockitem.h"

#if wxUSE_MENUS

#ifndef WX_PRECOMP
    #include "wx/app.h"
    #include "wx/log.h"
    #include "wx/menu.h"
#endif // WX_PRECOMP

#include "wx/osx/private.h"

// a mapping from wx ids to standard osx actions in order to support the native menu item handling
// if a new mapping is added, make sure the wxNonOwnedWindowController has a handler for this action as well

struct Mapping
{
    int menuid;
    SEL action;
};

Mapping sActionToWXMapping[] =
{
// as we don't have NSUndoManager support we must not use the native actions
#if 0
    { wxID_UNDO, @selector(undo:) },
    { wxID_REDO, @selector(redo:) },
#endif
    { wxID_CUT, @selector(cut:) },
    { wxID_COPY, @selector(copy:) },
    { wxID_PASTE, @selector(paste:) },
    { wxID_CLEAR, @selector(delete:) },
    { wxID_SELECTALL, @selector(selectAll:) },
    { 0, nullptr }
};

int wxOSXGetIdFromSelector(SEL action )
{
    int i = 0 ;
    while ( sActionToWXMapping[i].action != nil )
    {
        if ( sActionToWXMapping[i].action == action )
            return sActionToWXMapping[i].menuid;
        ++i;
    }

    return 0;
}

SEL wxOSXGetSelectorFromID(int menuId )
{
    int i = 0 ;
    while ( sActionToWXMapping[i].action != nil )
    {
        if ( sActionToWXMapping[i].menuid == menuId )
            return sActionToWXMapping[i].action;
        ++i;
    }

    return nil;
}

/*
void wxMacCocoaMenuItemSetAccelerator( UIMenuItem* menuItem, wxAcceleratorEntry* entry )
{
    if ( entry == nullptr )
    {
        [menuItem setKeyEquivalent:@""];
        return;
    }

#if 0 //  TODO wxIOS wxUSE_ACCEL
    unsigned int modifiers = 0 ;
    int key = entry->GetKeyCode() ;
    if ( key )
    {
        if (entry->GetFlags() & wxACCEL_CTRL)
            modifiers |= NSCommandKeyMask;

        if (entry->GetFlags() & wxACCEL_RAW_CTRL)
            modifiers |= NSControlKeyMask;

        if (entry->GetFlags() & wxACCEL_ALT)
            modifiers |= NSAlternateKeyMask ;

        // this may be ignored later for alpha chars

        if (entry->GetFlags() & wxACCEL_SHIFT)
            modifiers |= NSShiftKeyMask ;

        unichar shortcut = 0;
        if ( key >= WXK_F1 && key <= WXK_F15 )
        {
            shortcut = NSF1FunctionKey + ( key - WXK_F1 );
        }
        else
        {
            switch ( key )
            {
                case WXK_CLEAR :
                    shortcut = NSDeleteCharacter ;
                    break ;

                case WXK_PAGEUP :
                    shortcut = NSPageUpFunctionKey ;
                    break ;

                case WXK_PAGEDOWN :
                    shortcut = NSPageDownFunctionKey ;
                    break ;

                case WXK_NUMPAD_LEFT :
                    modifiers |= NSNumericPadKeyMask;
                    wxFALLTHROUGH;
                case WXK_LEFT :
                    shortcut = NSLeftArrowFunctionKey ;
                    break ;

                case WXK_NUMPAD_UP :
                    modifiers |= NSNumericPadKeyMask;
                    wxFALLTHROUGH;
                case WXK_UP :
                    shortcut = NSUpArrowFunctionKey ;
                    break ;

                case WXK_NUMPAD_RIGHT :
                    modifiers |= NSNumericPadKeyMask;
                    wxFALLTHROUGH;
                case WXK_RIGHT :
                    shortcut = NSRightArrowFunctionKey ;
                    break ;

                case WXK_NUMPAD_DOWN :
                    modifiers |= NSNumericPadKeyMask;
                    wxFALLTHROUGH;
                case WXK_DOWN :
                    shortcut = NSDownArrowFunctionKey ;
                    break ;

                case WXK_HOME :
                    shortcut = NSHomeFunctionKey ;
                    break ;

                case WXK_END :
                    shortcut = NSEndFunctionKey ;
                    break ;

                case WXK_NUMPAD_ENTER :
                    shortcut = NSEnterCharacter;
                    break;

                case WXK_BACK :
                case WXK_RETURN :
                case WXK_TAB :
                case WXK_ESCAPE :
                default :
                    if(entry->GetFlags() & wxACCEL_SHIFT)
                        shortcut = toupper(key);
                    else
                        shortcut = tolower(key);
                    break ;
            }
        }

        [menuItem setKeyEquivalent:[NSString stringWithCharacters:&shortcut length:1]];
        [menuItem setKeyEquivalentModifierMask:modifiers];
    }
#endif // wxUSE_ACCEL
}

*/

class wxMenuItemIPhoneImpl : public wxMenuItemImpl
{
public :
    wxMenuItemIPhoneImpl( wxMenuItem* peer, UIMenuElement* item ) : wxMenuItemImpl(peer), m_osxMenuItem(wxCFRetain(item))
    {
    }

    ~wxMenuItemIPhoneImpl();

    void SetBitmap( const wxBitmapBundle& bitmap ) override
    {
    }

    void Enable( bool enable ) override
    {
        UIMenuElement* menuElement = m_osxMenuItem.get();
        if ( [menuElement isKindOfClass:UIAction.class] )
        {
            UIAction* action = (UIAction*) menuElement;
            if ( enable )
                action.attributes = action.attributes & ~UIMenuElementAttributesDisabled;
            else
                action.attributes = action.attributes | UIMenuElementAttributesDisabled;
        }
    }

    void Check( bool check ) override
    {
        UIMenuElement* menuElement = m_osxMenuItem.get();
        if ( [menuElement isKindOfClass:UIAction.class] )
        {
            UIAction* action = (UIAction*) menuElement;
            action.state = check ? UIMenuElementStateOn : UIMenuElementStateOff;
        }
    }

    void Hide( bool hide ) override
    {
        UIMenuElement* menuElement = m_osxMenuItem.get();
        if ( [menuElement isKindOfClass:UIAction.class] )
        {
            UIAction* action = (UIAction*) menuElement;
            if ( hide )
                action.attributes = action.attributes | UIMenuElementAttributesHidden;
            else
                action.attributes = action.attributes & ~UIMenuElementAttributesHidden;
        }
    }

    void SetLabel( const wxString& text, wxAcceleratorEntry *entry ) override
    {
        // recreate, it's readonly
    }

    bool DoDefault() override;

    void * GetHMenuItem() override { return m_osxMenuItem; }

protected :
    wxCFRef<UIMenuElement*> m_osxMenuItem ;
} ;

wxMenuItemIPhoneImpl::~wxMenuItemIPhoneImpl()
{
}

bool wxMenuItemIPhoneImpl::DoDefault()
{
    bool handled=false;
    int menuid = m_peer->GetId();

#if 0 //  TODO wxIOS
    NSApplication *theNSApplication = [NSApplication sharedApplication];
    if (menuid == wxID_OSX_HIDE)
    {
        [theNSApplication hide:nil];
        handled=true;
    }
    else if (menuid == wxID_OSX_HIDEOTHERS)
    {
        [theNSApplication hideOtherApplications:nil];
        handled=true;
    }
    else if (menuid == wxID_OSX_SHOWALL)
    {
        [theNSApplication unhideAllApplications:nil];
        handled=true;
    }
    else if (menuid == wxApp::s_macExitMenuItemId)
    {
        wxTheApp->ExitMainLoop();
    }
#endif
    return handled;
}

wxMenuItemImpl* wxMenuItemImpl::Create( wxMenuItem* peer, wxMenu *pParentMenu,
                       int menuid,
                       const wxString& text,
                       wxAcceleratorEntry *entry,
                       const wxString& WXUNUSED(strHelp),
                       wxItemKind kind,
                       wxMenu *pSubMenu )
{
    wxMenuItemImpl* c = nullptr;
    UIMenuElement* item = nil;

    if ( kind == wxITEM_SEPARATOR )
    {
        UIAction* menuItem = [UIAction actionWithTitle:@"" image:nil identifier:nil handler: ^( UIAction* action) {} ];
        item = menuItem;
    }
    else
    {
        wxCFStringRef cfText(text);

        if ( pSubMenu )
        {
            pSubMenu->GetPeer()->SetTitle( text );
            UIMenu* submenu = pSubMenu->GetHMenu();
            item = submenu;
        }
        else
        {
            wxString identifier = wxString::Format( wxT("%p"), peer );
            wxCFStringRef cfidentifier(identifier);
            // currently in the iOS 14 Beta UICommands trigger a layout violation so stick with UIActions for the time being
            if ( entry )
            {
                //  TODO UIKeyCommand* command = [UIKeyCommand commandWithTitle ...]

                UIAction* menuitem = [UIAction actionWithTitle:cfText.AsNSString() image:nil identifier:cfidentifier.AsNSString()
                                                   handler: ^( UIAction* action) { peer->GetMenu()->HandleCommandProcess(peer);} ];
                item = menuitem;
            }
            else
            {
                /*
                UICommand* command = [UICommand commandWithTitle:cfText.AsNSString() image:nil action:@selector(menuItemAction:) propertyList:nil];
                 */

                UIAction* menuitem = [UIAction actionWithTitle:cfText.AsNSString() image:nil identifier:cfidentifier.AsNSString()
                                                   handler: ^( UIAction* action) { peer->GetMenu()->HandleCommandProcess(peer);} ];
                item = menuitem;
            }
        }
    }
    c = new wxMenuItemIPhoneImpl( peer, item );
    return c;
}

#endif
