/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.menubar;

import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;


/**
 * On Mac, {@link MenuBarEnhancer#setupMenu} plugs a listener on the About and the
 * Preferences menu items of the standard "application" menu in the menu bar.
 * On Windows or Linux, it adds relevant items to a given {@link Menu} linked to
 * the same listeners.
 */
public final class MenuBarEnhancer {

    private MenuBarEnhancer() {
    }

    /**
     * Creates an instance of {@link IMenuBarEnhancer} specific to the current platform
     * and invoke its {@link IMenuBarEnhancer#setupMenu} to updates the menu bar.
     * <p/>
     * Depending on the platform, this will either hook into the existing About menu item
     * and a Preferences or Options menu item or add new ones to the given {@code swtMenu}.
     * Depending on the platform, the menu items might be decorated with the
     * given {@code appName}.
     * <p/>
     * Potential errors are reported through {@link IMenuBarCallback}.
     *
     * @param appName Name used for the About menu item and similar. Must not be null.
     * @param swtMenu For non-mac platform this is the menu where the "About" and
     *          the "Options" menu items are created. Typically the menu might be
     *          called "Tools". Must not be null.
     * @param callbacks Callbacks called when "About" and "Preferences" menu items are invoked.
     *          Must not be null.
     * @return A actual {@link IMenuBarEnhancer} implementation. Never null.
     *          This is currently not of any use for the caller but is left in case
     *          we want to expand the functionality later.
     */
    public static IMenuBarEnhancer setupMenu(
            String appName,
            final Menu swtMenu,
            IMenuBarCallback callbacks) {

        IMenuBarEnhancer enhancer = getEnhancer(callbacks);

        // Default implementation for generic platforms
        if (enhancer == null) {
            enhancer = new IMenuBarEnhancer() {

                public MenuBarMode getMenuBarMode() {
                    return MenuBarMode.GENERIC;
                }

                public void setupMenu(
                        String appName,
                        Display display,
                        final IMenuBarCallback callbacks) {
                    if (swtMenu.getItemCount() > 0) {
                        new MenuItem(swtMenu, SWT.SEPARATOR);
                    }

                    // Note: we use "Preferences" on Mac and "Options" on Windows/Linux.
                    final MenuItem pref = new MenuItem(swtMenu, SWT.NONE);
                    pref.setText("&Options...");

                    final MenuItem about = new MenuItem(swtMenu, SWT.NONE);
                    about.setText("&About...");

                    pref.addSelectionListener(new SelectionAdapter() {
                        @Override
                        public void widgetSelected(SelectionEvent e) {
                            try {
                                pref.setEnabled(false);
                                callbacks.onPreferencesMenuSelected();
                                super.widgetSelected(e);
                            } finally {
                                pref.setEnabled(true);
                            }
                        }
                    });

                    about.addSelectionListener(new SelectionAdapter() {
                        @Override
                        public void widgetSelected(SelectionEvent e) {
                            try {
                                about.setEnabled(false);
                                callbacks.onAboutMenuSelected();
                                super.widgetSelected(e);
                            } finally {
                                about.setEnabled(true);
                            }
                        }
                    });
                }
            };
        }

        enhancer.setupMenu(appName, swtMenu.getDisplay(), callbacks);
        return enhancer;
    }


    public static IMenuBarEnhancer setupMenuManager(
            String appName,
            Display display,
            final IMenuManager menuManager,
            final IAction aboutAction,
            final IAction preferencesAction,
            final IAction quitAction) {

        IMenuBarCallback callbacks = new IMenuBarCallback() {
            public void printError(String format, Object... args) {
                System.err.println(String.format(format, args));
            }

            public void onPreferencesMenuSelected() {
                if (preferencesAction != null) {
                    preferencesAction.run();
                }
            }

            public void onAboutMenuSelected() {
                if (aboutAction != null) {
                    aboutAction.run();
                }
            }
        };

        IMenuBarEnhancer enhancer = getEnhancer(callbacks);

        // Default implementation for generic platforms
        if (enhancer == null) {
            enhancer = new IMenuBarEnhancer() {

                public MenuBarMode getMenuBarMode() {
                    return MenuBarMode.GENERIC;
                }

                public void setupMenu(
                        String appName,
                        Display display,
                        final IMenuBarCallback callbacks) {
                    if (!menuManager.isEmpty()) {
                        menuManager.add(new Separator());
                    }

                    if (aboutAction != null) {
                        menuManager.add(aboutAction);
                    }
                    if (preferencesAction != null) {
                        menuManager.add(preferencesAction);
                    }
                    if (quitAction != null) {
                        if (aboutAction != null || preferencesAction != null) {
                            menuManager.add(new Separator());
                        }
                        menuManager.add(quitAction);
                    }
                }
            };
        }

        enhancer.setupMenu(appName, display, callbacks);
        return enhancer;
    }

    private static IMenuBarEnhancer getEnhancer(IMenuBarCallback callbacks) {
        IMenuBarEnhancer enhancer = null;
        String p = SWT.getPlatform();
        String className = null;
        if ("cocoa".equals(p)) {                                                  //$NON-NLS-1$
            className = "com.android.menubar.internal.MenuBarEnhancerCocoa";      //$NON-NLS-1$
        }

        if (System.getenv("DEBUG_SWTMENUBAR") != null) {
            callbacks.printError("DEBUG SwtMenuBar: SWT=%1$s, class=%2$s", p, className);
        }

        if (className != null) {
            try {
                Class<?> clazz = Class.forName(className);
                enhancer = (IMenuBarEnhancer) clazz.newInstance();
            } catch (Exception e) {
                // Log an error and fallback on the default implementation.
                callbacks.printError(
                        "Failed to instantiate %1$s: %2$s",                       //$NON-NLS-1$
                        className,
                        e.toString());
            }
        }
        return enhancer;
    }
}
