/*
 * 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 java.awt.datatransfer.Transferable;
import java.util.SortedMap;
import java.io.IOException;
import java.security.AccessController;
import java.util.HashMap;
import java.util.Map;
import sun.awt.UNIXToolkit;
import sun.awt.datatransfer.DataTransferer;
import sun.awt.datatransfer.SunClipboard;
import sun.awt.datatransfer.ClipboardTransferable;
import sun.security.action.GetIntegerAction;

/**
 * A class which interfaces with the X11 selection service in order to support
 * data transfer via Clipboard operations.
 */
public final class XClipboard extends SunClipboard implements OwnershipListener
{
    private final XSelection selection;
    // Time of calling XConvertSelection().
    private long convertSelectionTime;
    // The flag used not to call XConvertSelection() if the previous SelectionNotify
    // has not been processed by checkChange().
    private volatile boolean isSelectionNotifyProcessed;
    // The property in which the owner should place requested targets
    // when tracking changes of available data flavors (practically targets).
    private volatile XAtom targetsPropertyAtom;

    private static final Object classLock = new Object();

    private static final int defaultPollInterval = 200;

    private static int pollInterval;

    private static Map<Long, XClipboard> targetsAtom2Clipboard;

    /**
     * Creates a system clipboard object.
     */
    public XClipboard(String name, String selectionName) {
        super(name);
        selection = new XSelection(XAtom.get(selectionName));
        selection.registerOwershipListener(this);
    }

    /*
     * NOTE: This method may be called by privileged threads.
     *       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
     */
    public void ownershipChanged(final boolean isOwner) {
        if (isOwner) {
            checkChangeHere(contents);
        } else {
            lostOwnershipImpl();
        }
    }

    protected synchronized void setContentsNative(Transferable contents) {
        SortedMap formatMap = DataTransferer.getInstance().getFormatsForTransferable
                (contents, DataTransferer.adaptFlavorMap(flavorMap));
        long[] formats = DataTransferer.keysToLongArray(formatMap);

        if (!selection.setOwner(contents, formatMap, formats,
                                XToolkit.getCurrentServerTime())) {
            this.owner = null;
            this.contents = null;
        }
    }

    public long getID() {
        return selection.getSelectionAtom().getAtom();
    }

    @Override
    public synchronized Transferable getContents(Object requestor) {
        if (contents != null) {
            return contents;
        }
        return new ClipboardTransferable(this);
    }

    /* Caller is synchronized on this. */
    protected void clearNativeContext() {
        selection.reset();
    }


    protected long[] getClipboardFormats() {
        return selection.getTargets(XToolkit.getCurrentServerTime());
    }

    protected byte[] getClipboardData(long format) throws IOException {
        return selection.getData(format, XToolkit.getCurrentServerTime());
    }

    private void checkChangeHere(Transferable contents) {
        if (areFlavorListenersRegistered()) {
            checkChange(DataTransferer.getInstance().
                        getFormatsForTransferableAsArray(contents, flavorMap));
        }
    }

    private static int getPollInterval() {
        synchronized (XClipboard.classLock) {
            if (pollInterval <= 0) {
                pollInterval = AccessController.doPrivileged(
                        new GetIntegerAction("awt.datatransfer.clipboard.poll.interval",
                                             defaultPollInterval));
                if (pollInterval <= 0) {
                    pollInterval = defaultPollInterval;
                }
            }
            return pollInterval;
        }
    }

    private XAtom getTargetsPropertyAtom() {
        if (null == targetsPropertyAtom) {
            targetsPropertyAtom =
                    XAtom.get("XAWT_TARGETS_OF_SELECTION:" + selection.getSelectionAtom().getName());
        }
        return targetsPropertyAtom;
    }

