
class Graphics
{
   // instance variables

   char[][] grid;		// a 2-dim'l grid of chars
   int rows, 			// Number of rows in the grid
       cols;			// Number of columns in the grid

/*******************************************************/
    public Graphics()				// Zero-param constructor
    {
       this(50, 50);				// Call 2-param constructor
    }						// to construct grid of
						// default size.
/*******************************************************/
    public Graphics( int rows, int cols )	// 2-param constructor
    {
       this.rows = rows; this.cols = cols;	// "this" is an object of type
       grid = new char[rows][cols];		// Graphics

       int width = cols, height = rows;
       clearRect( 0,0, width, height );		// Clear the grid
    }

/*******************************************************/
    // Fill rectangle on grid with spaces ' '.  The area to be
    // cleared is given by the (x, y) coordinates of its upper left
    // corner and its width and height.
 
    public void clearRect( int x, int y, int width, int height )
    {
       for (int j = x; j < x + width; j++)
          for (int i = y; i < y + height; i++)
             grid[i][j] = ' ';
    }

/*******************************************************/
    // Display the grid on the standard output

    public void show()
    {
      for (int i = 0; i < rows; i++)
       {
         for (int j = 0; j < cols; j++)
            System.out.print(grid[i][j]);
         System.out.println("");
       }
    }

/*******************************************************/
    private static int sign( int x )             // Compute sign of x
    {
      int s = 0;
      if ( x < 0 ) s = -1;
      if ( x > 0 ) s = 1;
      return s;
    }

/*******************************************************/
    private static int gcd( int m, int n )// Compute greatest common divisor of
    {					  // m and n.  Used by drawLine()
       m = Math.abs(m); n = Math.abs(n);

       int r;
       while ( n != 0 )
        {
           r = m%n;
           m = n; n = r;
        }

       return m;
    }

/*******************************************************/
    // Draw a line on the grid from point (x1,y1) to (x2,y2)
    
    public void drawLine( int x1,int y1, int x2,int y2 )
    {
    System.out.println("drawLine: x1 = " + x1 + " y1 = " + y1);
       int xs = sign(x2 - x1);
       int ys = sign(y2 - y1);

       int g = gcd( x2-x1, y2-y1);
       int xIncr = (x2 - x1)/g;
       int yIncr = (y2 - y1)/g;

       while ( xs*(x2 - x1) >= 0 && ys*(y2 - y1) >= 0 )
       {
          grid[y1][x1] = '*';
          x1 += xIncr;
          y1 += yIncr;
       }
    }

/*******************************************************/
    public void drawBorder()
    {
      for ( int i = 0; i < rows; i++ )      // Plot left & right vertical
      {                                     // borders
         grid[i][0] = '+';
         grid[i][cols - 1] = '+';
      }
 
      for ( int j = 0; j < cols; j++ )      // Plot top and bottom
      {                                     // horizontal borders
         grid[0][j] = '+';
         grid[rows - 1][j] = '+';
      }
    }
}	// end of class Graphics
