package LocalNavigation;

import java.awt.Color;

import Carmen.*;

/**
 * <p>Message used to send a point to the GUI</p>
 * 
 * <p>Examples:
 * <pre>
 *    (new GUIPointMessage(0.5, 0.5, SonarGUI.X_POINT).publish(); //use curent color
 *    (new GUIPointMessage(Color.BLUE, 0.0, 0.2, SonarGUI.O_POINT)).publish();
 * </pre></p>
 *
 * @author vona
 **/
public class GUIPointMessage extends GUIMessage {

  /**
   * <p>The point's x coordinate in world frame (m).</p>
   **/
  public double x;

  /**
   * <p>The point's y coordinate in world frame (m).</p>
   **/
  public double y;

  /**
   * <p>The point's visual shape, see {@link SonarGUI#addPoint}.</p>
   **/
  public int shape;
  
  private static final String CARMEN_GUI_POINT_NAME = "carmen_gui_point";
  private static final String CARMEN_GUI_POINT_FMT =
    "{double, double, int, int, int, int, double, string};";
  private static final int IPC_QUEUE_LENGTH = 10;
  
  /**
   * <p>Create a new GUIPointMessage.</p>
   *
   * <p>{@link #timestamp} and {@link #host} are set to the current time and
   * host, respectively.</p>
   *
   * @param r the red color component, negative to use current color
   * @param g the green color component, negative to use current color
   * @param b the blue color component, negative to use current color
   * @param x the point's x coordinate in world frame (m)
   * @param y the point's y coordinate in world frame (m)
   * @param shape the point's shape, see {@link SonarGUI#addPoint}
   **/
  public GUIPointMessage(int r, int g, int b,
                         double x, double y, int shape) {
    super(r, g, b);
    this.x = x;
    this.y = y;
    this.shape = shape;
  }
 
  /**
   * <p>Covers {@link #GUIPointMessage(int, int, int, double, double,
   * int)}.</p>
   *
   * @param color the color, or null to use current
   **/
  public GUIPointMessage(Color color, double x, double y, int shape) {
    this((color != null) ? color.getRed() : -1,
         (color != null) ? color.getGreen() : -1,
         (color != null) ? color.getBlue() : -1,
         x, y, shape);
  }

  /**
   * <p>Convenience cover of {@link #GUIPointMessage(int, int, int,
   * double, double, int)}, always uses current color.</p>
   **/
  public GUIPointMessage(double x, double y, int shape) {
    this(-1, -1, -1, x, y, shape);
  }
  
  /**
   * <p>Create a new GUIPointMessage.</p>
   *
   */
  public GUIPointMessage() {
    timestamp = Util.getTime();
    host = Util.getHostName();    
  }
  
  
  /**
   * <p>Subscribe a class to GUIPointMessages.</p>
   * 
   * @param handler a GUIPointHandler
   */
  public static void subscribe(GUIPointHandler handler) {
    subscribe(CARMEN_GUI_POINT_NAME, CARMEN_GUI_POINT_FMT, handler, 
              GUIPointMessage.class, "handle");
    IPC.IPC.setMsgQueueLength(CARMEN_GUI_POINT_NAME, IPC_QUEUE_LENGTH);
  }
  
  /**
   * <p>Publish GUIPointMessage to subscribers</p>
   */
  public void publish() {
    publish(CARMEN_GUI_POINT_NAME, CARMEN_GUI_POINT_FMT, this);
  }
}
