/*
 * 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.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;
import java.awt.Color;
import java.awt.image.ColorModel;

/**
 * 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
   */
  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.
   */
  public boolean isPersistent()
  {
    return true;
  }

  /**
   * Write this to specified stream
   */
  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();
    }
  }
}