import util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.io.*;
import java.util.*;

public class DesktopButton extends JButton implements DropTargetListener {
    
    Paint backgroundPaint;
    DropTarget dropTarget;

    public DesktopButton() {
	// Set up appearance:
	setBorderPainted(false);
	setFocusPainted(false);
	// setContentAreaFilled(false);  /* Purpose was to prevent button
				         /* from highlighting when pressed.
				          * Not needed, since paintComponent
					  * method has been overridden. */
	
	setSize(300,300);
	setPreferredSize(new Dimension(300,300));
	setMinimumSize(new Dimension(300,300));
	backgroundPaint = new GradientPaint(new Point(0,0),Color.green,new Point(200,0),Color.blue);

	// Set up DND:
	dropTarget = new DropTarget(this,this); 
    }

    public void paintComponent(Graphics g) {
	((Graphics2D)g).setPaint(backgroundPaint);
	g.fillRect(0,0,getWidth(),getHeight());
    }
    
    /** Interface DropTargetListener */
    public void dragEnter (DropTargetDragEvent dtde)
    {
	Debug.print("drop target entered in drag");
	// Examine the available DataFlavors.  If no acceptable flavor
	// is found, we will reject the drag.
	DataFlavor[] flavors = dtde.getCurrentDataFlavors();
	if (okFlavor(flavors))
	    dtde.acceptDrag (DnDConstants.ACTION_MOVE);
	else dtde.rejectDrag();
    }
    
    public void dragExit (DropTargetEvent dropTargetEvent) {}
    public void dragOver (DropTargetDragEvent dropTargetDragEvent) {}
    public void dropActionChanged (DropTargetDragEvent dropTargetDragEvent){}
    
    public synchronized void drop (DropTargetDropEvent dtde) {
	try {
	    Debug.print("drop attempted");
	    Transferable tr = dtde.getTransferable();
	    DataFlavor[] flavors = tr.getTransferDataFlavors();
	    if (okFlavor(flavors)) {
		dtde.acceptDrop(DnDConstants.ACTION_MOVE);
		String[] data = getText(tr);
		boolean reposition = false;
		for (int i=0; i<data.length; i++) 
		    if (data[i].equals("Reposition me"))
			reposition = true;
		if (reposition && tr.isDataFlavorSupported(new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType))) {
		    Object transferData = tr.getTransferData(new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType));
		    ((JComponent)transferData).setLocation(dtde.getLocation()); 		} else {
		    System.err.println ("Rejected");
		    dtde.rejectDrop();
		}
		dtde.getDropTargetContext().dropComplete(true);
	    } else {
		System.err.println ("Rejected");
		dtde.rejectDrop();
	    }
	} catch (Exception e) {
	    e.printStackTrace();
	    dtde.rejectDrop();
	}
    }
    
    /** Utility function for use in deciding whether or not to 
     *  accept drags and drops. 
     */
    public boolean okFlavor(DataFlavor[] flavors) {
	Debug.print("Available flavors:");
	boolean accept = false;
	if (flavors.length==0)
	    Debug.print("  none");
	else for (int i=0; i<flavors.length; i++) {
	    Debug.print("  " + flavors[i].getMimeType());
	    if (flavors[i].getMimeType().startsWith("text/plain")) {
		accept = true;
		Debug.print("    (acceptable)");
	    } else if (flavors[i].isFlavorSerializedObjectType()) {
		accept = true;
		Debug.print("    (acceptable)");
	    }
	}
	return accept;
    }

    /** Utility function for getting the text content of a transferable.
     */
    private String[] getText(Transferable t) {
	DataFlavor[] flavors = t.getTransferDataFlavors();
	Vector v = new Vector();
	try {
	    for (int i=0; i<flavors.length; i++) {
		// Is i'th flavor a type of text?  If so, add it to v.
		if (flavors[i].isMimeTypeEqual(DataFlavor.stringFlavor)) 
		    v.add(t.getTransferData(flavors[i]));
		else if (flavors[i].getMimeType().startsWith("text/plain")) {
		    BufferedReader in = new BufferedReader(flavors[i].getReaderForText(t));
		    v.add(in.readLine());
		    in.close();
		}
	    }
	} catch (Exception e) {
	    e.printStackTrace();
	}
	// Copy the text over into a String[].
	String[] rv = new String[v.size()];
	for (int i=0; i<rv.length; i++) {
	    rv[i] = (String)v.elementAt(i);
	    Debug.print("Why do you say, \"" + rv[i] + "?\"");
	}
	return rv;
    }
    
}




