/*
 * 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.
 */

import ilog.views.IlvGraphic;
import ilog.views.IlvRect;
import ilog.views.sdm.IlvSDMEngine;
import ilog.views.sdm.renderer.IlvFilterSDMRenderer;
import ilog.views.sdm.renderer.IlvRendererUtil;
import ilog.views.sdm.renderer.IlvSDMRenderer;

import java.util.Collection;

/**
 * The class <code>FlagRenderer</code> is a filtering renderer that
 * sticks various <code>IlvGraphic</code>s (the flags) to a node.  Flags are located
 * in a separate layer, typically over all other layers to have them
 * always visible.

 * <P>This renderer defines the following graphic properties:
 * <UL>
 * <LI>Flag: An <code>IlvGraphic</code> that represents the decorations.<\LI>
 * <\UL>
 * */
public class FlagRenderer  extends IlvFilterSDMRenderer {

  private int _flagLayer = 20;
  static final String[] REND_CLASS = {"renderer",
                                      "flagRenderer" };
  static final String FLAG = "Flag";
  static final String FLAG_GRAPHICS = "Flag-graphic";
  //////////////////////
  // Constructors

  /**
   * Creates a new flag renderer for a specified
   * filtered renderer.
   */
  public FlagRenderer(IlvSDMRenderer renderer) {
    super(renderer);
  }
  
  /**
   * Creates a new flag renderer with a <code>null</code>
   * filtered renderer.
   */
  public FlagRenderer() {
    this(null);
  }

  /////////////////////////
  // Bean properties

  /**
   * Sets the flag layer. Default is 20.
   * */
  public void setFlagLayer(int v) {
    _flagLayer = v;
  }
    
  /* 
   * Returns the debug level of the current configuration style sheet.
   * @see setDebugMask
   */
  public int getFlagLayer() {
    return _flagLayer;
  }
    
    
  ///////////////////////////
  // Filtering overload
    
  /**
   * Creates flag.
   */
  public void addNodeGraphic(IlvSDMEngine engine,
                             java.lang.Object node,
                             IlvGraphic graphic,
                             boolean redraw) {
    super.addNodeGraphic(engine,node,graphic,redraw);
    checkNode(engine, node, graphic);
  }

  /**
   * Recreates flag.
   */
  public void propertiesChanged(IlvSDMEngine engine,
      Object object,
      Collection<String> propertyNames,
      IlvGraphic graphic) {
    super.propertiesChanged(engine,object,propertyNames,graphic);
    if (!engine.getModel().isLink(object)) {
      cleanNode(engine, graphic);
      checkNode(engine, object, graphic);
    }
  }

  /**
   * Clears flag.
   */
  public void removeNodeGraphic(IlvSDMEngine engine,
                                java.lang.Object node,
                                IlvGraphic graphic,
                                boolean redraw) {
    super.removeNodeGraphic(engine, node, graphic, redraw);
    cleanNode(engine, graphic);
  }

  /**
   * Adjusts flag position.
   */
  public void nodeGraphicBBoxChanged(IlvSDMEngine engine,
                                     java.lang.Object node,
                                     IlvGraphic graphic,
                                     IlvRect oldBBox,
                                     IlvRect newBBox,
                                     java.lang.String[] pseudoClasses) {
    super.nodeGraphicBBoxChanged(engine,node,graphic,
                                 oldBBox,newBBox,pseudoClasses);
    moveFlag(newBBox, (IlvGraphic)graphic.getProperty(FLAG_GRAPHICS));
  }

  //////////////
  // Local method

  // Manage graphic props
  private void checkNode(IlvSDMEngine engine, Object obj, 
                         IlvGraphic graphic) {
    if (!graphic.isVisible())
      return;
    Object rawFlag = IlvRendererUtil.getGraphicProperty(engine, obj, 
                                                        FLAG, REND_CLASS, null);
    if (rawFlag != null && rawFlag instanceof IlvGraphic) {
      IlvGraphic g = (IlvGraphic) rawFlag;
      IlvRect r = graphic.boundingBox(null);
      moveFlag(r, g);
      engine.getGrapher().addObject(g, _flagLayer, true);
      graphic.setProperty(FLAG_GRAPHICS, g);
    }
  }

  // Remove previous flag
  private void cleanNode(IlvSDMEngine engine, IlvGraphic graphic) {
    Object previous = graphic.getProperty(FLAG_GRAPHICS);
    if (previous != null) {
      engine.getGrapher().removeObject((IlvGraphic)previous,true);
      graphic.removeProperty(FLAG_GRAPHICS);
    }
  }

  // Adjust flag position
  private void moveFlag(IlvRect newBBox, IlvGraphic source) {
    if (source == null)
      return;
    IlvRect sourceRect = source.boundingBox(null);
    source.move(newBBox.x+newBBox.width-source.boundingBox(null).width, newBBox.y-12);
  }
}