// Author: Matt Oefinger - Oefinger Enterprises, Inc.: www.oefingerenterprises.com

// COPYRIGHT NOTICE: This software is Copyright of Massachusetts Institute of Technology. 
// All rights reserved.

// Last revised 16 May 2007 by GBM (george@mit.edu)

import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import javax.imageio.ImageIO.*;
import java.awt.image.*;
import javax.imageio.ImageIO;

public class hermes extends JApplet
{ 
    static String SERVER = "http://physionet.org/";
    static String RECORD_ID = "N/A";
    static String DATABASE = "N/A";
    static Integer SUBJECT_AGE = new Integer(0);
    static String ANNOTATOR = "N/A";
    static String parsedb = null;


    // All Annotation Types
    static String[] Annotations = {"N","L","R","B","A","a","J","S","V","r","F","e","j","n","E","/","f","Q","?","[","!","]","x","(",")","p","t","u","`","'","^","|","~","+","s","T","*","D","=","\"","@"};


    int Width = 1000;
    int Height = 800;

    public void init()
    {
	Toolkit t = Toolkit.getDefaultToolkit();
	Dimension dd = t.getScreenSize();
	Width = (dd.width * 4) / 5;
	Height = (dd.height * 4) / 5;
	String s = getParameter("WIDTH");
	if (s != null) {
	    try {
		int n = Integer.parseInt(s);
		if (n <= dd.width) Width = n;
	    }
            catch(NumberFormatException e) { }
	}

	s = getParameter("HEIGHT");
	if (s != null) {
	    try {
		int n = Integer.parseInt(s);
		if (n <= dd.height) Height = n;
	    }
            catch(NumberFormatException e) { }
	}
    }

