//
// bar.class
// Stef Coene <stef.coene@docum.org>
//
// This java applet fetches an URL from a web-server and creates a bar
//   in green, yellow and red.
//

import java.applet.* ;
import java.awt.* ;
import java.net.* ;
import java.io.* ;

public class bar extends Applet implements Runnable {
	// First we write everything to bufferimage.  After that, that buffered image is written to the screen.  We use bufferg to write to this image.
	private Image bufferimage ;
	private Graphics bufferg ;

	private Dimension d ; // Size of the applet
	private int bgOffset = 180 ;	// Used to adjust the white balance for the background.  The bigger the number, the whiter the background
	private Color backgroundcolor ;	//  background color of the bar
	private int bgCol1 = 255 ;	// left space we left open around the bar
	private int bgCol2 = 255 ;	// left space we left open around the bar
	private int bgCol3 = 255 ;	// left space we left open around the bar
	private Color lightGreen  ;	//  background color of the bar
	private Color lightYellow ;	//  background color of the bar
	private Color lightRed    ;	//  background color of the bar

	private int fontSize = 12 ;
	private Font font ;
	private FontMetrics fontMetrics ;

	private int lSpace = 2 ;	// left space we left open around the bar
	private int rSpace = 2 ;	// right space we left open around the bar
	private int tSpace = 2 ;	// top space we left open around the bar
	private int bSpace = 2 ;	// bottom space we left open around the bar

	private int speed = 3 ;		// in seconds, time between updates
	private int max   = 100 ;	// maximum counter we can get as input
					// this max is also used to calculate the input as %

	private int Data ;		// Last fetched counter
	private int DataPro ;		// Last fetched counter in %
	private int i ;
	private int greenSize ;		// Size of the green part of the bar
	private int yellowSize ;	// Size of the yellow part of the bar
	private int redSize ;		// Size of the red part of the bar

	private boolean showPro = true ;	// Do we show the number in % at the bottom of the graph
	private boolean showCou = true ;	// Do we show the number in the bar

	private int red = 90 ;		// default red size
	private int yellow = 80 ;	// default yellow size

	private String dataSource = "http://scne/cgi-bin/rand.pl" ;

	public Thread graphthread = null ;

	public void init () {
		// Get the parameters for this applet
		String param ;
		param = getParameter("dataSource") ;
		if (param != null)
			dataSource = param ;

		param = getParameter("red") ;
		if (param != null)
			red = Integer.parseInt(param) ;

		param = getParameter("yellow") ;
		if (param != null)
			yellow = Integer.parseInt(param) ;

		param = getParameter("lSpace") ;
		if (param != null)
			lSpace = Integer.parseInt(param) ;

		param = getParameter("tSpace") ;
		if (param != null)
			tSpace = Integer.parseInt(param) ;

		param = getParameter("rSpace") ;
		if (param != null)
			rSpace = Integer.parseInt(param) ;

		param = getParameter("bSpace") ;
		if (param != null)
			bSpace = Integer.parseInt(param) ;

		param = getParameter("max") ;
		if (param != null)
			max = Integer.parseInt(param) ;

		param = getParameter("showPro") ;
		if (param != null) {
			if (!param.equals("true")) {
				showPro = false ;
			}
		}

		param = getParameter("showCou") ;
		if (param != null) {
			if (!param.equals("true")) {
				showCou = false ;
			}
		}

		param = getParameter("speed") ;
		if (param != null)
			speed = Integer.parseInt(param) ;

		param = getParameter("bgOffset") ;
		if (param != null)
			bgOffset = Integer.parseInt(param) ;

		param = getParameter("bgCol1") ;
		if (param != null) {
			bgCol1 = Integer.parseInt(param) ;
			if ( bgCol1 > 255 ) bgOffset = 255 ;
			if ( bgCol1 < 0   ) bgOffset = 0 ;
		}
		param = getParameter("bgCol2") ;
		if (param != null) {
			bgCol2 = Integer.parseInt(param) ;
			if ( bgCol2 > 255 ) bgOffset = 255 ;
			if ( bgCol2 < 0   ) bgOffset = 0 ;
		}
		param = getParameter("bgCol3") ;
		if (param != null) {
			bgCol3 = Integer.parseInt(param) ;
			if ( bgCol3 > 255 ) bgOffset = 255 ;
			if ( bgCol3 < 0   ) bgOffset = 0 ;
		}

		// Make sure 0 < Data < max
		if ( Data > max ) 
			Data = max ;
		if ( Data < 0 ) 
			Data = 0 ;

		// Make sure 0 < bgOffset < max
		if ( bgOffset > 255 ) 
			bgOffset = 255 ;
		if ( bgOffset < 0 ) 
			bgOffset = 0 ;

		// Calculate the background
		lightGreen  = new Color (bgOffset,255,bgOffset) ;	//  background color of the bar
		lightYellow = new Color (255,255,bgOffset) ;		//  background color of the bar
		lightRed    = new Color (255,bgOffset,bgOffset) ;	//  background color of the bar
		backgroundcolor = new Color (bgCol1,bgCol2,bgCol3) ;

		// Get the size of the applet 
		d = getSize () ;

		// Calculate the size of the colors
		// If we show the counter in %, we need to reserve some extra place
		if ( showPro ) {
			redSize    = (d.height-tSpace-bSpace-fontSize)*(100-red)/100 ;
			yellowSize = (d.height-tSpace-bSpace-fontSize)*(red-yellow)/100 ;
			greenSize  =  d.height-tSpace-bSpace-fontSize-redSize-yellowSize ;
		} else {
			redSize    = (d.height-tSpace-bSpace)*(100-red)/100 ;
			yellowSize = (d.height-tSpace-bSpace)*(red-yellow)/100 ;
			greenSize  =  d.height-tSpace-bSpace-redSize-yellowSize ;
		}

		// initializee the buffered image
		bufferimage = createImage (d.width,d.height) ;
		bufferg = bufferimage.getGraphics() ;
	}

