/* ======================================================================
   Parts Copyright 2006 University of Leeds, Oxford University, University of the Highlands and Islands.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

====================================================================== */

package org.bodington.applet.test;

import java.awt.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
import java.util.Hashtable;
import java.util.List;
import java.util.Iterator;
import java.io.*;
import java.io.IOException;
import javax.swing.JList;
import javax.swing.DefaultListModel;

public class DNDList extends javax.swing.JList implements java.awt.dnd.DragGestureListener, java.awt.dnd.DragSourceListener, java.awt.dnd.DropTargetListener, org.bodington.applet.test.DNDComponentInterface
{
  /**
   * enables this component to be a dropTarget
   */

  DropTarget dropTarget = null;

  /**
   * enables this component to be a Drag Source
   */
  DragSource dragSource = null;


  /**
   * constructor - initializes the DropTarget and DragSource.
   */

  public DNDList() {
    
    dropTarget = new DropTarget (this, this);
    dragSource = new DragSource();
    dragSource.createDefaultDragGestureRecognizer( this, DnDConstants.ACTION_MOVE, this);
  }

  /**
   * is invoked when you are dragging over the DropSite
   * 
   */

  public void dragEnter (DropTargetDragEvent event) {
    
    // debug messages for diagnostics 
    System.out.println( "dragEnter");
    event.acceptDrag (DnDConstants.ACTION_MOVE);
  }

  /**
   * is invoked when you are exit the DropSite without dropping
   *
   */

  public void dragExit (DropTargetEvent event) {
    System.out.println( "dragExit");
    
  }

  /**
   * is invoked when a drag operation is going on
   * 
   */

  public void dragOver (DropTargetDragEvent event) {
    System.out.println( "dragOver");
  }

  /**
   * a drop has occurred
   * 
   */

 
  public void drop (DropTargetDropEvent event) {
    
    try {
        Transferable transferable = event.getTransferable();
                   
        // we accept only Strings      
        if (transferable.isDataFlavorSupported (DataFlavor.stringFlavor)){
        
            event.acceptDrop(DnDConstants.ACTION_MOVE);
            String s = (String)transferable.getTransferData ( DataFlavor.stringFlavor);
            addElement( s );
            event.getDropTargetContext().dropComplete(true);
        } 
        else{
            event.rejectDrop();
        }
    }
    catch (IOException exception) {
        exception.printStackTrace();
        System.err.println( "Exception" + exception.getMessage());
        event.rejectDrop();
    } 
    catch (UnsupportedFlavorException ufException ) {
      ufException.printStackTrace();
      System.err.println( "Exception" + ufException.getMessage());
      event.rejectDrop();
    }
  }

  /**
   * is invoked if the use modifies the current drop gesture
   * 
   */
    

  public void dropActionChanged ( DropTargetDragEvent event ) {
  }

  /**
   * a drag gesture has been initiated
   * 
   */
  
  public void dragGestureRecognized( DragGestureEvent event) {
    
    Object selected = getSelectedValue();
    if ( selected != null ){
        StringSelection text = new StringSelection( selected.toString()); 
        
        // as the name suggests, starts the dragging
        dragSource.startDrag (event, DragSource.DefaultMoveDrop, text, this);
    } else {
        System.out.println( "nothing was selected");   
    }
  }

  /**
   * this message goes to DragSourceListener, informing it that the dragging 
   * has ended
   * 
   */

  public void dragDropEnd (DragSourceDropEvent event) {   
    if ( event.getDropSuccess()){
        removeElement();
    }
  }

  /**
   * this message goes to DragSourceListener, informing it that the dragging 
   * has entered the DropSite
   * 
   */

  public void dragEnter (DragSourceDragEvent event) {
    System.out.println( " dragEnter");
  }

  /**
   * this message goes to DragSourceListener, informing it that the dragging 
   * has exited the DropSite
   * 
   */

  public void dragExit (DragSourceEvent event) {
    System.out.println( "dragExit");
    
  }

  /**
   * this message goes to DragSourceListener, informing it that the dragging is currently 
   * ocurring over the DropSite
   * 
   */

  public void dragOver (DragSourceDragEvent event) {
    System.out.println( "dragExit");
    
  }

  /**
   * is invoked when the user changes the dropAction
   * 
   */
   
  public void dropActionChanged ( DragSourceDragEvent event) {
    System.out.println( "dropActionChanged"); 
  }

  /**
   * adds elements to itself
   * 
   */
   
   public void addElement( Object s ){
        (( DefaultListModel )getModel()).addElement (s.toString());
  }

  /**
   * removes an element from itself
   */
   
  public void removeElement(){
    (( DefaultListModel)getModel()).removeElement( getSelectedValue());
  }
  

}
