/** S-Grapher Lite
 @version 0.7c
 Copyright (c) 1997-2008, @author Bruno Andrighetto
 All Rights Reserved

This applet allows the user to select an S-Graph pattern to draw.
Also, the user can select a colour setting.

*/

// S-Grapher Lite for Java
// Version 0.7c (23-05-08)
//		- modified parameters to work with larger applet dimensions
//		- removed browser selection pulldown
//		- changed "Redraw" label to "Force Redraw"
// Version 0.7b (21-05-08)
//		- changed font on splash screen
//		- replaced == with equals() for all strings
// Version 0.7a (15-09-97)
//		- integrated version includes option for 'inxs=true" parameter
//		- calculates and uses midpoint of applet
//		- added getAppletInfo() method
//		- tweaked apperance of applet
// Version 0.6a4
//		- fixed netscape problem more efficiently (I hope)
// Version 0.6a3
//		- fixed 'Redraw' bug (incorrectly set numSGs to 1)
// Version 0.6a2
//		- 'splash' preset
//		- asks for browser
//		- no 'Redraw Method' choice
// Version 0.6a
//		- option to draw all-at-once, or line-by-line (not for Netscape)
// Version 0.6
//		- uses double-buffering to fix redraw problem (refer "Exploring Java, p 349 ff)
//		- therefore, image is drawn all at once, rather than line by line 
// Version 0.5x5
//		- removed INXS stuff
// Version 0.5x4
//		- accepts HTML tag parameters
//		- added 'INXS 2'
// Version 0.5x3
//		- split into two source files
// Version 0.5x2
//		- better info hiding
// Version 0.5x
//		- applied Java standards for variable names etc
//		- better implementation of SGParameters object
// refer to 'Lite' version for earlier history
// refer to standard development version for earlier history

import java.awt.*;
import java.lang.*;
import java.applet.Applet;

// import SGParameters;

public class SGrapherLite extends Applet
{
	SGParameters sg = new SGParameters();
	final static int maxSGs = 5;
	SGParameters sgs[] = new SGParameters[maxSGs];
	int numSGs, numOfColrs;

	int midX, midY;

	String currentPreset;
	String currentColour;
	String currentMethod;

	Choice ch, chColr, chRedraw, chBrowser;
	Label patternLabel, colourLabel, redrawLabel, browserLabel;

	boolean netscape;
	boolean allAtOnce;
	boolean firstTime;
	boolean inxs;

	boolean isSplashScreen;
	Font splashFont1, splashFont2;

	Graphics graphicsOb;
	int theWidth, theHeight;
	String theBrowser;
	String inxsFlag;

	Graphics og;
	Image offScrImg;

	// return information about the applet
	public String getAppletInfo()
	{
		return "S-Grapher Lite v0.7c\n" +
				"Copyright © 1997-2008 Bruno Andrighetto <codebase@geocities.com>\n\n" +
				"This applet displays patterns called S-Graphs\n\n";
	}

	// initialise the applet
	public void init()
	{
		// get the applet parameters
		processHTMLParams();

		// initialise some flags
		inxs = "true".equals(inxsFlag.toLowerCase());
		netscape = true;
		allAtOnce = false;
		firstTime = true;
		isSplashScreen = (inxs ? false : true);

		// calculate midpoint of applet
		midX = theWidth/2;
		midY = theHeight/2;

		// initialise some variables
		if (inxs)
		{
			// display 'INXS' preset at start
			numSGs = 5;
			currentPreset = "INXS";
			// "big-I"
			sgs[0] = new SGParameters(3.0, 3.0, 15, 50, numOfColrs, 270.0, 180.0, midX-50, midY-50);
			// "big-N"
			sgs[1] = new SGParameters(1.0, 3.0, 20, 50, numOfColrs, 270.0, 0.0, midX+50, midY-50);
			// "big-X, pt 1"
			sgs[2] = new SGParameters(3.0, 3.0, 15, 50, numOfColrs, 270.0, 180.0, midX-50, midY+50);
			// "big-X, pt 2"
			sgs[3] = new SGParameters(3.0, 3.0, 15, 50, numOfColrs, 90.0, 180.0, midX-50, midY+50);
			// "big-S"
			sgs[4] = new SGParameters(3.0, 1.0, 20, 50, numOfColrs, 45.0, 45.0, midX+50, midY+50);
		}
		else
		{
			// display splash s-graph at start
			numSGs = 1;
			currentPreset = "splash";
			setupSplashScreen();
		}
		currentColour = "Multi";
		currentMethod = "line-by-line";

		// initialise some static SGParameters class varaibles
		SGParameters.setMultiColrs(true);
		SGParameters.setRandomColrs(false);

		setBackground(Color.white);
		graphicsOb = this.getGraphics();

		initAppletLayout();

		numOfColrs = chColr.getSelectedIndex() + 1;

		// setup off-screen image
		if (offScrImg == null)
			offScrImg = createImage((int) getSize().getWidth(), (int) getSize().getHeight());
		og = offScrImg.getGraphics();
	}

