package GlobalNavigation;

import java.awt.Color;
import java.awt.geom.*;
import java.util.*;

import Carmen.*;

import LocalNavigation.GUIMessage;

/**
 * <p>Message used to send a list of rects to the GUI</p>
 * 
 * <p>Examples:
 * <pre>
 *    (new GUIRectsMessage(list, false).publish(); //use curent color
 *    (new GUIRectsMessage(Color.BLUE, list, true)).publish();
 * </pre></p>
 *
 * @author vona
 **/
public class GUIRectsMessage extends Message {

  /**
   * <p>The total number of rects.</p>
   **/
  public int n;

  /**
   * <p>The rects.</p>
   **/
  public Rectangle2D.Double[] rect;

  /**
   * <p>The red color components.</p>
   **/
  public int[] r;

  /**
   * <p>The green color components.</p>
   **/
  public int[] g;

  /**
   * <p>The blue color components.</p>
   **/
  public int[] b;

  /**
   * <p>Whether to fill the rects.</p>
   **/
  public int filled;
  
  private static final String CARMEN_GUI_RECTS_NAME = "carmen_gui_rects";
  private static final String CARMEN_GUI_RECTS_FMT =
    "{int, <{double, double, double, double}:1>, <int:1>, <int:1>, <int:1>, int, double, string};";
  private static final int IPC_QUEUE_LENGTH = 10;

  /**
   * <p>Create a new GUIRectsMessage.</p>
   *
   * <p>{@link #timestamp} and {@link #host} are set to the current time and
   * host, respectively.</p>
   *
   * @param colors the colors (copied)
   * @param rects the rects (referenced)
   * @param filled whether to fill the rects
   **/
  public GUIRectsMessage(List<Color> colors,
                         List<Rectangle2D.Double> rects,
                         boolean filled) {
    n = rects.size();

    r = new int[n];
    g = new int[n];
    b = new int[n];

    rect = new Rectangle2D.Double[n];

    Iterator<Color> colorIt = colors.iterator();
    Iterator<Rectangle2D.Double> rectIt = rects.iterator();

    for (int i = 0; i < n; i++) {
     
      Color color = colorIt.next();

      r[i] = color.getRed();
      g[i] = color.getGreen();
      b[i] = color.getBlue();

      rect[i] = rectIt.next();
    }

    this.filled = (filled) ? 1 : 0;
  }
 
  /**
   * <p>Create a new GUIRectsMessage.</p>
   *
   */
  public GUIRectsMessage() {
    timestamp = Util.getTime();
    host = Util.getHostName();    
  }
  
  /**
   * <p>Check whether the rects are filled.</p>
   *
   * @return true iff the rects are filled
   **/
  public boolean isFilled() {
    return (filled != 0);
  }
  
  /**
   * <p>Subscribe a class to GUIRectsMessages.</p>
   * 
   * @param handler a GUIRectsHandler
   */
  public static void subscribe(GUIRectsHandler handler) {
    subscribe(CARMEN_GUI_RECTS_NAME, CARMEN_GUI_RECTS_FMT, handler, 
              GUIRectsMessage.class, "handle");
    IPC.IPC.setMsgQueueLength(CARMEN_GUI_RECTS_NAME, IPC_QUEUE_LENGTH);
  }
  
  /**
   * <p>Publish GUIRectsMessage to subscribers</p>
   */
  public void publish() {
    publish(CARMEN_GUI_RECTS_NAME, CARMEN_GUI_RECTS_FMT, this);
  }
}
