//******************************************************************************
// Scrollie.java:	Applet
//
//******************************************************************************
import java.applet.*;
import java.awt.*;
import java.util.Random;

//==============================================================================
// Main Class for applet Scrollie
//
//==============================================================================
public class Scrollie extends Applet implements Runnable
{

	Image OffScreenImage;
	Graphics OffScreenGraphic;
	TextArea theText;
	int iAppWidth, iAppHeight, iTextLineHeight, iIndex, iCharsPerLine;
	int iFontSize;

	// THREAD SUPPORT:
	//		m_Scrollie	is the Thread object for the applet
	//--------------------------------------------------------------------------
	Thread	 m_Scrollie = null;


	// Scrollie Class Constructor
	//--------------------------------------------------------------------------
	public Scrollie()
	{

	}//constructor

	// APPLET INFO SUPPORT:
	//		The getAppletInfo() method returns a string describing the applet's
	// author, copyright date, or miscellaneous information.
    //--------------------------------------------------------------------------
	public String getAppletInfo()
	{
		return "Name: Scrollie\r\n" +
		       "Author: jp\r\n" +
		       "Created with Microsoft Visual J++ Version 1.0";
	}//getAppletInfo method


	// The init() method is called by the AWT when an applet is first loaded or
	// reloaded.  Override this method to perform whatever initialization your
	// applet needs, such as initializing data structures, loading images or
	// fonts, creating frame windows, setting the layout manager, or adding UI
	// components.
    //--------------------------------------------------------------------------
	public void init()
	{
        // If you use a ResourceWizard-generated "control creator" class to
        // arrange controls in your applet, you may want to call its
        // CreateControls() method from within this method. Remove the following
        // call to resize() before adding the call to CreateControls();
        // CreateControls() does its own resizing.
        //----------------------------------------------------------------------

		int i;

		try{
			iAppWidth = Integer.parseInt(getParameter("width"));
			iAppHeight = Integer.parseInt(getParameter("height"));
		}//try
		catch(Exception e){
			iAppWidth=320;		//Default sizes if not passed as parameters
			iAppHeight=240;
		}//catch
		try{
			iFontSize = Integer.parseInt(getParameter("fontsize"));
		}//try
		catch(Exception e){
			iFontSize = 12;
		}//catch

		System.out.println("Creating applet with height=" + iAppHeight + ", width=" + iAppWidth + ", FontSize=" + iFontSize);

		//iTextLineHeight = 10;

		setBackground(new Color(255,255,255));

		resize(iAppWidth, iAppHeight);

	}//init method

	// Place additional applet clean up code here.  destroy() is called when
	// when you applet is terminating and being unloaded.
	//-------------------------------------------------------------------------
	public void destroy()
	{
		// TODO: Place applet cleanup code here
	}

	// Scrollie Paint Handler
	//--------------------------------------------------------------------------
	public void paint(Graphics g)
	{
		g.drawImage(OffScreenImage,0,0,this);
	}

	//The update method will draw the off-screen graphics and cause this
	//to be repainted
	public void update(Graphics g) 
	{
		if(OffScreenImage!=null){
			if(OffScreenGraphic==null){
				OffScreenGraphic= OffScreenImage.getGraphics();			//Off screen graphic for buffering	
				OffScreenGraphic.setFont(new Font("Courier", 0, iFontSize));
				
				//Now get the font specs
				FontMetrics fm = OffScreenGraphic.getFontMetrics();
				iTextLineHeight = fm.getHeight();
				System.out.println("The text height is " + iTextLineHeight);
				iCharsPerLine = (int)iAppWidth / fm.stringWidth("x");

			}
			
			ScrollTextUp(OffScreenGraphic);

			DrawNewString(OffScreenGraphic);			

			g.drawImage(OffScreenImage,0,0,this);
		}
		else{
			OffScreenImage = createImage(iAppWidth, iAppHeight);	//Off screen image for double buffering
		}

	}//update method


	//This will scroll the off screen graphic object up one line of text
	public void ScrollTextUp(Graphics g){
		g.copyArea(0,iTextLineHeight, iAppWidth, iAppHeight-iTextLineHeight, 0, -iTextLineHeight);
		g.setColor(new Color(255,255,255));	//Set color to white
		g.fillRect(0,iAppHeight-iTextLineHeight, iAppWidth, iTextLineHeight);
	}//ScrollTextUp method

	//This method will draw a new string at the bottom of the off-screen
	//graphic.  It calls CreateRandomString to create the random string
	public void DrawNewString(Graphics g){
		
		String s = CreateRandomString();	
	
		g.setColor(new Color(0,0,0));
		g.drawString(s, 0, iAppHeight - g.getFontMetrics().getDescent());

	}//DrawStrings method

	public String CreateRandomString(){
		String s = new String();
		double f;
		int i;

		while( s.length() < iCharsPerLine){
			i=0;
			
			f = Math.random();
			f*=1000;
			f = f*(126-33)/999;
			i = 33+ (int)Math.rint(f);
			s += (char)i;
		}//while
		return s;
	}//CreateRandomString method


	//		The start() method is called when the page containing the applet
	// first appears on the screen. The AppletWizard's initial implementation
	// of this method starts execution of the applet's thread.
	//--------------------------------------------------------------------------
	public void start()
	{
		if (m_Scrollie == null)
		{
			m_Scrollie = new Thread(this);
			m_Scrollie.start();
		}

	}//start method
	
	//		The stop() method is called when the page containing the applet is
	// no longer on the screen. The AppletWizard's initial implementation of
	// this method stops execution of the applet's thread.
	//--------------------------------------------------------------------------
	public void stop()
	{
		if (m_Scrollie != null)
		{
			m_Scrollie.stop();
			m_Scrollie = null;
		}

		// TODO: Place additional applet stop code here
	}

	// THREAD SUPPORT
	//		The run() method is called when the applet's thread is started. If
	// your applet performs any ongoing activities without waiting for user
	// input, the code for implementing that behavior typically goes here. For
	// example, for an applet that performs animation, the run() method controls
	// the display of images.
	//--------------------------------------------------------------------------
	public void run()
	{
		while (true)
		{
			try
			{
				repaint();
				// TODO:  Add additional thread-specific code here
				Thread.sleep(50);
				showStatus("Sending encrypted transmission...");
			}
			catch (InterruptedException e)
			{
				// TODO: Place exception-handling code here in case an
				//       InterruptedException is thrown by Thread.sleep(),
				//		 meaning that another thread has interrupted this one
				stop();
			}
		}
	}



	// TODO: Place additional applet code here

}