	// normal applet opens with a 'big-S' S-graph
	public void setupSplashScreen()
	{
		// use big-S parameters
		sgs[0] = new SGParameters(3.0, 1.0, 25, 80, numOfColrs, 45.0, 45.0, 150, 200);
		numSGs = 1;

		// setup fonts
		splashFont1 = new Font("Helvetica", Font.BOLD, 24);
		splashFont2 = new Font("Helvetica", Font.ITALIC, 14);
	}

	// prepare applet's UI
	public void initAppletLayout()
	{
		// create some panels:
		Panel Panel1 = new Panel();
		Panel Panel2 = new Panel();

		// create a layout for the panels
		setLayout(new BorderLayout());
		add("North", Panel1);
		add("South", Panel2);

		// change the background colour of the panels
		Panel1.setBackground(new Color(223, 223, 223));
		Panel2.setBackground(new Color(223, 223, 223));

		//
		patternLabel = new Label("Pattern:", Label.RIGHT);

		// add some choice options:
		ch = new Choice();
		if (inxs)
		{
			ch.addItem("INXS");
			ch.addItem("INXS 2");
			ch.addItem("big-I");
			ch.addItem("big-N");
			ch.addItem("big-X");
			ch.addItem("big-S");
			ch.addItem("five-point star");
		}
		else  // setup normal choice list
		{
			ch.addItem("splash");
			ch.addItem("classic 1020");
			ch.addItem("wings");
			ch.addItem("x-man");
			ch.addItem("rebellion");
			ch.addItem("federation");
			// ch.addItem("big-I");
			ch.addItem("big-N");
			ch.addItem("big-X");
			ch.addItem("big-S");
			ch.addItem("big-D");
			ch.addItem("five-point star");
			ch.addItem("six-point star");
			ch.addItem("seven-point star");
			ch.addItem("big-alpha");
			ch.addItem("collar");
			ch.addItem("doughnut");
			//ch.addItem("INXS");
			//ch.addItem("INXS 2");
		}
		// ch.select("splash");

		//
		colourLabel = new Label(" Colour Setting:", Label.RIGHT);

		// add some choice options:
		chColr = new Choice();
		chColr.addItem("One");
		chColr.addItem("Two");
		chColr.addItem("Three");
		chColr.addItem("Four");
		chColr.addItem("Five");
		chColr.addItem("Six");
		chColr.addItem("Multi");
		chColr.addItem("Random");

		chColr.select("Multi");

		// add choice lists to the (north) panel
		Panel1.add(patternLabel);
		Panel1.add(ch);
		Panel1.add(colourLabel);
		Panel1.add(chColr);

		//
		// browserLabel = new Label(" Browser:", Label.RIGHT);

		// add some choice options:
		// chBrowser = new Choice();
		// chBrowser.addItem("Netscape");
		// chBrowser.addItem("MSIE");
		// chBrowser.addItem("Other");

		// Panel2.add(browserLabel);
		// Panel2.add(chBrowser);

		// add redraw button
		Button reDraw;
		Panel2.add(reDraw = new Button("Force Redraw"));
		reDraw.setBackground(Color.white);
	}

	// draw contents of applet
	public void paint( Graphics g )
	{
		// System.out.println("* paint() called");
		if (netscape || allAtOnce)
		{
			if (firstTime)
			{
				showStatus("  Please wait while drawing S-Graph offscreen ...");
				// draw off-screen first
				og.setColor(Color.white);
				og.fillRect(0, 0, (int) getSize().getWidth(), (int) getSize().getHeight());
				// og.clearRect(0, 0, theWidth, theHeight);  -- background is light grey!
				for (int i=0; i<numSGs; i++)
				{
					sg = sgs[i];
					sg.draw(og);
				}
				if (isSplashScreen)
					drawSplashScreen(og);
				firstTime = false;
			}
			// copy from off-screen image
			g.drawImage(offScrImg, 0, 0, this);
		}
		else
		{
			// original version:
			showStatus("  Redrawing S-Graph ...");
			g.clearRect(0, 0, theWidth, theHeight);
			for (int i=0; i<numSGs; i++)
			{
				sg = sgs[i];
				sg.draw(g);
			}
			if (isSplashScreen)
				drawSplashScreen(g);
		}
		// browser fix
		postEvent( new Event( this, Event.MOUSE_ENTER, "" ) );

		showStatus("  S-Grapher Lite for Java, by Bruno Andrighetto");
	}

