/*
 * Copyright (c) 2003, 2008, 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.
 */

package sun.awt.X11;

import sun.misc.Unsafe;

import sun.util.logging.PlatformLogger;

import java.awt.AWTKeyStroke;
import java.awt.event.InputEvent;

/**
 * Common class for all XEmbed protocol participating classes.
 * Contains constant definitions and helper routines.
 */
public class XEmbedHelper {
    private static final PlatformLogger xembedLog = PlatformLogger.getLogger("sun.awt.X11.xembed");
    final static Unsafe unsafe = Unsafe.getUnsafe();

    final static int XEMBED_VERSION = 0,
        XEMBED_MAPPED = (1 << 0);
/* XEMBED messages */
    final static int XEMBED_EMBEDDED_NOTIFY     =       0;
    final static int XEMBED_WINDOW_ACTIVATE  =  1;
    final static int XEMBED_WINDOW_DEACTIVATE =         2;
    final static int XEMBED_REQUEST_FOCUS               =3;
    final static int XEMBED_FOCUS_IN    =       4;
    final static int XEMBED_FOCUS_OUT   =       5;
    final static int XEMBED_FOCUS_NEXT  =       6;
    final static int XEMBED_FOCUS_PREV  =       7;
/* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */
    final static int XEMBED_GRAB_KEY = 8;
    final static int XEMBED_UNGRAB_KEY = 9;
    final static int XEMBED_MODALITY_ON         =       10;
    final static int XEMBED_MODALITY_OFF        =       11;
    final static int XEMBED_REGISTER_ACCELERATOR =    12;
    final static int XEMBED_UNREGISTER_ACCELERATOR=   13;
    final static int XEMBED_ACTIVATE_ACCELERATOR  =   14;

    final static int NON_STANDARD_XEMBED_GTK_GRAB_KEY = 108;
    final static int NON_STANDARD_XEMBED_GTK_UNGRAB_KEY = 109;

//     A detail code is required for XEMBED_FOCUS_IN. The following values are valid:
/* Details for  XEMBED_FOCUS_IN: */
    final static int XEMBED_FOCUS_CURRENT       =       0;
    final static int XEMBED_FOCUS_FIRST         =       1;
    final static int XEMBED_FOCUS_LAST  =       2;

// Modifiers bits
    final static int XEMBED_MODIFIER_SHIFT   = (1 << 0);
    final static int XEMBED_MODIFIER_CONTROL = (1 << 1);
    final static int XEMBED_MODIFIER_ALT     = (1 << 2);
    final static int XEMBED_MODIFIER_SUPER   = (1 << 3);
    final static int XEMBED_MODIFIER_HYPER   = (1 << 4);

    static XAtom XEmbedInfo;
    static XAtom XEmbed;

    XEmbedHelper() {
        if (XEmbed == null) {
            XEmbed = XAtom.get("_XEMBED");
            if (xembedLog.isLoggable(PlatformLogger.FINER)) xembedLog.finer("Created atom " + XEmbed.toString());
        }
        if (XEmbedInfo == null) {
            XEmbedInfo = XAtom.get("_XEMBED_INFO");
            if (xembedLog.isLoggable(PlatformLogger.FINER)) xembedLog.finer("Created atom " + XEmbedInfo.toString());
        }
    }

    void sendMessage(long window, int message) {
        sendMessage(window, message, 0, 0, 0);
    }
    void sendMessage(long window, int message, long detail, long data1, long data2) {
        XClientMessageEvent msg = new XClientMessageEvent();
        msg.set_type((int)XConstants.ClientMessage);
        msg.set_window(window);
        msg.set_message_type(XEmbed.getAtom());
        msg.set_format(32);
        msg.set_data(0, XToolkit.getCurrentServerTime());
        msg.set_data(1, message);
        msg.set_data(2, detail);
        msg.set_data(3, data1);
        msg.set_data(4, data2);
        XToolkit.awtLock();
        try {
            if (xembedLog.isLoggable(PlatformLogger.FINE)) xembedLog.fine("Sending " + XEmbedMessageToString(msg));
            XlibWrapper.XSendEvent(XToolkit.getDisplay(), window, false, XConstants.NoEventMask, msg.pData);
        }
        finally {
            XToolkit.awtUnlock();
        }
        msg.dispose();
    }

