/**
 *  WindApplet
 *  
 *  Copyright 2007 by Henrik Persson <root@fulhack.info>.
 * 
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as 
 *  published by the Free Software Foundation.
 *
 *  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.
 *
 *  The GNU General Public License can be found at www.gnu.org.
 */

import java.applet.Applet;
import java.awt.Color;
import java.awt.BasicStroke;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;

import javax.swing.JOptionPane;

public class WindApplet extends Applet implements MouseListener {
	private static final long serialVersionUID = 1L;
	BufferedImage bi;
	
	private static final String version = "0.93.1";
	
	/**
	 * Initialize the applet.
	 * @param args
	 */
	public void init() {
		this.setSize(300, 300);
		this.addMouseListener(this);
		
		int wind;

		// Get our parameter..
		String param = getParameter("wind-direction");
		if(param != null)
		{
			try
			{
				wind = Integer.parseInt(param);
			}
			catch (NumberFormatException e)
			{
				wind = -1;
			}
		}
		else wind = -1;
		
		if(wind == -1)
		{
			wind = 0;
			JOptionPane.showMessageDialog(this, "Error parsing wind direction.\n\nNumerFormatException was thrown.", 
					"Parse error", JOptionPane.ERROR_MESSAGE);
		}
		
		bi = new BufferedImage(this.getWidth(), this.getHeight(),
				BufferedImage.TYPE_INT_RGB);
		
		// Make bi all white.
		for(int i=0;i<bi.getHeight();i++)
		{
			for(int j=0;j<bi.getWidth();j++)
			{
				bi.setRGB(j, i, 0xFFFFFF);
			}
		}
		
		Graphics2D g = bi.createGraphics();

		g.setBackground(Color.white);
		
		// Antialiasing
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                             RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
		
        // TODO: Check if all those really are needed. Could not get it to work otherwise but seems excessive.
		AffineTransform ox = g.getTransform();
		AffineTransform orig = (AffineTransform)ox.clone();
		AffineTransform ax = (AffineTransform)ox.clone();
		AffineTransform bx = (AffineTransform)ox.clone();
		
		// TODO: Make this configurable?
		ax.rotate(Math.toRadians(30), 150, 150); // Rotate for runway heading
		g.setTransform(ax);
		
		g.setStroke(new BasicStroke(2.0f));
		
		g.setColor(Color.WHITE);
		g.fillRect(0, 0, bi.getWidth(), bi.getHeight());

		g.setColor(Color.BLACK);
		g.drawOval(4, 4, bi.getWidth()-8, bi.getHeight()-8);

		g.setColor(new Color(0x10AA10));
		g.fillRect(bi.getWidth()/2-20, 20, 40, bi.getHeight()-40);
		
		g.setColor(Color.black);
		g.drawString("03", bi.getWidth()/2-7, bi.getHeight()-30);

		bx.rotate(Math.toRadians(210), 184, 28);
		g.setTransform(bx);
		g.drawString("21", 150-7, 30);
		
		// Reverse the arrow direction..
		double deg = (wind+180)%360;
		ox.rotate(Math.toRadians(deg), 150, 150);
		g.setTransform(ox);
		
		g.setColor(new Color(0xFF0000));
		g.setStroke(new BasicStroke(6.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER));	

		// Draw arrow.
		g.drawLine(bi.getWidth()/2, bi.getHeight()/2, 
				   bi.getWidth()/2, bi.getHeight()/2 + 100);
		g.drawLine(bi.getWidth()/2, bi.getHeight()/2, bi.getWidth()/2-10, bi.getHeight()/2+20);
		g.drawLine(bi.getWidth()/2, bi.getHeight()/2, bi.getWidth()/2+10, bi.getHeight()/2+20);

		g.setTransform(orig);
		g.setStroke(new BasicStroke(2.0f));
		g.setColor(Color.black);

		g.setFont(new Font("Arial", Font.BOLD, 14));
		
		g.drawString("N", 146, 20);
		g.drawString("S", 146, 285);
		g.drawString("W", 15, 155);
		g.drawString("E", 280, 155);
		
		// Add markers every 30 degrees around the compass rose
		AffineTransform degx = (AffineTransform)orig.clone();
		g.setTransform(degx);
		
		for(int i=0; i <= 360; i+=30)
		{
			degx.rotate(Math.toRadians(30), 150, 150);
			g.setTransform(degx);
			g.drawLine(150, 0, 150, 8); 
		}
	}

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

	public void paint(Graphics g) {
		g.drawImage(bi, 0, 0, this);
	}

	public void mousePressed(MouseEvent e) {
		
	}

	public void mouseReleased(MouseEvent e) {
	}

	public void mouseClicked(MouseEvent e) {
		JOptionPane.showMessageDialog(this, "WindApplet v"+version+"\n\nCopyright 2007 by\nHenrik Persson <root@fulhack.info>\n\nLicensed under the GNU GPL", "About", JOptionPane.INFORMATION_MESSAGE);
	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}
}

