package demo.view.realizer;

import demo.view.DemoBase;
import y.geom.YDimension;
import y.geom.YRectangle;
import y.view.NodeLabel;
import y.view.NodeRealizer;
import y.view.Graph2DListener;
import y.view.Graph2DEvent;
import y.base.Node;
import y.view.SizeConstraintProvider;

import java.awt.EventQueue;

/**
 * Demonstrates how to achieve automatic node size adjustment according to the node's label.
 */
public class AutoNodeBoundsDemo2 extends DemoBase {
  public AutoNodeBoundsDemo2() {
    view.getGraph2D().addGraph2DListener(new LabelChangedListener());
  }

  class LabelChangedListener implements Graph2DListener{
    private double minWidth = 40.0;
    private double minHeight = 40.0;
    private boolean ignoreWidth = false;
    private boolean ignoreHeight = false;
    private double hSpace = 2.0;
    private double vSpace = 2.0;

    public void onGraph2DEvent(Graph2DEvent e) {
      Node v = null;
      String p = e.getPropertyName();
      if(e.getSubject() instanceof NodeLabel && "text".equals(p)){
        v = ((NodeLabel)e.getSubject()).getNode();
      } else if(e.getSubject() instanceof Node &&  "realizer".equals(p)){
        v = (Node)e.getSubject();
      }

      if(v != null){
        adjustNodeSize(view.getGraph2D().getRealizer(v));
      }
    }

    private void adjustNodeSize(NodeRealizer nr) {
      if (nr.labelCount() < 1) {
        return;
      }

      double minWidth = this.minWidth;
      double minHeight = this.minHeight;
      double maxWidth = Double.POSITIVE_INFINITY;
      double maxHeight = Double.POSITIVE_INFINITY;
      final SizeConstraintProvider scp = nr.getSizeConstraintProvider();
      if (scp != null) {
        final YDimension min = scp.getMinimumSize();
        if (min != null) {
          if (minWidth < min.width) {
            minWidth = min.width;
          }
          if (minHeight < min.height) {
            minHeight = min.height;
          }
        }
        final YDimension max = scp.getMaximumSize();
        if (max != null) {
          maxWidth = max.width;
          maxHeight = max.height;
        }
      }

      final NodeLabel nl = nr.getLabel();
      final YRectangle lb = nl.getBox();

      if (!ignoreWidth) {
        double width = lb.width + 2 * hSpace;
        if (width < minWidth) {
          width = minWidth;
        }
        if (width > maxWidth) {
          width = maxWidth;
        }
        nr.setWidth(width);
      }
      if (!ignoreHeight) {
        double height = lb.height + 2 * vSpace;
        if (height < minHeight) {
          height = minHeight;
        }
        if (height > maxHeight) {
          height = maxHeight;
        }
        nr.setHeight(height);
      }
    }
  }

  public static void main( String[] args ) {
    EventQueue.invokeLater(new Runnable() {
      public void run() {
        initLnF();
        (new AutoNodeBoundsDemo2()).start("Auto Node Bounds Demo");
      }
    });
  }
}
