/*
//  FileName: GraphUnit.java
//  
//  Vijay Konkimalla
//  07 Dec 95
//
//  Objective: 
//
//  $Author: konki $
//  $Log: GraphUnit.java,v $
# Revision 1.3  1996/04/01  21:37:50  konki
# Added variables hashkey + select. Took care of packetization
#
# Revision 1.2  1996/03/11  21:00:30  konki
# *** empty log message ***
#
# Revision 1.1  1996/02/18  23:10:28  konki
# Initial revision
#
# Revision 1.1  1996/02/18  23:10:28  konki
# Initial revision
# 
//  $Id: GraphUnit.java,v 1.3 1996/04/01 21:37:50 konki Exp $
*/

package wb;

import  java.awt.*;
import  java.io.*;


/**
 * GraphUnit, base class of all the objects and messages that float around
 * all the participants over the network. This is the base representation
 * of graph objects that are stored in the repositary. A lot of things like
 * selection, alteration, Id (Key/hashcode) are not yet incorporated.
 * Definitions about the possible types are imported indirectly thro the 
 * Interface GTypes. 
 * Clonability, user level finalization (public) has to be incorporated for
 * better memory management.
 */
public class GraphUnit extends Object implements GTypes
{
    /**
     * Type of the GraphUnit
     */
    protected int type;                   

    /**
     * bounds of the GraphUnit. these could be used in a varity of ways
     */
    protected int xmin, ymin, xmax, ymax; 

    /**
     * Color of the GraphUnit
     */
    protected Color color;

    /**
     * BytePackOutputStream using which the instance details are sent over the
     * network.
     */
    protected BytePackOutputStream bpos = null;
  
    /**
     * ByteUnPackInputStream using which the instance details are received 
     * over the network.
     */
    protected ByteUnPackInputStream buis = null;

    /**
     * HashCode of this unit
     * this is assigned at the time of creation using the hashCode() of Object.
     * however, this is set appropriately when read from stream.
     */
    protected int hashkey;

    /**
     * boolean to indicate that the object is in select mode
     * this data is not transported.
     */
    protected boolean select;

    /**
     * Helper routine for base setup 
     * @param x1 x-coordinate of the min x (bound)
     * @param y1 y-coordinate of the min y (bound)
     * @param x2 x-coordinate of the max x (bound)
     * @param y2 y-coordinate of the max y (bound)
     */
    protected void setup( int x1, int y1, int x2, int y2 )
    {
        xmin = (x1 < x2) ? x1 : x2;
        ymin = (y1 < y2) ? y1 : y2;
        xmax = (x1 > x2) ? x1 : x2;
        ymax = (y1 > y2) ? y1 : y2;
        select = false;
    }

    /**
     * Helper routine for base setup 
     * @param x1 x-coordinate of the min x (bound)
     * @param y1 y-coordinate of the min y (bound)
     * @param x2 x-coordinate of the max x (bound)
     * @param y2 y-coordinate of the max y (bound)
     * @param arg Color of the Object
     */
    protected void setup( int x1, int y1, int x2, int y2, Color arg )
    {
        setup(x1,y1,x2,y2);
        color = arg;
    }

    /**
     * Creates an instance of GraphUnit, Provided to handle sub-classing
     */
    GraphUnit()
    {
    }

    /**
     * Creates an instance of GraphUnit with Color "arg"
     * @param arg the Color of the GraphUnit
     */
    public GraphUnit( Color arg )
    {
        color = arg;
        hashkey = hashCode();
        select = false;
    }

    /**
     * Creates an instance of GraphUnit with Color "arg"
     * @param x1 x-coordinate of the min x (bound)
     * @param y1 y-coordinate of the min y (bound)
     * @param x2 x-coordinate of the max x (bound)
     * @param y2 y-coordinate of the max y (bound)
     * @param arg the Color of the GraphUnit
     */
    public GraphUnit( int x1, int y1, int x2, int y2 )
    {
        setup(x1,y1,x2,y2);
        hashkey = hashCode();
    }

    /**
     * Creates an instance of GraphUnit with Color "arg"
     * @param x1 x-coordinate of the min x (bound)
     * @param y1 y-coordinate of the min y (bound)
     * @param x2 x-coordinate of the max x (bound)
     * @param y2 y-coordinate of the max y (bound)
     * @param arg the Color of the GraphUnit
     */
    public GraphUnit( int x1, int y1, int x2, int y2, Color arg)
    {
        setup(x1,y1,x2,y2);
        color = arg;
        hashkey = hashCode();
    }

    /**
     * Creates an instance of GraphUnit by reading data from the 
     * DataInputStream. Useful for creating objects directly from the
     * network. Uses helper routines like (basedepacketize). Must be handled
     * with care when subclassed.
     * @param din, DataInputStream from which the data is read.
     * @exception IOException, throws IOException when there is a read error
     * @see #basedepacketize
     */
    public GraphUnit( DataInputStream din ) throws IOException
    {
        basedepacketize( din );
        buis = null;
        select = false;
    }

