package demo.view;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.datatransfer.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.swing.AbstractAction;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;

import y.view.Drawable;
import y.view.Graph2D;
import y.view.Graph2DView;
import y.view.ViewMode;

/**
 * This demo shows how to copy a selected region of the graph view as an image to 
 * the system clipboard.
 */
public class CopyViewToClipboardDemo extends ViewActionDemo {
  SelectRegionViewMode selectRegionMode;

  public CopyViewToClipboardDemo() {
    selectRegionMode = new SelectRegionViewMode();
  }

  protected JToolBar createToolBar() {
    JToolBar bar = super.createToolBar();

    JToggleButton btn = new JToggleButton("Activate Selection Mode");
    btn.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ev) {
        JToggleButton btn = (JToggleButton)ev.getSource();
        if (btn.isSelected()) {
          view.removeViewMode(editMode);
          view.addViewMode(selectRegionMode);
        }
        else {
          selectRegionMode.reactivateParent();
          view.removeViewMode(selectRegionMode);
          view.addViewMode(editMode);
        }
      }
    });
    bar.add(btn);
    bar.add(new CopyRegionAction());
    return bar;
  }
  
  /**
   * Simple view mode that allows to select a region of the view for further processing 
   * purposes.
   */
  static class SelectRegionViewMode extends ViewMode {
    SelectedRegion region = null;
    Point2D pivot;

    public void mousePressedLeft(double x, double y) {
      pivot = new Point2D.Double(x, y);
    }

    public void mouseDraggedLeft(double x, double y) {
      if (region == null) {
        region = new SelectedRegion();
        view.addDrawable(region);
      }
      region.setFrameFromDiagonal(pivot, new Point2D.Double(x, y));
      view.updateView();
    }

    public void mouseReleasedLeft(double x, double y) {
      if (region != null) {
        region.setFrameFromDiagonal(pivot, new Point2D.Double(x, y));
        view.updateView();
      }
    }

    public void reactivateParent() {
      view.removeDrawable(region);
      region = null;
      view.updateView();
    }
  }
  
  /**
   * Simple graphical representation of a selected region.
   */
  static class SelectedRegion extends Rectangle2D.Double implements Drawable {
    public void paint(Graphics2D gfx) {
      gfx.setColor(Color.black);
      gfx.draw(this);
    }
  }
  
  /**
   * Action that copies a selected region of the view as an image to the system 
   * clipboard.
   */
  class CopyRegionAction extends AbstractAction {
    CopyRegionAction() {
      super("Copy Region to Clipboard");
    }

    public void actionPerformed(ActionEvent ev) {
      Rectangle2D region = selectRegionMode.region;
      if (region != null) {
        Graph2D graph = view.getGraph2D();
        Graph2DView viewPort = new Graph2DView(graph);
        graph.setCurrentView(viewPort);
        viewPort.setSize((int)region.getWidth(), (int)region.getHeight());
        viewPort.setViewPoint2D(region.getX(), region.getY());

        BufferedImage image = 
            new BufferedImage(viewPort.getWidth(), viewPort.getHeight(), 
                              BufferedImage.TYPE_INT_ARGB);
        viewPort.paintVisibleContent((Graphics2D)image.getGraphics());
        ImageTransferable it = new ImageTransferable(image);
        Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();
        clip.setContents(it, it);
        graph.removeView(viewPort);
      }
    }
  }
  
  /**
   * Transferable implementation which is used for communication with the system 
   * clipboard.
   */
  static class ImageTransferable implements Transferable, ClipboardOwner {
    Image image;

    ImageTransferable(Image img) {
      this.image = img;
    }

    public DataFlavor[] getTransferDataFlavors() {
      return new DataFlavor[] {DataFlavor.imageFlavor};
    }

    public boolean isDataFlavorSupported(DataFlavor flavor) {
      return DataFlavor.imageFlavor.equals(flavor);
    }

    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
      return image;
    }
    
    // Empty ClipBoardOwner implementation.
    public void lostOwnership(Clipboard clipboard, Transferable contents) {}
  }

  public static void main(String[] args) {
    CopyViewToClipboardDemo demo = new CopyViewToClipboardDemo();
    demo.start(demo.getClass().getName());
  }
}
