import com.sun.kjava.*;
import java.util.*;

/**
 * A scrolling TextBox object.  This is basically the
 * com.sun.kjava.ScrollTextBox object with the bugs ironed out.  I was
 * unable to subclass ScrollTextBox and still get access to the bugs, so
 * this is my interim solution.
 *
 * You need to control this class from a registered Spotlet. In the
 * Spotlet class, implement penDown(), penMove() and keyDown() to 
 * call the handlePenDown(), handlePenMove() and handleKeyDown() 
 * methods of this class.
 *
 * @author Robert Evans, rbevans@akane.jhuapl.edu
 */

public class BasicScrollTextBox extends TextBox implements ScrollOwner {

    protected StringBuffer textBuffer = new StringBuffer("");
    protected VerticalScrollBar vsb;

    protected int minVal;
    protected int maxVal;
    protected int curVal;
    protected int visibleLines;
    protected int numLines;

    protected BasicScrollTextBox() {
    }
    
    /**
     * Create a new ScrollTextBox2 object.
     *
     * @param t the initial text
     * @param x the X coordinate of the ScrollTextBox2's position
     * @param y the Y coordinate of the ScrollTextBox2's position
     * @param w the width
     * @param h the height
     */
    public BasicScrollTextBox(String t, int x, int y, int w, int h) {
        super(t, x, y, w - VerticalScrollBar.SCROLL_BAR_WIDTH, h);
	init();
        vsb = new VerticalScrollBar(this);
	vsb.setBounds(x+width,
                      yPos, height, 0, maxVal, curVal);
  }

    /**
     * Reset the display bounds of the ScrollTextBox2.
     *
     * @param x the new X coordinate of the ScrollTextBox2's position
     * @param y the new Y coordinate of the ScrollTextBox2's position
     * @param w the new width
     * @param h the new height
     */
    public void setBounds(int x, int y, int w, int h) {
      if((x == xPos) && (y == yPos) && (w == width) && (h == height)) {
          // setting the bounds the same is a no-op.
          return;
      }
      super.setBounds(x, y, w-VerticalScrollBar.SCROLL_BAR_WIDTH, h);
      init();
      vsb.setBounds(xPos+width,
		    yPos, height, 0, maxVal, curVal);
    }

    public String getText() {
	return textBuffer.toString();
    }
    /**
     * Set the text.
     *
     * @param t a String representing the new text.
     */
  public void setText(String t) {
    super.setText(t);
    textBuffer = new StringBuffer(t);
    init();
    // reset the scrollbar to the new size
    vsb.setBounds(xPos+width,
                  yPos, height, 0, maxVal, curVal);
  }


    /**
     * Set the text.
     *
     * @param t a String representing the new text.
     */
  public void addText(String t) {
    super.setText(textBuffer.toString() + t);
    textBuffer.append(t);
    init();
    // reset the scrollbar to the new size
    vsb.setBounds(xPos+width,
                  yPos, height, 0, maxVal, curVal);
  }

    
    public void handleKeyDown(int keyCode) {
        vsb.handleKeyDown(keyCode);
    }
    
    /**
     * Initialize the object.
     */
  protected void init() {
	numLines = getNumLines();
	visibleLines = height/heightM;

	maxVal = numLines - visibleLines;
	minVal = 0;
	curVal = 0;

	if(maxVal < 0) {
	  maxVal = 0;
	}
  }

    /**
     * Is this point inside the bounds of the object?
     *
     * @param x the X coordinate of the position to test
     * @param y the Y coordinate of the position to test
     * @return true of the point is inside our bounds
     */
    public boolean contains(int x, int y) {
        return vsb.contains(x, y);
    }

    /**
     * The pen has gone down at (x, y).  Do the right thing.
     *
     * @param x the X coordinate of the pen position
     * @param y the Y coordinate of the pen position
     */
  public void handlePenDown(int x, int y) {
    vsb.handlePenDown(x,y);
  }
  
    /**
     * The pen has moved at (x, y).  Do the right thing.
     *
     * @param x the X coordinate of the pen position
     * @param y the Y coordinate of the pen position
     */
  public void handlePenMove(int x, int y) {
    vsb.handlePenMove(x, y);
  }


    /**
     * Paint the ScrollTextBox2.
     */
  public void paint() {
        vsb.paint();
	
	this.g.setDrawRegion(xPos, yPos, width, height);
	
	this.g.drawRectangle(xPos, yPos, width, height, this.g.ERASE, this.g.SIMPLE);
	int x = xPos;
	int y = yPos;
	int first = 0;
	int last = 0;
	int numLines = (lineStarts.size() > curVal+visibleLines) ? curVal+visibleLines : lineStarts.size();
	for(int i=curVal; i<numLines; i++) {
	    first = lineStarts.valueAt(i);
	    last = lineEnds.valueAt(i);
	    if(first != last) {
		if(text.charAt(first) == ' ') {
		    first++;
		}
		this.g.drawString(text.substring(first, last), x, y);
	    }
	    y += heightM;
	}
	
	this.g.resetDrawRegion();
    
  }

    /**
     * Set the current scroll value and repaint.
     *
     * @param val the new scroll value.
     */
  public void setScrollValue(int val) {
      if (val < 0)
	  curVal = 0;
      else 
	  curVal = val;
      paint();
  }
}








    