    /**
     * Helper routine for Stream based constructor. When sub-classed, care must
     * be taken to match with the other helper method "basepacketize"
     * while unpacking the data from the ByteUnPackInputSteam
     * @param din, DataInputStream from which the data is read.
     * @exception IOException, throws IOException when there is a read error
     * @see #basepacketize
     * @see ByteUnPackInputStream
     */
    protected void basedepacketize( DataInputStream din ) throws IOException
    {
        int bytecount = din.readInt();
        if ( buis == null ) {
            buis = new ByteUnPackInputStream( din );
        }
        buis.fill(bytecount);
        type = buis.readInt();
        xmin = buis.readInt();
        ymin = buis.readInt();
        xmax = buis.readInt();
        ymax = buis.readInt();
        color = new Color(buis.readInt());
        hashkey = buis.readInt();
    }

    /**
     * Helper routine for Object transport. When sub-classed, care must
     * be taken to match with the other helper method "basedepacketize"
     * while packing the data to the BytePackOutputStream.
     * Once the data is sync'd to a buffer, if the object is modified
     * there is no way this change would be reflected in the byte pack.
     * I guess there should a way to resync, if this object is modified
     * @param dos, DataOutputStream to which the data is to be written.
     * @exception IOException, throws IOException when there is a read error
     * @see #basedepacketize
     * @see BytePackOututStream
     */
    protected void basepacketize( DataOutputStream dos ) throws IOException
    {
        if ( bpos == null ) {
            bpos = new BytePackOutputStream( dos );
        }
        bpos.writeInt(type);
        bpos.writeInt(xmin);
        bpos.writeInt(ymin);
        bpos.writeInt(xmax);
        bpos.writeInt(ymax);
        bpos.writeInt(color.getRGB());
        bpos.writeInt(hashkey);
// should write to OutputStream the number of bytes that will be followed. 
// useful for recovery
//      bpos.sync();
    }

    /** 
     * Sets the type of graphunit 
     * @param arg the type of GraphUnit. It should match with the 
     *                type defined in the interface GTypes
     * @see #gettype
     * @see GTypes
     */
    public void settype( int arg )
    {
        type = arg;     
    }

    /** 
     * gets the type of graphunit 
     * @return int the type of this graph unit
     * @see #settype
     * @see GTypes
     */
    public int gettype()
    {
        return type;
    }

    /** 
     * gets the hashkey of graphunit 
     * @return int the hashkey of this graph unit
     */
    public int gethashkey()
    {
        return hashkey;
    }

    /** 
     * set the color of this graphunit 
     * @param arg the Color of this graph unit
     */
    public void setcolor( Color arg )
    {
        color = arg;
    }

    /**
     * helper routine to render the graph unit to the graphics.
     * called  for screen update 
     * @param g Graphics
     */
    public void paint( Graphics g )
    {
    }

    /**
     * helper routine to render the graph unit in the background color
     * to the graphics. Gives the effect of erasing the object
     * @param g Graphics
     * @param arg Color of the background
     */
    public void erase( Graphics g, Color arg )
    {
    }

    /**
     * method for Object transport.
     * NOTE: Once the data is sync'd to a buffer, if the object is modified
     * there is no way this change would be reflected in the byte pack.
     * I guess there should a way to resync, if this object is modified
     * @param dos, DataOutputStream to which the data is to be written.
     * @exception IOException, throws IOException when there is a read error
     * @see #basedepacketize
     * @see #basepacketize
     * @see BytePackOututStream
     */
    public void packetize( DataOutputStream dos) throws IOException
    {
        if ( bpos == null ) {
            basepacketize(dos);
        }
        dos.writeInt(bpos.size());
        bpos.sync(dos);        
//        bpos = null;
    }

    /**
     * Add the next coordinate.
     * @param x the x-coridinate
     * @param y the y-coridinate
     */
    public void addnext( int x, int y )
    {
    }

    /**
     * Add the next char.
     * @param key the character
     */
    public void addnext( char key )
    {
    }

    /**
     * Add the next integer.
     * @param x the integer
     */
    public void addnext( int x )
    {
    }

    /**
     * Append the String
     * @param chardata the String
     */
    public void addnext( String chardata )
    {
    }

    /**
     * isValid is very useful in determine'g  miscellaneous objects 
     * at the time of creation. 
     * @return boolean true if valid
     *                 else false
     */
    public boolean isValid()
    {
        return true;
    }
  
    /**
     * Method to check if the current object handles enclose the passed 
     * point
     * @param x x-coordinate of the point
     * @param y y-coordinate of the point
     * @return boolean true if the point(x,y) is enclosed in one of the
     *                      handles assigned to this unit.
     */
    public boolean  isInside( int x, int y )
    {
        return false;
    }

    /**
     * Method to set the graphunit in select mode
     */
    public void setSelect()
    {
        select = true;
    }

    /**
     * Method to Reset the graphunit in select mode
     */
    public void ResetSelect()
    {
        select = false;
    }

    /**
     * Method to check the select status
     * @return true iff select is true
     */
    public boolean isSelect()
    {
        return select;
    }

}

/*
 * End of file: GraphUnit.java
 */