package org.apache.tools.ant.taskdefs.optional.ide;

/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import java.util.Vector;
import java.awt.Frame;
import java.awt.Dialog;
import java.awt.Panel;
import java.awt.MenuBar;
import java.awt.Menu;
import java.awt.MenuItem;
import java.awt.Label;
import java.awt.TextField;
import java.awt.TextArea;
import java.awt.List;
import java.awt.Choice;
import java.awt.Button;
import java.awt.FileDialog;
import java.awt.FlowLayout;
import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.Font;
import java.awt.SystemColor;
import java.awt.event.ActionListener;
import java.awt.event.ItemListener;
import java.awt.event.TextListener;
import java.awt.event.WindowListener;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.TextEvent;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeListener;
import org.apache.tools.ant.Main;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.Project;

/**
 * This is a simple grafical user interface to provide the information needed by ANT and
 * to start the build-process within IBM VisualAge for Java.
 * <p>
 * I was using AWT to make it independent from the JDK-version. Please don't ask me for a Swing-version:
 * I am very familiar with Swing and I really think that it's not necessary for such a simple gui!
 * <p>
 * It is completely developed in VAJ using the visual composition editor. About 90% of the code is generated by VAJ,
 * but in fact I did a lot of <i>code-beautification</i> ;-).
 * <p>
 * @version 1.0 h
 * @author: Christoph Wilhelms, TUI Infotec GmbH
 */
public class VAJAntToolGUI extends Frame {
	/**
	 * Members 
	 */
	private VAJBuildLogger logger = new VAJBuildLogger();
	private String lineSeparator = "\r\n";
	private PrivateEventHandler iEventHandler = new PrivateEventHandler();

	/**
	 * Members of the main-window
	 */
	// main model
	private VAJBuildInfo iBuildInfo = null;
	// Menue
	private MenuBar iAntMakeMenuBar = null;
	private Menu iFileMenu = null;
	private MenuItem iSaveMenuItem = null;
	private MenuItem iMenuSeparator = null;
	private MenuItem iShowLogMenuItem = null;
	private Menu iHelpMenu = null;
	private MenuItem iAboutMenuItem = null;
	// Container
	private Panel iContentsPane = null;
	private Panel iOptionenPanel = null;
	private Panel iCommandButtonPanel = null;
	private FlowLayout iCommandButtonPanelFlowLayout = null;
	// Project name
	private Label iProjectLabel = null;
	private Label iProjectText = null;
	// XML-file 
	private Label iBuildFileLabel = null;
	private TextField iBuildFileTextField = null;
	private boolean iConnPtoP2Aligning = false;
	private Button iBrowseButton = null;
	private FileDialog iFileDialog = null;
	// Options
	private Choice iMessageOutputLevelChoice = null;
	private Label iMessageOutputLevelLabel = null;
	private Label iTargetLabel = null;
	private List iTargetList = null;
	// Command-buttons
	private Button iBuildButton = null;
	private Button iReloadButton = null;	
	private Button iCloseButton = null;
	/**
	 * log-Window
	 */
	// Container
	private Frame iMessageFrame = null;
	private Panel iMessageCommandPanel = null;
	private Panel iMessageContentPanel = null;
	// Components
	private TextArea iMessageTextArea = null;
	private Button iMessageOkButton = null;
	private Button iMessageClearLogButton = null;
	/**
	 * About-dialog
	 */
	// Container
	private Dialog iAboutDialog = null;
	private Panel iAboutDialogContentPanel = null;
	private Panel iAboutInfoPanel = null;
	private Panel iAboutCommandPanel = null;
	// Labels
	private Label iAboutTitleLabel = null;
	private Label iAboutDevLabel = null;
	private Label iAboutContactLabel = null;
	// Buttons
	private Button iAboutOkButton = null;

	/**
	 * This internal BuildLogger, to be honest, is just a BuildListener. 
	 * It does nearly the same as the DefaultLogger, but uses the Loggin-Window for output.
	 */
	private class VAJBuildLogger implements BuildListener {
		private long startTime = System.currentTimeMillis();

		/**
		 * VAJBuildLogger constructor comment.
		 */
		public VAJBuildLogger() {
			super();
		}

		/**
		 *  Fired after the last target has finished. This event
		 *  will still be thrown if an error occured during the build.
		 *
		 *  @see BuildEvent#getException()
		 */
		public void buildFinished(BuildEvent event) {
			Throwable error = event.getException();

			if (error == null) {
				getMessageTextArea().append(lineSeparator + "BUILD SUCCESSFUL");
			}
			else {
				getMessageTextArea().append(lineSeparator + "BUILD FAILED" + lineSeparator);

				if (error instanceof BuildException) {
					getMessageTextArea().append(error.toString());

					Throwable nested = ((BuildException)error).getException();
					if (nested != null) {
						nested.printStackTrace(System.err);
					}
				}
				else {
					error.printStackTrace(System.err);
				}
			}

			getMessageTextArea().append(lineSeparator + "Total time: " + formatTime(System.currentTimeMillis() - startTime));
		}

		/**
		 *  Fired before any targets are started.
		 */
		public void buildStarted(BuildEvent event) {
			startTime = System.currentTimeMillis();
			getMessageTextArea().append(lineSeparator);
		}

		/**
		 *  Fired whenever a message is logged.
		 *
		 *  @see BuildEvent#getMessage()
		 *  @see BuildEvent#getPriority()
		 */
		public void messageLogged(BuildEvent event) {
			if (event.getPriority() <= getBuildInfo().getOutputMessageLevel()) {
				String msg = "";
				if (event.getTask() != null)
					msg = "[" + event.getTask().getTaskName() + "] ";
				getMessageTextArea().append(lineSeparator + msg + event.getMessage());
			}
		}

