/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.examples.imageanalyzer;


import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.printing.*;
import org.eclipse.swt.custom.*;
import java.util.*;
import java.net.*;
import java.io.*;
import java.text.MessageFormat;

public class ImageAnalyzer {
	static ResourceBundle bundle = ResourceBundle.getBundle("examples_images");
	Display display;
	Shell shell;
	Canvas imageCanvas, paletteCanvas;
	Label typeLabel, sizeLabel, depthLabel, transparentPixelLabel,
		timeToLoadLabel, screenSizeLabel, backgroundPixelLabel,
		locationLabel, disposalMethodLabel, delayTimeLabel,
		repeatCountLabel, paletteLabel, dataLabel, statusLabel;
	Combo backgroundCombo, scaleXCombo, scaleYCombo, alphaCombo;
	Button incrementalCheck, transparentCheck, maskCheck, backgroundCheck;
	Button previousButton, nextButton, animateButton;
	StyledText dataText;
	Sash sash;
	Color whiteColor, blackColor, redColor, greenColor, blueColor, canvasBackground;
	Font fixedWidthFont;
	Cursor crossCursor;
	GC imageCanvasGC;
	
	int paletteWidth = 140; // recalculated and used as a width hint
	int ix = 0, iy = 0, py = 0; // used to scroll the image and palette
	float xscale = 1, yscale = 1; // used to scale the image
	int alpha = 255; // used to modify the alpha value of the image
	boolean incremental = false; // used to incrementally display an image
	boolean transparent = true; // used to display an image with transparency
	boolean showMask = false; // used to display an icon mask or transparent image mask
	boolean showBackground = false; // used to display the background of an animated image
	boolean animate = false; // used to animate a multi-image file
	Thread animateThread; // draws animated images
	Thread incrementalThread; // draws incremental images
	String lastPath; // used to seed the file dialog
	String currentName; // the current image file or URL name
	String fileName; // the current image file
	ImageLoader loader; // the loader for the current image file
	ImageData[] imageDataArray; // all image data read from the current file
	int imageDataIndex; // the index of the current image data
	ImageData imageData; // the currently-displayed image data
	Image image; // the currently-displayed image
	Vector incrementalEvents; // incremental image events
	long loadTime = 0; // the time it took to load the current image
	
	static final int INDEX_DIGITS = 4;
	static final int ALPHA_CONSTANT = 0;
	static final int ALPHA_X = 1;
	static final int ALPHA_Y = 2;

