/*
 * Copyright 2003-2007 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.awt.X11;

import java.awt.AWTKeyStroke;
import java.util.logging.*;
import sun.awt.SunToolkit;
import java.awt.Component;
import java.awt.Container;

/**
 * Helper class implementing XEmbed protocol handling routines(client side)
 * Window which wants to participate in a protocol should create an instance,
 * call install and forward all XClientMessageEvents to it.
 */
public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher {
    private static final Logger xembedLog = Logger.getLogger("sun.awt.X11.xembed.XEmbedClientHelper");

    private XEmbeddedFramePeer embedded;
    private boolean active;
    private long server;
    private boolean applicationActive;

    XEmbedClientHelper() {
        super();
    }

    void install(XEmbeddedFramePeer embedded) {
        this.embedded = embedded;

        if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Installing xembedder on " + embedded);
        XToolkit.addEventDispatcher(embedded.getWindow(), this);
        long[] info = new long[] { XEMBED_VERSION, XEMBED_MAPPED };
        long data = Native.card32ToData(info);
        try {
            XEmbedInfo.setAtomData(embedded.getWindow(), data, 2);
        } finally {
            unsafe.freeMemory(data);
        }
        // XEmbeddedFrame is initially created with a null parent..
        // Here it is reparented to the proper parent window.
        long parentWindow = embedded.getParentWindowHandle();
        if (parentWindow != 0) {
            XToolkit.awtLock();
            try {
                XlibWrapper.XReparentWindow(XToolkit.getDisplay(),
                                            embedded.getWindow(),
                                            parentWindow,
                                            0, 0);
            } finally {
                XToolkit.awtUnlock();
            }
        }
        notifyReady();
    }

    void handleClientMessage(XEvent xev) {
        XClientMessageEvent msg = xev.get_xclient();
        if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine(msg.toString());
        if (msg.get_message_type() == XEmbed.getAtom()) {
            if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Embedded message: " + msgidToString((int)msg.get_data(1)));
            switch ((int)msg.get_data(1)) {
              case XEMBED_EMBEDDED_NOTIFY: // Notification about embedding protocol start
                  // NOTE: May be called two times because we send _SUN_XEMBED_START
                  active = true;
                  server = getEmbedder(embedded, msg);
                  // Check if window is reparented. If not - it was created with
                  // parent and so we should update it here.
                  if (!embedded.isReparented()) {
                      embedded.setReparented(true);
                      embedded.updateSizeHints();
                  }
                  embedded.notifyStarted();
                  break;
              case XEMBED_WINDOW_ACTIVATE:
                  applicationActive = true;
                  break;
              case XEMBED_WINDOW_DEACTIVATE:
                  if (applicationActive) {
                      applicationActive = false;
                      handleWindowFocusOut();
                  }
                  break;
              case XEMBED_FOCUS_IN: // We got focus!
                  // Check for direction
                  handleFocusIn((int)msg.get_data(2));
                  break;
              case XEMBED_FOCUS_OUT:
                  if (applicationActive) {
                      handleWindowFocusOut();
                  }
                  break;
            }
        }
    }
    void handleFocusIn(int detail) {
        if (embedded.focusAllowedFor()) {
            embedded.handleWindowFocusInSync(0);
        }
        switch(detail) {
          case XEMBED_FOCUS_CURRENT:
              // Do nothing - just restore to the current value
              break;
          case XEMBED_FOCUS_FIRST:
              SunToolkit.executeOnEventHandlerThread(embedded.target, new Runnable() {
                      public void run() {
                          Component comp = ((Container)embedded.target).getFocusTraversalPolicy().getFirstComponent((Container)embedded.target);
                          if (comp != null) {
                              comp.requestFocusInWindow();
                          }
                      }});
              break;
          case XEMBED_FOCUS_LAST:
              SunToolkit.executeOnEventHandlerThread(embedded.target, new Runnable() {
                      public void run() {
                          Component comp = ((Container)embedded.target).getFocusTraversalPolicy().getLastComponent((Container)embedded.target);
                          if (comp != null) {
                              comp.requestFocusInWindow();
                          }
                      }});
              break;
        }
    }

    public void dispatchEvent(XEvent xev) {
        switch(xev.get_type()) {
          case XlibWrapper.ClientMessage:
              handleClientMessage(xev);
              break;
          case XlibWrapper.ReparentNotify:
              handleReparentNotify(xev);
              break;
        }
    }
    public void handleReparentNotify(XEvent xev) {
        XReparentEvent re = xev.get_xreparent();
        server = re.get_parent();
    }
    boolean requestFocus() {
        if (active && embedded.focusAllowedFor()) {
            sendMessage(server, XEMBED_REQUEST_FOCUS);
            return true;
        }
        return false;
    }
    void handleWindowFocusOut() {
        // fix for 6269309: it is possible that we call this method twice
        // (for example, when receiving XEMBED_WINDOW_DEACTIVATE and then
        // XEMBED_FOCUS_OUT client messages), so we first need to check if
        // embedded is an active window before sending WINDOW_LOST_FOCUS
        // to shared code
        if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == embedded.target) {
            embedded.handleWindowFocusOutSync(null, 0);
        }
    }

    long getEmbedder(XWindowPeer embedded, XClientMessageEvent info) {
        // Embedder is the parent of embedded.
        return XlibUtil.getParentWindow(embedded.getWindow());
    }

    boolean isApplicationActive() {
        return applicationActive;
    }

    boolean isActive() {
        return active;
    }

    void traverseOutForward() {
        if (active) {
            sendMessage(server, XEMBED_FOCUS_NEXT);
        }
    }

    void traverseOutBackward() {
        if (active) {
            sendMessage(server, XEMBED_FOCUS_PREV);
        }
    }

    void registerAccelerator(AWTKeyStroke stroke, int id) {
        long sym = getX11KeySym(stroke);
        long mods = getX11Mods(stroke);
        sendMessage(server, XEMBED_REGISTER_ACCELERATOR, id, sym, mods);
    }
    void unregisterAccelerator(int id) {
        sendMessage(server, XEMBED_UNREGISTER_ACCELERATOR, id, 0, 0);
    }

    long getX11KeySym(AWTKeyStroke stroke) {
        XToolkit.awtLock();
        try {
            return XWindow.getKeySymForAWTKeyCode(stroke.getKeyCode());
        } finally {
            XToolkit.awtUnlock();
        }
    }

    long getX11Mods(AWTKeyStroke stroke) {
        return XWindow.getXModifiers(stroke);
    }

    void notifyReady() {
        long wnd = server;
        if (wnd == 0) {
            // Server is still 0, get the parent
            wnd = embedded.getParentWindowHandle();
        }
        sendMessage(wnd, _SUN_XEMBED_START);
    }
}
