<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">/*************************************************
 * Author: 	Evelyn Lai-Tee Cheok
 *			Department of Electrical Engineering
 *			Center for Telecommunications Research
 *			Schapiro Research Building
 *			Columbia University
 *
 * Email: 	laitee@ctr.columbia.edu
 *
 **************************************************/
import java.lang.*;
import java.awt.*;
import java.io.*;
import java.util.*;
import SketchArea;
import ObjType;
import SenderMCSocket;
import PacketHandler;


public class Text extends ObjBaseClass implements DrawObject, Cloneable {

	SketchArea parent;
	public int x1, y1, width, height;
	public int old_x1, old_y1, dist_x, dist_y;
	public String text;
	public int type;
	public int color = 0;
	public Color[] baseColors = new Color[20];
	public int obj_id = 0;
	Random rand_gen = new Random(System.currentTimeMillis());

	/**
	 * constructor
	 *
	 *@param parent SketchArea object reference
	 *@param c color type
	 *@return none
	 */

	public Text(SketchArea parent, String text, int c, FontMetrics fm) {

		super(parent.parent.senderSock, parent.parent.pkt_handler);
		this.parent = parent;
		this.text = text;
		Dimension dim = getStringDim(text, fm);
		this.width = dim.width;
		this.height = dim.height;
		type = ObjType.TEXT;
		baseColors = parent.colorpanel.getBaseColors();
		color = c;
		obj_id = (int) (rand_gen.nextFloat() * 2000);
	}

    /** Gets dimension of the string entered onto the textfield of the
      * whiteboard canvas.
      * @param text text entered
      * @returns dimension of the text entered
      **/
 
    public Dimension getStringDim(String text, FontMetrics fm) {
        Dimension fontDim = new Dimension();

        fontDim.width = fm.stringWidth(text);
        fontDim.height = fm.getHeight();
 
        return fontDim;
    }

	/**
	 * constructor
	 *
	 *@param parent SketchArea reference
	 *@return none
	 */

	public Text(SketchArea parent, String text, Dimension dim) {
		super(parent.parent.senderSock, parent.parent.pkt_handler);
		this.parent = parent;
		this.text = text;
		this.width = dim.width;
		this.height = dim.height;
		type = ObjType.TEXT;
		baseColors = parent.colorpanel.getBaseColors();
	}

	/**
	 * constructor
	 *
	 *@param parent SketchArea reference
	 *@return none
	 */

	public Text(SketchArea parent) {
		super(parent.parent.senderSock, parent.parent.pkt_handler);
		this.parent = parent;
		type = ObjType.TEXT;
		baseColors = parent.colorpanel.getBaseColors();
	}

	/** clones a text object by making an exact copy of this text object
	  * with values equal to the original values, except that the starting
	  * and ending points of the newly cloned text are translated by a value of
	  * TRANSLATE_X and TRANSLATE_Y defined in the ObjBaseClass.java.
	  * @return a cloned text object.
	  **/
	public Object clone() {
		try {
			Text clonetext = (Text)super.clone();
			clonetext.x1 += TRANSLATE_X;
			clonetext.y1 += TRANSLATE_Y;
			clonetext.obj_id = (int)(rand_gen.nextFloat() * 2000);
			return clonetext;
		} catch (CloneNotSupportedException e) {
			System.out.println("CLoneNotSupportedException : "+e);
			throw new InternalError(e.toString());
		}
	}

	/**
	 * event handler for mouse down while drawing
	 *
	 *@param x x value
	 *@param y y value
	 *@return true
	 */

	public boolean mouseDown(int x, int y) {

		x1 = x;
		y1 = y;

		return true;
	}

	/**
	 * event handler for mouse up when drawing objects. This event is
	 * not relevant to this class of text string objects. The event is
	 * not implemented though it's being declared due to compliance to
	 * the interface DrawObject.
	 *
	 *@param x x value
	 *@param y y value
	 *@return true
	 */

	public boolean mouseUp(int x, int y) {
		/* no mouseUp event for text object. However declared since
		 * this class implements interface DrawObject and mouseUp is 
		 * an abstract method declared in that interface.
		 **/

		 return true;
	}

	public void send() {
		assemble(ObjType.TEXT);
	}

	/**
	 * event handler for mouse drag when drawing the objects. Not
	 * relevant and hence not implemented though declared due to
	 * compliance to the interface DrawObject.
	 *
	 *@param x x value
	 *@param y y value
	 *@return true
	 */

	public boolean mouseDrag(int x, int y) {
		/* no implementation since not relevant to this class of 
		 * text string object.
		 **/

		 return true;
	}

	/**
	 * function called when moving the object
	 *
	 *@param x x value
	 *@param y y value
	 *@return void
	 */

	public void moving(Graphics g, int x, int y) {
		old_x1 = x1;
		old_y1 = y1;

		setBasePoint(x, y);
		clear(g);
		assemble(ObjType.MOVE);
	}

    public void setBasePoint(int x, int y) {
        x1 = x - dist_x;
        y1 = y + dist_y;
    }

    public void setBaseDist(Graphics g, int x, int y) {
        dist_x = x - x1;
        dist_y = y1 - y;
        erase(g, false);
    }

	public void recvd_moved_obj(Graphics g, int recvd_x1, int recvd_y1,
				     int recvd_x2, int recvd_y2) {
	/*	old_x = x2;
		old_y = y2;
		clean(g);
		x1 = recvd_x1;
		y1 = recvd_y1;
		x2 = recvd_x2;
		y2 = recvd_y2;
		paint(g);
		*/
	}

	/**
	 * set parameter after locating the last point
	 *
	 *@param g graphics context
	 *@param x x value
	 *@return y y value
	 */