	class TextPrompter extends Dialog {
		String message = "";
		String result = null;
		Shell dialog;
		Text text;
		public TextPrompter (Shell parent, int style) {
			super (parent, style);
		}
		public TextPrompter (Shell parent) {
			this (parent, SWT.APPLICATION_MODAL);
		}
		public String getMessage () {
			return message;
		}
		public void setMessage (String string) {
			message = string;
		}
		public String open () {
			dialog = new Shell(getParent(), getStyle());
			dialog.setText(getText());
			dialog.setLayout(new GridLayout());
			Label label = new Label(dialog, SWT.NULL);
			label.setText(message);
			label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			text = new Text(dialog, SWT.SINGLE | SWT.BORDER);
			GridData data = new GridData(GridData.FILL_HORIZONTAL);
			data.widthHint = 300;
			text.setLayoutData(data);
			Composite buttons = new Composite(dialog, SWT.NONE);
			GridLayout grid = new GridLayout();
			grid.numColumns = 2;
			buttons.setLayout(grid);
			buttons.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
			Button ok = new Button(buttons, SWT.PUSH);
			ok.setText(bundle.getString("OK"));
			data = new GridData();
			data.widthHint = 75;
			ok.setLayoutData(data);
			ok.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					result = text.getText();
					dialog.dispose();
				}
			});
			Button cancel = new Button(buttons, SWT.PUSH);
			cancel.setText(bundle.getString("Cancel"));
			data = new GridData();
			data.widthHint = 75;
			cancel.setLayoutData(data);
			cancel.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					dialog.dispose();
				}
			});
			dialog.setDefaultButton(ok);
			dialog.pack();
			dialog.open();
			while (!dialog.isDisposed()) {
				if (!display.readAndDispatch()) display.sleep();
			}
			return result;
		}
	}

	public static void main(String [] args) {
		Display display = new Display();
		ImageAnalyzer imageAnalyzer = new ImageAnalyzer();
		Shell shell = imageAnalyzer.open(display);
		
		while (!shell.isDisposed())
			if (!display.readAndDispatch()) display.sleep();
		display.dispose();
	}

	public Shell open(Display dpy) {
		// Create a window and set its title.
		this.display = dpy;
		shell = new Shell(display);
		shell.setText(bundle.getString("Image_analyzer"));
		
		// Hook resize and dispose listeners.
		shell.addControlListener(new ControlAdapter() {
			public void controlResized(ControlEvent event) {
				resizeShell(event);
			}
		});
		shell.addShellListener(new ShellAdapter() {
			public void shellClosed(ShellEvent e) {
				animate = false; // stop any animation in progress
				if (animateThread != null) {
					// wait for the thread to die before disposing the shell.
					while (animateThread.isAlive()) {
						if (!display.readAndDispatch()) display.sleep();
					}
				}
				e.doit = true;
			}
		});
		shell.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				// Clean up.
				if (image != null)
					image.dispose();
				whiteColor.dispose();
				blackColor.dispose();
				redColor.dispose();
				greenColor.dispose();
				blueColor.dispose();
				fixedWidthFont.dispose();
				crossCursor.dispose();
			}
		});

		// Create colors and fonts.
		whiteColor = new Color(display, 255, 255, 255);
		blackColor = new Color(display, 0, 0, 0);
		redColor = new Color(display, 255, 0, 0);
		greenColor = new Color(display, 0, 255, 0);
		blueColor = new Color(display, 0, 0, 255);
		fixedWidthFont = new Font(display, "courier", 10, 0);
		crossCursor = new Cursor(display, SWT.CURSOR_CROSS);
		
		// Add a menu bar and widgets.
		createMenuBar();
		createWidgets();
		shell.pack();
		
		// Create a GC for drawing, and hook the listener to dispose it.
		imageCanvasGC = new GC(imageCanvas);
		imageCanvas.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				imageCanvasGC.dispose();
			}
		});
		
		// Open the window
		shell.open();
		return shell;
	}

	void createWidgets() {
		// Add the widgets to the shell in a grid layout.
		GridLayout layout = new GridLayout();
		layout.marginHeight = 0;
		layout.numColumns = 2;
		shell.setLayout(layout);

		// Separate the menu bar from the rest of the widgets.
		Label separator = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
		GridData gridData = new GridData();
		gridData.horizontalSpan = 2;
		gridData.horizontalAlignment = GridData.FILL;
		separator.setLayoutData(gridData);
		
		// Add a composite to contain some control widgets across the top.
		Composite controls = new Composite(shell, SWT.NULL);
		RowLayout rowLayout = new RowLayout();
		rowLayout.marginTop = 0;
		rowLayout.marginBottom = 5;
		rowLayout.spacing = 8;
		controls.setLayout(rowLayout);
		gridData = new GridData();
		gridData.horizontalSpan = 2;
		controls.setLayoutData(gridData);
		
		// Combo to change the background.
		Group group = new Group(controls, SWT.NULL);
		group.setLayout(new RowLayout());
		group.setText(bundle.getString("Background"));
		backgroundCombo = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY);
		backgroundCombo.setItems(new String[] {
			bundle.getString("None"),
			bundle.getString("White"),
			bundle.getString("Black"),
			bundle.getString("Red"),
			bundle.getString("Green"),
			bundle.getString("Blue")});
		backgroundCombo.select(backgroundCombo.indexOf(bundle.getString("White")));
		backgroundCombo.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				changeBackground();
			}
		});
		
		// Combo to change the x scale.
		String[] values = {
			"0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "1",
			"1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "2",
			"3", "4", "5", "6", "7", "8", "9", "10",};
		group = new Group(controls, SWT.NULL);
		group.setLayout(new RowLayout());
		group.setText(bundle.getString("X_scale"));
		scaleXCombo = new Combo(group, SWT.DROP_DOWN);
		for (int i = 0; i < values.length; i++) {
			scaleXCombo.add(values[i]);
		}
		scaleXCombo.select(scaleXCombo.indexOf("1"));
		scaleXCombo.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				scaleX();
			}
		});
		
		// Combo to change the y scale.
		group = new Group(controls, SWT.NULL);
		group.setLayout(new RowLayout());
		group.setText(bundle.getString("Y_scale"));
		scaleYCombo = new Combo(group, SWT.DROP_DOWN);
		for (int i = 0; i < values.length; i++) {
			scaleYCombo.add(values[i]);
		}
		scaleYCombo.select(scaleYCombo.indexOf("1"));
		scaleYCombo.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				scaleY();
			}
		});
		
		// Combo to change the alpha value.
		group = new Group(controls, SWT.NULL);
		group.setLayout(new RowLayout());
		group.setText(bundle.getString("Alpha_K"));
		alphaCombo = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY);
		for (int i = 0; i <= 255; i += 5) {
			alphaCombo.add(String.valueOf(i));
		}
		alphaCombo.select(alphaCombo.indexOf("255"));
		alphaCombo.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				alpha();
			}
		});
		
		// Check box to request incremental display.
		group = new Group(controls, SWT.NULL);
		group.setLayout(new RowLayout());
		group.setText(bundle.getString("Display"));
		incrementalCheck = new Button(group, SWT.CHECK);
		incrementalCheck.setText(bundle.getString("Incremental"));
		incrementalCheck.setSelection(incremental);
		incrementalCheck.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				incremental = ((Button)event.widget).getSelection();
			}
		});

		// Check box to request transparent display.
		transparentCheck = new Button(group, SWT.CHECK);
		transparentCheck.setText(bundle.getString("Transparent"));
		transparentCheck.setSelection(transparent);
		transparentCheck.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				transparent = ((Button)event.widget).getSelection();
				if (image != null) {
					imageCanvas.redraw();
				}
			}
		});

		// Check box to request mask display.
		maskCheck = new Button(group, SWT.CHECK);
		maskCheck.setText(bundle.getString("Mask"));
		maskCheck.setSelection(showMask);
		maskCheck.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				showMask = ((Button)event.widget).getSelection();
				if (image != null) {
					imageCanvas.redraw();
				}
			}
		});

		// Check box to request background display.
		backgroundCheck = new Button(group, SWT.CHECK);
		backgroundCheck.setText(bundle.getString("Background"));
		backgroundCheck.setSelection(showBackground);
		backgroundCheck.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				showBackground = ((Button)event.widget).getSelection();
			}
		});

		// Group the animation buttons.
		group = new Group(controls, SWT.NULL);
		group.setLayout(new RowLayout());
		group.setText(bundle.getString("Animation"));

		// Push button to display the previous image in a multi-image file.
		previousButton = new Button(group, SWT.PUSH);
		previousButton.setText(bundle.getString("Previous"));
		previousButton.setEnabled(false);
		previousButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				previous();
			}
		});

		// Push button to display the next image in a multi-image file.
		nextButton = new Button(group, SWT.PUSH);
		nextButton.setText(bundle.getString("Next"));
		nextButton.setEnabled(false);
		nextButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				next();
			}
		});

		// Push button to toggle animation of a multi-image file.
		animateButton = new Button(group, SWT.PUSH);
		animateButton.setText(bundle.getString("Animate"));
		animateButton.setEnabled(false);
		animateButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				animate();
			}
		});

		// Label to show the image file type.
		typeLabel = new Label(shell, SWT.NULL);
		typeLabel.setText(bundle.getString("Type_initial"));
		typeLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		// Canvas to show the image.
		imageCanvas = new Canvas(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.NO_REDRAW_RESIZE);
		imageCanvas.setBackground(whiteColor);
		imageCanvas.setCursor(crossCursor);
		gridData = new GridData();
		gridData.verticalSpan = 15;
		gridData.horizontalAlignment = GridData.FILL;
		gridData.verticalAlignment = GridData.FILL;
		gridData.grabExcessHorizontalSpace = true;
		gridData.grabExcessVerticalSpace = true;
		imageCanvas.setLayoutData(gridData);
		imageCanvas.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent event) {
				if (image != null)
					paintImage(event);
			}
		});
		imageCanvas.addMouseMoveListener(new MouseMoveListener() {
			public void mouseMove(MouseEvent event) {
				if (image != null) {
					showColorAt(event.x, event.y);
				}
			}
		});

		// Set up the image canvas scroll bars.
		ScrollBar horizontal = imageCanvas.getHorizontalBar();
		horizontal.setVisible(true);
		horizontal.setMinimum(0);
		horizontal.setEnabled(false);
		horizontal.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				scrollHorizontally((ScrollBar)event.widget);
			}
		});
		ScrollBar vertical = imageCanvas.getVerticalBar();
		vertical.setVisible(true);
		vertical.setMinimum(0);
		vertical.setEnabled(false);
		vertical.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				scrollVertically((ScrollBar)event.widget);
			}
		});

		// Label to show the image size.
		sizeLabel = new Label(shell, SWT.NULL);
		sizeLabel.setText(bundle.getString("Size_initial"));
		sizeLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		// Label to show the image depth.
		depthLabel = new Label(shell, SWT.NULL);
		depthLabel.setText(bundle.getString("Depth_initial"));
		depthLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		// Label to show the transparent pixel.
		transparentPixelLabel = new Label(shell, SWT.NULL);
		transparentPixelLabel.setText(bundle.getString("Transparent_pixel_initial"));
		transparentPixelLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		// Label to show the time to load.
		timeToLoadLabel = new Label(shell, SWT.NULL);
		timeToLoadLabel.setText(bundle.getString("Time_to_load_initial"));
		timeToLoadLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		// Separate the animation fields from the rest of the fields.
		separator = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
		separator.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		// Label to show the logical screen size for animation.
		screenSizeLabel = new Label(shell, SWT.NULL);
		screenSizeLabel.setText(bundle.getString("Animation_size_initial"));
		screenSizeLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		// Label to show the background pixel.
		backgroundPixelLabel = new Label(shell, SWT.NULL);
		backgroundPixelLabel.setText(bundle.getString("Background_pixel_initial"));
		backgroundPixelLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		// Label to show the image location (x, y).
		locationLabel = new Label(shell, SWT.NULL);
		locationLabel.setText(bundle.getString("Image_location_initial"));
		locationLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		// Label to show the image disposal method.
		disposalMethodLabel = new Label(shell, SWT.NULL);
		disposalMethodLabel.setText(bundle.getString("Disposal_initial"));
		disposalMethodLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		// Label to show the image delay time.
		delayTimeLabel = new Label(shell, SWT.NULL);
		delayTimeLabel.setText(bundle.getString("Delay_initial"));
		delayTimeLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		// Label to show the background pixel.
		repeatCountLabel = new Label(shell, SWT.NULL);
		repeatCountLabel.setText(bundle.getString("Repeats_initial"));
		repeatCountLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		// Separate the animation fields from the palette.
		separator = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
		separator.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		// Label to show if the image has a direct or indexed palette.
		paletteLabel = new Label(shell, SWT.NULL);
		paletteLabel.setText(bundle.getString("Palette_initial"));
		paletteLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		// Canvas to show the image's palette.
		paletteCanvas = new Canvas(shell, SWT.BORDER | SWT.V_SCROLL | SWT.NO_REDRAW_RESIZE);
		paletteCanvas.setFont(fixedWidthFont);
		paletteCanvas.getVerticalBar().setVisible(true);
		gridData = new GridData();
		gridData.horizontalAlignment = GridData.FILL;
		gridData.verticalAlignment = GridData.FILL;
		GC gc = new GC(paletteLabel);
		paletteWidth = gc.stringExtent(bundle.getString("Max_length_string")).x;
		gc.dispose();
		gridData.widthHint = paletteWidth;
		gridData.heightHint = 16 * 11; // show at least 16 colors
		paletteCanvas.setLayoutData(gridData);
		paletteCanvas.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent event) {
				if (image != null)
					paintPalette(event);
			}
		});

		// Set up the palette canvas scroll bar.
		vertical = paletteCanvas.getVerticalBar();
		vertical.setVisible(true);
		vertical.setMinimum(0);
		vertical.setIncrement(10);
		vertical.setEnabled(false);
		vertical.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				scrollPalette((ScrollBar)event.widget);
			}
		});

		// Sash to see more of image or image data.
		sash = new Sash(shell, SWT.HORIZONTAL);
		gridData = new GridData();
		gridData.horizontalSpan = 2;
		gridData.horizontalAlignment = GridData.FILL;
		sash.setLayoutData(gridData);
		sash.addSelectionListener (new SelectionAdapter () {
			public void widgetSelected (SelectionEvent event) {
				if (event.detail != SWT.DRAG) {
					((GridData)paletteCanvas.getLayoutData()).heightHint = SWT.DEFAULT;
					Rectangle paletteCanvasBounds = paletteCanvas.getBounds();
					int minY = paletteCanvasBounds.y + 20;
					Rectangle dataLabelBounds = dataLabel.getBounds();
					int maxY = statusLabel.getBounds().y - dataLabelBounds.height - 20;
					if (event.y > minY && event.y < maxY) {
						Rectangle oldSash = sash.getBounds();
						sash.setBounds(event.x, event.y, event.width, event.height);
						int diff = event.y - oldSash.y;
						Rectangle bounds = imageCanvas.getBounds();
						imageCanvas.setBounds(bounds.x, bounds.y, bounds.width, bounds.height + diff);
						bounds = paletteCanvasBounds;
						paletteCanvas.setBounds(bounds.x, bounds.y, bounds.width, bounds.height + diff);
						bounds = dataLabelBounds;
						dataLabel.setBounds(bounds.x, bounds.y + diff, bounds.width, bounds.height);
						bounds = dataText.getBounds();
						dataText.setBounds(bounds.x, bounds.y + diff, bounds.width, bounds.height - diff);
						//shell.layout(true);
					}
				}
			}
		});

		// Label to show data-specific fields.
		dataLabel = new Label(shell, SWT.NULL);
		dataLabel.setText(bundle.getString("Pixel_data_initial"));
		gridData = new GridData();
		gridData.horizontalSpan = 2;
		gridData.horizontalAlignment = GridData.FILL;
		dataLabel.setLayoutData(gridData);
		
		// Text to show a dump of the data.
		dataText = new StyledText(shell, SWT.BORDER | SWT.MULTI | SWT.READ_ONLY | SWT.V_SCROLL | SWT.H_SCROLL);
		dataText.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
		dataText.setFont(fixedWidthFont);
		gridData = new GridData();
		gridData.horizontalSpan = 2;
		gridData.horizontalAlignment = GridData.FILL;
		gridData.verticalAlignment = GridData.FILL;
		gridData.heightHint = 128;
		gridData.grabExcessVerticalSpace = true;
		dataText.setLayoutData(gridData);
		dataText.addMouseListener(new MouseAdapter() {
			public void mouseDown(MouseEvent event) {
				if (image != null && event.button == 1) {
					showColorForData();
				}
			}
		});
		dataText.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent event) {
				if (image != null) {
					showColorForData();
				}
			}
		});
		
		// Label to show status and cursor location in image.
		statusLabel = new Label(shell, SWT.NULL);
		statusLabel.setText("");
		gridData = new GridData();
		gridData.horizontalSpan = 2;
		gridData.horizontalAlignment = GridData.FILL;
		statusLabel.setLayoutData(gridData);
	}
	
	Menu createMenuBar() {
		// Menu bar.
		Menu menuBar = new Menu(shell, SWT.BAR);
		shell.setMenuBar(menuBar);
		createFileMenu(menuBar);
		createAlphaMenu(menuBar);
		return menuBar;
	}
	
	void createFileMenu(Menu menuBar) {
		// File menu
		MenuItem item = new MenuItem(menuBar, SWT.CASCADE);
		item.setText(bundle.getString("File"));
		Menu fileMenu = new Menu(shell, SWT.DROP_DOWN);
		item.setMenu(fileMenu);

		// File -> Open File...
		item = new MenuItem(fileMenu, SWT.PUSH);
		item.setText(bundle.getString("OpenFile"));
		item.setAccelerator(SWT.MOD1 + 'O');
		item.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				menuOpenFile();
			}
		});
		
		// File -> Open URL...
		item = new MenuItem(fileMenu, SWT.PUSH);
		item.setText(bundle.getString("OpenURL"));
		item.setAccelerator(SWT.MOD1 + 'U');
		item.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				menuOpenURL();
			}
		});
		
		// File -> Reopen
		item = new MenuItem(fileMenu, SWT.PUSH);
		item.setText(bundle.getString("Reopen"));
		item.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				menuReopen();
			}
		});
		
		new MenuItem(fileMenu, SWT.SEPARATOR);
		
		// File -> Save
		item = new MenuItem(fileMenu, SWT.PUSH);
		item.setText(bundle.getString("Save"));
		item.setAccelerator(SWT.MOD1 + 'S');
		item.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				menuSave();
			}
		});
		
		// File -> Save As...
		item = new MenuItem(fileMenu, SWT.PUSH);
		item.setText(bundle.getString("Save_as"));
		item.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				menuSaveAs();
			}
		});
		
		// File -> Save Mask As...
		item = new MenuItem(fileMenu, SWT.PUSH);
		item.setText(bundle.getString("Save_mask_as"));
		item.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				menuSaveMaskAs();
			}
		});
		
		new MenuItem(fileMenu, SWT.SEPARATOR);
		
		// File -> Print
		item = new MenuItem(fileMenu, SWT.PUSH);
		item.setText(bundle.getString("Print"));
		item.setAccelerator(SWT.MOD1 + 'P');
		item.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				menuPrint();
			}
		});
		
		new MenuItem(fileMenu, SWT.SEPARATOR);

		// File -> Exit
		item = new MenuItem(fileMenu, SWT.PUSH);
		item.setText(bundle.getString("Exit"));
		item.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				shell.close();
			}
		});
	
	}

	void createAlphaMenu(Menu menuBar) {
		// Alpha menu
		MenuItem item = new MenuItem(menuBar, SWT.CASCADE);
		item.setText(bundle.getString("Alpha"));
		Menu alphaMenu = new Menu(shell, SWT.DROP_DOWN);
		item.setMenu(alphaMenu);

		// Alpha -> K
		item = new MenuItem(alphaMenu, SWT.PUSH);
		item.setText("K");
		item.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				menuComposeAlpha(ALPHA_CONSTANT);
			}
		});

		// Alpha -> (K + x) % 256
		item = new MenuItem(alphaMenu, SWT.PUSH);
		item.setText("(K + x) % 256");
		item.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				menuComposeAlpha(ALPHA_X);
			}
		});

		// Alpha -> (K + y) % 256
		item = new MenuItem(alphaMenu, SWT.PUSH);
		item.setText("(K + y) % 256");
		item.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				menuComposeAlpha(ALPHA_Y);
			}
		});
	}

	void menuComposeAlpha(int alpha_op) {
		if (image == null) return;
		animate = false; // stop any animation in progress
		Cursor waitCursor = new Cursor(display, SWT.CURSOR_WAIT);
		shell.setCursor(waitCursor);
		imageCanvas.setCursor(waitCursor);
		try {
			if (alpha_op == ALPHA_CONSTANT) {
				imageData.alpha = alpha;
			} else {
				imageData.alpha = -1;
				switch (alpha_op) {
					case ALPHA_X: 
						for (int y = 0; y < imageData.height; y++) {
						for (int x = 0; x < imageData.width; x++) {
							imageData.setAlpha(x, y, (x + alpha) % 256);
						}
						}
						break;
					case ALPHA_Y: 
						for (int y = 0; y < imageData.height; y++) {
						for (int x = 0; x < imageData.width; x++) {
							imageData.setAlpha(x, y, (y + alpha) % 256);
						}
						}
						break;
					default: break;
				}					
			}			
			displayImage(imageData);
		} finally {
			shell.setCursor(null);
			imageCanvas.setCursor(crossCursor);
			waitCursor.dispose();
		}
	}

	void menuOpenFile() {
		animate = false; // stop any animation in progress
		resetScaleCombos();
		
		// Get the user to choose an image file.
		FileDialog fileChooser = new FileDialog(shell, SWT.OPEN);
		if (lastPath != null)
			fileChooser.setFilterPath(lastPath);
		fileChooser.setFilterExtensions(new String[] { "*.bmp; *.gif; *.ico; *.jpg; *.pcx; *.png; *.tif", "*.bmp", "*.gif", "*.ico", "*.jpg", "*.pcx", "*.png", "*.tif" });
		fileChooser.setFilterNames(new String[] { bundle.getString("All_images") + " (bmp, gif, ico, jpg, pcx, png, tif)",
		                                          "BMP (*.bmp)", "GIF (*.gif)", "ICO (*.ico)", "JPEG (*.jpg)", "PCX (*.pcx)", "PNG (*.png)", "TIFF (*.tif)" });
		String filename = fileChooser.open();
		lastPath = fileChooser.getFilterPath();
		if (filename == null)
			return;

		Cursor waitCursor = new Cursor(display, SWT.CURSOR_WAIT);
		shell.setCursor(waitCursor);
		imageCanvas.setCursor(waitCursor);
		try {
			loader = new ImageLoader();
			if (incremental) {
				// Prepare to handle incremental events.
				loader.addImageLoaderListener(new ImageLoaderListener() {
					public void imageDataLoaded(ImageLoaderEvent event) {
						incrementalDataLoaded(event);
					}
				});
				incrementalThreadStart();
			}
			// Read the new image(s) from the chosen file.
			long startTime = System.currentTimeMillis();
			imageDataArray = loader.load(filename);
			loadTime = System.currentTimeMillis() - startTime;
			if (imageDataArray.length > 0) {
				// Cache the filename.
				currentName = filename;
				fileName = filename;
				
				// If there are multiple images in the file (typically GIF)
				// then enable the Previous, Next and Animate buttons.
				previousButton.setEnabled(imageDataArray.length > 1);
				nextButton.setEnabled(imageDataArray.length > 1);
				animateButton.setEnabled(imageDataArray.length > 1 && loader.logicalScreenWidth > 0 && loader.logicalScreenHeight > 0);
	
				// Display the first image in the file.
				imageDataIndex = 0;
				displayImage(imageDataArray[imageDataIndex]);
				resetScrollBars();
			}
		} catch (SWTException e) {
			showErrorDialog(bundle.getString("Loading_lc"), filename, e);
		} catch (SWTError e) {
			showErrorDialog(bundle.getString("Loading_lc"), filename, e);
		} finally {
			shell.setCursor(null);
			imageCanvas.setCursor(crossCursor);
			waitCursor.dispose();
		}
	}
	
	void menuOpenURL() {
		animate = false; // stop any animation in progress
		resetScaleCombos();
		
		// Get the user to choose an image URL.
		TextPrompter textPrompter = new TextPrompter(shell, SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
		textPrompter.setText(bundle.getString("OpenURLDialog"));
		textPrompter.setMessage(bundle.getString("EnterURL"));
		String urlname = textPrompter.open();
		if (urlname == null) return;

		Cursor waitCursor = new Cursor(display, SWT.CURSOR_WAIT);
		shell.setCursor(waitCursor);
		imageCanvas.setCursor(waitCursor);
		try {
			URL url = new URL(urlname);
			InputStream stream = url.openStream();
			loader = new ImageLoader();
			if (incremental) {
				// Prepare to handle incremental events.
				loader.addImageLoaderListener(new ImageLoaderListener() {
					public void imageDataLoaded(ImageLoaderEvent event) {
						incrementalDataLoaded(event);
					}
				});
				incrementalThreadStart();
			}
			// Read the new image(s) from the chosen file.
			long startTime = System.currentTimeMillis();
			imageDataArray = loader.load(stream);
			loadTime = System.currentTimeMillis() - startTime;
			if (imageDataArray.length > 0) {
				currentName = urlname;
				fileName = null;
				
				// If there are multiple images in the file (typically GIF)
				// then enable the Previous, Next and Animate buttons.
				previousButton.setEnabled(imageDataArray.length > 1);
				nextButton.setEnabled(imageDataArray.length > 1);
				animateButton.setEnabled(imageDataArray.length > 1 && loader.logicalScreenWidth > 0 && loader.logicalScreenHeight > 0);
	
				// Display the first image in the file.
				imageDataIndex = 0;
				displayImage(imageDataArray[imageDataIndex]);
				resetScrollBars();
			}
		} catch (Exception e) {
			showErrorDialog(bundle.getString("Loading_lc"), urlname, e);
		} finally {
			shell.setCursor(null);
			imageCanvas.setCursor(crossCursor);
			waitCursor.dispose();
		}
	}

	/*
	 * Called to start a thread that draws incremental images
	 * as they are loaded.
	 */
	void incrementalThreadStart() {
		incrementalEvents = new Vector();
		incrementalThread = new Thread("Incremental") {
			public void run() {
				// Draw the first ImageData increment.
				while (incrementalEvents != null) {
					// Synchronize so we don't try to remove when the vector is null.
					synchronized (ImageAnalyzer.this) {
						if (incrementalEvents != null) {
							if (incrementalEvents.size() > 0) {
								ImageLoaderEvent event = (ImageLoaderEvent) incrementalEvents.remove(0);
								if (image != null) image.dispose();
								image = new Image(display, event.imageData);
								imageData = event.imageData;
								imageCanvasGC.drawImage(
									image,
									0,
									0,
									imageData.width,
									imageData.height,
									imageData.x,
									imageData.y,
									imageData.width,
									imageData.height);
							} else {
								yield();
							}
						}
					}
				}
				display.wake();
			}
		};
		incrementalThread.setDaemon(true);
		incrementalThread.start();
	}
	
	/*
	 * Called when incremental image data has been loaded,
	 * for example, for interlaced GIF/PNG or progressive JPEG.
	 */
	void incrementalDataLoaded(ImageLoaderEvent event) {
		// Synchronize so that we do not try to add while
		// the incremental drawing thread is removing.
		synchronized (this) {
			incrementalEvents.addElement(event);
		}
	}
	
	void menuSave() {
		if (image == null) return;
		animate = false; // stop any animation in progress

		// If the image file type is unknown, we can't 'Save',
		// so we have to use 'Save As...'.
		if (imageData.type == SWT.IMAGE_UNDEFINED || fileName == null) {
			menuSaveAs();
			return;
		}

		Cursor waitCursor = new Cursor(display, SWT.CURSOR_WAIT);
		shell.setCursor(waitCursor);
		imageCanvas.setCursor(waitCursor);
		try {
			// Save the current image to the current file.
			loader.data = new ImageData[] {imageData};
			loader.save(fileName, imageData.type);
			
		} catch (SWTException e) {
			showErrorDialog(bundle.getString("Saving_lc"), fileName, e);
		} catch (SWTError e) {
			showErrorDialog(bundle.getString("Saving_lc"), fileName, e);
		} finally {
			shell.setCursor(null);
			imageCanvas.setCursor(crossCursor);
			waitCursor.dispose();
		}
	}

	void menuSaveAs() {
		if (image == null) return;
		animate = false; // stop any animation in progress

		// Get the user to choose a file name and type to save.
		FileDialog fileChooser = new FileDialog(shell, SWT.SAVE);
		fileChooser.setFilterPath(lastPath);
		if (fileName != null) {
			String name = fileName;
			int nameStart = name.lastIndexOf(java.io.File.separatorChar);
			if (nameStart > -1) {
				name = name.substring(nameStart + 1);
			}
			fileChooser.setFileName(name);
		}
		fileChooser.setFilterExtensions(new String[] { "*.bmp", "*.gif", "*.ico", "*.jpg", "*.png" });
		fileChooser.setFilterNames(new String[] { "BMP (*.bmp)", "GIF (*.gif)", "ICO (*.ico)", "JPEG (*.jpg)", "PNG (*.png)" });
		String filename = fileChooser.open();
		lastPath = fileChooser.getFilterPath();
		if (filename == null)
			return;

		// Figure out what file type the user wants saved.
		// We need to rely on the file extension because FileDialog
		// does not have API for asking what filter type was selected.
		int filetype = determineFileType(filename);
		if (filetype == SWT.IMAGE_UNDEFINED) {
			MessageBox box = new MessageBox(shell, SWT.ICON_ERROR);
			box.setMessage(createMsg(bundle.getString("Unknown_extension"), 
			                         filename.substring(filename.lastIndexOf('.') + 1)));
			box.open();
			return;
		}
		
		if (new java.io.File(filename).exists()) {
			MessageBox box = new MessageBox(shell, SWT.ICON_QUESTION | SWT.OK | SWT.CANCEL);
			box.setMessage(createMsg(bundle.getString("Overwrite"), filename));
			if (box.open() == SWT.CANCEL)
				return;
		}
		
		Cursor waitCursor = new Cursor(display, SWT.CURSOR_WAIT);
		shell.setCursor(waitCursor);
		imageCanvas.setCursor(waitCursor);
		try {
			// Save the current image to the specified file.
			loader.data = new ImageData[] {imageData};
			loader.save(filename, filetype);
			
			// Update the shell title and file type label,
			// and use the new file.
			fileName = filename;
			shell.setText(createMsg(bundle.getString("Analyzer_on"), filename));
			typeLabel.setText(createMsg(bundle.getString("Type_string"), fileTypeString(filetype)));

		} catch (SWTException e) {
			showErrorDialog(bundle.getString("Saving_lc"), filename, e);
		} catch (SWTError e) {
			showErrorDialog(bundle.getString("Saving_lc"), filename, e);
		} finally {
			shell.setCursor(null);
			imageCanvas.setCursor(crossCursor);
			waitCursor.dispose();
		}
	}

	void menuSaveMaskAs() {
		if (image == null || !showMask) return;
		if (imageData.getTransparencyType() == SWT.TRANSPARENCY_NONE) return;
		animate = false; // stop any animation in progress

		// Get the user to choose a file name and type to save.
		FileDialog fileChooser = new FileDialog(shell, SWT.SAVE);
		fileChooser.setFilterPath(lastPath);
		if (fileName != null) fileChooser.setFileName(fileName);
		fileChooser.setFilterExtensions(new String[] { "*.bmp", "*.gif", "*.ico", "*.jpg", "*.png" });
		fileChooser.setFilterNames(new String[] { "BMP (*.bmp)", "GIF (*.gif)", "ICO (*.ico)", "JPEG (*.jpg)", "PNG (*.png)" });
		String filename = fileChooser.open();
		lastPath = fileChooser.getFilterPath();
		if (filename == null)
			return;

		// Figure out what file type the user wants saved.
		// We need to rely on the file extension because FileDialog
		// does not have API for asking what filter type was selected.
		int filetype = determineFileType(filename);
		if (filetype == SWT.IMAGE_UNDEFINED) {
			MessageBox box = new MessageBox(shell, SWT.ICON_ERROR);
			box.setMessage(createMsg(bundle.getString("Unknown_extension"), 
			                         filename.substring(filename.lastIndexOf('.') + 1)));
			box.open();
			return;
		}
		
		if (new java.io.File(filename).exists()) {
			MessageBox box = new MessageBox(shell, SWT.ICON_QUESTION | SWT.OK | SWT.CANCEL);
			box.setMessage(createMsg(bundle.getString("Overwrite"), filename));
			if (box.open() == SWT.CANCEL)
				return;
		}
		
		Cursor waitCursor = new Cursor(display, SWT.CURSOR_WAIT);
		shell.setCursor(waitCursor);
		imageCanvas.setCursor(waitCursor);
		try {
			// Save the mask of the current image to the specified file.
			ImageData maskImageData = imageData.getTransparencyMask();
			loader.data = new ImageData[] {maskImageData};
			loader.save(filename, filetype);
			
		} catch (SWTException e) {
			showErrorDialog(bundle.getString("Saving_lc"), filename, e);
		} catch (SWTError e) {
			showErrorDialog(bundle.getString("Saving_lc"), filename, e);
		} finally {
			shell.setCursor(null);
			imageCanvas.setCursor(crossCursor);
			waitCursor.dispose();
		}
	}

	void menuPrint() {
		if (image == null) return;

		try {
			// Ask the user to specify the printer.
			PrintDialog dialog = new PrintDialog(shell, SWT.NULL);
			PrinterData printerData = dialog.open();
			if (printerData == null) return;
			
			Printer printer = new Printer(printerData);
			Point screenDPI = display.getDPI();
			Point printerDPI = printer.getDPI();
			int scaleFactor = printerDPI.x / screenDPI.x;
			Rectangle trim = printer.computeTrim(0, 0, 0, 0);
			if (printer.startJob(currentName)) {
				if (printer.startPage()) {
					GC gc = new GC(printer);
					int transparentPixel = imageData.transparentPixel;
					if (transparentPixel != -1 && !transparent) {
						imageData.transparentPixel = -1;
					}
					Image printerImage = new Image(printer, imageData);
					gc.drawImage(
						printerImage,
						0,
						0,
						imageData.width,
						imageData.height,
						-trim.x,
						-trim.y,
						scaleFactor * imageData.width,
						scaleFactor * imageData.height);
					if (transparentPixel != -1 && !transparent) {
						imageData.transparentPixel = transparentPixel;
					}
					printerImage.dispose();
					gc.dispose();
					printer.endPage();
				}
				printer.endJob();
			}
			printer.dispose();
		} catch (SWTError e) {
			MessageBox box = new MessageBox(shell, SWT.ICON_ERROR);
			box.setMessage(bundle.getString("Printing_error") + e.getMessage());
			box.open();
		}
	}

	void menuReopen() {
		if (currentName == null) return;
		animate = false; // stop any animation in progress
		resetScrollBars();
		resetScaleCombos();
		Cursor waitCursor = new Cursor(display, SWT.CURSOR_WAIT);
		shell.setCursor(waitCursor);
		imageCanvas.setCursor(waitCursor);
		try {
			loader = new ImageLoader();
			long startTime = System.currentTimeMillis();
			ImageData[] newImageData;
			if (fileName == null) {
				URL url = new URL(currentName);
				InputStream stream = url.openStream();
				newImageData = loader.load(stream);
			} else {
				newImageData = loader.load(fileName);
			}
			loadTime = System.currentTimeMillis() - startTime;
			imageDataIndex = 0;
			displayImage(newImageData[imageDataIndex]);

		} catch (Exception e) {
			showErrorDialog(bundle.getString("Reloading_lc"), currentName, e);
		} finally {	
			shell.setCursor(null);
			imageCanvas.setCursor(crossCursor);
			waitCursor.dispose();
		}
	}
	
	void changeBackground() {
		String background = backgroundCombo.getText();
		if (background.equals(bundle.getString("White"))) {
			imageCanvas.setBackground(whiteColor);
		} else if (background.equals(bundle.getString("Black"))) {
			imageCanvas.setBackground(blackColor);
		} else if (background.equals(bundle.getString("Red"))) {
			imageCanvas.setBackground(redColor);
		} else if (background.equals(bundle.getString("Green"))) {
			imageCanvas.setBackground(greenColor);
		} else if (background.equals(bundle.getString("Blue"))) {
			imageCanvas.setBackground(blueColor);
		} else {
			imageCanvas.setBackground(null);
		}
	}
	
	/*
	 * Called when the ScaleX combo selection changes.
	 */
	void scaleX() {
		try {
			xscale = Float.parseFloat(scaleXCombo.getText());
		} catch (NumberFormatException e) {
			xscale = 1;
			scaleXCombo.select(scaleXCombo.indexOf("1"));
		}
		if (image != null) {
			resizeScrollBars();
			imageCanvas.redraw();
		}
	}
	
	/*
	 * Called when the ScaleY combo selection changes.
	 */
	void scaleY() {
		try {
			yscale = Float.parseFloat(scaleYCombo.getText());
		} catch (NumberFormatException e) {
			yscale = 1;
			scaleYCombo.select(scaleYCombo.indexOf("1"));
		}
		if (image != null) {
			resizeScrollBars();
			imageCanvas.redraw();
		}
	}
	
	/*
	 * Called when the Alpha combo selection changes.
	 */
	void alpha() {
		try {
			alpha = Integer.parseInt(alphaCombo.getText());
		} catch (NumberFormatException e) {
			alphaCombo.select(alphaCombo.indexOf("255"));
			alpha = 255;
		}
	}
	
	/*
	 * Called when the mouse moves in the image canvas.
	 * Show the color of the image at the point under the mouse.
	 */
	void showColorAt(int mx, int my) {
		int x = mx - imageData.x - ix;
		int y = my - imageData.y - iy;
		showColorForPixel(x, y);
	}
	
	/*
	 * Called when a mouse down or key press is detected
	 * in the data text. Show the color of the pixel at
	 * the caret position in the data text.
	 */
	void showColorForData() {
		int delimiterLength = dataText.getLineDelimiter().length();
		int charactersPerLine = 6 + 3 * imageData.bytesPerLine + delimiterLength;
		int position = dataText.getCaretOffset();
		int y = position / charactersPerLine;
		if ((position - y * charactersPerLine) < 6 || ((y + 1) * charactersPerLine - position) <= delimiterLength) {
			statusLabel.setText("");
			return;
		}
		int dataPosition = position - 6 * (y + 1) - delimiterLength * y;
		int byteNumber = dataPosition / 3;
		int where = dataPosition - byteNumber * 3;
		int xByte = byteNumber % imageData.bytesPerLine;
		int x = -1;
		int depth = imageData.depth;
		if (depth == 1) { // 8 pixels per byte (can only show 3 of 8)
			if (where == 0) x = xByte * 8;
			if (where == 1) x = xByte * 8 + 3;
			if (where == 2) x = xByte * 8 + 7;
		}
		if (depth == 2) { // 4 pixels per byte (can only show 3 of 4)
			if (where == 0) x = xByte * 4;
			if (where == 1) x = xByte * 4 + 1;
			if (where == 2) x = xByte * 4 + 3;
		}
		if (depth == 4) { // 2 pixels per byte
			if (where == 0) x = xByte * 2;
			if (where == 1) x = xByte * 2;
			if (where == 2) x = xByte * 2 + 1;
		}
		if (depth == 8) { // 1 byte per pixel
			x = xByte;
		}
		if (depth == 16) { // 2 bytes per pixel
			x = xByte / 2;
		}
		if (depth == 24) { // 3 bytes per pixel
			x = xByte / 3;
		}
		if (depth == 32) { // 4 bytes per pixel
			x = xByte / 4;
		}
		if (x != -1) {
			showColorForPixel(x, y);
		} else {
			statusLabel.setText("");
		}
	}
	
	/*
	 * Set the status label to show color information
	 * for the specified pixel in the image.
	 */
	void showColorForPixel(int x, int y) {
		if (x >= 0 && x < imageData.width && y >= 0 && y < imageData.height) {
			int pixel = imageData.getPixel(x, y);
			RGB rgb = imageData.palette.getRGB(pixel);


			Object[] args = {new Integer(x),
					     new Integer(y),
					     new Integer(pixel),
					     Integer.toHexString(pixel),
					     rgb};
			if (pixel == imageData.transparentPixel) {
				statusLabel.setText(createMsg(bundle.getString("Color_at_trans"), args));
			} else {
				statusLabel.setText(createMsg(bundle.getString("Color_at"), args));
			}
		} else {
			statusLabel.setText("");
		}
	}
	
	/*
	 * Called when the Animate button is pressed.
	 */
	void animate() {
		animate = !animate;
		if (animate && image != null && imageDataArray.length > 1) {
			animateThread = new Thread(bundle.getString("Animation")) {
				public void run() {
					// Pre-animation widget setup.
					preAnimation();
					
					// Animate.
					try {
						animateLoop();
					} catch (final SWTException e) {
						display.syncExec(new Runnable() {
							public void run() {
								showErrorDialog(createMsg(bundle.getString("Creating_image"), 
										    new Integer(imageDataIndex+1)),
										    currentName, e);
							}
						});
					}
					
					// Post animation widget reset.
					postAnimation();
				}
			};
			animateThread.setDaemon(true);
			animateThread.start();
		}
	}
	
	/*
	 * Loop through all of the images in a multi-image file
	 * and display them one after another.
	 */
	void animateLoop() {
		// Create an off-screen image to draw on, and a GC to draw with.
		// Both are disposed after the animation.
		Image offScreenImage = new Image(display, loader.logicalScreenWidth, loader.logicalScreenHeight);
		GC offScreenImageGC = new GC(offScreenImage);
		
		try {
			// Use syncExec to get the background color of the imageCanvas.
			display.syncExec(new Runnable() {
				public void run() {
					canvasBackground = imageCanvas.getBackground();
				}
			});

			// Fill the off-screen image with the background color of the canvas.
			offScreenImageGC.setBackground(canvasBackground);
			offScreenImageGC.fillRectangle(
				0,
				0,
				loader.logicalScreenWidth,
				loader.logicalScreenHeight);
					
			// Draw the current image onto the off-screen image.
			offScreenImageGC.drawImage(
				image,
				0,
				0,
				imageData.width,
				imageData.height,
				imageData.x,
				imageData.y,
				imageData.width,
				imageData.height);

			int repeatCount = loader.repeatCount;
			while (animate && (loader.repeatCount == 0 || repeatCount > 0)) {
				if (imageData.disposalMethod == SWT.DM_FILL_BACKGROUND) {
					// Fill with the background color before drawing.
					Color bgColor = null;
					int backgroundPixel = loader.backgroundPixel;
					if (showBackground && backgroundPixel != -1) {
						// Fill with the background color.
						RGB backgroundRGB = imageData.palette.getRGB(backgroundPixel);
						bgColor = new Color(null, backgroundRGB);
					}
					try {
						offScreenImageGC.setBackground(bgColor != null ? bgColor : canvasBackground);
						offScreenImageGC.fillRectangle(
							imageData.x,
							imageData.y,
							imageData.width,
							imageData.height);
					} finally {
						if (bgColor != null) bgColor.dispose();
					}
				} else if (imageData.disposalMethod == SWT.DM_FILL_PREVIOUS) {
					// Restore the previous image before drawing.
					offScreenImageGC.drawImage(
						image,
						0,
						0,
						imageData.width,
						imageData.height,
						imageData.x,
						imageData.y,
						imageData.width,
						imageData.height);
				}
									
				// Get the next image data.
				imageDataIndex = (imageDataIndex + 1) % imageDataArray.length;
				imageData = imageDataArray[imageDataIndex];
				image.dispose();
				image = new Image(display, imageData);
				
				// Draw the new image data.
				offScreenImageGC.drawImage(
					image,
					0,
					0,
					imageData.width,
					imageData.height,
					imageData.x,
					imageData.y,
					imageData.width,
					imageData.height);
				
				// Draw the off-screen image to the screen.
				imageCanvasGC.drawImage(offScreenImage, 0, 0);
				
				// Sleep for the specified delay time before drawing again.
				try {
					Thread.sleep(visibleDelay(imageData.delayTime * 10));
				} catch (InterruptedException e) {
				}
				
				// If we have just drawn the last image in the set,
				// then decrement the repeat count.
				if (imageDataIndex == imageDataArray.length - 1) repeatCount--;
			}
		} finally {
			offScreenImage.dispose();
			offScreenImageGC.dispose();
		}
	}

	/*
	 * Pre animation setup.
	 */
	void preAnimation() {
		display.syncExec(new Runnable() {
			public void run() {
				// Change the label of the Animate button to 'Stop'.
				animateButton.setText(bundle.getString("Stop"));
				
				// Disable anything we don't want the user
				// to select during the animation.
				previousButton.setEnabled(false);
				nextButton.setEnabled(false);
				backgroundCombo.setEnabled(false);
				scaleXCombo.setEnabled(false);
				scaleYCombo.setEnabled(false);
				alphaCombo.setEnabled(false);
				incrementalCheck.setEnabled(false);
				transparentCheck.setEnabled(false);
				maskCheck.setEnabled(false);
				// leave backgroundCheck enabled
			
				// Reset the scale combos and scrollbars.
				resetScaleCombos();
				resetScrollBars();
			}
		});
	}

	/*
	 * Post animation reset.
	 */
	void postAnimation() {
		display.syncExec(new Runnable() {
			public void run() {
				// Enable anything we disabled before the animation.
				previousButton.setEnabled(true);
				nextButton.setEnabled(true);
				backgroundCombo.setEnabled(true);
				scaleXCombo.setEnabled(true);
				scaleYCombo.setEnabled(true);
				alphaCombo.setEnabled(true);
				incrementalCheck.setEnabled(true);
				transparentCheck.setEnabled(true);
				maskCheck.setEnabled(true);
			
				// Reset the label of the Animate button.
				animateButton.setText(bundle.getString("Animate"));
			
				if (animate) {
					// If animate is still true, we finished the
					// full number of repeats. Leave the image as-is.
					animate = false;
				} else {
					// Redisplay the current image and its palette.
					displayImage(imageDataArray[imageDataIndex]);
				}
			}
		});
	}

	/*
	 * Called when the Previous button is pressed.
	 * Display the previous image in a multi-image file.
	 */
	void previous() {
		if (image != null && imageDataArray.length > 1) {
			if (imageDataIndex == 0) {
				imageDataIndex = imageDataArray.length;
			}
			imageDataIndex = imageDataIndex - 1;
			displayImage(imageDataArray[imageDataIndex]);
		}	
	}

	/*
	 * Called when the Next button is pressed.
	 * Display the next image in a multi-image file.
	 */
	void next() {
		if (image != null && imageDataArray.length > 1) {
			imageDataIndex = (imageDataIndex + 1) % imageDataArray.length;
			displayImage(imageDataArray[imageDataIndex]);
		}	
	}

	void displayImage(ImageData newImageData) {
		if (incremental && incrementalThread != null) {
			// Tell the incremental thread to stop drawing.
			synchronized (this) {
				incrementalEvents = null;
			}
			
			// Wait until the incremental thread is done.
			while (incrementalThread.isAlive()) {
				if (!display.readAndDispatch()) display.sleep();
			}
		}
					
		// Dispose of the old image, if there was one.
		if (image != null) image.dispose();

		try {
			// Cache the new image and imageData.
			image = new Image(display, newImageData);
			imageData = newImageData;

		} catch (SWTException e) {
			showErrorDialog(bundle.getString("Creating_from") + " ", currentName, e);
			image = null;
			return;
		}

		// Update the widgets with the new image info.
		String string = createMsg(bundle.getString("Analyzer_on"), currentName);
		shell.setText(string);

		if (imageDataArray.length > 1) {
			string = createMsg(bundle.getString("Type_index"), 
			                   new Object[] {fileTypeString(imageData.type),
			                                 new Integer(imageDataIndex + 1),
			                                 new Integer(imageDataArray.length)});
		} else {
			string = createMsg(bundle.getString("Type_string"), fileTypeString(imageData.type));
		}
		typeLabel.setText(string);

		string = createMsg(bundle.getString("Size_value"), 
					 new Object[] {new Integer(imageData.width),
							   new Integer(imageData.height)});
		sizeLabel.setText(string);

		string = createMsg(bundle.getString("Depth_value"), new Integer(imageData.depth));
		depthLabel.setText(string);

		string = createMsg(bundle.getString("Transparent_pixel_value"), pixelInfo(imageData.transparentPixel));
		transparentPixelLabel.setText(string);

		string = createMsg(bundle.getString("Time_to_load_value"), new Long(loadTime));
		timeToLoadLabel.setText(string);

		string = createMsg(bundle.getString("Animation_size_value"), 
		                      new Object[] {new Integer(loader.logicalScreenWidth),
								new Integer(loader.logicalScreenHeight)});
		screenSizeLabel.setText(string);

		string = createMsg(bundle.getString("Background_pixel_value"), pixelInfo(loader.backgroundPixel));
		backgroundPixelLabel.setText(string);

		string = createMsg(bundle.getString("Image_location_value"), 
		                      new Object[] {new Integer(imageData.x), new Integer(imageData.y)});
		locationLabel.setText(string);

		string = createMsg(bundle.getString("Disposal_value"),
		                      new Object[] {new Integer(imageData.disposalMethod),
							      disposalString(imageData.disposalMethod)});
		disposalMethodLabel.setText(string);

		int delay = imageData.delayTime * 10;
		int delayUsed = visibleDelay(delay);
		if (delay != delayUsed) {
			string = createMsg(bundle.getString("Delay_value"), 
			                   new Object[] {new Integer(delay), new Integer(delayUsed)});
		} else {
			string = createMsg(bundle.getString("Delay_used"), new Integer(delay));
		}
		delayTimeLabel.setText(string);

		if (loader.repeatCount == 0) {
			string = createMsg( bundle.getString("Repeats_forever"), new Integer(loader.repeatCount));
		} else {
			string = createMsg(bundle.getString("Repeats_value"), new Integer(loader.repeatCount));
		}
		repeatCountLabel.setText(string);


		if (imageData.palette.isDirect) {
			string = bundle.getString("Palette_direct");
		} else {
			string = createMsg(bundle.getString("Palette_value"), new Integer(imageData.palette.getRGBs().length));
		}
		paletteLabel.setText(string);

		string = createMsg(bundle.getString("Pixel_data_value"), 
					 new Object[] {new Integer(imageData.bytesPerLine),
						         new Integer(imageData.scanlinePad),
							   depthInfo(imageData.depth)});
		dataLabel.setText(string);

		String data = dataHexDump(dataText.getLineDelimiter());
		dataText.setText(data);
		
		// bold the first column all the way down
		int index = 0;
		while((index = data.indexOf(':', index+1)) != -1) 
			dataText.setStyleRange(new StyleRange(index - INDEX_DIGITS, INDEX_DIGITS, dataText.getForeground(), dataText.getBackground(), SWT.BOLD));

		statusLabel.setText("");

		// Redraw both canvases.
		paletteCanvas.redraw();
		imageCanvas.redraw();
	}

	void paintImage(PaintEvent event) {
		Image paintImage = image;
		int transparentPixel = imageData.transparentPixel;
		if (transparentPixel != -1 && !transparent) {
			imageData.transparentPixel = -1;
			paintImage = new Image(display, imageData);
		}
		int w = Math.round(imageData.width * xscale);
		int h = Math.round(imageData.height * yscale);
		event.gc.drawImage(
			paintImage,
			0,
			0,
			imageData.width,
			imageData.height,
			ix + imageData.x,
			iy + imageData.y,
			w,
			h);
		if (showMask && (imageData.getTransparencyType() != SWT.TRANSPARENCY_NONE)) {
			ImageData maskImageData = imageData.getTransparencyMask();
			Image maskImage = new Image(display, maskImageData);
			event.gc.drawImage(
				maskImage,
				0,
				0,
				imageData.width,
				imageData.height,
				w + 10 + ix + imageData.x,
				iy + imageData.y,
				w,
				h);
			maskImage.dispose();
		}
		if (transparentPixel != -1 && !transparent) {
			imageData.transparentPixel = transparentPixel;
			paintImage.dispose();
		}
	}

	void paintPalette(PaintEvent event) {
		GC gc = event.gc;
		gc.fillRectangle(paletteCanvas.getClientArea());
		if (imageData.palette.isDirect) {
			// For a direct palette, display the masks.
			int y = py + 10;
			int xTab = 50;
			gc.drawString("rMsk", 10, y, true);
			gc.drawString(toHex4ByteString(imageData.palette.redMask), xTab, y, true);
			gc.drawString("gMsk", 10, y+=12, true);
			gc.drawString(toHex4ByteString(imageData.palette.greenMask), xTab, y, true);
			gc.drawString("bMsk", 10, y+=12, true);
			gc.drawString(toHex4ByteString(imageData.palette.blueMask), xTab, y, true);
			gc.drawString("rShf", 10, y+=12, true);
			gc.drawString(Integer.toString(imageData.palette.redShift), xTab, y, true);
			gc.drawString("gShf", 10, y+=12, true);
			gc.drawString(Integer.toString(imageData.palette.greenShift), xTab, y, true);
			gc.drawString("bShf", 10, y+=12, true);
			gc.drawString(Integer.toString(imageData.palette.blueShift), xTab, y, true);
		} else {
			// For an indexed palette, display the palette colors and indices.
			RGB[] rgbs = imageData.palette.getRGBs();
			if (rgbs != null) {
				int xTab1 = 40, xTab2 = 100;
				for (int i = 0; i < rgbs.length; i++) {
					int y = (i+1) * 10 + py;
					gc.drawString(String.valueOf(i), 10, y, true);
					gc.drawString(toHexByteString(rgbs[i].red) + toHexByteString(rgbs[i].green) + toHexByteString(rgbs[i].blue), xTab1, y, true);
					Color color = new Color(display, rgbs[i]);
					gc.setBackground(color);
					gc.fillRectangle(xTab2, y+2, 10, 10);
					color.dispose();
				}
			}
		}
	}
	
	void resizeShell(ControlEvent event) {
		if (image == null || shell.isDisposed())
			return;
		resizeScrollBars();
	}

	// Reset the scale combos to 1.
	void resetScaleCombos() {
		xscale = 1; yscale = 1;
		scaleXCombo.select(scaleXCombo.indexOf("1"));
		scaleYCombo.select(scaleYCombo.indexOf("1"));
	}
	
	// Reset the scroll bars to 0.
	void resetScrollBars() {
		if (image == null) return;
		ix = 0; iy = 0; py = 0;
		resizeScrollBars();
		imageCanvas.getHorizontalBar().setSelection(0);
		imageCanvas.getVerticalBar().setSelection(0);
		paletteCanvas.getVerticalBar().setSelection(0);
	}
	
	void resizeScrollBars() {
		// Set the max and thumb for the image canvas scroll bars.
		ScrollBar horizontal = imageCanvas.getHorizontalBar();
		ScrollBar vertical = imageCanvas.getVerticalBar();
		Rectangle canvasBounds = imageCanvas.getClientArea();
		int width = Math.round(imageData.width * xscale);
		if (width > canvasBounds.width) {
			// The image is wider than the canvas.
			horizontal.setEnabled(true);
			horizontal.setMaximum(width);
			horizontal.setThumb(canvasBounds.width);
			horizontal.setPageIncrement(canvasBounds.width);
		} else {
			// The canvas is wider than the image.
			horizontal.setEnabled(false);
			if (ix != 0) {
				// Make sure the image is completely visible.
				ix = 0;
				imageCanvas.redraw();
			}
		}
		int height = Math.round(imageData.height * yscale);
		if (height > canvasBounds.height) {
			// The image is taller than the canvas.
			vertical.setEnabled(true);
			vertical.setMaximum(height);
			vertical.setThumb(canvasBounds.height);
			vertical.setPageIncrement(canvasBounds.height);
		} else {
			// The canvas is taller than the image.
			vertical.setEnabled(false);
			if (iy != 0) {
				// Make sure the image is completely visible.
				iy = 0;
				imageCanvas.redraw();
			}
		}

		// Set the max and thumb for the palette canvas scroll bar.
		vertical = paletteCanvas.getVerticalBar();
		if (imageData.palette.isDirect) {
			vertical.setEnabled(false);
		} else { // indexed palette
			canvasBounds = paletteCanvas.getClientArea();
			int paletteHeight = imageData.palette.getRGBs().length * 10 + 20; // 10 pixels each index + 20 for margins.
			vertical.setEnabled(true);
			vertical.setMaximum(paletteHeight);
			vertical.setThumb(canvasBounds.height);
			vertical.setPageIncrement(canvasBounds.height);
		}
	}

	/*
	 * Called when the image canvas' horizontal scrollbar is selected.
	 */
	void scrollHorizontally(ScrollBar scrollBar) {
		if (image == null) return;
		Rectangle canvasBounds = imageCanvas.getClientArea();
		int width = Math.round(imageData.width * xscale);
		int height = Math.round(imageData.height * yscale);
		if (width > canvasBounds.width) {
			// Only scroll if the image is bigger than the canvas.
			int x = -scrollBar.getSelection();
			if (x + width < canvasBounds.width) {
				// Don't scroll past the end of the image.
				x = canvasBounds.width - width;
			}
			imageCanvas.scroll(x, iy, ix, iy, width, height, false);
			ix = x;
		}
	}
	
	/*
	 * Called when the image canvas' vertical scrollbar is selected.
	 */
	void scrollVertically(ScrollBar scrollBar) {
		if (image == null) return;
		Rectangle canvasBounds = imageCanvas.getClientArea();
		int width = Math.round(imageData.width * xscale);
		int height = Math.round(imageData.height * yscale);
		if (height > canvasBounds.height) {
			// Only scroll if the image is bigger than the canvas.
			int y = -scrollBar.getSelection();
			if (y + height < canvasBounds.height) {
				// Don't scroll past the end of the image.
				y = canvasBounds.height - height;
			}
			imageCanvas.scroll(ix, y, ix, iy, width, height, false);
			iy = y;
		}
	}

	/*
	 * Called when the palette canvas' vertical scrollbar is selected.
	 */
	void scrollPalette(ScrollBar scrollBar) {
		if (image == null) return;
		Rectangle canvasBounds = paletteCanvas.getClientArea();
		int paletteHeight = imageData.palette.getRGBs().length * 10 + 20;
		if (paletteHeight > canvasBounds.height) {
			// Only scroll if the palette is bigger than the canvas.
			int y = -scrollBar.getSelection();
			if (y + paletteHeight < canvasBounds.height) {
				// Don't scroll past the end of the palette.
				y = canvasBounds.height - paletteHeight;
			}
			paletteCanvas.scroll(0, y, 0, py, paletteWidth, paletteHeight, false);
			py = y;
		}
	}

	/*
	 * Return a String containing a line-by-line dump of
	 * the data in the current imageData. The lineDelimiter
	 * parameter must be a string of length 1 or 2.
	 */
	String dataHexDump(String lineDelimiter) {
		if (image == null) return "";
		char[] dump = new char[imageData.height * (6 + 3 * imageData.bytesPerLine + lineDelimiter.length())];
		int index = 0;
		for (int i = 0; i < imageData.data.length; i++) {
			if (i % imageData.bytesPerLine == 0) {
				int line = i / imageData.bytesPerLine;
				dump[index++] = Character.forDigit(line / 1000 % 10, 10);
				dump[index++] = Character.forDigit(line / 100 % 10, 10);
				dump[index++] = Character.forDigit(line / 10 % 10, 10);
				dump[index++] = Character.forDigit(line % 10, 10);
				dump[index++] = ':';
				dump[index++] = ' ';
			}
			byte b = imageData.data[i];
			dump[index++] = Character.forDigit((b & 0xF0) >> 4, 16);
			dump[index++] = Character.forDigit(b & 0x0F, 16);
			dump[index++] = ' ';
			if ((i + 1) % imageData.bytesPerLine == 0) {
				dump[index++] = lineDelimiter.charAt(0);
				if (lineDelimiter.length() > 1)
					dump[index++] = lineDelimiter.charAt(1);
			}
		}
		String result = "";
		try {
			result = new String(dump);
		} catch (OutOfMemoryError e) {
			/* Too much data to display in the text widget - truncate at 4M. */
			result = new String(dump, 0, 4 * 1024 * 1024) + "\n ...data dump truncated at 4M...";
		}
		return result;
	}
	
	/*
	 * Open an error dialog displaying the specified information.
	 */
	void showErrorDialog(String operation, String filename, Throwable e) {
		MessageBox box = new MessageBox(shell, SWT.ICON_ERROR);
		String message = createMsg(bundle.getString("Error"), new String[] {operation, filename});
		String errorMessage = "";
		if (e != null) {
			if (e instanceof SWTException) {
				SWTException swte = (SWTException) e;
				errorMessage = swte.getMessage();
				if (swte.throwable != null) {
					errorMessage += ":\n" + swte.throwable.toString();
				}
			} else if (e instanceof SWTError) {
				SWTError swte = (SWTError) e;
				errorMessage = swte.getMessage();
				if (swte.throwable != null) {
					errorMessage += ":\n" + swte.throwable.toString();
				}
			} else {
				errorMessage = e.toString();
			}
		}
		box.setMessage(message + errorMessage);
		box.open();
	}
	
	/*
	 * Return a String describing how to analyze the bytes
	 * in the hex dump.
	 */
	static String depthInfo(int depth) {
		Object[] args = {new Integer(depth), ""};
		switch (depth) {
			case 1:
				args[1] = createMsg(bundle.getString("Multi_pixels"), 
				                    new Object[] {new Integer(8), " [01234567]"});
				break;
			case 2:
				args[1] = createMsg(bundle.getString("Multi_pixels"),
				                    new Object[] {new Integer(4), "[00112233]"});
				break;
			case 4:
				args[1] = createMsg(bundle.getString("Multi_pixels"),
				                    new Object[] {new Integer(2), "[00001111]"});
				break;
			case 8:
				args[1] = bundle.getString("One_byte");
				break;
			case 16:
				args[1] = createMsg(bundle.getString("Multi_bytes"), new Integer(2));
				break;
			case 24:
				args[1] = createMsg(bundle.getString("Multi_bytes"), new Integer(3));
				break;
			case 32:
				args[1] = createMsg(bundle.getString("Multi_bytes"), new Integer(4));
				break;
			default:
				args[1] = bundle.getString("Unsupported_lc");
		}
		return createMsg(bundle.getString("Depth_info"), args);
	}
	
	/*
	 * Return the specified number of milliseconds.
	 * If the specified number of milliseconds is too small
	 * to see a visual change, then return a higher number.
	 */
	static int visibleDelay(int ms) {
		if (ms < 20) return ms + 30;
		if (ms < 30) return ms + 10;
		return ms;
	}

	/*
	 * Return the specified byte value as a hex string,
	 * preserving leading 0's.
	 */
	static String toHexByteString(int i) {
		if (i <= 0x0f)
			return "0" + Integer.toHexString(i);
		return Integer.toHexString(i & 0xff);
	}

	/*
	 * Return the specified 4-byte value as a hex string,
	 * preserving leading 0's.
	 * (a bit 'brute force'... should probably use a loop...)
	 */
	static String toHex4ByteString(int i) {
		String hex = Integer.toHexString(i);
		if (hex.length() == 1)
			return "0000000" + hex;
		if (hex.length() == 2)
			return "000000" + hex;
		if (hex.length() == 3)
			return "00000" + hex;
		if (hex.length() == 4)
			return "0000" + hex;
		if (hex.length() == 5)
			return "000" + hex;
		if (hex.length() == 6)
			return "00" + hex;
		if (hex.length() == 7)
			return "0" + hex;
		return hex;
	}
	
	/*
	 * Return a String describing the specified
	 * transparent or background pixel.
	 */
	static String pixelInfo(int pixel) {
		if (pixel == -1)
			return pixel + " (" + bundle.getString("None_lc") + ")";
		else
			return pixel + " (0x" + Integer.toHexString(pixel) + ")";
	}
	
	/*
	 * Return a String describing the specified disposal method.
	 */
	static String disposalString(int disposalMethod) {
		switch (disposalMethod) {
			case SWT.DM_FILL_NONE: return bundle.getString("None_lc");
			case SWT.DM_FILL_BACKGROUND: return bundle.getString("Background_lc");
			case SWT.DM_FILL_PREVIOUS: return bundle.getString("Previous_lc");
		}
		return bundle.getString("Unspecified_lc");
	}
	
	/*
	 * Return a String describing the specified image file type.
	 */
	static String fileTypeString(int filetype) {
		if (filetype == SWT.IMAGE_BMP)
			return "BMP";
		if (filetype == SWT.IMAGE_GIF)
			return "GIF";
		if (filetype == SWT.IMAGE_ICO)
			return "ICO";
		if (filetype == SWT.IMAGE_JPEG)
			return "JPEG";
		if (filetype == SWT.IMAGE_PNG)
			return "PNG";
		return bundle.getString("Unknown_ac");
	}
	
	/*
	 * Return the specified file's image type, based on its extension.
	 * Note that this is not a very robust way to determine image type,
	 * and it is only to be used in the absence of any better method.
	 */
	static int determineFileType(String filename) {
		String ext = filename.substring(filename.lastIndexOf('.') + 1);
		if (ext.equalsIgnoreCase("bmp"))
			return SWT.IMAGE_BMP;
		if (ext.equalsIgnoreCase("gif"))
			return SWT.IMAGE_GIF;
		if (ext.equalsIgnoreCase("ico"))
			return SWT.IMAGE_ICO;
		if (ext.equalsIgnoreCase("jpg") || ext.equalsIgnoreCase("jpeg"))
			return SWT.IMAGE_JPEG;
		if (ext.equalsIgnoreCase("png"))
			return SWT.IMAGE_PNG;
		return SWT.IMAGE_UNDEFINED;
	}
	
	static String createMsg(String msg, Object[] args) {
		MessageFormat formatter = new MessageFormat(msg);
		return formatter.format(args);
	}
	
	static String createMsg(String msg, Object arg) {
		MessageFormat formatter = new MessageFormat(msg);
		return formatter.format(new Object[]{arg});
	}
}
