/*
 * Primes.java
 *
 * Created on June 10, 2002, 9:45 AM
 */

package dant.test;

import java.rmi.*;
import java.rmi.registry.*;
import java.util.StringTokenizer;

import com.sun.grid.jgrid.*;

/**
 *
 * @author  dant
 */
public class Primes extends javax.swing.JFrame {
	private static final String WAITING = "Waiting to Start ";
	private static final String RUNNING = "Running ";
	private static final String FINISHED = "Finished with ";
	private static final String FIRST = "First Piece";
	private static final String SECOND = "Second Piece";
	private static final String THIRD = "Third Piece";
	private static ComputeEngine ce = null;
	
	/** Creates new form Primes */
	public Primes () {
		initComponents ();
	}
	
	/** This method is called from within the constructor to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	private void initComponents () {//GEN-BEGIN:initComponents
		jPanel1 = new javax.swing.JPanel ();
		queryField = new javax.swing.JTextField ();
		jButton1 = new javax.swing.JButton ();
		jLabel1 = new javax.swing.JLabel ();
		jPanel2 = new javax.swing.JPanel ();
		jLabel6 = new javax.swing.JLabel ();
		jLabel7 = new javax.swing.JLabel ();
		jLabel8 = new javax.swing.JLabel ();
		jPanel3 = new javax.swing.JPanel ();
		totalField = new javax.swing.JTextField ();
		jLabel2 = new javax.swing.JLabel ();
		
		addWindowListener (new java.awt.event.WindowAdapter () {
			public void windowClosing (java.awt.event.WindowEvent evt) {
				exitForm (evt);
			}
		});
		
		jPanel1.setLayout (new java.awt.BorderLayout (5, 5));
		
		jPanel1.setBorder (new javax.swing.border.EmptyBorder (new java.awt.Insets (4, 4, 4, 4)));
		jPanel1.add (queryField, java.awt.BorderLayout.CENTER);
		
		jButton1.setText ("Compute");
		jButton1.addActionListener (new java.awt.event.ActionListener () {
			public void actionPerformed (java.awt.event.ActionEvent evt) {
				submitJobs (evt);
			}
		});
		
		jPanel1.add (jButton1, java.awt.BorderLayout.EAST);
		
		jLabel1.setText ("Compute the Number of Primes");
		jLabel1.setHorizontalAlignment (javax.swing.SwingConstants.CENTER);
		jLabel1.setFont (new java.awt.Font ("Dialog", 1, 18));
		jPanel1.add (jLabel1, java.awt.BorderLayout.NORTH);
		
		getContentPane ().add (jPanel1, java.awt.BorderLayout.NORTH);
		
		jPanel2.setLayout (new java.awt.GridLayout (3, 1, 0, 20));
		
		jPanel2.setBorder (new javax.swing.border.EmptyBorder (new java.awt.Insets (4, 30, 4, 20)));
		jLabel6.setPreferredSize (new java.awt.Dimension (168, 17));
		jLabel6.setMinimumSize (new java.awt.Dimension (168, 17));
		jLabel6.setMaximumSize (new java.awt.Dimension (168, 17));
		jPanel2.add (jLabel6);
		
		jLabel7.setPreferredSize (new java.awt.Dimension (168, 17));
		jLabel7.setMinimumSize (new java.awt.Dimension (168, 17));
		jLabel7.setMaximumSize (new java.awt.Dimension (168, 17));
		jPanel2.add (jLabel7);
		
		jLabel8.setPreferredSize (new java.awt.Dimension (168, 17));
		jLabel8.setMinimumSize (new java.awt.Dimension (168, 17));
		jLabel8.setMaximumSize (new java.awt.Dimension (168, 17));
		jPanel2.add (jLabel8);
		
		getContentPane ().add (jPanel2, java.awt.BorderLayout.CENTER);
		
		jPanel3.setLayout (new java.awt.GridBagLayout ());
		java.awt.GridBagConstraints gridBagConstraints1;
		
		jPanel3.setBorder (new javax.swing.border.EmptyBorder (new java.awt.Insets (1, 1, 1, 5)));
		totalField.setEditable (false);
		totalField.setColumns (6);
		totalField.setText ("0");
		gridBagConstraints1 = new java.awt.GridBagConstraints ();
		gridBagConstraints1.gridx = 1;
		gridBagConstraints1.gridy = 0;
		jPanel3.add (totalField, gridBagConstraints1);
		
		jLabel2.setText ("Total:     ");
		gridBagConstraints1 = new java.awt.GridBagConstraints ();
		gridBagConstraints1.gridx = 0;
		gridBagConstraints1.gridy = 0;
		jPanel3.add (jLabel2, gridBagConstraints1);
		
		getContentPane ().add (jPanel3, java.awt.BorderLayout.EAST);
		
		pack ();
	}//GEN-END:initComponents
	
		private void submitJobs(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_submitJobs
			Storage storage = new Storage ();
			
			StringTokenizer range = new StringTokenizer (queryField.getText (), " ,-:");
			
			long begin = Long.parseLong (range.nextToken ());
			long end = Long.parseLong (range.nextToken ());
			long piece = (end - begin) / 3;
			
			Thread t1 = new Thread (new PrimeThread (begin, begin + piece - 1L, storage, 1));
			Thread t2 = new Thread (new PrimeThread (begin + piece, begin + 2L * piece - 1L, storage, 2));
			Thread t3 = new Thread (new PrimeThread (begin + 2L * piece, end, storage, 3));
			
			t1.start ();
			jLabel6.setText (RUNNING + FIRST);
			t2.start ();
			jLabel7.setText (RUNNING + SECOND);
			t3.start ();
			jLabel8.setText (RUNNING + THIRD);
		}//GEN-LAST:event_submitJobs
		
		/** Exit the Application */
    private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
			System.exit (0);
    }//GEN-LAST:event_exitForm
		
		/**
		 * @param args the command line arguments
		 */
		public static void main (String args[]) throws Exception {
			if (args.length != 2) {
				System.err.println ("Usage: java dant.test.Primes host port");
				System.exit (1);
			}
			
			System.setSecurityManager (new RMISecurityManager ());
			
			Registry r = LocateRegistry.getRegistry (args[0], Integer.parseInt (args[1]));
			ce = (ComputeEngine)r.lookup ("ComputeEngine");
			
			Primes p = new Primes ();
			
			p.jLabel6.setText (WAITING + FIRST);
			p.jLabel7.setText (WAITING + SECOND);
			p.jLabel8.setText (WAITING + THIRD);
			
			p.show ();
		}
		
		// Variables declaration - do not modify//GEN-BEGIN:variables
		private javax.swing.JPanel jPanel1;
		private javax.swing.JTextField queryField;
		private javax.swing.JButton jButton1;
		private javax.swing.JLabel jLabel1;
		private javax.swing.JPanel jPanel2;
		private javax.swing.JLabel jLabel6;
		private javax.swing.JLabel jLabel7;
		private javax.swing.JLabel jLabel8;
		private javax.swing.JPanel jPanel3;
		private javax.swing.JTextField totalField;
		private javax.swing.JLabel jLabel2;
		// End of variables declaration//GEN-END:variables
		
		class Storage {
			private int count = 0;
			private int total = 0;
			
			synchronized void add (int num, int total) {
				this.total += total;
				this.count++;
				
				this.finishedCompute (num, total);
				
				this.notify ();
			}
			
			synchronized int getTotal () {
				while (count < 3) {
					try {
						this.wait ();
					}
					catch (InterruptedException e) {
						//Don't care
					}
				}
				
				return total;
			}
			
			private void finishedCompute (int number, int total) {
				switch (number) {
					case 1:
						Primes.this.jLabel6.setText (FINISHED + FIRST);
						break;
					case 2:
						jLabel7.setText (FINISHED + SECOND);
						break;
					case 3:
						Primes.this.jLabel8.setText (FINISHED + THIRD);
						break;
				}
				
				Primes.this.totalField.setText (Integer.toString (this.total));
				Primes.this.repaint ();
			}
		}
		
		class PrimeThread implements Runnable {
			long start, end;
			Storage storage;
			int num;
			
			PrimeThread (long start, long end, Storage storage, int num) {
				this.start = start;
				this.end = end;
				this.storage = storage;
				this.num = num;
			}
			
			public void run () {
				PrimeFinder pf = new PrimeFinder (start, end);
				int primes = 0;
				
				try {
					primes = ((Integer)ce.compute (pf)).intValue ();
				}
				catch (Exception e) {
					e.printStackTrace ();
				}
				
				storage.add (num, primes);
			}
		}
}
