/** @(#) AnnoText.java 1.0 99/12/20 Larry Rodrigues
 **/
package com.vistech.shapes;
import java.awt.*;
import java.lang.Math;
import java.awt.geom.*;

/**  Represents an interactively drawable text string.
   * 
   * @version 1.0  20  Dec 1999
   * @author Larry Rodrigues
   **/
public class AnnoText extends Shapes implements Typable{
    /** Current string */
    public StringBuffer curStr = new StringBuffer();
    /** Latest character */
    public char curChar;
    public int totWid =0;
    public int curCount =0;
    protected Font font;
    public boolean backSpaceOn = false;
    public char lastChar;
  /** Initializes the AnnoText parameters.
    * The arguments provide the starting point  of the text.
    * @param  x  the x coordinate of the starting position.
    * @param  y  the y coordinate of the starting poistion.
    ***/
  public void init(int x , int y){
      st.x = x; st.y = y;
      totWid =0;
      curStr.setLength(0);
      curCount= 0;
  }

   /** Sets the current position.
    * Currently, this point is not being used in AnnoText.
    * @param  x  the x coordinate of the current position.
    * @param  y  the y coordinate of the current poistion.
    **/
   public void setCurPoint(int x , int y){
         cur.x = x; cur.y = y;
   }

   /** Sets the current character.
    * This method is specific to AnnoText class.
    * @param key the char
    **/
   public void setCurChar(int key){
      if((key == java.awt.event.KeyEvent.VK_BACK_SPACE)||
         (key == java.awt.event.KeyEvent.VK_DELETE)){
         int len = curStr.length();
         if(len <=0) return;
         curCount--;
         lastChar = curStr.charAt(len-1);
         curStr.deleteCharAt(len-1);
         backSpaceOn = true;
         return;
      }
      curChar = (char)key;
      curStr.append(curChar);
      curCount++;
   }

   /**
    * Gets the currently drawn string.
    * This method is specific to AnnoText class.
    * @return String the current string.
    **/
   public String getCurStr(){
      return curStr.toString();
   }

   /** Draws text over a Graphics context g.
    * This API does not check whether the text overflows
    * the borders of the component.
    * @param g the graphics object on which the shape is to  be drawn.
    **/
   public void drawInteractive(Graphics2D g ){
      font = g.getFont();
      char  c[] = new char[1];
      if(backSpaceOn) {
         c[0] = lastChar;
         FontMetrics fm =  g.getFontMetrics();
         int curWid = fm.charWidth(lastChar);
         g.setColor(Color.black);
         g.setXORMode(drawingColor);
         g.drawChars(c, 0,1,st.x + totWid-curWid,  st.y );
         totWid -= curWid;
         cur = new Point(st.x-totWid, st.y);
         backSpaceOn = false;
      }else {
        c[0] = curChar;
        FontMetrics fm =  g.getFontMetrics();
        int curWid = fm.charWidth(curChar);
        g.setColor(Color.black);
        g.setXORMode(drawingColor);
        g.drawChars(c, 0,1,st.x + totWid,  st.y );
        totWid += curWid;
        cur = new Point(st.x+totWid, st.y);
      }
  }

  public void drawPermanent(Graphics2D g){
     Font savedFont = g.getFont();
     g.setFont(font);
     g.setPaintMode();
     g.setColor(drawingColor);
     g.drawString(curStr.toString(),st.x, st.y);
     g.setFont(savedFont);
  }
   /**
    * Draws text.
    * @param g the graphics object on which the shape is to be drawn.
    **/
   public void draw(Graphics2D g){
      Font savedFont = g.getFont();
      g.setFont(font);
      if(curStr == null) return;
      g.setColor(Color.black);
      g.setXORMode(drawingColor);
      FontMetrics fm =  g.getFontMetrics();
      char  c[] = new char[1];
      int twid =0;
      for(int i=0; i<curStr.length();i++){
          c[0] = curStr.charAt(i);
          int curWid = fm.charWidth(c[0]);
             //g.setColor(drawingColor);
          g.drawChars(c, 0,1,st.x + twid,  st.y );
          twid += curWid;
      }
      g.setFont(savedFont);
   }

   public void move(Graphics2D g, int diffx, int diffy) {
      erase(g);
      st.x += diffx; st.y += diffy;
      cur.x += diffx; cur.y += diffy;
      draw(g);
      drawSmallRects(g);
   }
   public void erase(Graphics2D g){
      if(curStr == null) return;
      Font savedFont = g.getFont();
      g.setFont(font);

      g.setColor(Color.black);
      g.setXORMode(drawingColor);
      FontMetrics fm =  g.getFontMetrics();
      if(smallRectsOn) drawSmallRects(g);
      char  c[] = new char[1];
      int twid =0;

      for(int i=0; i<curStr.length();i++){
          c[0] = curStr.charAt(i);
          int curWid = fm.charWidth(c[0]);
             //g.setColor(drawingColor);
          g.drawChars(c, 0,1,st.x + twid,  st.y );
          twid += curWid;
      }
      g.setFont(savedFont);
   }

   public boolean contains(Graphics2D g, int x, int y){
        GeneralPath pa = new GeneralPath();
        pa.moveTo((float)(st.x-15), (float)(st.y-15));
        pa.lineTo((float)(st.x+15), (float)(st.y+15));
        pa.lineTo((float)(cur.x+15), (float)(cur.y+15));
        pa.lineTo((float)(cur.x-15), (float)(cur.y-15));
        pa.closePath();
        if(pa.contains((double)x, (double)y)) {
           drawSmallRects(g);
           return true;
        }else return false;
   }

   public void drawSmallRects(Graphics2D g) {
      smallRectsOn = !smallRectsOn;
      g.setColor(Color.black);
      g.setXORMode(drawingColor);

      int xp[] = new int[4];
      int yp[] = new int[4];
      xp[0] = st.x; yp[0] = st.y;
      xp[1] = cur.x; yp[1] = st.y;
      xp[2] = cur.x; yp[2] = cur.y;
      xp[3] = st.x; yp[3] = cur.y;
      for(int i=0; i< xp.length;i++) {
          int x, y;
          if(xp[i] > xp[(i+2)%4]) x = xp[i]+1;
          else x = xp[i]-6;
          if(yp[i] > yp[(i+2)%4]) y = yp[i]+1;
          else y = yp[i]-6;
          g.drawRect(x, y, 5,5);
      }
    }
}
