import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.URL;
import java.net.MalformedURLException;


/**
 * A simple app that will to 'vote' for something on the web by
 * requesting a preset URL. The vote url is hard-coded so that 'other'
 * people cannot use this very same applet for the same 'election' to their
 * own use, e.g. steal a vote from me. 
 *
 * <p>This applet will not circumvent 'smart' checks on the 
 * server side. But it will be a lesson to those script kiddies that thought
 * they didn't need to check if 'someone' already has cast a vote. </p>
 *
 * @author Jeroen Pulles
 */
public class VoteApp extends Object implements Runnable
{
	private int          m_count; // totals
	private int          m_stopat;
	private String       m_voteurl;
	private VoteWorker[] m_workers;
	private Thread       m_thread;
	
	public VoteApp(String url, int max)
	{
		m_count = 0;
		m_stopat = max;
		m_workers = new VoteWorker[5];
		m_voteurl = url;
		m_thread = new Thread(this, "VoteMeister");
		m_thread.start();
	}

	public void run()
	{
		System.out.println("VoteApp version 0.1");
		try {
			// start voting:
			for (int i = 0; i < m_workers.length; i++) {
				m_workers[i] = new VoteWorker(
					m_voteurl, this);
			}
		} catch (MalformedURLException e) {
			System.out.println(
				"Malformed URL: " + e.getMessage());
		} catch (SecurityException e) {
			System.out.println(
				"Security Exception: " + e.getMessage());
		}
		Thread t = Thread.currentThread();
		while (t == m_thread && m_count < m_stopat) {
			// just sit back and wait.
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
			}
		}
		System.out.println("Reached goal. I'm done.");
		stopVoting();
		System.exit(0);
	}
	
	
	public void stopVoting()
	{
		// stop all voteworkers:
		for (int i = 0; i < m_workers.length; i++) {
			VoteWorker v = m_workers[i];
			if (v != null) {
				v.stop();
			}
		}
	}

	
	public synchronized void incrementCount()
	{
		System.out.println(++m_count);
	}

	
	/** 
	 * Does the work of voting, by making a HTTP GET request to the URL.
	 */
	private class VoteWorker implements Runnable
	{
		private URL            m_url;
		private VoteApp        m_panel;
		private StringBuffer   m_result;
		private int            m_total;
		private Thread         m_VoteThread;

		public VoteWorker(String url, VoteApp vw) 
		throws MalformedURLException
		{
			m_url = new URL(url);
			m_panel = vw;
			m_result = new StringBuffer();
			m_total = 0;
			m_VoteThread = new Thread(this, "VoteWorker");
			m_VoteThread.start();
		}
		
		public void run()
		{
			String line = "--->"; 
			BufferedReader in = null;
			int linecount = 0;
			Thread currentThread = Thread.currentThread();
			while (currentThread == m_VoteThread) {
				System.out.println("GET " + m_url.toString());
				try {
					in = new BufferedReader(
						new InputStreamReader(
							m_url.openStream())
						);
					while ((line = in.readLine()) != null &&
						  linecount < 20) {
						m_result.append(line);
						linecount++;
					// ignore response after a few lines :-)
					}
					m_total++;
					m_panel.incrementCount();
				} catch (IOException e) {
					System.out.println(e.getMessage());
				} catch (ClassCastException c) {
					System.out.println(c.getMessage());
				}
				try {
					in.close();
				} catch (IOException e) {
				} catch (NullPointerException e) {
				}
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
				}
			}
		}

		public synchronized void stop()
		{
			m_VoteThread = null;
		}

	}



	public static void main(String[] args)
	{
		try {
			int max = Integer.parseInt(args[0]);
			new VoteApp(args[1], max);
		} catch (RuntimeException e) {
			e.printStackTrace();
		}
	}
	
} // Vote.java