    protected void registerClipboardViewerChecked() {
        // for XConvertSelection() to be called for the first time in getTargetsDelayed()
        isSelectionNotifyProcessed = true;

        boolean mustSchedule = false;
        synchronized (XClipboard.classLock) {
            if (targetsAtom2Clipboard == null) {
                targetsAtom2Clipboard = new HashMap<Long, XClipboard>(2);
            }
            mustSchedule = targetsAtom2Clipboard.isEmpty();
            targetsAtom2Clipboard.put(getTargetsPropertyAtom().getAtom(), this);
            if (mustSchedule) {
                XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(),
                                            new SelectionNotifyHandler());
            }
        }
        if (mustSchedule) {
            XToolkit.schedule(new CheckChangeTimerTask(), XClipboard.getPollInterval());
        }
    }

    private static class CheckChangeTimerTask implements Runnable {
        public void run() {
            for (XClipboard clpbrd : targetsAtom2Clipboard.values()) {
                clpbrd.getTargetsDelayed();
            }
            synchronized (XClipboard.classLock) {
                if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) {
                    XToolkit.schedule(this, XClipboard.getPollInterval());
                }
            }
        }
    }

    private static class SelectionNotifyHandler implements XEventDispatcher {
        public void dispatchEvent(XEvent ev) {
            if (ev.get_type() == XConstants.SelectionNotify) {
                final XSelectionEvent xse = ev.get_xselection();
                XClipboard clipboard = null;
                synchronized (XClipboard.classLock) {
                    if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) {
                        XToolkit.removeEventDispatcher(XWindow.getXAWTRootWindow().getWindow(), this);
                        return;
                    }
                    final long propertyAtom = xse.get_property();
                    clipboard = targetsAtom2Clipboard.get(propertyAtom);
                }
                if (null != clipboard) {
                    clipboard.checkChange(xse);
                }
            }
        }
    }

    protected void unregisterClipboardViewerChecked() {
        isSelectionNotifyProcessed = false;
        synchronized (XClipboard.classLock) {
            targetsAtom2Clipboard.remove(getTargetsPropertyAtom().getAtom());
        }
    }

    // checkChange() will be called on SelectionNotify
    private void getTargetsDelayed() {
        XToolkit.awtLock();
        try {
            long curTime = System.currentTimeMillis();
            if (isSelectionNotifyProcessed || curTime >= (convertSelectionTime + UNIXToolkit.getDatatransferTimeout()))
            {
                convertSelectionTime = curTime;
                XlibWrapper.XConvertSelection(XToolkit.getDisplay(),
                                              selection.getSelectionAtom().getAtom(),
                                              XDataTransferer.TARGETS_ATOM.getAtom(),
                                              getTargetsPropertyAtom().getAtom(),
                                              XWindow.getXAWTRootWindow().getWindow(),
                                              XConstants.CurrentTime);
                isSelectionNotifyProcessed = false;
            }
        } finally {
            XToolkit.awtUnlock();
        }
    }

    /*
     * Tracks changes of available formats.
     * NOTE: This method may be called by privileged threads.
     *       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
     */
    private void checkChange(XSelectionEvent xse) {
        final long propertyAtom = xse.get_property();
        if (propertyAtom != getTargetsPropertyAtom().getAtom()) {
            // wrong atom
            return;
        }

        final XAtom selectionAtom = XAtom.get(xse.get_selection());
        final XSelection changedSelection = XSelection.getSelection(selectionAtom);

        if (null == changedSelection || changedSelection != selection) {
            // unknown selection - do nothing
            return;
        }

        isSelectionNotifyProcessed = true;

        if (selection.isOwner()) {
            // selection is owner - do not need formats
            return;
        }

        long[] formats = null;

        if (propertyAtom == XConstants.None) {
            // We treat None property atom as "empty selection".
            formats = new long[0];
        } else {
            WindowPropertyGetter targetsGetter =
                new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
                                         XAtom.get(propertyAtom), 0,
                                         XSelection.MAX_LENGTH, true,
                                         XConstants.AnyPropertyType);
            try {
                targetsGetter.execute();
                formats = XSelection.getFormats(targetsGetter);
            } finally {
                targetsGetter.dispose();
            }
        }

        checkChange(formats);
    }
}
