/*
 * Copyright (c) 2014 Eike Stepper (Loehne, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.oomph.setup.internal.installer;

import org.eclipse.oomph.util.ReflectUtil;

import org.eclipse.swt.SWTException;
import org.eclipse.swt.widgets.Display;

import java.lang.reflect.Method;

/**
 * @author Eike Stepper
 */
@SuppressWarnings("nls")
public final class CocoaUtil
{
  private static final int ABOUT_ITEM_INDEX = 0;

  private static final int PREFERENCES_ITEM_INDEX = 2;

  private static final int QUIT_ITEM_INDEX = 10;

  private static final String TYPES = "@:@";

  private static Object invoke(Method method, Object target, Object... arguments)
  {
    return ReflectUtil.invokeMethod(method, target, arguments);
  }

  public static void register(Display display, final Runnable about, final Runnable preferences, final Runnable quit)
  {
    try
    {
      final Class<?> NSString = Class.forName("org.eclipse.swt.internal.cocoa.NSString");
      final Method NSString_stringWith = ReflectUtil.getMethod(NSString, "stringWith", String.class);

      final Class<?> Callback = Class.forName("org.eclipse.swt.internal.Callback");
      final Method Callback_getAddress = ReflectUtil.getMethod(Callback, "getAddress");
      final Method Callback_dispose = ReflectUtil.getMethod(Callback, "dispose");

      final Class<?> OS = Class.forName("org.eclipse.swt.internal.cocoa.OS");
      final Method OS_sel_registerName = ReflectUtil.getMethod(OS, "sel_registerName", String.class);
      final Method OS_objc_lookUpClass = ReflectUtil.getMethod(OS, "objc_lookUpClass", String.class);
      final Method OS_class_addMethod = ReflectUtil.getMethod(OS, "class_addMethod", long.class, long.class, long.class, String.class);

      final Class<?> NSApplication = Class.forName("org.eclipse.swt.internal.cocoa.NSApplication");
      final Method NSApplication_sharedApplication = ReflectUtil.getMethod(NSApplication, "sharedApplication");
      final Method NSApplication_mainMenu = ReflectUtil.getMethod(NSApplication, "mainMenu");

      final Class<?> NSMenu = Class.forName("org.eclipse.swt.internal.cocoa.NSMenu");
      final Method NSMenu_itemAtIndex = ReflectUtil.getMethod(NSMenu, "itemAtIndex", long.class);

      final Class<?> NSMenuItem = Class.forName("org.eclipse.swt.internal.cocoa.NSMenuItem");
      final Method NSMenuItem_submenu = ReflectUtil.getMethod(NSMenuItem, "submenu");
      final Method NSMenuItem_setTitle = ReflectUtil.getMethod(NSMenuItem, "setTitle", NSString);
      final Method NSMenuItem_setEnabled = ReflectUtil.getMethod(NSMenuItem, "setEnabled", boolean.class);
      final Method NSMenuItem_setAction = ReflectUtil.getMethod(NSMenuItem, "setAction", long.class);

      final long aboutItemSelected = (Long)invoke(OS_sel_registerName, null, "aboutMenuItemSelected:");
      final long preferencesItemSelected = (Long)invoke(OS_sel_registerName, null, "preferencesMenuItemSelected:");
      final long quitItemSelected = (Long)invoke(OS_sel_registerName, null, "quitMenuItemSelected:");

      Object callbackTarget = new Object()
      {
        @SuppressWarnings("unused")
        long actionProc(long id, long sel, long arg2)
        {
          if (sel == aboutItemSelected)
          {
            if (about != null)
            {
              about.run();
            }
          }
          else if (sel == preferencesItemSelected)
          {
            if (preferences != null)
            {
              preferences.run();
            }
          }
          else if (sel == quitItemSelected)
          {
            if (quit != null)
            {
              quit.run();
            }
          }

          return 0;
        }
      };

      @SuppressWarnings("restriction")
      final org.eclipse.swt.internal.Callback callback = new org.eclipse.swt.internal.Callback(callbackTarget, "actionProc", 3);
      final long callbackPointer = (Long)invoke(Callback_getAddress, callback);
      if (callbackPointer == 0)
      {
        throw new SWTException("No more callbacks");
      }

      final long classPointer = (Long)invoke(OS_objc_lookUpClass, null, "SWTApplicationDelegate");
      invoke(OS_class_addMethod, null, classPointer, aboutItemSelected, callbackPointer, TYPES);
      invoke(OS_class_addMethod, null, classPointer, preferencesItemSelected, callbackPointer, TYPES);
      invoke(OS_class_addMethod, null, classPointer, quitItemSelected, callbackPointer, TYPES);

      final Object application = invoke(NSApplication_sharedApplication, null);
      final Object mainMenu = invoke(NSApplication_mainMenu, application);
      final Object mainItem = invoke(NSMenu_itemAtIndex, mainMenu, (long)0);
      final Object appMenu = invoke(NSMenuItem_submenu, mainItem);

      final Object aboutItem = invoke(NSMenu_itemAtIndex, appMenu, (long)ABOUT_ITEM_INDEX);
      final Object preferencesItem = invoke(NSMenu_itemAtIndex, appMenu, (long)PREFERENCES_ITEM_INDEX);
      final Object quitItem = invoke(NSMenu_itemAtIndex, appMenu, (long)QUIT_ITEM_INDEX);

      final String appName = Display.getAppName();
      if (appName != null)
      {
        final Object aboutLabel = invoke(NSString_stringWith, null, "About " + appName);
        invoke(NSMenuItem_setTitle, aboutItem, aboutLabel);

        final Object quitLabel = invoke(NSString_stringWith, null, "Quit " + appName);
        invoke(NSMenuItem_setTitle, quitItem, quitLabel);
      }

      invoke(NSMenuItem_setAction, aboutItem, aboutItemSelected);
      invoke(NSMenuItem_setAction, preferencesItem, preferencesItemSelected);
      invoke(NSMenuItem_setAction, quitItem, quitItemSelected);

      invoke(NSMenuItem_setEnabled, preferencesItem, true);
      invoke(NSMenuItem_setEnabled, quitItem, true);

      display.disposeExec(new Runnable()
      {
        @Override
        public void run()
        {
          invoke(Callback_dispose, callback);
        }
      });
    }
    catch (Throwable t)
    {
      t.printStackTrace();
    }
  }
}