    static String msgidToString(int msg_id) {
        switch (msg_id) {
          case XEMBED_EMBEDDED_NOTIFY:
              return "XEMBED_EMBEDDED_NOTIFY";
          case XEMBED_WINDOW_ACTIVATE:
              return "XEMBED_WINDOW_ACTIVATE";
          case XEMBED_WINDOW_DEACTIVATE:
              return "XEMBED_WINDOW_DEACTIVATE";
          case XEMBED_FOCUS_IN:
              return "XEMBED_FOCUS_IN";
          case XEMBED_FOCUS_OUT:
              return "XEMBED_FOCUS_OUT";
          case XEMBED_REQUEST_FOCUS:
              return "XEMBED_REQUEST_FOCUS";
          case XEMBED_FOCUS_NEXT:
              return "XEMBED_FOCUS_NEXT";
          case XEMBED_FOCUS_PREV:
              return "XEMBED_FOCUS_PREV";
          case XEMBED_MODALITY_ON:
              return "XEMBED_MODALITY_ON";
          case XEMBED_MODALITY_OFF:
              return "XEMBED_MODALITY_OFF";
          case XEMBED_REGISTER_ACCELERATOR:
              return "XEMBED_REGISTER_ACCELERATOR";
          case XEMBED_UNREGISTER_ACCELERATOR:
              return "XEMBED_UNREGISTER_ACCELERATOR";
          case XEMBED_ACTIVATE_ACCELERATOR:
              return "XEMBED_ACTIVATE_ACCELERATOR";
          case XEMBED_GRAB_KEY:
              return "XEMBED_GRAB_KEY";
          case XEMBED_UNGRAB_KEY:
              return "XEMBED_UNGRAB_KEY";
          case NON_STANDARD_XEMBED_GTK_UNGRAB_KEY:
              return "NON_STANDARD_XEMBED_GTK_UNGRAB_KEY";
          case NON_STANDARD_XEMBED_GTK_GRAB_KEY:
              return "NON_STANDARD_XEMBED_GTK_GRAB_KEY";
          case XConstants.KeyPress | XEmbedServerTester.SYSTEM_EVENT_MASK:
              return "KeyPress";
          case XConstants.MapNotify | XEmbedServerTester.SYSTEM_EVENT_MASK:
              return "MapNotify";
          case XConstants.PropertyNotify | XEmbedServerTester.SYSTEM_EVENT_MASK:
              return "PropertyNotify";
          default:
              return "unknown XEMBED id " + msg_id;
        }
    }

    static String focusIdToString(int focus_id) {
        switch(focus_id) {
          case XEMBED_FOCUS_CURRENT:
              return "XEMBED_FOCUS_CURRENT";
          case XEMBED_FOCUS_FIRST:
              return "XEMBED_FOCUS_FIRST";
          case XEMBED_FOCUS_LAST:
              return "XEMBED_FOCUS_LAST";
          default:
              return "unknown focus id " + focus_id;
        }
    }

    static String XEmbedMessageToString(XClientMessageEvent msg) {
        return ("XEmbed message to " + Long.toHexString(msg.get_window()) + ": " + msgidToString((int)msg.get_data(1)) +
                ", detail: " + msg.get_data(2) +
                ", data:[" + msg.get_data(3) + "," + msg.get_data(4) + "]");

    }


    /**
     * Converts XEMBED modifiers mask into AWT InputEvent mask
     */
    int getModifiers(int state) {
        int mods = 0;
        if ((state & XEMBED_MODIFIER_SHIFT) != 0) {
            mods |= InputEvent.SHIFT_DOWN_MASK;
        }
        if ((state & XEMBED_MODIFIER_CONTROL) != 0) {
            mods |= InputEvent.CTRL_DOWN_MASK;
        }
        if ((state & XEMBED_MODIFIER_ALT) != 0) {
            mods |= InputEvent.ALT_DOWN_MASK;
        }
        // FIXME: What is super/hyper?
        // FIXME: Experiments show that SUPER is ALT. So what is Alt then?
        if ((state & XEMBED_MODIFIER_SUPER) != 0) {
            mods |= InputEvent.ALT_DOWN_MASK;
        }
//         if ((state & XEMBED_MODIFIER_HYPER) != 0) {
//             mods |= InputEvent.DOWN_MASK;
//         }
        return mods;
    }

    // Shouldn't be called on Toolkit thread.
    AWTKeyStroke getKeyStrokeForKeySym(long keysym, long state) {
        XBaseWindow.checkSecurity();

        int keycode;

        XToolkit.awtLock();
        try {
            XKeysym.Keysym2JavaKeycode kc = XKeysym.getJavaKeycode( keysym );
            if(kc == null) {
                keycode = java.awt.event.KeyEvent.VK_UNDEFINED;
            }else{
                keycode = kc.getJavaKeycode();
            }
        } finally {
            XToolkit.awtUnlock();
        }

        int modifiers = getModifiers((int)state);
        return AWTKeyStroke.getAWTKeyStroke(keycode, modifiers);
    }
}
