/*
 * 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 = "componentclasses.gif";
    Dimension imageSize = new Dimension(555, 189);
    Dimension preferredImageSize = new Dimension(200, 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;
    }
}
