import java.applet.*;
import java.awt.*;
import java.util.*;

// copyright 2002 mel@melaxis.de

public class SineScroller extends Applet implements Runnable
{
	Image offi;
	Graphics offg;
	Thread thread;
	int w = 0, h = 0;
	
	int sine[];
	String text = "This is a nifty sinescroller written by mel... enjoy it!";
	int textpos = 0;
	int textwidth = 0;
	int textheight = 0;
	int texty = 0;
	int textsteps = 1;			// 1=best quality, higher value=>worse quality
	
	Font font;
	FontMetrics fm;
	
	public void init()
	{
		setBackground(Color.black);
		w = getSize().width;
		h = getSize().height;
		textpos = w;
		
		font = new Font("SansSerif", Font.PLAIN, 36);
		fm = getFontMetrics(font);
		textwidth = fm.stringWidth(text);
		textheight = fm.getMaxDescent() + fm.getMaxAscent() + fm.getLeading();	//fm.getHeight();
		texty = textheight - fm.getMaxDescent();

		offi = createImage(w, h+textheight);
		offg = offi.getGraphics();
		offg.setFont(font);
		
		sine = new int[w+1];
		for (int i = 0; i <= w; i++)
		{
			sine[i] = (int)(Math.sin(i * (Math.PI / 180)) * (180 / Math.PI) * 1.5) + 150;
		}
	}
	
	public void start()
	{
		if (thread==null)
		{
			thread = new Thread(this);
			thread.start();
		}
	}
	
	public void stop()
	{
		if (thread!=null)
		{
			thread.stop();
		}
	}
	
	public void paint(Graphics g)
	{
		g.drawImage(offi, 0, 0, this);
	}
	
	public void update(Graphics g)
	{
		paint(g);
	}
	
	private void scrollImage()
	{
		textpos--;
		if (textpos < (-1*textwidth))
			textpos = w+1;
	}
	
	private void drawImage()
	{
		offg.setColor(Color.black);
		offg.fillRect(0,0,w,h+textheight);
		offg.setColor(Color.orange);
		offg.drawString(text, textpos, h+texty);
		for (int x = 0; x <= w; x+=textsteps)
		{
			int y = sine[x];
			offg.copyArea(x, h, textsteps, textheight, 0, -y);
		}
	}
	
	public void run()
	{
		while (true)
		{
			try
			{
				scrollImage();
				drawImage();
				repaint();
				Thread.sleep(1);
				Thread.yield();
			}
			catch (Exception ex)
			{
				ex.printStackTrace();
			}
		}
	}
}