// ServicePrimitive.java	(C) I. A. Robin, K. J. Turner	08/03/06

package simulator;

import java.awt.*;
import support.ProtocolEvent;

public class ServicePrimitive extends TSDSymbol {

  public static final int HEAD  = 0;
  public static final int TAIL  = 1;

  private static final int labelPadding = 5;
  private static int headLength = 8;
  private static int headWidth = 5;
  private int width;
  private boolean lToR;
  private String label;
  private int labelPos;

  public ServicePrimitive(
    ProtocolEvent event, boolean lToR, int col, int top, int height) {
    super(event, col, top);
    this.lToR = lToR;
    width = arrowWidth;
    this.height = height;
  }

  public void setLabel(String lbl, int pos) {
    label = lbl;
    labelPos = pos;
  }

  // Draw filled triangle at head of arrow
  // l = length, w = width of arrowhead

  private void drawHead(
   Graphics g, int xHead, int yHead, int xTail, int yTail, int l, int w) {
    int dx = xHead - xTail;
    int dy = yHead - yTail;
    int[] xh = new int[3];
    int[] yh = new int[3];
    xh[0] = xHead;
    yh[0] = yHead;
    float length = (float)(Math.sqrt(dx*dx + dy*dy));
    xh[1] = xh[0] - Math.round((l*dx + w*dy)/length);
    yh[1] = yh[0] + Math.round((w*dx - l*dy)/length);
    xh[2] = xh[0] - Math.round((l*dx - w*dy)/length);
    yh[2] = yh[0] - Math.round((w*dx + l*dy)/length);
    g.fillPolygon(xh, yh, 3);
  }

  private void drawLabel(
   Graphics g, int xHead, int yHead, int xTail, int yTail) {
    g.setFont(TimeSequenceDiagram.labelFont);
    FontMetrics fm = g.getFontMetrics(TimeSequenceDiagram.labelFont);
    int labelWidth = fm.stringWidth(label);
    int labelX = xTail - labelWidth - labelPadding;
    int labelY = (labelPos == HEAD)? yHead : yTail;
    if (lToR && labelPos == HEAD)
      labelX = xHead + labelPadding;
    if (!lToR  && labelPos == TAIL)
      labelX = xTail + labelPadding;
    if (!lToR  && labelPos == HEAD)
      labelX = xHead - labelWidth - labelPadding;
    g.drawString(label, labelX, labelY - 3);
  }

  // Draw arrow across column boundary from sourceCol
  // in specified direction (lToR = true/false)
  // with text label at "labelPos" (HEAD / TAIL)

  public void draw(Graphics g) {
    int xMid = inset + col*columnWidth;		// midpoint of shaft
    if (!lToR) xMid += columnWidth;
    // Locations of arrow head and tail
    int xHead = xMid + width/2;
    int xTail = xMid - width/2;
    if (!lToR) {				// adjust for rightwards arrow
      xHead -= width;
      xTail += width;
    }
    int yTail = top;
    int yHead = yTail + height;
    drawLabel(g, xHead, yHead, xTail, yTail);	// draw label
    g.drawLine(xTail, yTail, xHead, yHead);	// draw shaft of arrow
    if (lToR) {					// prepare head of arrow
      g.drawLine(xTail, yTail - 1, xHead - 4, yHead - 1);
      xHead += 2;
    }
    else {
      g.drawLine(xTail, yTail - 1, xHead + 4, yHead - 1);
      xHead -= 2;
    }
    drawHead(g, xHead, yHead, xTail, yTail, headLength, headWidth);
  }

}
