/*
 * Licensed Materials - Property of Rogue Wave Software, Inc. 
 * © Copyright Rogue Wave Software, Inc. 2014, 2015 
 * © 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 newgraphics;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;

import ilog.views.*;
import ilog.views.graphic.*;
import ilog.views.event.*;
import ilog.views.interactor.*;
import ilog.views.swing.*;
import ilog.views.util.*;
import ilog.views.util.swing.*;

/**
 * Displays JViews graphics objects that are created using <code>new</code>. Most
 * of the JViews examples read graphics from JViews .ivl files because it makes
 * the code more readable. This example demonstrates the creation of
 * JViews graphics classes in Java code. An example is provided for most of the
 * fundamental JViews graphics types. Furthermore, one type used here,
 * <code>MyZoomableReliefLabel</code>, demonstrates how to create a custom graphic by
 * extending an existing JViews graphic class.
 */
public class NewGraphics extends JApplet implements ActionListener
{
  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.
    if (IlvResourceUtil.isInApplet())
      IlvResourceUtil.setAvailableResourceSuffixes("", "_ja");
  }

  /**
   * Some primitives for creating the graphic objects. These are
   * initialized in <code>initPositionData()</code> and used in 
   * <code>addGraphicObjects()</code>.
   */
  public static final int DEFAULT_X = 25;
  public static final int DEFAULT_X_NAMES = 130;
  public static final int VERT_SPACING = 45;
  public static final int DEFAULT_WIDTH = 70;
  public static final int DEFAULT_HEIGHT = 30;
  
  private IlvPoint ptCenter = new IlvPoint();
  private IlvPoint ptLabel = new IlvPoint();
  private IlvPoint ptUpperLeft = new IlvPoint();
  private IlvPoint ptLowerLeft = new IlvPoint();
  private IlvRect rectBorder = new IlvRect();
  private IlvPoint[] points = new IlvPoint[6];
  private String[] SCALE_LABELS = new String[6];
  
  /**
   *  A counter for the <code>JButton</code>.
   */
  public int ctr = 1;
  
  /**
   * The JViews manager.
   */
  private IlvManager manager;
  
  /**
   * One view of the manager.
   */
  private IlvManagerView mgrview;
  
  /**
   * Initializes the applet.
   */
  public void init()
  {
    super.init();

    // 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);

    // Create the manager.
    manager = new IlvManager();
    // Create the view for the manager.
    mgrview = new IlvManagerView(manager);
    mgrview.setAntialiasing(true);
    // Avoid having a distorted view.
    mgrview.setKeepingAspectRatio(true);
    // Set the background of the view.
    mgrview.setBackground(Color.white);

    addGraphicObjects(0);
    // addFullZoomingGraphicObjects();

    IlvJScrollManagerView scrollview = new IlvJScrollManagerView(mgrview);
    mgrview.setWheelZoomingEnabled(true);
    scrollview.setWheelScrollingEnabled(true);
    
    getContentPane().add(scrollview, BorderLayout.CENTER);
    // Create a toolbar for basic zoom/unzoom operations.
    IlvJManagerViewControlBar toolbar = new IlvJManagerViewControlBar();
    toolbar.setFloatable(false);
    toolbar.setOrientation(JToolBar.HORIZONTAL);
    toolbar.setView(mgrview);
    ((IlvSelectInteractor)toolbar.getSelectInteractor()).setOpaqueMove(true);
    getContentPane().add(toolbar, BorderLayout.NORTH);
  }
  
  /**
   * Starts the applet.
   */
  public void start()
  {
  }
  
  /**
   * Stops the applet.
   */
  public void stop()
  {
  }

  /**
   * 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();
  }
  
  /**
   * Adds one of each JViews graphic type to the manager.
   */
  public void addGraphicObjects(int deltaX)
  {
    initPositionData(deltaX);
    // A bitmap.
    IlvIcon icon = null;
    try {
      icon = new IlvIcon(ilog.views.util.IlvImageUtil.
                         getImageFromFile(NewGraphics.class,
                         "logos.gif"),
                         rectBorder);
    } catch (java.io.IOException e) {
      e.printStackTrace();
    }
    manager.addObject(icon, false);
    addLabel("IlvIcon");
    
    // A graphic composed of other JViews graphics.
    movePositionData();
    IlvGraphicSet composite = new IlvGraphicSet();
    IlvReliefRectangle border = new IlvReliefRectangle(rectBorder);
    border.setBackground(Color.white);
    int edge = border.getThickness();
    border.moveResize(new IlvRect(rectBorder.x - (4 + edge),
                                  rectBorder.y - (4 + edge),
                                  rectBorder.width + 8 + 2 * edge,
                                  rectBorder.height + 8 + 2 * edge));
    composite.addObject(border, false);
    try {
      icon = new IlvIcon(ilog.views.util.IlvImageUtil.
                         getImageFromFile(NewGraphics.class,
                         "small.gif"),
                         rectBorder);
    } catch (java.io.IOException e) {
    }
    composite.addObject(icon, false);
    IlvPoint ptText = new IlvPoint(ptLowerLeft);
    ptText.translate(0, -15);
    IlvZoomableLabel lbl1 = new IlvZoomableLabel(ptText, "RogueWave");
    Font font = new Font(lbl1.getFont().getName(), Font.BOLD,
                         lbl1.getFont().getSize());
    lbl1.setFont(font);
    composite.addObject(lbl1, false);
    ptText.translate(0, +20);
    IlvZoomableLabel lbl2 = new IlvZoomableLabel(ptText, "JViews");
    lbl2.setFont(font);
    composite.addObject(lbl2, false);
    manager.addObject(composite, false);  // false => do not redraw yet.
    addLabel("IlvGraphicSet");
    
    // A custom graphic class.
    movePositionData();
    MyZoomableReliefLabel custom =
      new MyZoomableReliefLabel(ptCenter, "Custom\nGraphic");
    custom.setBackground(Color.pink);
    manager.addObject(custom, false);  // false => do not redraw yet.
    addLabel("MyZoomableReliefLabel");
    
    // A rectangle.
    movePositionData();
    IlvRectangle rectangle = new IlvRectangle(rectBorder);
    manager.addObject(rectangle, false);
    addLabel("IlvRectangle");
    
    // A relief rectangle.
    movePositionData();
    IlvReliefRectangle rlfrect = new IlvReliefRectangle(rectBorder);
    rlfrect.setBackground(Color.cyan);
    manager.addObject(rlfrect, false);
    addLabel("IlvReliefRectangle");
    
    // A relief label.
    movePositionData();
    IlvReliefLabel rlflbl = new IlvReliefLabel(rectBorder, "Text");
    rlflbl.setBackground(Color.yellow);
    manager.addObject(rlflbl, false);
    addLabel("IlvReliefLabel");
    
    // A shadow rectangle.
    movePositionData();
    IlvShadowRectangle shdwrect = new IlvShadowRectangle(rectBorder);
    shdwrect.setBackground(Color.red);
    manager.addObject(shdwrect, false);
    addLabel("IlvShadowRectangle");
    
    // A shadow label.
    movePositionData();
    IlvShadowLabel shdwlbl = new IlvShadowLabel(rectBorder,
                                                "Text", 3F, IlvDirection.BottomRight);
    shdwlbl.setBackground(Color.green);
    manager.addObject(shdwlbl, false);
    addLabel("IlvShadowLabel");
    
    // An ellipse.
    movePositionData();
    IlvEllipse ellipse = new IlvEllipse(rectBorder);
    manager.addObject(ellipse, false);
    addLabel("IlvEllipse");
    
    // An arc.
    movePositionData();
    IlvArc arc = new IlvArc(rectBorder, 90F, 205F);
    manager.addObject(arc, false);
    addLabel("IlvArc");
    
    // A filled polygon.
    movePositionData();
    IlvPolygon polygon = new IlvPolygon(points);
    polygon.setForeground(Color.green);
    manager.addObject(polygon, false);
    addLabel("IlvPolygon ");
    
    // A polyline.
    movePositionData();
    IlvPolyline polyline = new IlvPolyline(points);
    manager.addObject(polyline, false);
    addLabel("IlvPolyline");
    
    // An arrow ployline.
    movePositionData();
    IlvArrowPolyline apl = new IlvArrowPolyline(points);
    manager.addObject(apl, false);
    addLabel("IlvArrowPolyline");
    
    // A spline.
    movePositionData();
    IlvSpline spline = new IlvSpline(points);
    manager.addObject(spline, false);
    addLabel("IlvSpline");
    
    // A filled label.
    movePositionData();
    IlvFilledLabel fLabel = new IlvFilledLabel(ptCenter, "Some Text");
    fLabel.setBackground(Color.yellow);
    manager.addObject(fLabel, false);
    addLabel("IlvFilledLabel");
    
    // Non-zoomable text.
    movePositionData();
    IlvLabel label = new IlvLabel(ptCenter, "More Text");
    manager.addObject(label, false);  // false => do not redraw yet.
    addLabel("IlvLabel");
    
    // Zoomable text.
    movePositionData();
    IlvZoomableLabel zlabel = new IlvZoomableLabel(ptLowerLeft, "Zoom in!");
    manager.addObject(zlabel, false);  // false => do not redraw yet.
    addLabel("IlvZoomableLabel");
    
    // multi-line text with word wrap.
    movePositionData();
    IlvText tlabel = new IlvText(ptLowerLeft, "Multi-line text");
    tlabel.setWrappingWidth(rectBorder.width);
    tlabel.setWrappingMode(IlvText.WRAP_WORD);         
    manager.addObject(tlabel, false);  // false => do not redraw yet.
    addLabel("IlvText");       
    
    
    // A non-zooming marker.
    movePositionData();
    IlvMarker marker =
      new IlvMarker(ptCenter, IlvMarker.IlvMarkerFilledDiamond);
    marker.setForeground(Color.cyan);
    manager.addObject(marker, false);  // false => do not redraw yet.
    addLabel("IlvMarker");
    
    // A simple line.
    movePositionData();
    IlvLine line = new IlvLine(rectBorder.x, rectBorder.y,
                               rectBorder.x + rectBorder.width,
                               rectBorder.y + rectBorder.height);
    manager.addObject(line, false);  // false => do not redraw yet.
    addLabel("IlvLine");
    
    // An arrow line.
    movePositionData();
    IlvArrowLine aline = new IlvArrowLine(rectBorder.x,
                                          rectBorder.y + rectBorder.height,
                                          rectBorder.x + rectBorder.width,
                                          rectBorder.y,
                                          1.0F);
    manager.addObject(aline, false);  // false => do not redraw yet.
    addLabel("IlvArrowLine");
    
    // A linear scale.
    movePositionData();
    IlvRectangularScale scale =
      new IlvRectangularScale(ptUpperLeft, DEFAULT_WIDTH, SCALE_LABELS, 5,
                              IlvDirection.Left, IlvDirection.Bottom, 10F,
                              2F);
    manager.addObject(scale, false);  // false => do not redraw yet.
    addLabel("IlvRectangularScale");
    
    // A circular scale.
    movePositionData();
    IlvRect scalerect = new IlvRect(rectBorder);
    scalerect.height = scalerect.width;
    scalerect.translate(0, 20);
    IlvCircularScale cscale =
      new IlvCircularScale(scalerect, SCALE_LABELS,
                           90F, 360F, false, 5, 10F, 2F);
    manager.addObject(cscale, false);  // false => do not redraw yet.
    addLabel("IlvCircularScale");
    movePositionData(); // The scale is quite big so move further.
    movePositionData();
    
    // A Swing component wrapped in a JViews graphic.
    movePositionData();
    JButton jbtn = new JButton("Go");
    jbtn.addActionListener(this);
    IlvJComponentGraphic jcomp =
      new IlvJComponentGraphic(rectBorder, jbtn);
    manager.addObject(jcomp, false);  // false => do not redraw yet.
    addLabel("IlvJComponentGraphic");
    
    // A Java 2D shape object with a gradient fill.
    movePositionData();
    Shape shape = new Rectangle2D.Float(ptUpperLeft.x, ptUpperLeft.y,
                                        DEFAULT_WIDTH, DEFAULT_HEIGHT);
    IlvGeneralPath path = new IlvGeneralPath(shape);
    path.setFillPaint(
      new GradientPaint(new Point((int)ptUpperLeft.x + DEFAULT_WIDTH/2,
                                  (int)ptUpperLeft.y),
                                  Color.yellow,
                                  new Point((int)ptUpperLeft.x + DEFAULT_WIDTH/2,
                                            (int)ptUpperLeft.y + DEFAULT_HEIGHT),
                                            Color.red));
    manager.addObject(path, false);
    addLabel("IlvGeneralPath");
  }
  
  /**
   * Adds one of each JViews graphic type to the manager.
   * This is the same as previous method, except that this time, we encapsulate
   * each graphic in a IlvFullZoomingGraphic with transparency.
   * <p>
   * IlvFullZoomingGraphic if you need to make a nonzoomable object zoomable,
   * of if you want to add transparency to an object.
   * <p>
   * This method is currently not used in this sample. Uncomment the call
   * of this method inside init to see the effect of this method.
   */
  public void addFullZoomingGraphicObjects()
  {
    double initZoom = 1;
    float alpha = 0.3f;
    IlvFullZoomingGraphic fzg;

    addGraphicObjects(300);

    IlvGraphicVector v = new IlvGraphicVector();
    IlvGraphicEnumeration e = manager.getObjects();
    while (e.hasMoreElements()) {
      IlvGraphic g = e.nextElement();
      // cannot wrap IlvJComponentGraphic into any graphic handle
      if (g.boundingBox().x >= 300 && !(g instanceof IlvJComponentGraphic))
        v.addElement(g);
    }

    e = v.elements();
    while (e.hasMoreElements()) {
      IlvGraphic g = e.nextElement();
      IlvRect bbox = g.boundingBox();
      manager.removeObject(g, false);
      fzg = new IlvFullZoomingGraphic(g, initZoom);
      fzg.setAlpha(alpha);
      fzg.move(bbox.x, bbox.y);
      manager.addObject(fzg, false);
    }

    ptLabel.x = 300;
    ptLabel.y = -10;
    addLabel("Objects wrapped in IlvFullZoomingGraphic");
  }
  
  /**
   * Adds a non-zoomable label to the right of the current graphic object's
   * position.
   */
  public void addLabel(String text)
  {
    IlvZoomableLabel lbl = new IlvZoomableLabel(ptLabel, text);
    manager.addObject(lbl, false);
  }
  
  
  /**
   * Creates the points and rectangles used to create new graphics. This way
   * the graphic creation code is not cluttered with several position
   * calculations.
   */
  private void initPositionData(int deltaX)
  {
    int x = DEFAULT_X + deltaX;
    int w = DEFAULT_WIDTH;
    int y = VERT_SPACING/2;
    int h = DEFAULT_HEIGHT;
    ptCenter.move(x + w/2, y);
    ptLabel.move(DEFAULT_X_NAMES + deltaX, h + 5);
    rectBorder.reshape(x, (VERT_SPACING - h)/2, w, h);
    ptUpperLeft.move(x, y - h/2);
    ptLowerLeft.move(x, y + y/2);
    //// Creation of an array of points that describes a star.
    // upper-left
    points[0] = new IlvPoint(x, y + h/3);
    // upper-right
    points[1] = new IlvPoint(x + w, y + h/3);
    // lower-left
    points[2] = new IlvPoint(x + w/5, y + h);
    // top-center
    points[3] = new IlvPoint(x + w/2, y);
    // lower-right
    points[4] = new IlvPoint(x + 4*w/5, y + h);
    // upper-left
    points[5] = new IlvPoint(points[0]);
    // Labels for the scales.
    SCALE_LABELS[0] = new String();
    for ( int i = 1; i < SCALE_LABELS.length; i++ ) {
      SCALE_LABELS[i] = String.valueOf(i);
    }
  }
  
  /**
   * Moves the points and rectangles used to create new graphics. This is
   * called before creating each graphic above. This way the graphic creation
   * code is not cluttered with several position calculations.
   */
  private void movePositionData()
  {
    ptLabel.translate(0, VERT_SPACING);
    ptCenter.translate(0, VERT_SPACING);
    ptUpperLeft.translate(0, VERT_SPACING);
    ptLowerLeft.translate(0, VERT_SPACING);
    rectBorder.translate(0, VERT_SPACING);
    for ( int i = 0; i < points.length; i++ ) {
      points[i].translate(0, VERT_SPACING);
    }
  }
  
  /**
   * Handler for the embedded <code>JButton</code>.
   */
  public void actionPerformed(ActionEvent event)
  {
    ((JButton)event.getSource()).setText(String.valueOf(ctr++));
  }
  
  /**
   * A main method to run the demo as an application.
   */
  public static void main(String[] args)
  {
    // Sun recommends that to put the entire GUI initialization into the
    // AWT thread
    SwingUtilities.invokeLater(
      new Runnable() {
        public void run() {
          JFrame frame = new JFrame("Creation of IlvGraphic's");
          frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
              System.exit(0);
            }
          });
          NewGraphics applet = new NewGraphics();
          frame.getContentPane().add(applet);
          frame.setSize(300, 600);
          applet.init();
          applet.start();
          frame.setVisible(true);
        }
      });
  }
}