		/**
		 *  Fired when a target has finished. This event will
		 *  still be thrown if an error occured during the build.
		 *
		 *  @see BuildEvent#getException()
		 */
		public void targetFinished(BuildEvent event) {
		}

		/**
		 *  Fired when a target is started.
		 *
		 *  @see BuildEvent#getTarget()
		 */
		public void targetStarted(BuildEvent event) {
			if (getBuildInfo().getOutputMessageLevel() <= Project.MSG_INFO) {
				getMessageTextArea().append(lineSeparator + event.getTarget().getName() + ":");
			}
		}

		/**
		 *  Fired when a task has finished. This event will still
		 *  be throw if an error occured during the build.
		 *
		 *  @see BuildEvent#getException()
		 */
		public void taskFinished(BuildEvent event) {
		}

		/**
		 *  Fired when a task is started.
		 *
		 *  @see BuildEvent#getTask()
		 */
		public void taskStarted(BuildEvent event) {
		}
		/**
		 * Chris: HACK: remove when Ant-Refactoring is finished!
		 */
		public void buildSuccessful() {
			getMessageTextArea().append(lineSeparator + "BUILD SUCCESSFUL");
			getMessageTextArea().append(lineSeparator + "Total time: " + formatTime(System.currentTimeMillis() - startTime));
		}
		/**
		 * Chris: HACK: remove when Ant-Refactoring is finished!
		 */
		public void buildFailed(Throwable exc) {
			getMessageTextArea().append(lineSeparator + "BUILD FAILED" + lineSeparator);

			if (exc instanceof BuildException) {
				getMessageTextArea().append(exc.toString());

				Throwable nested = ((BuildException)exc).getException();
				if (nested != null) {
					nested.printStackTrace(System.err);
				}
			}
			else {
				exc.printStackTrace(System.err);
			}
			getMessageTextArea().append(lineSeparator + "Total time: " + formatTime(System.currentTimeMillis() - startTime));
		}
	}
	
	/**
	 * Eventhandler to handle all AWT-events
	 */
	private class PrivateEventHandler implements ActionListener, ItemListener, TextListener, WindowListener, PropertyChangeListener {
		/**
		 * ActionListener method
		 */
		public void actionPerformed(ActionEvent e) {
			try {
				/* #### Main App-Frame #### */
				// browse XML-File with filechooser
				if (e.getSource() == VAJAntToolGUI.this.getBrowseButton()) {
					getFileDialog().setDirectory(getBuildFileTextField().getText().substring(0, getBuildFileTextField().getText().lastIndexOf('\\') + 1));
					getFileDialog().setFile("*.xml");
					getFileDialog().show();
					if (!getFileDialog().getFile().equals("") ) {
						getBuildFileTextField().setText(getFileDialog().getDirectory() + getFileDialog().getFile());
					}
				}
				// dispose and exit application 
				if (e.getSource() == VAJAntToolGUI.this.getCloseButton()) {
					dispose();
					System.exit(0);
				}
				// start build-process
				if (e.getSource() == VAJAntToolGUI.this.getBuildButton()) 
					executeTarget();
				if (e.getSource() == VAJAntToolGUI.this.getReloadButton()) {
					try {
						getBuildInfo().updateTargetList();
						fillList();
					}
					catch (Throwable fileNotFound) {
						handleException(fileNotFound);
						getTargetList().removeAll();
						getBuildButton().setEnabled(false);
					}
				}
				// MenuItems
				if (e.getSource() == VAJAntToolGUI.this.getSaveMenuItem()) 
					saveBuildInfo();
				if (e.getSource() == VAJAntToolGUI.this.getAboutMenuItem()) 
					getAboutDialog().show();
				if (e.getSource() == VAJAntToolGUI.this.getShowLogMenuItem()) 
					getMessageFrame().show();
				/* #### About dialog #### */
				if (e.getSource() == VAJAntToolGUI.this.getAboutOkButton()) 
					getAboutDialog().dispose();
				/* #### Log frame #### */
				if (e.getSource() == VAJAntToolGUI.this.getMessageOkButton())
					getMessageFrame().dispose();
				if (e.getSource() == VAJAntToolGUI.this.getMessageClearLogButton()) 
					getMessageTextArea().setText("");
				if (e.getSource() == VAJAntToolGUI.this.getMessageOkButton()) 
					getMessageFrame().dispose();
			}
			catch (Throwable exc) {
				handleException(exc);
			}
		}

		/**
		 * ItemListener method
		 */
		public void itemStateChanged(ItemEvent e) {
			try {
				if (e.getSource() == VAJAntToolGUI.this.getTargetList()) 
					getBuildButton().setEnabled(true);
				if (e.getSource() == VAJAntToolGUI.this.getMessageOutputLevelChoice()) 
					getBuildInfo().setOutputMessageLevel(getMessageOutputLevelChoice().getSelectedIndex());
				if (e.getSource() == VAJAntToolGUI.this.getTargetList()) 
					getBuildInfo().setTarget(getTargetList().getSelectedItem());
			}
			catch (Throwable exc) {
				handleException(exc);
			}
		}
		
