/*
 * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL purposes and without
 * fee is hereby granted provided that this copyright notice
 * appears in all copies. Please refer to the file "copyright.html"
 * for further important copyright and licensing information.
 *
 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 */
import java.awt.*;
import java.applet.*;
import java.net.URL;

class ScrollableCanvas extends Canvas {
    Image image;
    int tx = 0;
    int ty = 0;
    Dimension preferredSize;

    ScrollableCanvas(Image img, Dimension prefSize) {
	image = img;
	preferredSize = prefSize;
    }

    public Dimension minimumSize() {
	return new Dimension(10, 10);
    }

    public Dimension preferredSize() {
	return preferredSize;
    }

    public void paint(Graphics g) {
	g.translate(-tx, -ty);
	g.drawImage(image, 0, 0, getBackground(), this);
    }
}

public class ImageScroller extends Applet {
    Scrollbar vert;
    Scrollbar horz;
    ScrollableCanvas canvas;
    boolean inAnApplet = true;
    String imageFile = "../images/people.gif";
    Dimension imageSize = new Dimension(600, 320);
    Dimension preferredImageSize = new Dimension(300, 100);

    //This method assumes this Applet is visible.
    public void init() {
	Image img;

	if (inAnApplet) {
	    img = getImage(getCodeBase(), imageFile);
	} else {
	    img = Toolkit.getDefaultToolkit().getImage(imageFile);
	}
	canvas = new ScrollableCanvas(img, preferredImageSize);

	//Create horizontal scrollbar.
	horz = new Scrollbar(Scrollbar.HORIZONTAL);

	//Create vertical scrollbar.
	vert = new Scrollbar(Scrollbar.VERTICAL);

	//Add Components to the Applet.
	setLayout(new BorderLayout());
	add("Center", canvas);
	add("East", vert);
	add("South", horz);

	validate();

	//Now that we've validated, then assuming this Applet is
	//visible, the canvas size is valid and we can adjust the
	//scrollbars to match the image area. [CHECK]
	resizeHorz();
	resizeVert();
    }

    public boolean handleEvent(Event evt) {
	switch (evt.id) {
	  case Event.SCROLL_LINE_UP:
	  case Event.SCROLL_LINE_DOWN:
	  case Event.SCROLL_PAGE_UP:
	  case Event.SCROLL_PAGE_DOWN:
	  case Event.SCROLL_ABSOLUTE:
	    if (evt.target == vert) {
		canvas.ty = ((Integer)evt.arg).intValue();
		canvas.repaint();
	    }
	    if (evt.target == horz) {
		canvas.tx = ((Integer)evt.arg).intValue();
		canvas.repaint();
	    }
	}
	return super.handleEvent(evt);
    }

    //Don't call this until the canvas size is valid.
    void resizeHorz() {
	int canvasWidth = canvas.size().width;

	if (canvasWidth <= 0) {
	    System.out.println("Canvas has no width; can't resize scrollbar");
	    return;
	}

	//Shift everything to the right if we're displaying empty space
	//on the right side.
	if ((canvas.tx + canvasWidth) > imageSize.width) {
	    int newtx = imageSize.width - canvasWidth;
	    if (newtx < 0) {
		newtx = 0;
	    }
	    canvas.tx = newtx;
	}

	horz.setValues(//draw the part of the image that starts at this x:
		       canvas.tx, 
		       //amount to scroll for a "page":
		       (int)(canvasWidth * 0.9), 
		       //minimum image x to specify:
		       0,
		       //maximum image x to specify:
		       imageSize.width - canvasWidth);
	//"visible" arg to setValues() has no effect after scrollbar is visible.
	horz.setPageIncrement((int)(canvasWidth * 0.9));
        return;
    }

    //Don't call this until the canvas size is valid.
    void resizeVert() {
	int canvasHeight = canvas.size().height;

	if (canvasHeight <= 0) {
	    System.out.println("Canvas has no height; can't resize scrollbar");
	    return;
	}

	//Shift everything downward if we're displaying empty space
	//on the bottom.
	if ((canvas.ty + canvasHeight) > imageSize.height) {
	    int newty = imageSize.height - canvasHeight;
	    if (newty < 0) {
		newty = 0;
	    }
	    canvas.ty = newty;
	}

	vert.setValues(//initially draw part of image starting at this y:
		       canvas.ty, 
		       //visible arg--amount to scroll for a "page":
		       (int)(canvasHeight * 0.9), 
		       //minimum image y to specify:
		       0,
		       //maximum image y to specify:
		       imageSize.height - canvasHeight);

	//"visible" arg to setValues() has no effect after scrollbar is visible.
	vert.setPageIncrement((int)(canvasHeight * 0.9));
        return;
    }

    public void paint(Graphics g) {
	//This method probably was called due to applet being resized.
	resizeHorz();
	resizeVert();

	return;
    }
}
