package TUGLaby;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceContext;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.InvalidDnDOperationException;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.ImageIcon;

/*
 * JBrickPanel.java
 *
 * Created on 25. August 2004, 18:28
 *
 * This is the visual representation of a single dragable condition
 * or action. A new type of dragable instance can easily created by
 * giving a new type name and images
 */

/**
 * 
 * @author auguan@sbox
 */

public class BrickPanel extends javax.swing.JPanel {

    private String brick_type_;

    private Image default_image_;

    private Image current_image_;

    private Image mouse_over_image_;

    private DragSource drag_source_;

    private DragGestureListener drag_gesture_listener_;

    public DragSourceListener drag_rule_listener_;

    private int drag_action_ = DnDConstants.ACTION_COPY; //FIXXME Reformat as

    // const

    /**
     * Creates new form JBrickPanel
     * 
     * @param brick_type
     * @param default_image
     * @param hover_image
     */
    public BrickPanel(String brick_type, Image default_image, Image hover_image) {

        default_image_ = default_image;
        this.mouse_over_image_ = hover_image;
        brick_type_ = brick_type;
        current_image_ = default_image_;

        drag_source_ = DragSource.getDefaultDragSource();
        drag_gesture_listener_ = new DragRuleGestureListener();
        drag_rule_listener_ = new DragRuleSourceListener();

        this.drag_source_.createDefaultDragGestureRecognizer(this,
                this.drag_action_, this.drag_gesture_listener_);

        this.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                current_image_ = mouse_over_image_;
                repaint();
            }

            public void mouseExited(java.awt.event.MouseEvent evt) {
                current_image_ = default_image_;
                repaint();
            }
        });

    }

    /**
     * Set a new bricktype
     * 
     * @param brick_type
     */
    public void setBrickType(String brick_type) {
        this.brick_type_ = brick_type;
    }

    /**
     * Set an new default image
     * 
     * @param default_image
     */
    public void setDefaultImage(Image default_image) {
        this.default_image_ = default_image;

    }

    /*
     * (non-Javadoc) Draws the panel with the given image
     * 
     * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
     */
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.drawImage(current_image_, 0, 0, this);

    }

    /** ************************************************************************ */
    public class DragRuleGestureListener implements DragGestureListener {

        /**
         * Start the drag if the operation is ok. uses
         * java.awt.datatransfer.StringSelection to transfer the label's data
         * 
         * @param e
         *            the event object
         */
        public void dragGestureRecognized(DragGestureEvent e) {

            // if the action is ok we go ahead
            // otherwise we punt
            // System.out.println(e.getDragAction());
            //if((e.getDragAction() & DragLabel.this.dragAction) == 0)
            //  return;
            // System.out.println( "kicking off drag");

            // get the label's text and put it inside a Transferable
            // Transferable transferable = new StringSelection(
            // DragLabel.this.getText() );
            Transferable transferable = new StringSelection(
                    BrickPanel.this.brick_type_);

            // now kick off the drag
            try {
                // initial cursor, transferrable, dsource listener
                e.startDrag(DragSource.DefaultCopyNoDrop, transferable,
                        BrickPanel.this.drag_rule_listener_);

                // or if dragSource is a variable
                // dragSource.startDrag(e, DragSource.DefaultCopyDrop,
                // transferable, dsListener);

                // or if you'd like to use a drag image if supported

                /*
                 * if(DragSource.isDragImageSupported() ) // cursor, image,
                 * point, transferrable, dsource listener
                 * e.startDrag(DragSource.DefaultCopyDrop, image, point,
                 * transferable, dsListener);
                 */

            } catch (InvalidDnDOperationException idoe) {
                // System.err.println( idoe );
            }
        }
    }

    /** ************************************************************************ */
    public class DragRuleSourceListener implements DragSourceListener {
        /**
         * @param e
         *            the event
         */
        public void dragDropEnd(DragSourceDropEvent e) {
            if (e.getDropSuccess() == false) {
                // System.out.println( "not successful");
                return;
            }

            /*
             * the dropAction should be what the drop target specified in
             * acceptDrop
             */
            // System.out.println( "dragdropend action " + e.getDropAction() );
            // this is the action selected by the drop target
            if (e.getDropAction() == DnDConstants.ACTION_MOVE) {
                // System.out.println("ACTION_MOVE choosen by drop target");
            }
        }

        /**
         * @param e
         *            the event
         */
        public void dragEnter(DragSourceDragEvent e) {
            // System.out.println( "draglabel enter " + e);
            DragSourceContext context = e.getDragSourceContext();
            //intersection of the users selected action, and the source and
            // target actions
            int myaction = e.getDropAction();
            if ((myaction & BrickPanel.this.drag_action_) != 0) {
                context.setCursor(DragSource.DefaultCopyDrop);
            } else {
                context.setCursor(DragSource.DefaultCopyNoDrop);
            }

        }

        /**
         * @param e
         *            the event
         */
        public void dragOver(DragSourceDragEvent e) {
            DragSourceContext context = e.getDragSourceContext();
            int sa = context.getSourceActions();
            int ua = e.getUserAction();
            int da = e.getDropAction();
            int ta = e.getTargetActions();
            // System.out.println("dl dragOver source actions" + sa);
            // System.out.println("user action" + ua);
            // System.out.println("drop actions" + da);
            // System.out.println("target actions" + ta);
        }

        /**
         * @param e
         *            the event
         */
        public void dragExit(DragSourceEvent e) {
            // System.out.println( "draglabel exit " + e);
            DragSourceContext context = e.getDragSourceContext();
            BrickPanel.this.current_image_ = BrickPanel.this.default_image_;
            BrickPanel.this.repaint();
        }

        /**
         * for example, press shift during drag to change to a link action
         * 
         * @param e
         *            the event
         */
        public void dropActionChanged(DragSourceDragEvent e) {
            DragSourceContext context = e.getDragSourceContext();
            context.setCursor(DragSource.DefaultCopyNoDrop);
        }

    }
}