		/**
		 * PropertyChangeListener method
		 */
		public void propertyChange(java.beans.PropertyChangeEvent evt) {
			if (evt.getSource() == VAJAntToolGUI.this.getBuildInfo() && (evt.getPropertyName().equals("projectName"))) 
				connectProjectNameToLabel();
			if (evt.getSource() == VAJAntToolGUI.this.getBuildInfo() && (evt.getPropertyName().equals("buildFileName"))) 
				connectBuildFileNameToTextField();
		}
		
		/**
		 * TextListener method
		 */
		public void textValueChanged(TextEvent e) {
			if (e.getSource() == VAJAntToolGUI.this.getBuildFileTextField()) 
				connectTextFieldToBuildFileName();
		}
		
		/**
		 * WindowListener methods
		 */
		public void windowClosing(WindowEvent e) {
			try {
				if (e.getSource() == VAJAntToolGUI.this) {
					dispose();
					System.exit(0);
				}
				if (e.getSource() == VAJAntToolGUI.this.getAboutDialog()) 
					getAboutDialog().dispose();
				if (e.getSource() == VAJAntToolGUI.this.getMessageFrame()) 
					getMessageFrame().dispose();
			}
			catch (Throwable exc) {
				handleException(exc);
			}
		}
		public void windowActivated(WindowEvent e) {};
		public void windowClosed(WindowEvent e) {};
		public void windowDeactivated(WindowEvent e) {};
		public void windowDeiconified(WindowEvent e) {};
		public void windowIconified(WindowEvent e) {};
		public void windowOpened(WindowEvent e) {};
	}
	
	/**
	 * AntMake default-constructor.
	 */
	private VAJAntToolGUI() {
		super();
		initialize();
	}
	/**
	 * AntMake constructor called by VAJAntTool integration.
	 * @param buildInfo VAJBuildInfo
	 */
	 
