/*
 * Licensed Materials - Property of Perforce Software, Inc. 
 * © Copyright Perforce Software, Inc. 2014, 2021 
 * © 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.Color;
import java.io.IOException;

import ilog.views.IlvGraphic;
import ilog.views.IlvPoint;
import ilog.views.IlvRect;
import ilog.views.IlvTransformer;
import ilog.views.graphic.IlvGraphicSet;
import ilog.views.graphic.IlvReliefRectangle;
import ilog.views.graphic.IlvZoomableLabel;
import ilog.views.io.IlvInputStream;
import ilog.views.io.IlvOutputStream;
import ilog.views.io.IlvReadFileException;

/**
 * Displays zoomable text above a relief rectangle.
 */
public class MyZoomableReliefLabel extends IlvGraphicSet
{
  private int margin = 4;
  private static final int LABEL_INDEX = 1;
  private static final int RECT_INDEX  = 0;
  
  /**
   * Computes the bounds for the relief rectangle based on the zoomable label.
   */
  private IlvRect computeRect(IlvZoomableLabel lbl) {
    if ( lbl == null ) {
      return null;
    }
    IlvRect rect = lbl.boundingBox(null);
    IlvReliefRectangle tempRect = null;
    try {
      tempRect = (IlvReliefRectangle)getObject(RECT_INDEX);
    } catch ( ArrayIndexOutOfBoundsException e ) {}
    if ( tempRect == null ) {
      tempRect = new IlvReliefRectangle(new IlvRect(0, 0, 10, 10));
    }
    int thickness = tempRect.getThickness();
    rect.x -= margin + thickness;
    rect.y -= margin + thickness;
    rect.width += (2 * margin) + 2 * thickness;
    rect.height += (2 * margin)  + 2 * thickness;
    return rect;
  }
  
  /**
   * Creates a new <code>IlvZoomableLabel</code> instance.
   * @param position The lower-left corner of the rectangle.
   * @param label The text of the label.
   */
  public MyZoomableReliefLabel(IlvPoint center, java.lang.String text) {
    super();
    IlvZoomableLabel lbl = new IlvZoomableLabel(center, text);
    int lines = getLineCount(text);
    lbl.translate(-lbl.boundingBox().width/2,
                  (lines - 2) * lbl.boundingBox().height/lines);
    IlvReliefRectangle rect = new IlvReliefRectangle(computeRect(lbl));
    addObjectAt(rect, RECT_INDEX, false);
    addObjectAt(lbl, LABEL_INDEX, false);
  }
  
  /**
   * Creates a new <code>IlvLabel</code> by copying an existing one.
   */
  public MyZoomableReliefLabel(MyZoomableReliefLabel source) {
    super(source);
    setMargin(source.getMargin());
  }
  
  /**
   * Reads the object from an <code>IlvInputStream</code>.
   * @param stream The input stream.
   * @exception IlvReadFileException if the format is not correct.
   */
  public MyZoomableReliefLabel(IlvInputStream stream)
  throws IlvReadFileException {
    super(stream);
    setMargin(stream.readInt("margin"));
  }
  
  Override
  public IlvGraphic copy() {
    return new MyZoomableReliefLabel(this);
  }
  
  /**
   * Writes the object to an <code>IlvOutputStream</code>.
   */
  Override
  public  void write(IlvOutputStream stream)
  throws IOException {
    super.write(stream);
    stream.write("margin", margin);
  }
  
  Override
  public IlvRect boundingBox(IlvTransformer t) {
    return getReliefRect().boundingBox(t);
  }
  
  /**
   * Returns the margin to be displayed around the text, but within the
   * central rectangle of the relief rectangle.
   * @see setMargin(int)
   */
  public int getMargin() {
    return margin;
  }
  
  /**
   * Changes the margin drawn around the text.
   * @see getMargin()
   */
  public void setMargin(int newValue) {
    margin = newValue;
  }
  
  /**
   * Returns the <code>IlvReliefRectangle</code> that is displayed in
   * the background.
   */
  public IlvReliefRectangle getReliefRect() {
    return (IlvReliefRectangle)getObject(RECT_INDEX);
  }
  
  /**
   * Returns the <code>IlvZoomableLabel</code> that is displayed in
   * the foreground.
   */
  public IlvZoomableLabel getLabel() {
    return (IlvZoomableLabel)getObject(LABEL_INDEX);
  }
  
  /**
   * Changes the label and recalculates the rectangle borders.
   */
  public void setLabel(java.lang.String label) {
    IlvZoomableLabel lbl = getLabel();
    lbl.setLabel(label);
    IlvRect rect = computeRect(lbl);
    IlvReliefRectangle reliefRect = getReliefRect();
    reliefRect.moveResize(rect);
  }
  
  /**
   * Returns the text color.
   */
  public Color getForeground() {
    return (Color)getLabel().getFillPaint();
  }
  
  /**
   * Changes the color of the text.
   */
  Override
  public void setForeground(Color c) {
    getLabel().setFillPaint(c);
  }
  
  /**
   * Returns the background color.
   */
  public Color getBackground() {
    return getReliefRect().getBackground();
  }
  
  /**
   * Changes the color of the relief rectangle.
   */
  Override
  public void setBackground(Color c) {
    getReliefRect().setBackground(c);
  }
  
  /**
   * Returns the edge thickness of the relief rectangle.
   */
  public int getThickness() {
    return getReliefRect().getThickness();
  }
  
  /**
   * Changes the edge thickness of the relief rectangle.
   */
  public void setRectThickness(int thickness) {
    getReliefRect().setThickness(thickness);
  }
  
  /**
   * Returns the foreground color of the relief rectangle.
   */
  public Color getRectForeground() {
    return getReliefRect().getForeground();
  }
  
  /**
   * Changes the foreground color of the relief rectangle.
   */
  public void setRectForeground(Color color) {
    getReliefRect().setForeground(color);
  }
  
  /**
   * Counts the number of lines in the string
   */
  public static int getLineCount(String testme) {
    if ( testme == null ) {
      return 0;
    }
    char ch = '\n';
    int ctr = 1;
    int pos = -1;
    while ( true ) {
      pos = testme.indexOf(ch, pos + 1);
      if ( pos > -1  ) {
        ctr++;
      } else {
        break;
      }
    }
    return ctr;
  }
}