/*
 * Copyright 2003-2005 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.datatransfer.Transferable;

import java.awt.dnd.DnDConstants;
import java.awt.dnd.InvalidDnDOperationException;

import java.util.Map;

/**
 * An abstract class for drag protocols on X11 systems.
 * Contains protocol-independent drag source code.
 *
 * @since 1.5
 */
abstract class XDragSourceProtocol {
    private final XDragSourceProtocolListener listener;

    private boolean initialized = false;

    private long targetWindow = 0;
    private long targetProxyWindow = 0;
    private int targetProtocolVersion = 0;
    private long targetWindowMask = 0;

    // Always use the XAWT root window as the drag source window.
    static long getDragSourceWindow() {
        return XWindow.getXAWTRootWindow().getWindow();
    }

    protected XDragSourceProtocol(XDragSourceProtocolListener listener) {
        if (listener == null) {
            throw new NullPointerException("Null XDragSourceProtocolListener");
        }
        this.listener = listener;
    }

    protected final XDragSourceProtocolListener getProtocolListener() {
        return listener;
    }

    /**
     * Returns the protocol name. The protocol name cannot be null.
     */
    public abstract String getProtocolName();

    /**
     * Initalizes a drag operation with the specified supported drop actions,
     * contents and data formats.
     *
     * @param actions a bitwise mask of <code>DnDConstants</code> that represent
     *                the supported drop actions.
     * @param contents the contents for the drag operation.
     * @param formats an array of Atoms that represent the supported data formats.
     * @param formats an array of Atoms that represent the supported data formats.
     * @throws InvalidDnDOperationException if a drag operation is already
     * initialized.
     * @throws IllegalArgumentException if some argument has invalid value.
     * @throws XException if some X call failed.
     */
    public final void initializeDrag(int actions, Transferable contents,
                                     Map formatMap, long[] formats)
      throws InvalidDnDOperationException,
             IllegalArgumentException, XException {
        XToolkit.awtLock();
        try {
            try {
                if (initialized) {
                    throw new InvalidDnDOperationException("Already initialized");
                }

                initializeDragImpl(actions, contents, formatMap, formats);

                initialized = true;
            } finally {
                if (!initialized) {
                    cleanup();
                }
            }
        } finally {
            XToolkit.awtUnlock();
        }
    }

    /* The caller must hold AWT_LOCK. */
    protected abstract void initializeDragImpl(int actions,
                                               Transferable contents,
                                               Map formatMap, long[] formats)
      throws InvalidDnDOperationException, IllegalArgumentException, XException;

    /**
     * Terminates the current drag operation (if any) and resets the internal
     * state of this object.
     *
     * @throws XException if some X call failed.
     */
    public void cleanup() {
        initialized = false;
        cleanupTargetInfo();
    }

    /**
     * Clears the information on the current drop target.
     *
     * @throws XException if some X call failed.
     */
    public void cleanupTargetInfo() {
        targetWindow = 0;
        targetProxyWindow = 0;
        targetProtocolVersion = 0;
    }

    /**
     * Processes the specified client message event.
     *
     * @returns true if the event was successfully processed.
     */
    public abstract boolean processClientMessage(XClientMessageEvent xclient)
      throws XException;

    /* The caller must hold AWT_LOCK. */
    public final boolean attachTargetWindow(long window, long time) {
        assert XToolkit.isAWTLockHeldByCurrentThread();

        TargetWindowInfo info = getTargetWindowInfo(window);
        if (info == null) {
            return false;
        } else {
            targetWindow = window;
            targetProxyWindow = info.getProxyWindow();
            targetProtocolVersion = info.getProtocolVersion();
            return true;
        }
    }

    /* The caller must hold AWT_LOCK. */
    public abstract TargetWindowInfo getTargetWindowInfo(long window);

    /* The caller must hold AWT_LOCK. */
    public abstract void sendEnterMessage(long[] formats, int sourceAction,
                                          int sourceActions, long time);
    /* The caller must hold AWT_LOCK. */
    public abstract void sendMoveMessage(int xRoot, int yRoot,
                                         int sourceAction, int sourceActions,
                                         long time);
    /* The caller must hold AWT_LOCK. */
    public abstract void sendLeaveMessage(long time);

    /* The caller must hold AWT_LOCK. */
    protected abstract void sendDropMessage(int xRoot, int yRoot,
                                            int sourceAction, int sourceActions,
                                            long time);

    public final void initiateDrop(int xRoot, int yRoot,
                                   int sourceAction, int sourceActions,
                                   long time) {
        XWindowAttributes wattr = new XWindowAttributes();
        try {
            XToolkit.WITH_XERROR_HANDLER(XToolkit.IgnoreBadWindowHandler);
            int status = XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
                                                          targetWindow, wattr.pData);

            XToolkit.RESTORE_XERROR_HANDLER();

            if (status == 0 ||
                (XToolkit.saved_error != null &&
                 XToolkit.saved_error.get_error_code() != XlibWrapper.Success)) {
                throw new XException("XGetWindowAttributes failed");
            }

            targetWindowMask = wattr.get_your_event_mask();
        } finally {
            wattr.dispose();
        }

        XToolkit.WITH_XERROR_HANDLER(XToolkit.IgnoreBadWindowHandler);
        XlibWrapper.XSelectInput(XToolkit.getDisplay(), targetWindow,
                                 targetWindowMask |
                                 XlibWrapper.StructureNotifyMask);

        XToolkit.RESTORE_XERROR_HANDLER();

        if (XToolkit.saved_error != null &&
            XToolkit.saved_error.get_error_code() != XlibWrapper.Success) {
            throw new XException("XSelectInput failed");
        }

        sendDropMessage(xRoot, yRoot, sourceAction, sourceActions, time);
    }

    protected final void finalizeDrop() {
        XToolkit.WITH_XERROR_HANDLER(XToolkit.IgnoreBadWindowHandler);
        XlibWrapper.XSelectInput(XToolkit.getDisplay(), targetWindow,
                                 targetWindowMask);
        XToolkit.RESTORE_XERROR_HANDLER();
    }

    public abstract boolean processProxyModeEvent(XClientMessageEvent xclient,
                                                  long sourceWindow);

    protected final long getTargetWindow() {
        return targetWindow;
    }

    protected final long getTargetProxyWindow() {
        if (targetProxyWindow != 0) {
            return targetProxyWindow;
        } else {
            return targetWindow;
        }
    }

    protected final int getTargetProtocolVersion() {
        return targetProtocolVersion;
    }

    public static class TargetWindowInfo {
        private final long proxyWindow;
        private final int protocolVersion;
        public TargetWindowInfo(long proxy, int version) {
            proxyWindow = proxy;
            protocolVersion = version;
        }
        public long getProxyWindow() {
            return proxyWindow;
        }
        public int getProtocolVersion() {
            return protocolVersion;
        }
    }
}
