package charactermanaj.ui;

import java.awt.Desktop;
import java.awt.Image;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.logging.Logger;

import javax.imageio.ImageIO;

import charactermanaj.Main;

/**
 * Mac OS X用のOracle JDK9以降のメインフレームサポートクラス.<br>
 * スクリーンメニューのハンドラなどを接続している.<br>
 *
 * JDK9以降はAppleのeawtがなくなってOracleのAPIを使う必要があるため.<br>
 * @author seraphy
 */
public class MainFramePartialForMacOSX9 {

	/**
	 * ロガー
	 */
	private static final Logger logger = Logger.getLogger(MainFramePartialForMacOSX.class.getName());

	private MainFramePartialForMacOSX9() {
		super();
	}

	/**
	 * DockIconを設定する
	 *
	 * @throws Exception 失敗した場合
	 */
	public static void setupDockIcon() throws Exception {
		Class<?> taskbarCls = Class.forName("java.awt.Taskbar");
		Object taskbar = taskbarCls.getMethod("getTaskbar").invoke(null);
		Method setIconImageMethod = taskbarCls.getMethod("setIconImage", Image.class);
		Image icon = ImageIO.read(Main.class.getResource("/icons/icon.png"));
		setIconImageMethod.invoke(taskbar, icon);
	}

	/**
	 * スクリーンメニューを設定する
	 *
	 * @param mainFrame メインフレーム
	 * @throws Exception 失敗
	 */
	public static void setupScreenMenu() throws Exception {
		// Java9以降であればOracle実装でスクリーンメニュー類を設定する.
		// (jdk5でコンパイルする都合上、無理矢理リフレクション経由のDynamicProxyでハンドラを作っている)

		Desktop desktop = Desktop.getDesktop();
		Class<?> aboutHandlerCls = Class.forName("java.awt.desktop.AboutHandler");
		Object aboutHandler = Proxy.newProxyInstance(Main.class.getClassLoader(),
				new Class<?>[] { aboutHandlerCls }, new InvocationHandler() {
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						if (method.getName().equals("handleAbout")) {
							MainFrame.getActivedMainFrame().onAbout();
							return null;
						}
						logger.warning("aboutHandler called=" + method.getName());
						return null;
					}
				});
		desktop.getClass().getMethod("setAboutHandler", aboutHandlerCls).invoke(desktop, aboutHandler);

		Class<?> preferenceHandlerCls = Class.forName("java.awt.desktop.PreferencesHandler");
		Object preferenceHandler = Proxy.newProxyInstance(Main.class.getClassLoader(),
				new Class<?>[] { preferenceHandlerCls }, new InvocationHandler() {
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						if (method.getName().equals("handlePreferences")) {
							MainFrame.getActivedMainFrame().onPreferences();
							return null;
						}
						logger.warning("preferenceHandler called=" + method.getName());
						return null;
					}
				});
		desktop.getClass().getMethod("setPreferencesHandler",
				preferenceHandlerCls).invoke(desktop, preferenceHandler);

		Class<?> quitHandlerCls = Class.forName("java.awt.desktop.QuitHandler");
		Object quitHandler = Proxy.newProxyInstance(Main.class.getClassLoader(),
				new Class<?>[] { quitHandlerCls }, new InvocationHandler() {
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						if (method.getName().equals("handleQuitRequestWith")) {
							MainFrame.closeAllProfiles();
							System.exit(0);
							return null;
						}
						logger.warning("quitHandler called=" + method.getName());
						return null;
					}
				});
		desktop.getClass().getMethod("setQuitHandler", quitHandlerCls).invoke(desktop, quitHandler);
	}
}