	public VAJAntToolGUI(VAJBuildInfo newBuildInfo) {
		super();
		setBuildInfo(newBuildInfo);
		initialize();
	}
	/**
	 * This method is used to center dialogs.
	 */
	public static void centerDialog(Dialog dialog) {
		dialog.setLocation((Toolkit.getDefaultToolkit().getScreenSize().width / 2) - (dialog.getSize().width / 2), (java.awt.Toolkit.getDefaultToolkit().getScreenSize().height / 2) - (dialog.getSize().height / 2));
	}
	/**
	 * connectBuildFileNameToTextField:  (BuildInfo.buildFileName <--> BuildFileTextField.text)
	 */
	private void connectBuildFileNameToTextField() {
		/* Set the target from the source */
		try {
			if (iConnPtoP2Aligning == false) {
				iConnPtoP2Aligning = true;
				if ((getBuildInfo() != null)) {
					getBuildFileTextField().setText(getBuildInfo().getBuildFileName());
				}
				iConnPtoP2Aligning = false;
			}
		} catch (Throwable iExc) {
			iConnPtoP2Aligning = false;
			handleException(iExc);
		}
	}
	/**
	 * connectProjectNameToLabel:  (BuildInfo.vajProjectName <--> ProjectText.text)
	 */
	private void connectProjectNameToLabel() {
		/* Set the target from the source */
		try {
			if ((getBuildInfo() != null)) {
				getProjectText().setText(getBuildInfo().getVAJProjectName());
			}
		} catch (Throwable iExc) {
			handleException(iExc);
		}
	}
	/**
	 * connectTextFieldToBuildFileName:  (BuildInfo.buildFileName <--> BuildFileTextField.text)
	 */
	private void connectTextFieldToBuildFileName() {
		/* Set the source from the target */
		try {
			if (iConnPtoP2Aligning == false) {
				iConnPtoP2Aligning = true;
				if ((getBuildInfo() != null)) {
					getBuildInfo().setBuildFileName(getBuildFileTextField().getText());
				}
				iConnPtoP2Aligning = false;
			}
		} catch (Throwable iExc) {
			iConnPtoP2Aligning = false;
			handleException(iExc);
		}
	}
	/**
	 * external build of a .jar-file
	 */
	private void executeTarget() {
		try	{
			getMessageFrame().show();
			// Chris: HACK: remove when Ant-Refactoring is finished!
			logger.buildStarted(null);
			getBuildInfo().executeProject(logger);
			// Chris: HACK: remove when Ant-Refactoring is finished!
			logger.buildSuccessful();			
		}
		catch (Throwable exc) {
			// We aren't interested in exceptions! All necessary information has been written to the logging-window!
			// Unfortunately ANT-Refactoring isn't done yet!
			// Chris: HACK: remove when Ant-Refactoring is finished!
			logger.buildFailed( exc );			
		}
		return;
	}
	/**
	 * Fills the taget-list with project-targets
	 */
	private void fillList() {
		getTargetList().removeAll();
		Vector targets = getBuildInfo().getProjectTargets();
		for (int i = 0;i < targets.size(); i++) {
			getTargetList().add(targets.elementAt(i).toString());
		}
		getTargetList().select(iBuildInfo.getProjectTargets().indexOf(iBuildInfo.getTarget()));
		if (getTargetList().getSelectedIndex() >= 0) {
			getBuildButton().setEnabled(true);
		}
	}
	/**
	 * Copied from DefaultLogger to provide the same time-format.
	 */
	public static String formatTime(long millis) {
		long seconds = millis / 1000;
		long minutes = seconds / 60;

		if (minutes > 0) {
			return Long.toString(minutes) + " minute"
				+ (minutes == 1 ? " " : "s ")
				+ Long.toString(seconds%60) + " second"
				+ (seconds%60 == 1 ? "" : "s");
		}
		else {
			return Long.toString(seconds) + " second"
				+ (seconds%60 == 1 ? "" : "s");
		}
	}
	/**
	 * Return the AboutCommandPanel property value.
	 * @return java.awt.Panel
	 */
	private Panel getAboutCommandPanel() {
		if (iAboutCommandPanel == null) {
			try {
				iAboutCommandPanel = new Panel();
				iAboutCommandPanel.setName("AboutCommandPanel");
				iAboutCommandPanel.setLayout(new java.awt.FlowLayout());
				getAboutCommandPanel().add(getAboutOkButton(), getAboutOkButton().getName());
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iAboutCommandPanel;
	}
	/**
	 * Return the AboutContactLabel property value.
	 * @return java.awt.Label
	 */
	private Label getAboutContactLabel() {
		if (iAboutContactLabel == null) {
			try {
				iAboutContactLabel = new Label();
				iAboutContactLabel.setName("AboutContactLabel");
				iAboutContactLabel.setAlignment(java.awt.Label.CENTER);
				iAboutContactLabel.setText("contact: wolf.siberski@tui.de or christoph.wilhelms@tui.de");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iAboutContactLabel;
	}
	/**
	 * Return the AboutDevLabel property value.
	 * @return java.awt.Label
	 */
	private Label getAboutDevLabel() {
		if (iAboutDevLabel == null) {
			try {
				iAboutDevLabel = new Label();
				iAboutDevLabel.setName("AboutDevLabel");
				iAboutDevLabel.setAlignment(java.awt.Label.CENTER);
				iAboutDevLabel.setText("developed by Wolf Siberski & Christoph Wilhelms");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iAboutDevLabel;
	}
	/**
	 * Return the AboutDialog property value.
	 * @return java.awt.Dialog
	 */
	private Dialog getAboutDialog() {
		if (iAboutDialog == null) {
			try {
				iAboutDialog = new Dialog(this);
				iAboutDialog.setName("AboutDialog");
				iAboutDialog.setResizable(false);
				iAboutDialog.setLayout(new java.awt.BorderLayout());
				iAboutDialog.setBounds(550, 14, 383, 142);
				iAboutDialog.setModal(true);
				iAboutDialog.setTitle("About...");
				getAboutDialog().add(getAboutDialogContentPanel(), "Center");
				iAboutDialog.pack();
				centerDialog(iAboutDialog);
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iAboutDialog;
	}
	/**
	 * Return the AboutDialogContentPanel property value.
	 * @return java.awt.Panel
	 */
	private Panel getAboutDialogContentPanel() {
		if (iAboutDialogContentPanel == null) {
			try {
				iAboutDialogContentPanel = new Panel();
				iAboutDialogContentPanel.setName("AboutDialogContentPanel");
				iAboutDialogContentPanel.setLayout(new java.awt.BorderLayout());
				getAboutDialogContentPanel().add(getAboutCommandPanel(), "South");
				getAboutDialogContentPanel().add(getAboutInfoPanel(), "Center");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iAboutDialogContentPanel;
	}
	/**
	 * Return the AboutInfoPanel property value.
	 * @return java.awt.Panel
	 */
	private Panel getAboutInfoPanel() {
		if (iAboutInfoPanel == null) {
			try {
				iAboutInfoPanel = new Panel();
				iAboutInfoPanel.setName("AboutInfoPanel");
				iAboutInfoPanel.setLayout(new GridBagLayout());

				GridBagConstraints constraintsAboutTitleLabel = new GridBagConstraints();
				constraintsAboutTitleLabel.gridx = 0; constraintsAboutTitleLabel.gridy = 0;
				constraintsAboutTitleLabel.fill = GridBagConstraints.HORIZONTAL;
				constraintsAboutTitleLabel.weightx = 1.0;
				constraintsAboutTitleLabel.weighty = 1.0;
				constraintsAboutTitleLabel.insets = new Insets(4, 0, 4, 0);
				getAboutInfoPanel().add(getAboutTitleLabel(), constraintsAboutTitleLabel);

				GridBagConstraints constraintsAboutDevLabel = new GridBagConstraints();
				constraintsAboutDevLabel.gridx = 0; constraintsAboutDevLabel.gridy = 1;
				constraintsAboutDevLabel.fill = GridBagConstraints.HORIZONTAL;
				constraintsAboutDevLabel.weightx = 1.0;
				constraintsAboutDevLabel.insets = new Insets(4, 0, 0, 0);
				getAboutInfoPanel().add(getAboutDevLabel(), constraintsAboutDevLabel);

				GridBagConstraints constraintsAboutContactLabel = new GridBagConstraints();
				constraintsAboutContactLabel.gridx = 0; constraintsAboutContactLabel.gridy = 2;
				constraintsAboutContactLabel.fill = GridBagConstraints.HORIZONTAL;
				constraintsAboutContactLabel.weightx = 1.0;
				constraintsAboutContactLabel.insets = new Insets(2, 0, 4, 0);
				getAboutInfoPanel().add(getAboutContactLabel(), constraintsAboutContactLabel);
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iAboutInfoPanel;
	}
	/**
	 * Return the AboutMenuItem property value.
	 * @return java.awt.MenuItem
	 */
	private MenuItem getAboutMenuItem() {
		if (iAboutMenuItem == null) {
			try {
				iAboutMenuItem = new MenuItem();
				iAboutMenuItem.setLabel("About...");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iAboutMenuItem;
	}
	/**
	 * Return the AboutOkButton property value.
	 * @return java.awt.Button
	 */
	private Button getAboutOkButton() {
		if (iAboutOkButton == null) {
			try {
				iAboutOkButton = new Button();
				iAboutOkButton.setName("AboutOkButton");
				iAboutOkButton.setLabel("OK");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iAboutOkButton;
	}
	/**
	 * Return the AboutTitleLabel property value.
	 * @return java.awt.Label
	 */
	private Label getAboutTitleLabel() {
		if (iAboutTitleLabel == null) {
			try {
				iAboutTitleLabel = new Label();
				iAboutTitleLabel.setName("AboutTitleLabel");
				iAboutTitleLabel.setFont(new Font("Arial", 1, 12));
				iAboutTitleLabel.setAlignment(Label.CENTER);
				iAboutTitleLabel.setText("Ant VisualAge for Java Tool-Integration");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iAboutTitleLabel;
	}
	/**
	 * Return the AntMakeMenuBar property value.
	 * @return java.awt.MenuBar
	 */
	private MenuBar getAntMakeMenuBar() {
		if (iAntMakeMenuBar == null) {
			try {
				iAntMakeMenuBar = new MenuBar();
				iAntMakeMenuBar.add(getFileMenu());
				iAntMakeMenuBar.add(getHelpMenu());
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iAntMakeMenuBar;
	}
	/**
	 * Return the BrowseButton property value.
	 * @return Button
	 */
	private Button getBrowseButton() {
		if (iBrowseButton == null) {
			try {
				iBrowseButton = new Button();
				iBrowseButton.setName("BrowseButton");
				iBrowseButton.setLabel("...");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iBrowseButton;
	}
	/**
	 * Return the BuildButton property value.
	 * @return java.awt.Button
	 */
	private Button getBuildButton() {
		if (iBuildButton == null) {
			try {
				iBuildButton = new Button();
				iBuildButton.setName("BuildButton");
				iBuildButton.setLabel("Build");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iBuildButton;
	}
	/**
	 * Return the BuildFileLabel property value.
	 * @return java.awt.Label
	 */
	private Label getBuildFileLabel() {
		if (iBuildFileLabel == null) {
			try {
				iBuildFileLabel = new Label();
				iBuildFileLabel.setName("BuildFileLabel");
				iBuildFileLabel.setText("Ant-Buildfile:");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iBuildFileLabel;
	}
	/**
	 * Return the BuildFileTextField property value.
	 * @return java.awt.TextField
	 */
	private TextField getBuildFileTextField() {
		if (iBuildFileTextField == null) {
			try {
				iBuildFileTextField = new TextField();
				iBuildFileTextField.setName("BuildFileTextField");
				iBuildFileTextField.setBackground(SystemColor.textHighlightText);
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iBuildFileTextField;
	}
	/**
	 * Return the BuildInfo property value.
	 * @return org.apache.tools.ant.taskdefs.optional.ide.VAJBuildInfo
	 */
	private VAJBuildInfo getBuildInfo() {
		return iBuildInfo;
	}
	/**
	 * Return the CloseButton property value.
	 * @return java.awt.Button
	 */
	private Button getCloseButton() {
		if (iCloseButton == null) {
			try {
				iCloseButton = new Button();
				iCloseButton.setName("CloseButton");
				iCloseButton.setLabel("Close");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iCloseButton;
	}
	/**
	 * Return the CommandButtonPanel property value.
	 * @return java.awt.Panel
	 */
	private Panel getCommandButtonPanel() {
		if (iCommandButtonPanel == null) {
			try {
				iCommandButtonPanel = new Panel();
				iCommandButtonPanel.setName("CommandButtonPanel");
				iCommandButtonPanel.setLayout(getCommandButtonPanelFlowLayout());
				iCommandButtonPanel.setBackground(SystemColor.control);
				iCommandButtonPanel.add(getReloadButton());
				getCommandButtonPanel().add(getBuildButton(), getBuildButton().getName());
				getCommandButtonPanel().add(getCloseButton(), getCloseButton().getName());
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iCommandButtonPanel;
	}
	/**
	 * Return the CommandButtonPanelFlowLayout property value.
	 * @return java.awt.FlowLayout
	 */
	private FlowLayout getCommandButtonPanelFlowLayout() {
		FlowLayout iCommandButtonPanelFlowLayout = null;
		try {
			/* Create part */
			iCommandButtonPanelFlowLayout = new FlowLayout();
			iCommandButtonPanelFlowLayout.setAlignment(FlowLayout.RIGHT);
		} catch (Throwable iExc) {
			handleException(iExc);
		};
		return iCommandButtonPanelFlowLayout;
	}
	/**
	 * Return the ContentsPane property value.
	 * @return java.awt.Panel
	 */
	private Panel getContentsPane() {
		if (iContentsPane == null) {
			try {
				iContentsPane = new Panel();
				iContentsPane.setName("ContentsPane");
				iContentsPane.setLayout(new BorderLayout());
				getContentsPane().add(getCommandButtonPanel(), "South");
				getContentsPane().add(getOptionenPanel(), "Center");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iContentsPane;
	}
	/**
	 * Return the FileDialog property value.
	 * @return java.awt.FileDialog
	 */
	private FileDialog getFileDialog() {
		if (iFileDialog == null) {
			try {
				iFileDialog = new FileDialog(this);
				iFileDialog.setName("FileDialog");
				iFileDialog.setLayout(null);
				centerDialog(iFileDialog);
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iFileDialog;
	}
	/**
	 * Return the FileMenu property value.
	 * @return java.awt.Menu
	 */
	private Menu getFileMenu() {
		if (iFileMenu == null) {
			try {
				iFileMenu = new Menu();
				iFileMenu.setLabel("File");
				iFileMenu.add(getSaveMenuItem());
				iFileMenu.add(getMenuSeparator());
				iFileMenu.add(getShowLogMenuItem());
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iFileMenu;
	}
	/**
	 * Return the HelpMenu property value.
	 * @return java.awt.Menu
	 */
	private Menu getHelpMenu() {
		if (iHelpMenu == null) {
			try {
				iHelpMenu = new Menu();
				iHelpMenu.setLabel("Help");
				iHelpMenu.add(getAboutMenuItem());
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iHelpMenu;
	}
	/**
	 * Return the MenuSeparator1 property value.
	 * @return java.awt.MenuItem
	 */
	private MenuItem getMenuSeparator() {
		if (iMenuSeparator == null) {
			try {
				iMenuSeparator = new MenuItem();
				iMenuSeparator.setLabel("-");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iMenuSeparator;
	}
	/**
	 * Return the MessageClearLogButton property value.
	 * @return java.awt.Button
	 */
	private Button getMessageClearLogButton() {
		if (iMessageClearLogButton == null) {
			try {
				iMessageClearLogButton = new Button();
				iMessageClearLogButton.setName("MessageClearLogButton");
				iMessageClearLogButton.setLabel("Clear Log");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iMessageClearLogButton;
	}
	/**
	 * Return the MessageCommandPanel property value.
	 * @return java.awt.Panel
	 */
	private Panel getMessageCommandPanel() {
		if (iMessageCommandPanel == null) {
			try {
				iMessageCommandPanel = new Panel();
				iMessageCommandPanel.setName("MessageCommandPanel");
				iMessageCommandPanel.setLayout(new FlowLayout());
				getMessageCommandPanel().add(getMessageClearLogButton(), getMessageClearLogButton().getName());
				getMessageCommandPanel().add(getMessageOkButton(), getMessageOkButton().getName());
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iMessageCommandPanel;
	}
	/**
	 * Return the MessageContentPanel property value.
	 * @return java.awt.Panel
	 */
	private Panel getMessageContentPanel() {
		if (iMessageContentPanel == null) {
			try {
				iMessageContentPanel = new Panel();
				iMessageContentPanel.setName("MessageContentPanel");
				iMessageContentPanel.setLayout(new BorderLayout());
				iMessageContentPanel.setBackground(SystemColor.control);
				getMessageContentPanel().add(getMessageTextArea(), "Center");
				getMessageContentPanel().add(getMessageCommandPanel(), "South");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iMessageContentPanel;
	}
	/**
	 * Return the MessageFrame property value.
	 * @return java.awt.Frame
	 */
	private Frame getMessageFrame() {
		if (iMessageFrame == null) {
			try {
				iMessageFrame = new Frame();
				iMessageFrame.setName("MessageFrame");
				iMessageFrame.setLayout(new BorderLayout());
				iMessageFrame.setBounds(0, 0, 750, 250);
				iMessageFrame.setTitle("Message Log");
				iMessageFrame.add(getMessageContentPanel(), "Center");
				iMessageFrame.setLocation((Toolkit.getDefaultToolkit().getScreenSize().width / 2) - (iMessageFrame.getSize().width / 2), (java.awt.Toolkit.getDefaultToolkit().getScreenSize().height / 2));
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iMessageFrame;
	}
	/**
	 * Return the MessageOkButton property value.
	 * @return java.awt.Button
	 */
	private Button getMessageOkButton() {
		if (iMessageOkButton == null) {
			try {
				iMessageOkButton = new Button();
				iMessageOkButton.setName("MessageOkButton");
				iMessageOkButton.setLabel("Close");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iMessageOkButton;
	}
	/**
	 * Return the MessageOutputLevelChoice property value.
	 * @return java.awt.Choice
	 */
	private Choice getMessageOutputLevelChoice() {
		if (iMessageOutputLevelChoice == null) {
			try {
				iMessageOutputLevelChoice = new Choice();
				iMessageOutputLevelChoice.setName("MessageOutputLevelChoice");
				iMessageOutputLevelChoice.add("Error");
				iMessageOutputLevelChoice.add("Warning");
				iMessageOutputLevelChoice.add("Info");
				iMessageOutputLevelChoice.add("Verbose");
				iMessageOutputLevelChoice.add("Debug");
				iMessageOutputLevelChoice.select(2);
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iMessageOutputLevelChoice;
	}
	/**
	 * Return the MessageOutputLevelLabel property value.
	 * @return java.awt.Label
	 */
	private Label getMessageOutputLevelLabel() {
		if (iMessageOutputLevelLabel == null) {
			try {
				iMessageOutputLevelLabel = new Label();
				iMessageOutputLevelLabel.setName("MessageOutputLevelLabel");
				iMessageOutputLevelLabel.setText("Message Level:");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iMessageOutputLevelLabel;
	}
	/**
	 * Return the MessageTextArea property value.
	 * @return java.awt.TextArea
	 */
	private TextArea getMessageTextArea() {
		if (iMessageTextArea == null) {
			try {
				iMessageTextArea = new TextArea();
				iMessageTextArea.setName("MessageTextArea");
				iMessageTextArea.setFont(new Font("monospaced", 0, 12));
				iMessageTextArea.setText("");
				iMessageTextArea.setEditable(false);
				iMessageTextArea.setEnabled(true);
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iMessageTextArea;
	}
	/**
	 * Return the Panel1 property value.
	 * @return java.awt.Panel
	 */
	private Panel getOptionenPanel() {
		if (iOptionenPanel == null) {
			try {
				iOptionenPanel = new Panel();
				iOptionenPanel.setName("OptionenPanel");
				iOptionenPanel.setLayout(new GridBagLayout());
				iOptionenPanel.setBackground(SystemColor.control);

				GridBagConstraints constraintsProjectLabel = new GridBagConstraints();
				constraintsProjectLabel.gridx = 0; constraintsProjectLabel.gridy = 0;
				constraintsProjectLabel.anchor = GridBagConstraints.WEST;
				constraintsProjectLabel.insets = new Insets(4, 4, 4, 4);
				getOptionenPanel().add(getProjectLabel(), constraintsProjectLabel);

				GridBagConstraints constraintsBuildFileLabel = new GridBagConstraints();
				constraintsBuildFileLabel.gridx = 0; constraintsBuildFileLabel.gridy = 1;
				constraintsBuildFileLabel.anchor = GridBagConstraints.WEST;
				constraintsBuildFileLabel.insets = new Insets(4, 4, 4, 4);
				getOptionenPanel().add(getBuildFileLabel(), constraintsBuildFileLabel);

				GridBagConstraints constraintsTargetLabel = new GridBagConstraints();
				constraintsTargetLabel.gridx = 0; constraintsTargetLabel.gridy = 2;
				constraintsTargetLabel.anchor = GridBagConstraints.NORTHWEST;
				constraintsTargetLabel.insets = new Insets(4, 4, 4, 4);
				getOptionenPanel().add(getTargetLabel(), constraintsTargetLabel);

				GridBagConstraints constraintsProjectText = new GridBagConstraints();
				constraintsProjectText.gridx = 1; constraintsProjectText.gridy = 0;
				constraintsProjectText.gridwidth = 2;
				constraintsProjectText.fill = GridBagConstraints.HORIZONTAL;
				constraintsProjectText.anchor = GridBagConstraints.WEST;
				constraintsProjectText.insets = new Insets(4, 4, 4, 4);
				getOptionenPanel().add(getProjectText(), constraintsProjectText);

				GridBagConstraints constraintsBuildFileTextField = new GridBagConstraints();
				constraintsBuildFileTextField.gridx = 1; constraintsBuildFileTextField.gridy = 1;
				constraintsBuildFileTextField.fill = GridBagConstraints.HORIZONTAL;
				constraintsBuildFileTextField.anchor = GridBagConstraints.WEST;
				constraintsBuildFileTextField.weightx = 1.0;
				constraintsBuildFileTextField.insets = new Insets(4, 4, 4, 4);
				getOptionenPanel().add(getBuildFileTextField(), constraintsBuildFileTextField);

				GridBagConstraints constraintsBrowseButton = new GridBagConstraints();
				constraintsBrowseButton.gridx = 2; constraintsBrowseButton.gridy = 1;
				constraintsBrowseButton.insets = new Insets(4, 4, 4, 4);
				getOptionenPanel().add(getBrowseButton(), constraintsBrowseButton);

				GridBagConstraints constraintsTargetList = new GridBagConstraints();
				constraintsTargetList.gridx = 1; constraintsTargetList.gridy = 2;
				constraintsTargetList.gridheight = 2;
				constraintsTargetList.fill = GridBagConstraints.BOTH;
				constraintsTargetList.weightx = 1.0;
				constraintsTargetList.weighty = 1.0;
				constraintsTargetList.insets = new Insets(4, 4, 4, 4);
				getOptionenPanel().add(getTargetList(), constraintsTargetList);

				GridBagConstraints constraintsMessageOutputLevelLabel = new GridBagConstraints();
				constraintsMessageOutputLevelLabel.gridx = 0; constraintsMessageOutputLevelLabel.gridy = 4;
				constraintsMessageOutputLevelLabel.anchor = GridBagConstraints.WEST;
				constraintsMessageOutputLevelLabel.insets = new Insets(4, 4, 4, 4);
				getOptionenPanel().add(getMessageOutputLevelLabel(), constraintsMessageOutputLevelLabel);

				GridBagConstraints constraintsMessageOutputLevelChoice = new GridBagConstraints();
				constraintsMessageOutputLevelChoice.gridx = 1; constraintsMessageOutputLevelChoice.gridy = 4;
				constraintsMessageOutputLevelChoice.fill = GridBagConstraints.HORIZONTAL;
				constraintsMessageOutputLevelChoice.anchor = GridBagConstraints.WEST;
				constraintsMessageOutputLevelChoice.weightx = 1.0;
				constraintsMessageOutputLevelChoice.insets = new Insets(4, 4, 4, 4);
				getOptionenPanel().add(getMessageOutputLevelChoice(), constraintsMessageOutputLevelChoice);
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iOptionenPanel;
	}
	/**
	 * Return the ProjectLabel property value.
	 * @return java.awt.Label
	 */
	private Label getProjectLabel() {
		if (iProjectLabel == null) {
			try {
				iProjectLabel = new Label();
				iProjectLabel.setName("ProjectLabel");
				iProjectLabel.setText("Projectname:");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iProjectLabel;
	}
	/**
	 * Return the ProjectText property value.
	 * @return java.awt.Label
	 */
	private Label getProjectText() {
		if (iProjectText == null) {
			try {
				iProjectText = new Label();
				iProjectText.setName("ProjectText");
				iProjectText.setText(" ");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iProjectText;
	}
	/**
	 * Return the ReloadButton property value.
	 * @return java.awt.Button
	 */
	private Button getReloadButton() {
		if (iReloadButton == null) {
			try {
				iReloadButton = new Button();
				iReloadButton.setName("ReloadButton");
				iReloadButton.setLabel("(Re)Load");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iReloadButton;
	}
	/**
	 * Return the SaveMenuItem property value.
	 * @return java.awt.MenuItem
	 */
	private MenuItem getSaveMenuItem() {
		if (iSaveMenuItem == null) {
			try {
				iSaveMenuItem = new MenuItem();
				iSaveMenuItem.setLabel("Save BuildInfo To Repository");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iSaveMenuItem;
	}
	/**
	 * Return the ShowLogMenuItem property value.
	 * @return java.awt.MenuItem
	 */
	private MenuItem getShowLogMenuItem() {
		if (iShowLogMenuItem == null) {
			try {
				iShowLogMenuItem = new MenuItem();
				iShowLogMenuItem.setLabel("Log");
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iShowLogMenuItem;
	}
	/**
	 * Return the TargetLabel property value.
	 * @return java.awt.Label
	 */
	private Label getTargetLabel() {
		if (iTargetLabel == null) {
			try {
				iTargetLabel = new Label();
				iTargetLabel.setName("TargetLabel");
				iTargetLabel.setText("Target:");
				iTargetLabel.setEnabled(true);
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iTargetLabel;
	}
	/**
	 * Return the TargetList property value.
	 * @return java.awt.List
	 */
	private List getTargetList() {
		if (iTargetList == null) {
			try {
				iTargetList = new List();
				iTargetList.setName("TargetList");
				iTargetList.setEnabled(true);
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
		return iTargetList;
	}
	/**
	 * Called whenever the part throws an exception.
	 * @param exception Throwable
	 */
	private void handleException(Throwable exception) {
		// Write exceptions to the log-window
		getMessageTextArea().append(lineSeparator + lineSeparator + exception.getMessage());
		getMessageFrame().show();
		
	}
	/**
	 * Initializes connections
	 * @exception Exception The exception description.
	 */
	private void initConnections() throws Exception {
		this.addWindowListener(iEventHandler);
		getBrowseButton().addActionListener(iEventHandler);
		getCloseButton().addActionListener(iEventHandler);
		getBuildButton().addActionListener(iEventHandler);
		getSaveMenuItem().addActionListener(iEventHandler);
		getAboutOkButton().addActionListener(iEventHandler);
		getAboutMenuItem().addActionListener(iEventHandler);
		getMessageOkButton().addActionListener(iEventHandler);
		getMessageClearLogButton().addActionListener(iEventHandler);
		getMessageOkButton().addActionListener(iEventHandler);
		getShowLogMenuItem().addActionListener(iEventHandler);
		getAboutDialog().addWindowListener(iEventHandler);
		getMessageFrame().addWindowListener(iEventHandler);
		getReloadButton().addActionListener(iEventHandler);
		getTargetList().addItemListener(iEventHandler);
		getMessageOutputLevelChoice().addItemListener(iEventHandler);
		getBuildFileTextField().addTextListener(iEventHandler);
		connectProjectNameToLabel();
		connectBuildFileNameToTextField();
	}
	/**
	 * Initialize the class.
	 */
	private void initialize() {
		try {
			setName("AntMake");
			setMenuBar(getAntMakeMenuBar());
			setLayout(new java.awt.BorderLayout());
			setSize(389, 222);
			setTitle("Ant VisualAge for Java Tool-Integration");
			add(getContentsPane(), "Center");
			initConnections();
		} catch (Throwable iExc) {
			handleException(iExc);
		}
		setLocation((Toolkit.getDefaultToolkit().getScreenSize().width / 2) - (getSize().width / 2), (java.awt.Toolkit.getDefaultToolkit().getScreenSize().height / 2) - (getSize().height));
		if ((getTargetList().getItemCount() == 0) || (getTargetList().getSelectedIndex() < 0)) {
			getBuildButton().setEnabled(false);
		}
	}
	/**
	 * Saves the build-informations to repository
	 */
	private void saveBuildInfo() {
		try {
			VAJAntTool.saveBuildData(getBuildInfo());
		}
		catch (Throwable exc) {
			// This Exception occurs when you try to write into a versioned project
			handleException( exc );
		}
		return;
	}
	/**
	 * Set the BuildInfo to a new value.
	 * @param newValue org.apache.tools.ant.taskdefs.optional.vaj.VAJBuildInfo
	 */
	private void setBuildInfo(VAJBuildInfo newValue) {
		if (iBuildInfo != newValue) {
			try {
				/* Stop listening for events from the current object */
				if (iBuildInfo != null) {
					iBuildInfo.removePropertyChangeListener(iEventHandler);
				}
				iBuildInfo = newValue;

				/* Listen for events from the new object */
				if (iBuildInfo != null) {
					iBuildInfo.addPropertyChangeListener(iEventHandler);
				}
				connectProjectNameToLabel();
				connectBuildFileNameToTextField();

				// Select the log-level given by BuildInfo
				getMessageOutputLevelChoice().select(iBuildInfo.getOutputMessageLevel());
				fillList();
				// BuildInfo can conly be saved to a VAJ project if tool API is called via the projects context-menu
				if ((iBuildInfo.getVAJProjectName() == null) || (iBuildInfo.getVAJProjectName().equals(""))) {
					getSaveMenuItem().setEnabled(false);
				}
			} catch (Throwable iExc) {
				handleException(iExc);
			}
		}
	}
}
