/* nsanim.java */

/* 
 * Copyright (C) 1995 Mark Boyns <boyns@sdsu.edu>
 *
 * nsanim
 * <URL:http://www.sdsu.edu/~boyns/java/nsanim/>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

import java.applet.*;
import java.awt.*;

class Animation
{
    private final int ANIMATION_WIDTH = 60;
    private final int ANIMATION_HEIGHT = 60;
    private final int ANIMATION_FRAMES = 40;
    private nsanim parent;
    private Image frames = null;
    private int frame = 0;
    private int x;
    private int y;
    private int dir = 1;
    private int zoom = 0;

    Animation (nsanim parent, int x, int y, Image frames)
    {
	this.parent = parent;
	this.x = x;
	this.y = y;
	this.frames = frames;
    }

    public void forward ()
    {
	dir = 1;
    }

    public void reverse ()
    {
	dir = -1;
    }

    public void zoom ()		// not yet
    {
	zoom = 0;
    }

    public void unzoom ()	// not yet
    {
	zoom = 0;
    }
    
    public void paint (Graphics g)
    {
	Graphics gc;

	if (zoom != 0)
	{
	    int zw = 0, zh = 0, zx = 0, zy = 0;
	    
	    zw = (int) (ANIMATION_WIDTH * 1.5);
	    zh = (int) (ANIMATION_HEIGHT * 1.5);
	    
	    zx = x - zw/2;
	    zy = y - zh/2;

	    gc = g.create (zx, zy, zw, zh);
	    gc.drawImage (frames, 0, -(frame * ANIMATION_HEIGHT), zw, zh, parent);
	    gc.dispose ();
	}
	else
	{
	    int nx = x - ANIMATION_WIDTH/2;
	    int ny = y - ANIMATION_HEIGHT/2;
	    gc = g.create (nx, ny, ANIMATION_WIDTH, ANIMATION_HEIGHT);
	    gc.drawImage (frames, 0, -(frame * ANIMATION_HEIGHT), parent);
	    gc.dispose ();
	}

	frame += dir;

	if (frame == -1)
	{
	    frame = ANIMATION_FRAMES - 1;
	}
	else if (frame == ANIMATION_FRAMES)
	{
	    frame = 0;
	}
    }
    
}

public class nsanim extends java.applet.Applet implements Runnable
{
    private Animation animation;
    private MediaTracker tracker;
    private Image animationImages;
    private int delay = 100;
    private Thread thread = null;

    public void init ()
    {
	tracker = new MediaTracker (this);
	animationImages = getImage (getDocumentBase (), "anim/all.gif");
	tracker.addImage (animationImages, 0);
	animation = new Animation (this, 120, 120, animationImages);

	try
        {
            showStatus ("Loading 40K image strip...");
            tracker.waitForAll ();
        }
        catch (InterruptedException e)
        {
            return;
        }

	setBackground (Color.black);
	resize (240, 240);
    }

    public void run ()
    {
	for (;;)
	{
	    repaint ();
	    try
	    {
		Thread.sleep (delay);
	    }
	    catch (InterruptedException e)
	    {
	    }
	}
    }

    public void stop ()
    {
	if (thread != null)
	{
	    thread.stop ();
	    thread = null;
	}
    }

    /* Handle mouse events. */
    public boolean mouseDown (Event e, int x, int y)
    {
	return true;
    }
    
    /* Handle keyboard events. */
    public boolean keyDown (Event e, int key)
    {
	switch (key)
	{
	case '\n':
	    if (thread == null)
	    {
		thread = new Thread (this);
		thread.start ();
	    }
	    else
	    {
		thread.stop ();
		thread = null;
	    }
	    break;
	    
	case '+':
	case '=':
	    delay -= 25;
	    if (delay < 25)
	    {
		delay = 25;
	    }
	    break;

	case '-':
	case '_':
	    delay += 25;
	    break;
	    
	case '>':
	case '.':
	    animation.forward ();
	    repaint ();
	    break;

	case '<':
	case ',':
	    animation.reverse ();
	    repaint ();
	    break;

	case 'Z':
	    animation.zoom ();
	    repaint ();
	    break;

	case 'z':
	    animation.unzoom ();
	    repaint ();
	    break;
	    
	case ' ':
	    repaint ();
	    break;
	}

	return true;
    }

    /* Don't clear the screen; just call paint. */
    public void update (Graphics g)
    {
	paint (g);
    }

    /* Paint the screen. */
    public void paint (Graphics g)
    {
	if (tracker.checkID (0, true))
	{
	    animation.paint (g);
	}
    }
}

/*
Local variables:
eval: (progn (make-local-variable 'compile-command) (setq compile-command (concat "javac " buffer-file-name)))
End:
*/
