/*
 * Licensed Materials - Property of Rogue Wave Software, Inc. 
 * © Copyright Rogue Wave Software, Inc. 2014, 2016 
 * © Copyright IBM Corp. 2009, 2014
 * © Copyright ILOG 1996, 2009
 * All Rights Reserved.
 *
 * Note to U.S. Government Users Restricted Rights:
 * The Software and Documentation were developed at private expense and
 * are "Commercial Items" as that term is defined at 48 CFR 2.101,
 * consisting of "Commercial Computer Software" and
 * "Commercial Computer Software Documentation", as such terms are
 * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
 * as applicable.
 */

package demo.grapher;

import ilog.views.*;
import ilog.views.swing.*;
import ilog.views.interactor.*;
import ilog.views.accelerator.*;
import ilog.views.graphic.*;
import ilog.views.util.*;
import ilog.views.util.swing.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

/**
 * The main applet class.
 */
public class BigGrapher 
  extends JApplet
{
  static {
    // This applet is designed to run only with default resource bundle
    // and various selected other resource bundles.
    // Setting the available resource suffixes avoids that the applet
    // tries to load resource bundles for other locales over the net,
    // even if the current locale of the browser is different.
    IlvResourceUtil.setAvailableResourceSuffixes("", "_ja");
  }

  /** Number of children we create at each level. */
  private static final int CHILDS = 5;

  /** For Layouting the nodes **/
  private static final int NODE_SIZE = 30;
  private static final int MIN_XSPACE = 60;
  private static final int MIN_YSPACE = 20;
  private float minpos = 0;

  /** The grapher.*/
  private IlvGrapher grapher;

  /** The view of the grapher.*/
  private IlvManagerView mgrview;

  /**
   * Initializes the applet.
   */
  public void init()
  {
    super.init();
    getContentPane().setLayout(new BorderLayout(0,0));

    // This sample uses JViews Diagrammer features. When deploying an
    // application that includes this code, you need to be in possession
    // of a Rogue Wave JViews Diagrammer Deployment license.
//    IlvProductUtil.DeploymentLicenseRequired(
//        IlvProductUtil.JViews_Diagrammer_Deployment);

    // Creates the grapher.
    grapher = new IlvGrapher();

    // Creates the view of the grapher.
    mgrview = new IlvManagerView(grapher, null);

    // Sets Anti-aliasing on.
    mgrview.setAntialiasing(true);
    
    // Setting parameters for selection handles.
    IlvHandlesSelection.defaultHandleColor = new Color(153, 153, 255);
    IlvHandlesSelection.defaultHandleBackgroundColor = Color.white;
    IlvHandlesSelection.defaultHandleShape = IlvHandlesSelection.SQUARE_SHAPE;

    mgrview.setKeepingAspectRatio(true);
    // Adds objects in the grapher and layout them
    addSubtree(0, 3, grapher);
    
    // Installs a selection interactor.
    IlvSelectInteractor interactor = new IlvSelectInteractor();
    interactor.setOpaqueMove(true);
    mgrview.pushInteractor(interactor);

    // Installs some accelerators.
    grapher.addAccelerator(new IlvIdentityAccelerator(KeyEvent.KEY_PRESSED,
                    KeyEvent.VK_I, 0));
    grapher.addAccelerator(new IlvZoomOutAccelerator(KeyEvent.KEY_PRESSED,
                    KeyEvent.VK_U, KeyEvent.CTRL_MASK));
    grapher.addAccelerator(new IlvZoomInAccelerator(KeyEvent.KEY_PRESSED,
                                                    KeyEvent.VK_Z, KeyEvent.CTRL_MASK));
    grapher.addAccelerator(new IlvFitToSizeAccelerator(KeyEvent.KEY_PRESSED, 
                                                       KeyEvent.VK_F, 0));
    grapher.addAccelerator(new IlvRotateAccelerator(KeyEvent.KEY_PRESSED, 
                                                    KeyEvent.VK_R, 0));
    grapher.addAccelerator(new IlvScrollUpAccelerator(KeyEvent.KEY_PRESSED,
                                                      KeyEvent.VK_UP, 0));
    grapher.addAccelerator(new IlvScrollDownAccelerator(KeyEvent.KEY_PRESSED,
                                                        KeyEvent.VK_DOWN, 0));
    grapher.addAccelerator(new IlvScrollRightAccelerator(KeyEvent.KEY_PRESSED,
                                                         KeyEvent.VK_RIGHT, 0));
    grapher.addAccelerator(new IlvScrollLeftAccelerator(KeyEvent.KEY_PRESSED,
                                                        KeyEvent.VK_LEFT, 0));
    IlvJScrollManagerView scrollview = new IlvJScrollManagerView(mgrview);
      
    mgrview.setWheelZoomingEnabled(true);
    scrollview.setWheelScrollingEnabled(true);

    getContentPane().add(scrollview, BorderLayout.CENTER);
  }

  /**
   * Called when this applet starts its execution.
   */
  public void start() 
  {
    // Ensures the root object is in the middle.
    mgrview.translate(30, -grapher.boundingBox().height/2 + getHeight()/2, true);
  }

  /**
   * Called when this applet is being reclaimed in order to destroy
   * any resources that it has allocated.
   */
  public void destroy()
  {
    super.destroy();

    // This method is intended to workaround memory management issues
    // in the Sun JRE. Please refer to the method documentation for more
    // details and a description of the known issues.
    IlvSwingUtil.cleanupApplet();
  }

  /**
   * Generates a subtree and layout it. If ilog.views.graphlayout package
   * is available, this can advantageously be replaced by using a <code>IlvTreeLayout</code>.
   * @param actlevel the actual level
   * @param maxlevel the maximal level
   * @param grapher the grapher
   * @param minpos The desired minimal position of the subtree at parent.
   * @return The root of the subtree.
   */
  private IlvGraphic addSubtree(int actlevel, int maxlevel, IlvGrapher grapher)
  {
    Color color = new Color(Math.min(50 + actlevel * 40, 255),
                            Math.min(50 + actlevel * 40, 255),
                            Math.min(100 + actlevel * 40, 255));

    IlvGraphic node = new IlvReliefRectangle(new IlvRect(0,0,NODE_SIZE,NODE_SIZE));
    node.setBackground(color);
    grapher.addNode(node, 1, false);

    IlvRect rect;
    IlvGraphic child;
    IlvLinkImage link;
    float minChildPos = Float.MAX_VALUE;
    float maxChildPos = - Float.MAX_VALUE;

    if (actlevel < maxlevel) {
      for (int i = 0; i < CHILDS; i++) {
        child = addSubtree(actlevel+1, maxlevel, grapher);
        rect = child.boundingBox();
        minpos = Math.max(minpos, rect.y + rect.height + MIN_YSPACE);
        minChildPos = Math.min(minChildPos, rect.y);
        maxChildPos = Math.max(maxChildPos, rect.y + rect.height);
        link = new IlvLinkImage(node, child, true);
        link.setForeground(color);
        link.setLineWidth(2);
        grapher.addLink(link, 0, false);
      }
    }

    if (minChildPos < maxChildPos)
      grapher.moveObject(node,
                         actlevel * (NODE_SIZE + MIN_XSPACE),
                         0.5f * (maxChildPos + minChildPos - NODE_SIZE),
                         false);
    else
      grapher.moveObject(node,
                         actlevel * (NODE_SIZE + MIN_XSPACE),
                         minpos,
                         false);

    return node;
  }
}