package org.eclipse.ant.internal.ui;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */

import java.net.*;
import java.util.*;import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.*;import org.eclipse.jface.dialogs.ErrorDialog;import org.eclipse.jface.preference.IPreferenceStore;import org.eclipse.jface.preference.PreferenceConverter;import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Font;import org.eclipse.swt.graphics.RGB;import org.eclipse.ui.plugin.AbstractUIPlugin;

/**
 * The plug-in runtime class for the AntUI plug-in.
 */
public final class AntUIPlugin extends AbstractUIPlugin{

	/**
	 * Unique identifier constant (value <code>"org.eclipse.ant.ui"</code>)
	 * for the Ant UI plug-in.
	 */
	public static final String PI_ANTUI= "org.eclipse.ant.ui";
	
	public static final String PROPERTIES_MESSAGES = "org.eclipse.ant.internal.ui.messages";
	
	private static final String ANT_ICON_RELATIVE_PATH = "icons/basic/cview/ant_view.gif";
	
	/**
	 * The single instance of this plug-in runtime class.
	 */
	private static AntUIPlugin plugin;
	
	private final static int MAX_HISTORY_SIZE= 5;
	/**
	 * The most recent debug launches
	 */
	private IFile[] antHistory = new IFile[MAX_HISTORY_SIZE];
	

public AntUIPlugin(IPluginDescriptor desc) {
	super(desc);
	plugin= this;
}

public static AntUIPlugin getPlugin() {
	return plugin;
}

public static ResourceBundle getResourceBundle() {
	try {
		return ResourceBundle.getBundle(PROPERTIES_MESSAGES);
	} catch (MissingResourceException e) {
		ErrorDialog.openError(
			plugin.getWorkbench().getActiveWorkbenchWindow().getShell(),
			Policy.bind("exception.missingResourceBundle"),
			Policy.bind("exception.missingResourceBundle.message"),
			new Status(IStatus.ERROR,PI_ANTUI,0,Policy.bind("exception.missingResourceBundle.message"),e));
		return null;
	}
}

/**
 * Adds the given file to the history: 
 * - if the file doesn't exist: put it at the first place
 * - if it exists and is already at the first place: does nothing
 * - if it exists and is not at the first place: move it to the first place
 * 
 * @param the file
 */
public void addToHistory(IFile file) {
	if (file.equals(antHistory[0]))
		return;
		
	int index;
	for (index=1; index<MAX_HISTORY_SIZE; index++)
		if (file.equals(antHistory[index]))
			break;
	if (index == MAX_HISTORY_SIZE)
		index--;
	for (int i=index; i>0; i--)
		antHistory[i] = antHistory[i-1];
	antHistory[0] = file;	
}

/**
 * Returns the history of the AntPlugin, i.e. the files that were executed previously
 * 
 * @return an array containing the files
 */
public IFile[] getHistory() {
	return antHistory;	
}

/**
 * Returns the ImageDescriptor for the Ant icon.
 * 
 * @return the ImageDescriptor object
 */
ImageDescriptor getAntIconImageDescriptor() {
	try {
		URL installURL = getDescriptor().getInstallURL();
		URL url = new URL(installURL,ANT_ICON_RELATIVE_PATH);
		return ImageDescriptor.createFromURL(url);
	} catch (MalformedURLException e) {
		return null;
	}
}

/**
 * @see AbstractUIPlugin#initializeDefaultPreferences
 */
protected void initializeDefaultPreferences(IPreferenceStore prefs) {
	prefs.setDefault(IAntPreferenceConstants.AUTO_SAVE, false);
	prefs.setDefault(IAntPreferenceConstants.INFO_LEVEL, true);
	prefs.setDefault(IAntPreferenceConstants.VERBOSE_LEVEL, false);
	prefs.setDefault(IAntPreferenceConstants.DEBUG_LEVEL, false);

	PreferenceConverter.setDefault(prefs, IAntPreferenceConstants.CONSOLE_ERROR_RGB, new RGB(255, 0, 0)); 		// red - exactly the same as debug Consol
	PreferenceConverter.setDefault(prefs, IAntPreferenceConstants.CONSOLE_WARNING_RGB, new RGB(255, 100, 0)); 	// orange
	PreferenceConverter.setDefault(prefs, IAntPreferenceConstants.CONSOLE_INFO_RGB, new RGB(0, 0, 255)); 		// blue
	PreferenceConverter.setDefault(prefs, IAntPreferenceConstants.CONSOLE_VERBOSE_RGB, new RGB(0, 200, 125));	// green
	PreferenceConverter.setDefault(prefs, IAntPreferenceConstants.CONSOLE_DEBUG_RGB, new RGB(0, 0, 0));			// black
	
}

}
