/*
 * NodeResizing.java
 *
 */

import demo.view.ViewActionDemo;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.*;
import java.util.Iterator;

import javax.swing.AbstractAction;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;

import y.base.*;
import y.view.*;

public class NodeResizing extends ViewActionDemo
{
  //////////////////////////////////////////////////////////////////////////////
  private ViewMode continuousHSM, originalHSM, singleHSM;
  private NodeRealizer continuousNR, originalNR;
  
  //////////////////////////////////////////////////////////////////////////////
  public NodeResizing()
  {
    Graph2DListener g2dl = new Graph2DListener(){
      public void onGraph2DEvent(Graph2DEvent ev)
      {
        if (ev.getSubject() instanceof NodeRealizer &&
            ev.getPropertyName().equals("size"))
        {
          Node n = ((NodeRealizer)ev.getSubject()).getNode();
          double oldV[] = (double[])ev.getOldValue();
          double newV[] = (double[])ev.getNewValue();
          System.out.print("OLD: " + n + "(w: " + oldV[0])
          System.out.print(", h: " + oldV[1] + ") --> ");
          System.out.print("NEW: " + n + "(w: " + newV[0])
          System.out.println(", h: " + newV[1] + ")");
        }
      }
    };
    view.getGraph2D().addGraph2DListener(g2dl);
    
    continuousHSM = new ContinuousHSM();
    continuousNR = new ContinuousNR();
    singleHSM = new SingleHSM();
  }
  
  //////////////////////////////////////////////////////////////////////////////
  protected JToolBar createToolBar()
  {
    JToolBar bar = super.createToolBar();
    
    JToggleButton btn1 = new JToggleButton("Custom HotSpotMode");
    btn1.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent ev)
      {
        JToggleButton btn = (JToggleButton)ev.getSource();
        if(btn.isSelected())
        {
          originalHSM = editMode.getHotSpotMode();
          editMode.setHotSpotMode(continuousHSM);
        }
        else
          editMode.setHotSpotMode(originalHSM);
      }
    });
    
    JToggleButton btn2 = new JToggleButton("Custom NodeRealizer");
    btn2.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent ev)
      {
        JToggleButton btn = (JToggleButton)ev.getSource();
        if(btn.isSelected())
        {
          originalNR = view.getGraph2D().getDefaultNodeRealizer();
          view.getGraph2D().setDefaultNodeRealizer(continuousNR);
        }
        else
          view.getGraph2D().setDefaultNodeRealizer(originalNR);
      }
    });
    
    bar.addSeparator();
    bar.add(btn1);
    bar.add(btn2);
    
    return bar;
  }
  
  //////////////////////////////////////////////////////////////////////////////
  /**
   * Custom HotSpotMode implementation that continuously fires events when a 
   * node gets resized. 
   */
  class ContinuousHSM extends HotSpotMode
  {
    protected void updateNodeRealizerBounds(NodeRealizer vr, 
                                            double x, double y, 
                                            double w, double h)
    {
      double oldValue[] = { vr.getWidth(), vr.getHeight() };
      // Call to 'super' is important. 
      super.updateNodeRealizerBounds(vr, x, y, w, h);
      double newValue[] = { vr.getWidth(), vr.getHeight() };
      
      Node n = vr.getNode();
      Graph2D g = (Graph2D)n.getGraph();
      Graph2DEvent e = new Graph2DEvent(g, vr, "size", oldValue, newValue);
      
      // Inform *all* listeners registered with the Graph2D instance. 
      Iterator li = g.getGraph2DListeners();
      while (li.hasNext())
        ((Graph2DListener)li.next()).onGraph2DEvent(e);
    }
  }
  
  //////////////////////////////////////////////////////////////////////////////
  /**
   * Custom NodeRealizer implementation that continuously fires events when a 
   * node gets resized. 
   */
  class ContinuousNR extends ShapeNodeRealizer
  {
    public void setSize(double width, double height) 
    {
      double oldValue[] = { this.width, this.height };
      // Call to 'super' is important. 
      super.setSize(width, height);
      double newValue[] = { this.width, this.height };
      
      Node n = getNode();
      Graph2D g = (Graph2D)n.getGraph();
      Graph2DEvent e = new Graph2DEvent(g, this, "size", oldValue, newValue);
      
      // Inform *all* listeners registered with the Graph2D instance. 
      Iterator li = g.getGraph2DListeners();
      while (li.hasNext())
        ((Graph2DListener)li.next()).onGraph2DEvent(e);
    }
    
    /**
     * Important method. Without it, the node realizer would not work properly. 
     */
    public NodeRealizer createCopy(NodeRealizer nr) 
    {
      return new ContinuousNR(nr);
    }
    
    public ContinuousNR(NodeRealizer nr){ super(nr); }
    public ContinuousNR(){ super(); }
  }
  
  //////////////////////////////////////////////////////////////////////////////
  public static void main(String args[])
  {
    NodeResizing demo = new NodeResizing();
    demo.startInFrame("Node Resizing");
  }
}