	// synchronized : maks sure only 1 thread can paint the applet
	public synchronized void paint (Graphics g) {
		if ( bufferg != null ) { // make sure the buffer image is initialized
			// Fill the image with a color
			bufferg.setColor (backgroundcolor) ;
			bufferg.fillRect (0,0,d.width,d.height) ;

			// Get a new counter
			try {
				URL theURL = new URL(dataSource);

				BufferedReader input = new BufferedReader (new InputStreamReader(theURL.openStream())) ;
				Data = Integer.parseInt(input.readLine()) ;
				DataPro = Data * 100 / max ;
				input.close();

			} catch (MalformedURLException e) {
				System.out.println("Exception: " + e);
			} catch (IOException e) {
				System.out.println("Exception: " + e);
			}

			// Draw the background 
			bufferg.setColor(lightRed);
			bufferg.fillRect (lSpace,tSpace,d.width-lSpace-rSpace,redSize) ;
			bufferg.setColor(lightYellow);
			bufferg.fillRect (lSpace,tSpace+redSize,d.width-lSpace-rSpace,yellowSize) ;
			bufferg.setColor(lightGreen);
			bufferg.fillRect (lSpace,tSpace+redSize+yellowSize,d.width-lSpace-rSpace,greenSize) ;

			// Draw the foreground
			int height = (d.height-tSpace-bSpace-fontSize)*(100-DataPro)/100 ;
			if ( DataPro > red ) {
				bufferg.setColor(Color.red);
				bufferg.fillRect (lSpace,tSpace+height,d.width-lSpace-rSpace,redSize-height) ;
				bufferg.setColor(Color.yellow);
				bufferg.fillRect (lSpace,tSpace+redSize,d.width-lSpace-rSpace,yellowSize) ;
				bufferg.setColor(Color.green);
				bufferg.fillRect (lSpace,tSpace+redSize+yellowSize,d.width-lSpace-rSpace,greenSize) ;
			} else {
				if ( DataPro > yellow ) {
					bufferg.setColor(Color.yellow);
					bufferg.fillRect (lSpace,tSpace+height,d.width-lSpace-rSpace,redSize+yellowSize-height) ;
					bufferg.setColor(Color.green);
					bufferg.fillRect (lSpace,tSpace+redSize+yellowSize,d.width-lSpace-rSpace,greenSize) ;
				} else {
					bufferg.setColor(Color.green);
					bufferg.fillRect (lSpace,tSpace+height,d.width-lSpace-rSpace,greenSize+yellowSize+redSize-height) ;
				}
			}

			// Draw the counter
			bufferg.setColor(Color.black);
			font = new Font("Arial", Font.BOLD, fontSize) ;
			setFont(font) ;
			fontMetrics = getFontMetrics(font) ;
			if ( showPro ) {
				bufferg.drawString (""+DataPro+"%",d.width/2-fontMetrics.stringWidth(""+DataPro+"%")/2,d.height-bSpace) ;
			}

			// If the max = 100, we don't show the number in the bar since it's the same number as you can find on the bottom of the bar
			if ( ( max != 100 ) && ( showCou ) ) {
				// Make sure we draw the counter in the bar and not above it
				// We don't need the height anymore so we can savely change it
				if ( height < fontSize ) 
					height = fontSize ;
				bufferg.drawString (""+Data,d.width/2-fontMetrics.stringWidth(""+Data)/2,tSpace+height) ;
			}

			g.drawImage (bufferimage,0,0,this) ;
		}
	}

	public void start () {
		if ( graphthread == null ) {
			graphthread = new Thread (this,"graphthread") ;
			graphthread.start () ;
		}
	}

	public void stop  () {
		if (( graphthread != null) && graphthread.isAlive() )
			graphthread.stop () ;
		graphthread = null ;
	}

	public void run () {
		while (true) {
			repaint () ;
			try { Thread.sleep (speed*1000) ; }
			catch (InterruptedException e) { }
		}
	}

	public synchronized void update (Graphics g) {
		paint (g) ;
	}

	public int getIntegerParameter (String name) {
		String value  = getParameter (name) ;
		int intvalue ;
		try { intvalue = Integer.parseInt (value); }
		catch (NumberFormatException e) { return 5; }
		return intvalue ;
	}
}
