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

import java.awt.Color;
import java.awt.image.ColorModel;

import ilog.views.IlvGraphic;
import ilog.views.IlvPoint;
import ilog.views.graphic.IlvPolyline;
import ilog.views.io.IlvInputStream;
import ilog.views.io.IlvOutputStream;
import ilog.views.io.IlvPersistentObject;
import ilog.views.io.IlvReadFileException;
import ilog.views.maps.IlvFeatureAttribute;
import ilog.views.maps.IlvFeatureAttributeProperty;
import ilog.views.maps.IlvFeatureRenderer;
import ilog.views.maps.IlvMapFeature;
import ilog.views.maps.IlvMapRenderException;
import ilog.views.maps.attribute.IlvDoubleAttribute;
import ilog.views.maps.attribute.IlvIntegerAttribute;
import ilog.views.maps.geometry.IlvMapMultiPointInterface;
import ilog.views.maps.projection.IlvProjectionUtil;
import ilog.views.maps.rendering.IlvIntervalColorModel;
import ilog.views.maps.srs.coordtrans.IlvCoordinateTransformation;
import ilog.views.maps.srs.coordtrans.IlvCoordinateTransformationException;

/**
 * A renderer to process IlvMapLineString geometries, with a capacity to color
 * produced graphics using a colormodel. Color of produced graphics is based on
 * the integer or decimal value of a specified attribute. The final color is
 * computed using a colormodel.
 */
public class ColorLineRenderer implements IlvFeatureRenderer {
  /**
   * Colormodel and attribute name for finding color index
   */
  private ColorModel myColorModel;
  private String myAttributeName;

  /**
   * Constructs a new ColorLineRenderer
   * 
   * @param colormodel
   *          the colormodel to use
   * @param attributeName
   *          the name of attribute that contain the value for coloring.
   */
  public ColorLineRenderer(ColorModel colormodel, String attributeName) {
    myColorModel = colormodel;
    myAttributeName = attributeName;
  }

  /**
   * Translates the feature into a graphic object
   */
  Override
  public IlvGraphic makeGraphic(IlvMapFeature feature, IlvCoordinateTransformation tr)
      throws IlvMapRenderException, IlvCoordinateTransformationException {
    // Check that we can process this geometry
    IlvMapMultiPointInterface multiPoint;
    try {
      multiPoint = (IlvMapMultiPointInterface) feature.getGeometry();
    } catch (Exception e) {
      throw new IlvMapRenderException("not a multi point geometry");
    }

    // Check that we have to do something
    int pointCount = multiPoint.getPointCount();
    if (pointCount == 0)
      return null;

    // Allocate polyline point array
    IlvPoint p[] = new IlvPoint[pointCount];

    // Convert points
    for (int i = 0; i < pointCount; i++) {
      p[i] = new IlvPoint();
      IlvProjectionUtil.ToViews(tr, multiPoint.getPoint(i), p[i]);
    }
    // Create the graphic object, without duplicating the p[] array
    IlvPolyline poly = new IlvPolyline(p, false);

    // Find the attribute to set the color
    int colorIndex = 0;
    IlvFeatureAttributeProperty attributeList = feature.getAttributes();
    if (attributeList != null) {
      try {
        IlvFeatureAttribute attribute = null;
        attribute = attributeList.getAttribute(myAttributeName);
        if (attribute instanceof IlvIntegerAttribute)
          colorIndex = ((IlvIntegerAttribute) attribute).getValue();
        else if (attribute instanceof IlvDoubleAttribute)
          colorIndex = (int) ((IlvDoubleAttribute) attribute).getValue();
      } catch (IllegalArgumentException e) {
        colorIndex = 0;
      }
    }
    Color color = new Color(myColorModel.getRed(colorIndex), myColorModel.getGreen(colorIndex),
        myColorModel.getBlue(colorIndex));
    poly.setForeground(color);

    // returns created object
    return poly;
  }

  //
  // Constructors and methods to implement persistence
  //

  /**
   * Returns true if the object must be saved.
   */
  Override
  public boolean isPersistent() {
    return true;
  }

  /**
   * Write this to specified stream
   */
  Override
  public void write(IlvOutputStream stream) throws java.io.IOException {
    stream.write("attributeName", myAttributeName);
    if (myColorModel instanceof IlvPersistentObject)
      stream.write("colorModel", (IlvPersistentObject) myColorModel);
    else
      System.err.println("Warning : colormodel not saved");
  }

  /**
   * Constructs a new ColorLineRenderer from stream
   */
  public ColorLineRenderer(IlvInputStream stream) throws IlvReadFileException {
    myAttributeName = stream.readString("attributeName");
    try {
      myColorModel = (ColorModel) stream.readPersistentObject("colorModel");
    } catch (IlvReadFileException e) {
      // Get default colormodel
      myColorModel = IlvIntervalColorModel.MakeElevationColorModel();
    }
  }
}