/*
 * @(#)ScrollPanel.java		0.1 96/01/09  Jesse Hammons
 *
 * Copyright (c) 1996 Jesse Hammons
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *   
 * Contact author for use policy on software and documentation
 */



import java.awt.Panel;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Dimension;
import java.awt.Scrollbar;
import java.awt.Image;
import java.awt.Graphics;
import java.awt.Component;
import java.awt.Event;

/**
  * ScrollPanel is a generic Panel with scrollbars.  If a client Component is 
  * assigned to a ScrollPanel, The ScrollPanel will set up the scrollbars so 
  * that the Component can be scrolled around if the size of the client is 
  * larger than the inside of the ScrollPanel. 
  *
  * @version 0.1, 09 Jan 1996
  * @author Jesse Hammons
  */

public class ScrollPanel extends Panel {
  RepaintScrollbar horiz, vert;
  int prevx=0, prevy=0;
  boolean first = true;
  GridBagLayout g;
  GridBagConstraints c;

  Image osimg = null;
  Image biggest = null;
  Dimension bigSize;
  Graphics off;
  Dimension imSize;
  int ImgW, ImgH;
  
  /**
    * Creates a ScrollPanel with no client Component.
    */
/*  public ScrollPanel() {
    this(null);
  } */
  
  /**
    * Creates a ScrollPanel with the specified client Componenent.
    * @param client the client Component
    */
  public ScrollPanel(Image img, int w, int h) {
    super();
    int gap = 0;
    horiz = new RepaintScrollbar(this, Scrollbar.HORIZONTAL);
    vert = new RepaintScrollbar(this, Scrollbar.VERTICAL);

    setLayout(new java.awt.BorderLayout());
    add("East", vert);
    add("South", horiz);

    setImage(img, w, h);
  }

  public void setImage(Image img, int w, int h) {
    osimg = img;
    ImgW = w;
    ImgH = h;
    reshape();
    repaint();
  }
  
  
  /**
    * Paints the ScrollPanel the the Graphics context g.
    * @param g the Graphics context to paint to
    */
  public void paint(Graphics g) {
    Dimension s = size();
    Dimension d;
    int x = horiz.getValue();
    int y = vert.getValue();
    int dx = x - prevx;
    int dy = y - prevy;
	int vw = vert.size().width;
	int hh = horiz.size().height;
/*	off.clipRect(vw, 0, size().width-vw, size().height-hh); */
/*	g.copyArea(prevx, prevy, s.width-dx, s.height-dy, dx, dy);
	g.clipRect(-x, -y, dx, dy); */
	g.drawImage(osimg, -x, -y, this);

    prevx = x;
    prevy = y;
  }// paint()

  /**
    * Updates the ScrollPanel using the Graphics context g.
    * equivalent to paint(g).
    * @param g the Graphics context to use
    * @see #paint 
    */
  public void update(Graphics g) {
    paint(g);
  }


  private void dbg(String s) {
    System.out.println(s);
  }
  
  /**
    * Reshapes the ScrollPanel to the specified bounding box, and resets
    * the Scrollbars to the appropriate maximum values, page sizes, etc.
    * @param x	the X coordinate 
    * @param y	the Y coordinate
    * @param w  the width of the bounding box
    * @param h	the height of the bounding box
    */
  public void reshape(int x, int y, int w, int h) {
    super.reshape(x, y, w, h);
    Dimension s = size();
    int vpage, hpage;

    vpage = s.height;
    hpage = s.width;

    vert.setValues(vert.getValue(), vpage, 0, ImgH-s.height);
    horiz.setValues(horiz.getValue(), hpage, 0, ImgW-s.width);
  } //reshape()

  public void reshape() {
    Dimension s = size();
    int vpage, hpage;

    vpage = s.height;
    hpage = s.width;

    vert.setValues(vert.getValue(), vpage, 0, ImgH-s.height);
    horiz.setValues(horiz.getValue(), hpage, 0, ImgW-s.width);
  }
} // ScrollPanel    



class RepaintScrollbar extends Scrollbar {
  Component callBack = null;
  
  public RepaintScrollbar(Component cb, int orientation) {
    super(orientation);
    callBack = cb;
  }
  public RepaintScrollbar(int orientation) {
    super(orientation);
  }

  public void setCallBack(Component cb) {
    callBack = cb;
  }
  
  public Component getCallBack() {
    return callBack;
  }

  public boolean handleEvent(Event e) {
    if (callBack != null)
      callBack.repaint();
    return true;
  }
}
  