	public void moveUP(Graphics g, int x, int y) {
		setBasePoint(x, y);
		clear(g);
	}

	/**
	 * set drawing color
	 *
	 *@param g graphics context
	 *@param c color
	 *@return void
	 */

	public void setPenColor(Graphics g, int c) {
		g.setColor(baseColors[c]);
		//g.setXORMode(Color.white);
	}

	/**
	 * draw object which is passed from network
	 *
	 *@param xx1 start point
	 *@param yy1 start point
	 *@param xx2 end point
	 *@param yy2 end point
	 *@return void
	 */

	public void draw(int xx1, int yy1, int xx2, int yy2, int col, int obj_id_recvd) {
		int oldColor;
		 x1 = xx1;
		 y1 = yy1;
		 width = xx2;
		 height = yy2;

		 this.color = col;
		 paint(parent.offscreenG);
		 parent.repaint();
		 obj_id = obj_id_recvd;
		 parent.addStack((Object) this);
	}

	/**
	 * draw the object by pen color
	 *
	 *@param g graphics context
	 *@return void
	 */

	public void paint(Graphics g) {
		g.setColor(baseColors[color]);
		g.drawString(text, x1, y1);
	}

	/**
	 * clear up object on the whiteboard
	 *
	 *@param g Graphics context
	 *@return void
	 */

	public void clear(Graphics g) {
		clean(g);
		paint(g);
	}

	public void clean(Graphics g) {
		g.setColor(parent.getBackground());
		g.drawString(text, old_x1, old_y1);
	}

	public void erase(Graphics g, boolean send_del_req) {
		g.setColor(parent.getBackground());
		g.drawString(text, x1, y1);
		if (send_del_req == true)
			assemble(ObjType.DELETE);
	}


	/**
	 * assembles the Line object's parameters based on application-specific
	 * format before calling superclass's BaseClassAssemble for assembling
	 * this resulting packet with the RTP header. This function is called
	 * by mouseUp Event.
	 *
	 *@author Lai-Tee Cheok
	 *
	 *@return void
	 */

	public void assemble(int ObjectType) {
		ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
		DataOutputStream dataStream = new DataOutputStream(byteStream);
		 byte[] data_buf = new byte[1024];
		 System.out.println("OBJECT ID sent = " + obj_id);
		 try {
			dataStream.writeByte(DataType.WBDataType);
			dataStream.writeByte(ObjectType);
			dataStream.writeInt(obj_id);
			if (ObjectType != ObjType.DELETE) {
				dataStream.writeByte((byte) color);
				if (ObjectType == ObjType.TEXT) {
					dataStream.writeByte(text.length());
					dataStream.writeBytes(text);
				}
				dataStream.writeShort(x1);
				dataStream.writeShort(y1);
				dataStream.writeShort(width);
				dataStream.writeShort(height);
			}
		} catch(java.io.IOException e) {
			System.out.println("IOException in Text Object assembling: " + e);
		}

		data_buf = byteStream.toByteArray();
		BaseClassAssemble(data_buf);

		//System.out.println("num. of valide bytes in the bytestream = " + byteStream.size());
		//System.out.println("DataType.WBDataType = " + DataType.WBDataType);
	}

	/**
	 * retrieves Line object's parameters from the received packet and
	 * display the line on the drawing canvas of the whiteboard.
	 *
	 * @author: Lai-Tee Cheok
	 *
	 *@param buf buffer that holds parameters in the form of byte array.
	 *@return void
	 */

	public void processInData(byte[] buf) {
		/*
		 * the received parameters should not be assigned as global
		 * variables form so that these values won't clash with the
		 * global variables that we want to send out.
		 */
		int received_x1 = 0;
		int received_y1 = 0;
		int received_width = 0;
		int received_height = 0;
		int col = 0;
		int obj_id_recvd = 0;
		int text_len = 0;
		ByteArrayInputStream byteStream = new ByteArrayInputStream(buf);
		DataInputStream dataStream = new DataInputStream(byteStream);

		 try {
			obj_id_recvd = dataStream.readInt();
			col = dataStream.readByte() &amp; 255;
			text_len = (int)dataStream.readByte();

			/* Note very carefully here that we need to assign
			 * the text_byte_buf[] a size EXACTLY the same as 
			 * that of the text string received. Otherwise, the length
			 * of the text string : text, will have a length that of the
			 * text_byte_buf[] (which might be assigned as 1024 bytes),
			 * instead of the actual length of the text string received.
			 * It is important to get the length right if we are to send
			 * this text string again. If this text string sent has a length
			 * of 1024 (due to us assigning byte text_byte_buf[] = new byte[1024]),
			 * then the receiver will try to read 1024 length of text, when the 
			 * text has actually a length less than that !!!
			 **/
			byte text_byte_buf[] = new byte[text_len];
			dataStream.read(text_byte_buf, 0, text_len);
			text = new String(text_byte_buf, 0);

			received_x1 = dataStream.readUnsignedShort();
			received_y1 = dataStream.readUnsignedShort();
			received_width = dataStream.readUnsignedShort();
			received_height = dataStream.readUnsignedShort();
		} catch(java.io.IOException e) {
			System.out.println("IOException in reading Obj_type: " + e);
		}

		System.out.println("^^^^^^^^^^^^^ Text parameters received ^^^^^^^^^^^^^");
		System.out.println("OBJECT ID received = " + obj_id_recvd);
		System.out.println("text_len = "+text_len);
		System.out.println("text string = " + text);
		draw(received_x1, received_y1, received_width, received_height, col, obj_id_recvd);
	}

	/**
	 * return type of the object
	 *
	 *@return type
	 */

	public int getType() {
		return type;
	}

	public int getObjID() {
		return obj_id;
	}

}
</pre></body></html>