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);
        }

    }
}