	// override normal update() method - implements double-buffering
	public void update( Graphics g )
	{
		// System.out.println("* update() called");
		if (netscape || allAtOnce)
		{
			// draw off-screen first
			showStatus("  Please wait while drawing S-Graph offscreen ...");
			og.setColor(Color.white);
			og.fillRect(0, 0, (int) getSize().getWidth(), (int) getSize().getHeight());
			for (int i=0; i<numSGs; i++)
			{
				sg = sgs[i];
				sg.draw(og);
			}
			if (isSplashScreen)
				drawSplashScreen(og);
		}
		// call paint() to draw the graph to main screen 
		paint(g);
	}

	// handle action events
	public boolean action(Event evt, Object arg)
	{
		String label = (String) arg;
		boolean redraw = false;
		boolean savedNetscape = netscape;

		// check browser
		netscape = true;  // (chBrowser.getSelectedItem().equals("Netscape"));
		if (netscape != savedNetscape)
			redraw = true;

		// did user change colour?
		if (!(chColr.getSelectedItem().equals(currentColour)))
		{
			// save which item was selected
			currentColour = chColr.getSelectedItem();

			redraw = true;
		}

		// check if changed preset pattern
		else if (!(ch.getSelectedItem().equals(currentPreset)))
		{
			// save which item was selected
			currentPreset = ch.getSelectedItem();

			redraw = true;
		}

/*		// check if changed redraw method
		else if (!(chRedraw.getSelectedItem().equals(currentMethod)))
		{
			// save which item was selected
			currentMethod = chRedraw.getSelectedItem();

			// toggle flag
			allAtOnce = !allAtOnce;
		}
*/
		// has user requested a redraw?
		if ("Force Redraw".equals(arg))
		{
			// this is the only way a netscape user will be able to see line-by-line drawing
			if (netscape || allAtOnce)
			{
				showStatus("  Redrawing S-Graph ...");
				graphicsOb.setColor(Color.white);
				graphicsOb.fillRect(0, 0, (int) getSize().getWidth(), (int) getSize().getHeight());
				for (int i=0; i<numSGs; i++)
				{
					sg = sgs[i];
					sg.draw(graphicsOb);
				}
				if (isSplashScreen)
					drawSplashScreen(graphicsOb);

				showStatus("  S-Grapher Lite for Java, by Bruno Andrighetto");
			}
			else
			{
				// set the redraw flag
				redraw = true;
			}
		}

		if (redraw)
		{
			numOfColrs = 1;
			numSGs = 1;  // defaults

			// determine number of colours
			numOfColrs = chColr.getSelectedIndex() + 1;
			SGParameters.setMultiColrs(chColr.getSelectedItem().equals("Multi"));
			SGParameters.setRandomColrs(chColr.getSelectedItem().equals("Random"));

			isSplashScreen = false;
			
			// check which preset pattern
			if (ch.getSelectedItem().equals("classic 1020"))
				sgs[0] = new SGParameters(2.0, 3.0, 100, 100, numOfColrs, 0.0, 0.0, midX, midY);
			else if (ch.getSelectedItem().equals("wings"))
				sgs[0] = new SGParameters(1.0, 4.0, 40, 100, numOfColrs, 0.0, 90.0, midX, midY);
			else if (ch.getSelectedItem().equals("x-man"))
				sgs[0] = new SGParameters(2.0, 4.0, 65, 100, numOfColrs, 90.0, 90.0, midX, midY);
			else if (ch.getSelectedItem().equals("rebellion"))
				sgs[0] = new SGParameters(2.0, 2.0, 100, 100, numOfColrs, 90.0, 90.0, midX, midY);
			else if (ch.getSelectedItem().equals("federation"))
				sgs[0] = new SGParameters(1.0, 2.0, 30, 100, numOfColrs, 0.0, 90.0, midX, midY);
			else if (ch.getSelectedItem().equals("big-I"))
				sgs[0] = new SGParameters(3.0, 3.0, 30, 100, numOfColrs, 270.0, 180.0, midX, midY);
			else if (ch.getSelectedItem().equals("big-N"))
				sgs[0] = new SGParameters(1.0, 3.0, 35, 100, numOfColrs, 270.0, 0.0, midX, midY);
			else if (ch.getSelectedItem().equals("big-X"))
			{
				numSGs = 2;
				sgs[0] = new SGParameters(3.0, 3.0, 30, 100, numOfColrs, 270.0, 180.0, midX, midY);
				sgs[1] = new SGParameters(3.0, 3.0, 30, 100, numOfColrs, 90.0, 180.0, midX, midY);
			}
			else if (ch.getSelectedItem().equals("big-S"))
				sgs[0] = new SGParameters(3.0, 1.0, 35, 100, numOfColrs, 45.0, 45.0, midX, midY);
			else if (ch.getSelectedItem().equals("big-D"))
				sgs[0] = new SGParameters(4.0, 2.0, 65, 100, numOfColrs, 0.0, 0.0, midX, midY);
			else if (ch.getSelectedItem().equals("five-point star"))
				sgs[0] = new SGParameters(4.0, 4.0, 100, 40, numOfColrs, 90.0, 270.0, midX, midY);
			else if (ch.getSelectedItem().equals("six-point star"))
				sgs[0] = new SGParameters(5.0, 5.0, 100, 50, numOfColrs, 180.0, 0.0, midX, midY);
			else if (ch.getSelectedItem().equals("seven-point star"))
				sgs[0] = new SGParameters(6.0, 6.0, 100, 50, numOfColrs, 270.0, 90.0, midX, midY);
			else if (ch.getSelectedItem().equals("big-alpha"))
				sgs[0] = new SGParameters(2.0, 3.0, 20, 100, numOfColrs, 0.0, 180.0, midX, midY);
			else if (ch.getSelectedItem().equals("collar"))
				sgs[0] = new SGParameters(1.0, 4.0, 100, 60, numOfColrs, 0.0, 90.0, midX, midY);
			else if (ch.getSelectedItem().equals("doughnut"))
				sgs[0] = new SGParameters(1.0, 1.0, 50, 100, numOfColrs, 90.0, 90.0, midX, midY);
			else if (ch.getSelectedItem().equals("splash"))
			{
				isSplashScreen = true;
				sgs[0] = new SGParameters(3.0, 1.0, 25, 80, numOfColrs, 45.0, 45.0, 150, 200);
			}
			else if (ch.getSelectedItem().equals("INXS"))
			{
				numSGs = 5;
				// "big-I"
				sgs[0] = new SGParameters(3.0, 3.0, 15, 50, numOfColrs, 270.0, 180.0, midX-50, midY-50);
				// "big-N"
				sgs[1] = new SGParameters(1.0, 3.0, 20, 50, numOfColrs, 270.0, 0.0, midX+50, midY-50);
				// "big-X, pt 1"
				sgs[2] = new SGParameters(3.0, 3.0, 15, 50, numOfColrs, 270.0, 180.0, midX-50, midY+50);
				// "big-X, pt 2"
				sgs[3] = new SGParameters(3.0, 3.0, 15, 50, numOfColrs, 90.0, 180.0, midX-50, midY+50);
				// "big-S"
				sgs[4] = new SGParameters(3.0, 1.0, 20, 50, numOfColrs, 45.0, 45.0, midX+50, midY+50);
			}
			else if (ch.getSelectedItem().equals("INXS 2"))
			{
				numSGs = 5;
				// "big-I"
				sgs[0] = new SGParameters(3.0, 3.0, 15, 50, numOfColrs, 270.0, 180.0, midX-150, midY-25);
				// "big-N"
				sgs[1] = new SGParameters(1.0, 3.0, 20, 50, numOfColrs, 270.0, 0.0, midX-50, midY-25);
				// "big-X, pt 1"
				sgs[2] = new SGParameters(3.0, 3.0, 15, 50, numOfColrs, 270.0, 180.0, midX+50, midY-25);
				// "big-X, pt 2"
				sgs[3] = new SGParameters(3.0, 3.0, 15, 50, numOfColrs, 90.0, 180.0, midX+50, midY-25);
				// "big-S"
				sgs[4] = new SGParameters(3.0, 1.0, 20, 50, numOfColrs, 45.0, 45.0, midX+150, midY-25);
			}

			// now draw it and return
			repaint();
			return true;
		}

		return true;
	}

	// extra splash screen graphics
	public void drawSplashScreen( Graphics g )
	{
		g.setFont(splashFont1);
		g.setColor((Color.blue).darker());
		g.drawString(" - Grapher Lite", 200, 205);
		g.setFont(splashFont2);
		g.setColor(Color.black);
		g.drawString(" by Bruno Andrighetto", 300, 300);
	}

	// get html parameters
	public void processHTMLParams()
	{
		String parameter;

		parameter = getParameter("canvaswidth");
		theWidth = (parameter == null ? (int) getSize().getWidth() : Integer.parseInt(parameter));
		parameter = getParameter("canvasheight");
		theHeight = (parameter == null ? (int) getSize().getHeight() : Integer.parseInt(parameter));
		parameter = getParameter("browsername");
		theBrowser = (parameter == null ? "unknown" : parameter);
		parameter = getParameter("inxs");
		inxsFlag = (parameter == null ? "false" : parameter);
	}
}
