public class Screen
{
  private int width;
  private int height;
  private Line theScreen[];
  private char fill;

  public Screen(int w, int h, char f)
  {
    this.width = w;
    this.height = h;
    this.fill = f;
    this.theScreen = new Line[height];
    for(int i = 0; i < height; i++)
    {
      this.theScreen[i] = new Line(this.width, this.fill);
    }
  }

  public Screen(int w, int h)
  {
    this(w, h, ' ');
  }

  public int getWidth()
  {
    return this.width;
  }

  public int getHeight()
  {
    return this.height;
  }

  public void setPixel(int x, int y, char c)
  {
    if(y >= 0 && y < height)
    {
      theScreen[y].setPixel(x, c);
    }
  }

  public char getPixel(int x, int y)
  {
    if(y < 0 || y >= height)
      return this.fill;
    else
      return this.theScreen[y].getPixel(x);
  }

  public void hLine(int x1, int x2, int y, char c)
  {
    for(int x = Math.min(x1, x2); x <= Math.max(x1, x2); x++)
    {
      setPixel(x, y, c);
    }
  }

  public void vLine(int x, int y1, int y2, char c)
  {
    for(int y = Math.min(y1, y2); y <= Math.max(y1, y2); y++)
    {
      setPixel(x, y, c);
    }
  }

  public void drawRect(int x1, int y1, int x2, int y2, char c)
  {
    hLine(x1, x2, y1, c);
    hLine(x1, x2, y2, c);
    vLine(x1, y1, y2, c);
    vLine(x2, y1, y2, c);
  }

  public void fillRect(int x1, int y1, int x2, int y2, char c)
  {
    for(int y = Math.min(y1, y2); y <= Math.max(y1, y2); y++)
    {
      hLine(x1, x2, y, c);
    }
  }
/*
  public void line(int x1, int y1, int x2, int y2, char c)
  {
    int y, x;
    int delx = x1 - x2;
    int dely = y1 - y2;
    if(Math.abs(delx) > Math.abs(dely))
    {
      for(x = Math.min(x1, x2); x <= Math.max(x1, x2); x++)
      {
        y = (x - x2) * dely / delx + y2;
        setPixel(x, y, c);
      }
    }
    else
    {
      for(y = Math.min(y1, y2); y <= Math.max(y1, y2); y++)
      {
        x = (y - y2) * delx / dely + x2;
        setPixel(x, y, c);
      }
    } 
  }
*/
//  Bresenham's algorithm
  public void line(int x1, int y1, int x2, int y2, char c)
  {
    int delx = x2 - x1;
    int dely = y2 - y1;      
    int incx, incy;
    int x = x1;
    int y = y1;
    int errx, erry;
    int error;

    if(delx > 0)
      incx = 1;
    else
      incx = -1;
    if(dely > 0)
      incy = 1;
    else
      incy = -1;

    if(incx == 1)
      dely = -dely;
    if(incy == -1)
      delx = -delx;

    error = 0;
    setPixel(x, y, c);
    while(x != x2 || y != y2)
    {
      errx = error + dely;
      erry = error + delx;
      if(Math.abs(errx) < Math.abs(erry))
      {
        x += incx;
        error = errx;
      }
      else
      {
        y += incy;
        error = erry;
      }
      setPixel(x, y, c);
    }
  }

  public String toString()
  {
    String retval = "";
    for(int y = 0; y < height; y++)
    {
      retval += theScreen[y] + "\n";
    }
    return retval + "\n";
  }

  public static void main(String args[])
  {
    Screen myScreen =new Screen(50, 20, ' ');
    myScreen.line(1, 1, 40, 10, '+');
    System.out.println(myScreen);
  }
}