    public hermes()
    {
	final Container contentPane = getContentPane();
	final JTabbedPane tp = new JTabbedPane();
	tp.setBackground(Color.white);    

	String panel1_name = "Record Selection";
	String panel2_name = "Waveform Viewer";

	// panel creation   
	final JPanel panel1 = new JPanel(new GridBagLayout());
	final GridBagConstraints c_p1 = new GridBagConstraints();
	final JPanel panel2 = new JPanel(new GridBagLayout());
	final GridBagConstraints c_p2 = new GridBagConstraints();

	// panel background color defaults
	panel1.setBackground(Color.white);    
	panel2.setBackground(Color.white);    

	// panel 1 specifics
    
	//ALI ADDED THE FOLLOWING CODE
	//A vector to hold the name values of all physiobank databases
	Vector DBs = new Vector();

	//These are the data structures which will hold the values for
	//records and annotations in the respective comboboxes
	final DefaultComboBoxModel AnnotVals = new DefaultComboBoxModel();    
	final DefaultComboBoxModel RecVals = new DefaultComboBoxModel();

   
	//ALI HAS MODIFIED THE FOLLOWING CODE TO INTERACT WITH A NEW CGI SCRIPT
	//CGI script parses database list and returns data to DBS vector
	try                                // get new signal
	    {
		URL u1 = new URL(SERVER + "/cgi-bin/hermes/list_dbs.cgi"); 
		URLConnection conn1 = u1.openConnection(); 
		HttpURLConnection httpConn1 = (HttpURLConnection) conn1;
		int responseCode1 = httpConn1.getResponseCode(); 
		if(responseCode1 == HttpURLConnection.HTTP_OK)
		    {
			InputStream in1 = httpConn1.getInputStream(); 
			Reader reader1 = new InputStreamReader(in1);
			BufferedReader bufferedReader1 =
			    new BufferedReader(reader1);
			String line1;
			while((line1 = bufferedReader1.readLine()) != null)
			    {
				DBs.addElement(line1);
			    }
			bufferedReader1.close();
		    }
		httpConn1.disconnect();
	    }
	catch (MalformedURLException e)
	    {System.out.println("Malformed URL:" + e);}
	catch (IOException e) {System.out.println("IOException:" + e);}
   
	//ALI ADDED 2 NEW LABELS, 1 FOR DATABASE AND 1 FOR ANNOTATOR
	final JLabel p1_label0 = new JLabel("Please Select a Database");
	final JLabel p1_label2 = new JLabel("Please Select a Record");
	JLabel db1_label = new JLabel("");
	final JLabel p1_label3 = new JLabel("Please Select an Annotator");
	final JLabel load_label =
	    //   new JLabel("Width =");
	    new JLabel("(loading may take a few seconds)");

	//ALI ADDED 3 NEW COMBOBOXES
	final JComboBox db1 = new JComboBox(RecVals);
	db1.setToolTipText("Click here to scroll through available records");
	final JComboBox annot_box = new JComboBox(AnnotVals);
	annot_box.setToolTipText(
	    "Click here to scroll through available annotators");
	final JComboBox db_box = new JComboBox(DBs);
	db_box.setToolTipText(
	    "Click here to scroll through available databases");
	
	final JPanel dbpanel = new JPanel(new GridBagLayout());
	dbpanel.setBorder(
	    BorderFactory.createCompoundBorder(
	        BorderFactory.createTitledBorder("Physionet Edition"),
		BorderFactory.createEmptyBorder(5,5,5,5)));
	dbpanel.setPreferredSize(new Dimension(600,400));
	dbpanel.setBackground(Color.WHITE);    
	
	//ALI ADDED A NEW BUTTON TO MAKE NEW DATABASE SELECTION
	final JButton panel1_loadrec = new JButton("Load Record");
	panel1_loadrec.setToolTipText(
	    "Click here to view associated waveforms");
	final JButton refreshdb = new JButton("Select New Database");
	refreshdb.setToolTipText(
	    "Click here to select records from a different database");
	
	//ALI ADDED DATABASE COMBOBOX LISTENER 
	//This listener grabs a database's respective records and
	//annotations and activates their comboboxes
	db_box.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent ec)
		{
		    
		    JComboBox cb =(JComboBox)ec.getSource();
		    String dbselect = (String)cb.getSelectedItem();
		    //  p1_label0.setText("Selected Database: " + dbselect);
		    char temp [] = dbselect.toCharArray();
		    for(int k=0; k<dbselect.length();k++)
			if(temp[k]=='(')
			    parsedb = dbselect.substring(k+1,
							 dbselect.length()-1);
		    p1_label0.setText("Selected Database: " + dbselect);
		    DATABASE = parsedb;
		    try                                // get new signal
			{
			    URL u = new URL(SERVER +
					    "/cgi-bin/hermes/list_recs.cgi?db="
					    + parsedb); 
			    URLConnection conn = u.openConnection(); 
			    HttpURLConnection httpConn =
				(HttpURLConnection) conn;
			    int responseCode = httpConn.getResponseCode(); 
			    if(responseCode == HttpURLConnection.HTTP_OK)
				{
				    InputStream in =
					httpConn.getInputStream(); 
				    Reader reader = new InputStreamReader(in);
				    BufferedReader bufferedReader =
					new BufferedReader(reader);
				    String line;
				    RecVals.removeAllElements();
				    AnnotVals.removeAllElements();    
				    db1.removeAllItems();
				    annot_box.removeAllItems();
				    db1.repaint();
				    annot_box.repaint();
				    while((line = bufferedReader.readLine())
					  != null)
					{
					    RecVals.addElement(line);
					}
				    bufferedReader.close();
				}
			    httpConn.disconnect();
			}
		    
		    catch (MalformedURLException e)
			{System.out.println("Malformed URL:" + e);}
		    catch (IOException e)
			{System.out.println("IOException:" + e);}
		    
		    try                                // get new signal
			{
			    URL u3 = new URL(SERVER +
			       "/cgi-bin/hermes/list_annots.cgi?db=" + parsedb); 
			    URLConnection conn3 = u3.openConnection(); 
			    HttpURLConnection httpConn3 =
				(HttpURLConnection) conn3;
			    int responseCode3 = httpConn3.getResponseCode(); 
			    if(responseCode3 == HttpURLConnection.HTTP_OK)
				{
				    InputStream in3 =
					httpConn3.getInputStream(); 
				    Reader reader3 =
					new InputStreamReader(in3);
				    BufferedReader bufferedReader3 =
					new BufferedReader(reader3);
				    String line3;
				    
				    while((line3 = bufferedReader3.readLine())
					  != null)
					{
					    AnnotVals.addElement(line3);
					}
				    bufferedReader3.close();
				}
			    httpConn3.disconnect();
			}
		    
		    catch (MalformedURLException e)
			{System.out.println("Malformed URL:" + e);}
		    catch (IOException e)
			{System.out.println("IOException:" + e);}
		    
		    db_box.setToolTipText(
    "Click 'Select New Database' below to select records from a new database");

		    //Disable the combobox after selection
		    //user forced to press select new database button
		    db_box.disable();

		    c_p1.anchor = GridBagConstraints.NORTH;
		    c_p1.gridx = 0;
		    c_p1.gridy = 6;
		    c_p1.weightx = 0.0;
		    c_p1.weighty = 0.0;
		    c_p1.ipadx = 0;
		    c_p1.ipady = 10;
		    dbpanel.add(p1_label2,c_p1);
		
		    c_p1.anchor = GridBagConstraints.CENTER;
		    c_p1.gridx = 0;
		    c_p1.gridy = 7;
		    c_p1.weightx = 0.0;
		    c_p1.weighty = 0.0;
		    c_p1.gridheight = 1;
		    c_p1.ipadx = 10;
		    c_p1.ipady = 10;
		    dbpanel.add(db1,c_p1);
		    
		    c_p1.anchor = GridBagConstraints.CENTER;
		    c_p1.gridx = 0;
		    c_p1.gridy = 8;
		    c_p1.weightx = 0.0;
		    c_p1.weighty = 0.0;
		    c_p1.ipadx = 0;
		    c_p1.ipady = 10;
		    dbpanel.add(new JLabel("    "),c_p1);
	    
		    c_p1.anchor = GridBagConstraints.NORTH;
		    c_p1.gridx = 0;
		    c_p1.gridy = 9 ;
		    c_p1.weightx = 0.0;
		    c_p1.weighty = 0.0;
		    c_p1.ipadx = 0;
		    c_p1.ipady = 10;
		    dbpanel.add(p1_label3,c_p1);
		
		    c_p1.anchor = GridBagConstraints.CENTER;
		    c_p1.gridx = 0;
		    c_p1.gridy = 10;
		    c_p1.weightx = 0.0;
		    c_p1.weighty = 0.0;
		    c_p1.gridheight = 1;
		    c_p1.ipadx = 10;
		    c_p1.ipady = 10;
		    dbpanel.add(annot_box,c_p1);
		
		    c_p1.anchor = GridBagConstraints.CENTER;
		    c_p1.gridx = 0;
		    c_p1.gridy = 11;
		    c_p1.weightx = 0.0;
		    c_p1.weighty = 0.0;
		    c_p1.gridheight = 1;
		    c_p1.ipadx = 10;
		    c_p1.ipady = 10;
		    dbpanel.add(new JLabel(""),c_p1);
		
		    c_p1.anchor = GridBagConstraints.CENTER;
		    c_p1.gridx = 0;
		    c_p1.gridy = 12;
		    c_p1.weightx = 0.0;
		    c_p1.weighty = 0.0;
		    c_p1.gridheight = 1;
		    c_p1.gridwidth = 2;
		    c_p1.ipadx = 10;
		    c_p1.ipady = 10;
		    dbpanel.add(new JLabel(""),c_p1);
		
		    c_p1.anchor = GridBagConstraints.SOUTH;
		    c_p1.gridx = 0;
		    c_p1.gridy = 13;
		    c_p1.weightx = 0.0;
		    c_p1.weighty = 0.0;
		    c_p1.gridwidth = 2;
		    c_p1.ipadx = 10;
		    c_p1.ipady = 10;
		    dbpanel.add(panel1_loadrec,c_p1);
		
		    c_p1.anchor = GridBagConstraints.SOUTH;
		    c_p1.gridx = 0;
		    c_p1.gridy = 14;
		    c_p1.weightx = 0.0;
		    c_p1.weighty = 0.0;
		    c_p1.gridwidth = 2;
		    c_p1.ipadx = 10;
		    c_p1.ipady = 10;
		    dbpanel.add(load_label,c_p1);

		    c_p1.anchor = GridBagConstraints.CENTER;
		    c_p1.gridx = 0;
		    c_p1.gridy = 4;
		    c_p1.weightx = 0.0;
		    c_p1.weighty = 0.0;
		    c_p1.ipadx = 10;
		    c_p1.ipady = 10;
		    dbpanel.add(refreshdb,c_p1);

		    panel1.validate();
		    panel1.repaint();
		}
	    });
    
	//ALI ADDED THIS RECORD COMBOBOX LISTENER
	//This listener updates the selected record label
	db1.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    JComboBox cb = (JComboBox)event.getSource();
		    String selected = (String)cb.getSelectedItem();
		    p1_label2.setText("Selected Record: " + selected);
		    RECORD_ID = selected;
		    panel1.validate();
		}
	    });
	
	//ALI ADDED THIS ANNOTATION COMBOBOX LISTENER
	//This listener updates the selected annotator label
	annot_box.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    JComboBox cb = (JComboBox)event.getSource();
		    String selected = (String)cb.getSelectedItem();
		    ANNOTATOR = selected;
		    p1_label3.setText("Selected Annotator: " + ANNOTATOR);
		    panel1.validate();
		    
		    dbpanel.remove(p1_label0);
		    dbpanel.remove(db_box);
		    panel1.validate();

		    c_p1.anchor = GridBagConstraints.NORTH;//NORTH
		    c_p1.gridx = 0;
		    c_p1.gridy = 0;
		    c_p1.weightx = 0.0;
		    c_p1.weighty = 0.0;
		    c_p1.ipadx = 0;
		    c_p1.ipady = 10;
		    dbpanel.add(p1_label0,c_p1);
		    panel1.validate();

		    c_p1.anchor = GridBagConstraints.CENTER;	
		    c_p1.gridx = 0;
		    c_p1.gridy = 1;
		    c_p1.weightx = 0.0;
		    c_p1.weighty = 0.0;
		    c_p1.gridheight = 1;
		    c_p1.ipadx = 10;
		    c_p1.ipady = 10;
		    dbpanel.add(db_box,c_p1);
		    panel1.validate();
		}
	    });

	//ALI ADDED THIS 'NEW DATABASE BUTTON' LISTENER
	//THIS LISTENER REMOVES RECORD AND ANNOTATION COMBOBOXES AND
	//ALLOWS NEW DATABASE SELECTION

	refreshdb.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{		
		    //Clearing the datastructures of current database
		    //	RecVals.removeAllElements();
		    //AnnotVals.removeAllElements();    
		    //db1.removeAllItems();
		    //annot_box.removeAllItems();
		
		    //setting label to default values
		    p1_label0.setText("Please Select a Database");
               			
		    //Removing GUI objects from dbpanel
		    dbpanel.remove(annot_box);
		    dbpanel.remove(db1);
		    dbpanel.remove(panel1_loadrec);
		    dbpanel.remove(refreshdb);
		    dbpanel.remove(p1_label2);
		    dbpanel.remove(p1_label3);
		    dbpanel.remove(load_label);
		    //Enable the select new database combobox
		    db_box.enable();
		    db_box.setToolTipText(
		        "Click here to scroll through available databases");
		    panel1.validate();
		    panel1.repaint();
		}
	    });

	c_p1.anchor = GridBagConstraints.NORTH;
	c_p1.gridx = 0;
	c_p1.gridy = 0;
	c_p1.weightx = 0.0;
	c_p1.weighty = 0.0;
	c_p1.ipadx = 0;
	c_p1.ipady = 10;
	dbpanel.add(p1_label0,c_p1);
   
	c_p1.anchor = GridBagConstraints.CENTER;
	c_p1.gridx = 0;
	c_p1.gridy = 1;
	c_p1.weightx = 0.0;
	c_p1.weighty = 0.0;
	c_p1.gridheight = 1;
	c_p1.ipadx = 10;
	c_p1.ipady = 10;
	dbpanel.add(db_box,c_p1);

	c_p1.anchor = GridBagConstraints.CENTER;
	c_p1.gridx = 0;
	c_p1.gridy = 2;
	c_p1.weightx = 0.0;
	c_p1.weighty = 0.0;
	c_p1.gridheight = 1;
	c_p1.ipadx = 0;
	c_p1.ipady = 10;
	dbpanel.add(new JLabel(""),c_p1);

	c_p1.anchor = GridBagConstraints.CENTER;
	c_p1.gridx = 0;
	c_p1.gridy = 3;
	c_p1.weightx = 0.0;
	c_p1.weighty = 0.0;
	c_p1.gridheight = 1;
	c_p1.gridwidth = 2;
	c_p1.ipadx = 0;
	c_p1.ipady = 10;
	dbpanel.add(new JLabel(""),c_p1);

	c_p1.anchor = GridBagConstraints.CENTER;
	c_p1.gridx = 0;
	c_p1.gridy = 5;
	c_p1.weightx = 0.0;
	c_p1.weighty = 0.0;
	c_p1.ipadx = 0;
	c_p1.ipady = 10;
	dbpanel.add(new JLabel("    "),c_p1);
    
	c_p1.anchor = GridBagConstraints.CENTER;
	c_p1.gridx = 0;
	c_p1.gridy = 1;
	c_p1.weightx = 0.0;
	c_p1.weighty = 0.0;
	c_p1.gridwidth = 2;
	c_p1.gridheight = 1;
	panel1.add(dbpanel,c_p1);
    
	// panel 2 specifics
  
	//ALI HAS MODIFIED THIS SCRIPT PATH WITH DATABASE AND RECORD INFO
	// CGI scripts for data grabbing
	final String CGI2_ECG_RECORDINFO = SERVER +
	    "/cgi-bin/hermes/get_recordinfo_wrapper.cgi?db=" + DATABASE +
	    "&rec="; 
	final String CGI2_ECG_SIGNALS = SERVER +
	    "/cgi-bin/hermes/get_ecg_waveform_wrapper.cgi?db=" + DATABASE +
	    "&rec=";  

	// build GUI for the panel       
	JLabel label2 = new JLabel("Record ID: " + RECORD_ID);

	ImageIcon back_icon = createAppletImageIcon("full-rev16.gif", "");
	final JButton prev2 = new JButton(back_icon);
	prev2.setToolTipText("Back one page");

	ImageIcon halfback_icon = createAppletImageIcon("half-rev16.gif","");
	final JButton prev2_half = new JButton(halfback_icon);
	prev2_half.setToolTipText("Back 1/2 page");

	ImageIcon halffwd_icon = createAppletImageIcon("half-fwd16.gif","");
	final JButton next2_half = new JButton(halffwd_icon);
	next2_half.setToolTipText("Forward 1/2 page");

	ImageIcon fwd_icon = createAppletImageIcon("full-fwd16.gif","");
	final JButton next2 = new JButton(fwd_icon);
	next2.setToolTipText("Forward one page");

	ImageIcon pause_icon = createAppletImageIcon("Pause16.gif","");
	JButton pause2 = new JButton(pause_icon);
	pause2.setToolTipText("Pause playback");

	ImageIcon play_icon = createAppletImageIcon("Play16.gif","");
	JButton play2 = new JButton(play_icon);
	play2.setToolTipText("Start playback");

	ImageIcon stop_icon = createAppletImageIcon("Stop16.gif","");
	JButton stop2 = new JButton("Reset");
	stop2.setToolTipText("Stop playback, return to beginning of record");
 
	JButton rewind2 = new JButton(back_icon);
	rewind2.setToolTipText("Click to return to waveform start point");
	/*
	ImageIcon zoom_in = createAppletImageIcon("ZoomIn16.gif","zoom in");
	JButton zoom_in_x = new JButton(zoom_in);
	zoom_in_x.setToolTipText("Click to Zoom-in on X-Axis");

	ImageIcon zoom_out = createAppletImageIcon("ZoomOut16.gif","zoom out");
	JButton zoom_out_x = new JButton(zoom_out);
	zoom_out_x.setToolTipText("Click to Zoom-out on X-Axis");

	JButton zoom_in_y = new JButton(zoom_in);
	zoom_in_y.setToolTipText("Click to Zoom-in on Y-Axis");

	JButton zoom_out_y = new JButton(zoom_out);
	zoom_out_y.setToolTipText("Click to Zoom-out on Y-Axis");
	*/
	JComboBox annot2 = new JComboBox(Annotations);
	annot2.setToolTipText("Select annotation for search");
    
	JButton createimage = new JButton("Email To:");

	// create buttons with keyboard mnemonics
	JButton del_annot = new JButton("delete");
	JButton add_annot = new JButton(" add ");

	final JButton prev_annot = new JButton("prev");
	prev_annot.setToolTipText("Search for previous annotation instance");
	final JButton next_annot = new JButton("next");
	next_annot.setToolTipText("Search for next annotation instance");

	del_annot.setMnemonic(KeyEvent.VK_D);
	add_annot.setMnemonic(KeyEvent.VK_A); 
	prev_annot.setMnemonic(KeyEvent.VK_P);
	next_annot.setMnemonic(KeyEvent.VK_N); 

	// do not allow addition or deletion of annotations in this version
	del_annot.setEnabled(false);
	add_annot.setEnabled(false);

	//was false
	prev_annot.setEnabled(true);
	next_annot.setEnabled(true);

	final JSlider p2_slider2 = new JSlider(0,100,5);
                  // note: must initialize child slider property below
                  // after registering action listener for this object
	p2_slider2.putClientProperty("JSlider.isFilled",Boolean.TRUE);
	p2_slider2.setMajorTickSpacing(20);
	p2_slider2.setMinorTickSpacing(5);
	p2_slider2.setPaintTicks(true);
	p2_slider2.setPaintLabels(false);
	p2_slider2.setBackground(Color.white);    

	final JSlider zoomx_slider = new JSlider(0,100,50);
                  // note: must initialize child slider property below
                  // after registering action listener for this object
	zoomx_slider.putClientProperty("JSlider.isFilled",Boolean.TRUE);
	zoomx_slider.setMajorTickSpacing(20);
	zoomx_slider.setMinorTickSpacing(5);
	zoomx_slider.setPaintTicks(true);
	zoomx_slider.setPaintLabels(false);
	zoomx_slider.setBackground(Color.white);   

	final JSlider zoomy_slider = new JSlider(JSlider.VERTICAL,0,100,20);
                  // note: must initialize child slider property below
                  // after registering action listener for this object
	zoomy_slider.putClientProperty("JSlider.isFilled",Boolean.TRUE);
	zoomy_slider.setMajorTickSpacing(20);
	zoomy_slider.setMinorTickSpacing(5);
	zoomy_slider.setPaintTicks(true);
	zoomy_slider.setPaintLabels(false);
	zoomy_slider.setBackground(Color.white);    

	final JSlider movieslider = new JSlider(JSlider.HORIZONTAL,0,100,0);
                  // note: must initialize child slider property below
                  // after registering action listener for this object
	movieslider.putClientProperty("JSlider.isFilled",Boolean.TRUE);
	//movieslider.setMajorTickSpacing(20);
	//movieslider.setMinorTickSpacing(5);
	movieslider.setPaintTicks(false);
	movieslider.setPaintLabels(false);
	movieslider.setBackground(Color.white);    

	final JTextField emailaddress = new JTextField("ENTER YOUR ADDRESS");

	final MultiChannel_Movie_Canvas child_canvas2 =
	    new MultiChannel_Movie_Canvas(label2,10,10);    //10, 10  
	child_canvas2.setLabelParams(0,200,1,"INT",0,1,1,"INT", "", "");
	// x data is 1 sample/pixel
	child_canvas2.setDoubleBuffered(true);
 
	child_canvas2.add_movie_button(play2);
	child_canvas2.add_movie_button(pause2);
	child_canvas2.add_movie_button(stop2);
	child_canvas2.add_movie_button(rewind2);

	// do not allow child to override - not enabled at any time
	child_canvas2.add_browser_button(prev2_half);
	child_canvas2.add_browser_button(next2_half);
	child_canvas2.add_browser_button(prev2);
	child_canvas2.add_browser_button(next2);
	child_canvas2.add_browser_button(prev_annot);
	child_canvas2.add_browser_button(next_annot);

	child_canvas2.setyedge(15);

	// put canvases into JScrollPanes for layout manager - note
	// scrolling disabled but JScrollPane necessary for adding
	// Objects
	final JScrollPane scp2_bot =
	    new JScrollPane(child_canvas2,
			    ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
			    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
	// size the scrollpanes
	scp2_bot.setPreferredSize(new Dimension(Width-50,Height-200));

	final JComboBox selectsignal = new JComboBox(child_canvas2.sigs);
	selectsignal.setToolTipText("Select active signal");
	JButton addsignal = new JButton("Show");
	addsignal.setToolTipText("Click to make selected signal visible");
	JButton removesignal = new JButton("Hide");
	removesignal.setToolTipText("Click to hide selected signal");

	// assign action listeners to buttons and slider
	prev2.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    child_canvas2.prev_button_click();
		    float starttmp = (float)child_canvas2.START_INDEX;
		    float endtmp = (float)child_canvas2.END_INDEX;
		    float offset = starttmp/endtmp;
		    float jumpto = (float)100 * offset;
		    movieslider.setValue((int)jumpto);
		}
	    }
				);

	next2.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    child_canvas2.next_button_click();
		    float starttmp = (float)child_canvas2.START_INDEX;
		    float endtmp = (float)child_canvas2.END_INDEX;
		    float offset = starttmp/endtmp;
		    float jumpto = (float)100 * offset;
		    movieslider.setValue((int)jumpto);
		}
	    }
				);

	prev2_half.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    child_canvas2.prev_button_half_click();
		    float starttmp = (float)child_canvas2.START_INDEX;
		    float endtmp = (float)child_canvas2.END_INDEX;
		    float offset = starttmp/endtmp;
		    float jumpto = (float)100 * offset;
		    movieslider.setValue((int)jumpto);
		}
	    }
				     );

	next2_half.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    child_canvas2.next_button_half_click();
		    float starttmp = (float)child_canvas2.START_INDEX;
		    float endtmp = (float)child_canvas2.END_INDEX;
		    float offset = starttmp/endtmp;
		    float jumpto = (float)100 * offset;
		    movieslider.setValue((int)jumpto);
		}
	    }
				     );

	/*
	zoom_in_x.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    child_canvas2.zoom_in_x_click();
		}
	    }
				    );

	zoom_out_x.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    child_canvas2.zoom_out_x_click();
		}
	    }
				     );

	zoom_in_y.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    child_canvas2.zoom_in_y_click();
		}
	    }
				    );

	zoom_out_y.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    child_canvas2.zoom_out_y_click();
		}
	    }
	    );
	    */

	prev_annot.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    child_canvas2.prev_annot();
		    child_canvas2.ANNOT_ADVANCE = 1;
		    child_canvas2.TEMP_START_INDEX = child_canvas2.START_INDEX;
		    float starttmp = (float)child_canvas2.START_INDEX;
		    float endtmp = (float)child_canvas2.END_INDEX;
		    float offset = starttmp/endtmp;
		    float jumpto = (float)100 * offset;
		    movieslider.setValue((int)jumpto);
		}
	    }
				     );

	next_annot.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    child_canvas2.next_annot();
		    child_canvas2.ANNOT_ADVANCE = 1;
		    child_canvas2.TEMP_START_INDEX = child_canvas2.START_INDEX;
		    float starttmp = (float)child_canvas2.START_INDEX;
		    float endtmp = (float)child_canvas2.END_INDEX;
		    float offset = starttmp/endtmp;
		    float jumpto = (float)100 * offset;
		    movieslider.setValue((int)(jumpto + .5));
		}
	    }
				     );

	annot2.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    JComboBox cb = (JComboBox)event.getSource();
		    String selected = (String)cb.getSelectedItem();
		    child_canvas2.set_active_annotation(selected);
		}
	    }
				 );

	selectsignal.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    JComboBox cb = (JComboBox)event.getSource();
		    String selected = (String)cb.getSelectedItem();
		    child_canvas2.set_active_signal(selected);
		}
	    }
				       );
     
	addsignal.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{ 
		    child_canvas2.addsignal_button_click();
		}
	    }
				    );
	removesignal.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{ 
		    child_canvas2.removesignal_button_click();
		}
	    }
				       );

	pause2.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{ 
		    next2.setEnabled(true);
		    next2_half.setEnabled(true);
		    prev2.setEnabled(true);
		    prev2_half.setEnabled(true);
		    movieslider.setEnabled(true);
		    child_canvas2.movie_pause_button_click();
		    float starttmp = (float)child_canvas2.START_INDEX;
		    float endtmp = (float)child_canvas2.END_INDEX;
		    float offset = starttmp/endtmp;
		    float jumpto = (float)100 * offset;
		    movieslider.setValue((int)jumpto);		
		}
	    }
				 );

	createimage.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    try                                // get new signal
			{
			    char temp [] = ANNOTATOR.toCharArray();
			    for(int k=0; k<ANNOTATOR.length();k++)
				{
				    if(temp[0]=='(')
					{
					    ANNOTATOR = "";
					    break;
					}
				    if(temp[k]=='-')
					{
					    ANNOTATOR =
						ANNOTATOR.substring(0, k);
					    break;
					}
				}

			    String addy = emailaddress.getText();
			    URL u = new URL(SERVER +
				"/cgi-bin/hermes/makechart.cgi?database=" + 
				DATABASE + "&record=" +RECORD_ID +
				"&addy=" + addy + "&annotator=" + ANNOTATOR + 
				"&width=medium&tstart=" + 
  (int)((child_canvas2.START_INDEX/child_canvas2.SAMPLING_FREQUENCY)+.5)); 
			    URLConnection conn = u.openConnection(); 
			    conn.setDoOutput(true);
			    conn.connect();
			
			    HttpURLConnection httpConn =
				(HttpURLConnection) conn;
			    int responseCode = httpConn.getResponseCode(); 
			    if(responseCode == HttpURLConnection.HTTP_OK)
				{
				    PrintStream out = new PrintStream(
					          httpConn.getOutputStream());
				
				    out.print("done"); //does this do anything?
				    out.flush();
				}
			    httpConn.disconnect();
			}
		
		    catch (MalformedURLException e)
			{System.out.println("Malformed URL:" + e);}
		    catch (IOException e)
			{System.out.println("IOException:" + e);}
		}
	    }
				      );

	play2.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    child_canvas2.movie_play_button_click();
		    movieslider.setEnabled(false);
		}
	    }
				);

	stop2.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    child_canvas2.movie_stop_button_click();
		    p2_slider2.setValue(5);
		    zoomy_slider.setValue(20);
		    zoomx_slider.setValue(50);
		    movieslider.setValue(0);
		    movieslider.setEnabled(true);
		}
	    }
				);

	rewind2.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    child_canvas2.movie_rewind_button_click();
		}
	    }
				  );

	p2_slider2.addChangeListener(new ChangeListener()
	    {
		public void stateChanged(ChangeEvent e)
		{         
		    child_canvas2.slider_slid(
				   ((JSlider)e.getSource()).getValue());
		}
	    }
				     );

	zoomx_slider.addChangeListener(new ChangeListener()
	    {
		public void stateChanged(ChangeEvent e)
		{         
		    child_canvas2.slider_slid1(
				   ((JSlider)e.getSource()).getValue());
		    float starttmp = (float)child_canvas2.START_INDEX;
		    float endtmp = (float)child_canvas2.END_INDEX;
		    float offset = starttmp/endtmp;
		    float jumpto = (float)100 * offset;
		    movieslider.setValue((int)jumpto);
		}
	    }
				       );

	zoomy_slider.addChangeListener(new ChangeListener()
	    {
		public void stateChanged(ChangeEvent e)
		{         
		    child_canvas2.slider_slid2(
				   ((JSlider)e.getSource()).getValue());
		}
	    }
				       );


	movieslider.addChangeListener(new ChangeListener()
	    {
		public void stateChanged(ChangeEvent e)
		{         
		    child_canvas2.slider_movie(
				   ((JSlider)e.getSource()).getValue());
		}
	    }
				      );

	// initialize the active annotation in the child to the 0th element
	child_canvas2.set_active_annotation(Annotations[0]);
    
	c_p2.anchor = GridBagConstraints.CENTER;
	c_p2.gridx = 2;
	c_p2.gridy = 1;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 9;
	panel2.add(scp2_bot,c_p2);

	final JPanel browserpanel = new JPanel(new GridBagLayout());
	browserpanel.setBorder(
	    BorderFactory.createCompoundBorder(
		BorderFactory.createTitledBorder(
		    "Record Navigation"),
		BorderFactory.createEmptyBorder(5,5,5,5)));
	browserpanel.setBackground(Color.white);    

	final JPanel visibilitypanel = new JPanel(new GridBagLayout());
	visibilitypanel.setBorder(
	    BorderFactory.createCompoundBorder(
		BorderFactory.createTitledBorder(
		    "Signal Visibility"),
		BorderFactory.createEmptyBorder(5,5,5,5)));
	visibilitypanel.setBackground(Color.white);    

	c_p2.anchor = GridBagConstraints.NORTH;
	c_p2.gridx = 0;
	c_p2.gridy = 0;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	c_p2.gridheight = 1;
	browserpanel.add(new JLabel("Seek: "),c_p2);

	c_p2.anchor = GridBagConstraints.CENTER;
	c_p2.gridx = 1;
	c_p2.gridy = 0;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 13;
	c_p2.gridheight = 1;
	c_p2.fill = GridBagConstraints.HORIZONTAL;
	browserpanel.add(movieslider,c_p2);

	c_p2.fill = GridBagConstraints.NONE;

	c_p2.gridx = 0;
	c_p2.gridy = 1;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	c_p2.gridheight = 1;
	browserpanel.add(new JLabel("Zoom-X: "),c_p2);

	c_p2.gridx = 1;
	c_p2.gridy = 1;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	c_p2.gridheight = 2;
	browserpanel.add(zoomx_slider,c_p2);

	c_p2.anchor = GridBagConstraints.EAST;
	c_p2.gridx = 4;
	c_p2.gridy = 1;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	c_p2.fill = GridBagConstraints.VERTICAL;
	// make same spacing as for buttons
	browserpanel.add(prev2,c_p2);

	c_p2.anchor = GridBagConstraints.EAST;
	c_p2.gridx = 5;
	c_p2.gridy = 1;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	c_p2.fill = GridBagConstraints.VERTICAL;
	// make same spacing as for buttons
	browserpanel.add(prev2_half,c_p2);

	c_p2.anchor = GridBagConstraints.EAST;
	c_p2.gridx = 6;
	c_p2.gridy = 1;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	c_p2.fill = GridBagConstraints.VERTICAL;
	// make same spacing as for buttons
	browserpanel.add(pause2,c_p2);

	c_p2.anchor = GridBagConstraints.EAST;
	c_p2.gridx = 7;
	c_p2.gridy = 1;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	c_p2.fill = GridBagConstraints.VERTICAL;
	// make same spacing as for buttons
	browserpanel.add(stop2,c_p2);

	c_p2.anchor = GridBagConstraints.WEST;
	c_p2.gridx = 8;
	c_p2.gridy = 1;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	browserpanel.add(play2,c_p2);

	c_p2.anchor = GridBagConstraints.WEST;
	c_p2.gridx = 9;
	c_p2.gridy = 1;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	browserpanel.add(next2_half,c_p2); 

	c_p2.anchor = GridBagConstraints.WEST;
	c_p2.gridx = 10;
	c_p2.gridy = 1;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	browserpanel.add(next2,c_p2);

	c_p2.gridx = 11;
	c_p2.gridy = 1;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	browserpanel.add(p2_slider2,c_p2);
    
	c_p2.anchor = GridBagConstraints.CENTER;
	c_p2.gridx = 11;
	c_p2.gridy = 3;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	browserpanel.add(new JLabel("Adjust Speed"),c_p2);

	c_p2.anchor = GridBagConstraints.CENTER;
	c_p2.gridx = 4;
	c_p2.gridy = 2;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 3;
	browserpanel.add(new JLabel("                    "),c_p2);

	c_p2.fill = GridBagConstraints.HORIZONTAL;
	// make same spacing as for buttons
	c_p2.gridx = 8;
	c_p2.gridy = 3;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 2;
	c_p2.gridheight = 0;
	c_p2.anchor = GridBagConstraints.SOUTH;
	browserpanel.add(next_annot,c_p2);
    
	c_p2.anchor = GridBagConstraints.SOUTH;
	c_p2.gridx = 7;
	c_p2.gridy = 3;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	c_p2.gridheight = 0;
	c_p2.fill = GridBagConstraints.HORIZONTAL;
	// make same spacing as for buttons
	browserpanel.add(annot2,c_p2);

	c_p2.fill = GridBagConstraints.HORIZONTAL;
	// make same spacing as for buttons
	c_p2.gridx = 5;
	c_p2.gridy = 3;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 2;
	c_p2.gridheight = 0;
	browserpanel.add(prev_annot,c_p2);

	c_p2.fill = GridBagConstraints.NONE;
	c_p2.gridx = 0;
	c_p2.gridy = 3;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 2;
	c_p2.gridheight = 0;
	c_p2.anchor = GridBagConstraints.WEST;
	browserpanel.add(createimage,c_p2);
   
	emailaddress.setColumns(14);
	c_p2.fill = GridBagConstraints.NONE;
	c_p2.gridx = 1;
	c_p2.gridy = 3;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 2;
	c_p2.gridheight = 0;
	c_p2.anchor = GridBagConstraints.EAST;
	browserpanel.add(emailaddress,c_p2);

	c_p2.anchor = GridBagConstraints.CENTER;
	c_p2.gridx = 1;
	c_p2.gridy = 3;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 3;
	panel2.add(new JLabel("                    "),c_p2);

	c_p2.anchor = GridBagConstraints.CENTER;
	c_p2.gridx = 0;
	c_p2.gridy = 2;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 3;
	panel2.add(new JLabel("                                   "),c_p2);

	c_p2.anchor = GridBagConstraints.WEST;
	c_p2.gridx = 3; //5
	c_p2.gridy = 2; //2
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	c_p2.gridheight = 1;
	panel2.add(browserpanel,c_p2);

	c_p2.anchor = GridBagConstraints.WEST;
	c_p2.gridx = 0;
	c_p2.gridy = 1;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	c_p2.gridheight = 1;
	panel2.add(new JLabel("Zoom-Y: "),c_p2);

	c_p2.anchor = GridBagConstraints.WEST;
	c_p2.gridx = 1;
	c_p2.gridy = 1;
	c_p2.weightx = 0.0;
	c_p2.weighty = 0.0;
	c_p2.gridwidth = 1;
	c_p2.gridheight = 1;
	panel2.add(zoomy_slider,c_p2);


	// give CustomCanvas objects the appropriate URL signal source
	panel1_loadrec.addActionListener(new ActionListener()
	    {
		public void actionPerformed(ActionEvent event)
		{
		    next2.setEnabled(true);
		    next2_half.setEnabled(true);
		    prev2.setEnabled(true);
		    prev2_half.setEnabled(true);
		    next_annot.setEnabled(true);
		    prev_annot.setEnabled(true);
		    movieslider.setValue(0);
	   	
		    String selected_rec = new String(RECORD_ID);
		    String url = new String();
		    String url2 = new String();
		    String url9 = new String();

		    //ALI ADDED THIS NEW SCRIPT PATH
		    url = SERVER +
			"/cgi-bin/hermes/get_recordinfo_wrapper.cgi?db=" +
			DATABASE + "&rec=" + selected_rec;
		    url2 = SERVER +
			"/cgi-bin/hermes/get_ecg_waveform_wrapper.cgi?db=" +
			DATABASE + "&rec=" +selected_rec;
		    url9 = SERVER +
			"/cgi-bin/hermes/get_ecg_annotation_wrapper.cgi?db=" +
			DATABASE + "&rec=" +selected_rec;

		    char temp [] = ANNOTATOR.toCharArray();
		    for(int k=0; k<ANNOTATOR.length();k++)
			{
			    if(temp[0]=='(')
				{
				    ANNOTATOR = "";
				    break;
				}
			    if(temp[k]=='-')
				{
				    ANNOTATOR = ANNOTATOR.substring(0, k);
				    break;
				}
			}

		    p2_slider2.setValue(5);
  

		    //initializing URL and annotation type in child_canvas
		    child_canvas2.reset();
		    child_canvas2.load(url,url2,url9, ANNOTATOR, DATABASE,
				       selected_rec);
	    
		    // make the waveform tab visible
		    tp.setSelectedIndex(1); 
		}
	    }
					 );

	JScrollPane panel1_scroller =
	   new JScrollPane(panel1,
			   ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
			   ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
	JScrollPane panel2_scroller =
	   new JScrollPane(panel2,
			   ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
			   ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

	panel1.setPreferredSize(new Dimension(Width+50,Height+200));
	panel2.setPreferredSize(new Dimension(Width+50,Height));
   
	JScrollBar jsb1 = panel1_scroller.getVerticalScrollBar();
	jsb1.setValue((jsb1.getMaximum()/2)+100);
  
	JScrollBar jsb2 = panel2_scroller.getVerticalScrollBar();
	jsb2.setMaximum((jsb2.getMaximum() * 2)-50);
	jsb2.setValue(jsb2.getMinimum());

	JScrollBar jsb2h = panel2_scroller.getHorizontalScrollBar();
	jsb2h.setValue(10);
   
	// add panels to JTabbedPane
	tp.addTab(panel1_name,panel1_scroller);
	tp.addTab(panel2_name,panel2_scroller);

	// add JTabbed Pane to main container
	SpringLayout layout = new SpringLayout();
	contentPane.setLayout(layout);
	contentPane.setBackground(Color.white);    
	contentPane.add(tp,BorderLayout.CENTER);
   
	layout.putConstraint(SpringLayout.EAST, contentPane, 5,
			     SpringLayout.EAST, tp);
	layout.putConstraint(SpringLayout.SOUTH, contentPane, 5,
			     SpringLayout.SOUTH, tp);

	/* // Uncomment this block to run applet in its own frame.
	final JFrame frame = new JFrame("Hermes Viewer");
	frame.getContentPane().add(contentPane, BorderLayout.CENTER);
	frame.pack();
	frame.setVisible(true);
	*/
    }

    public void setmenu(String holder, JCheckBoxMenuItem cbMenuItem,
			JMenu submenu)
    {
	cbMenuItem = new JCheckBoxMenuItem(holder);
	submenu.add(cbMenuItem);
    }
   
    public String parsestring(String annrec)
    {
	char temp [] = annrec.toCharArray();
	for(int k=0; k<annrec.length();k++)
	    {
		if(temp[0]=='(')
		    {
			break;
		    }
		if(temp[k]=='-')
		    {
			annrec = annrec.substring(0, k);
			break;
		    }
	    }
	return annrec;
    }
    
    public String ServerRequest(String Server_URL)
    {
	String output = "";
    
	try
	    {
		URL u = new URL(Server_URL);
		InputStream in = u.openStream();
		in = new BufferedInputStream(in);
		// buffer stream to increase performance
		Reader r = new InputStreamReader(in);
		// chain the input stream to a reader
		int c;
		while((c = r.read()) != -1)
		    {
			output += ((char) c);
		    }         
	    }
	catch(MalformedURLException e)
	    {
	    }
	catch(IOException e)
	    {
	    }
	return output;
    }
  
    //Returns an ImageIcon, or null if the path was invalid. 
    //When running an applet using Java Plug-in, 
    //getResourceAsStream is more efficient than getResource.
    protected static ImageIcon createAppletImageIcon(String path,
						     String description) 
    {
	int MAX_IMAGE_SIZE = 75000; //Change this to the size of
                                    //your biggest image, in bytes.
	int count = 0;
	BufferedInputStream imgStream =
	    new BufferedInputStream(hermes.class.getResourceAsStream(path));
        if (imgStream != null) {
            byte buf[] = new byte[MAX_IMAGE_SIZE];
            try {
                count = imgStream.read(buf);
            } catch (IOException ieo) {
                System.err.println("Couldn't read stream from file: " + path);
            }

            try {
                imgStream.close();
            } catch (IOException ieo) {
		System.err.println("Can't close file " + path);
            }

            if (count <= 0) {
                System.err.println("Empty file: " + path);
                return null;
            }
            return new ImageIcon(Toolkit.getDefaultToolkit().createImage(buf),
                                 description);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }
 
}
