gt: 		fd_removeButton.right = new FormAttachment(100, -8);
context: /*******************************************************************************
   * Copyright (c) 2011 McCOMSoft. All rights reserved.
   *******************************************************************************/
  package com.mccomsoft.palitanlitrato;
  
  /**
   * Palitan Litrato - Tagalog for Change Photo.
   *
   */
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.util.LinkedList;
  import java.util.Properties;
  import java.util.Random;
  
  import org.eclipse.swt.SWT;
  import org.eclipse.swt.dnd.DND;
  import org.eclipse.swt.dnd.DropTarget;
  import org.eclipse.swt.events.KeyAdapter;
  import org.eclipse.swt.events.KeyEvent;
  import org.eclipse.swt.events.MouseAdapter;
  import org.eclipse.swt.events.MouseEvent;
  import org.eclipse.swt.events.SelectionAdapter;
  import org.eclipse.swt.events.SelectionEvent;
  import org.eclipse.swt.events.ShellAdapter;
  import org.eclipse.swt.events.ShellEvent;
  import org.eclipse.swt.layout.FillLayout;
  import org.eclipse.swt.layout.FormAttachment;
  import org.eclipse.swt.layout.FormData;
  import org.eclipse.swt.layout.FormLayout;
  import org.eclipse.swt.widgets.Button;
  import org.eclipse.swt.widgets.Combo;
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.swt.widgets.DirectoryDialog;
  import org.eclipse.swt.widgets.Display;
  import org.eclipse.swt.widgets.Event;
  import org.eclipse.swt.widgets.Group;
  import org.eclipse.swt.widgets.Label;
  import org.eclipse.swt.widgets.List;
  import org.eclipse.swt.widgets.Listener;
  import org.eclipse.swt.widgets.Menu;
  import org.eclipse.swt.widgets.MenuItem;
  import org.eclipse.swt.widgets.MessageBox;
  import org.eclipse.swt.widgets.Shell;
  import org.eclipse.swt.widgets.TabFolder;
  import org.eclipse.swt.widgets.TabItem;
  import org.eclipse.swt.widgets.Tray;
  import org.eclipse.swt.widgets.TrayItem;
  
  import com.mccomsoft.utils.FileUtils;
  import com.swtdesigner.SWTResourceManager;
  
  public class PalitanLitrato {
  
  	// TODO apply style
  	// TODO windows 0,1,2 center,tile,stretch
  	// TODO linux, 0,1,2,3,4 tiled,zoomed,centered,scaled,fill screen
  	// TODO (Joe) I right-click on your toolbar icon, and hit next Image, and
  	// receive a Tiled image (my existing was centered).
  	// I hit Next Image again and nothing happens, so I hit Previous Image and
  	// nothing happens, same tiled image.
  
  	private Label mRememberToApplyLabelOptions;
  	private Combo comboStyle;
  	private Combo comboMode;
  	private static final String PALITAN_LITRATO_ABOUT = "PalitanLitrato (TM) - Change Photo\nBy Dilton McGowan II";
  
  	private class WallpaperInfo {
  		public String msCurrentPath = "";
  		public String msLastPath = "";
  		public IMAGE_STYLE_OPTIONS_WIN32 mStyleWIN32 = IMAGE_STYLE_OPTIONS_WIN32.NONE;
  		public IMAGE_STYLE_OPTIONS_LINUX mStyleLINUX = IMAGE_STYLE_OPTIONS_LINUX.NONE;
  	}
  
  	private WallpaperInfo mWallpaperInfo = new WallpaperInfo();
  
  	private enum IMAGE_FILE_EXTENSIONS {
  		JPG("jpg"), JPEG("jpeg"), PNG("png"), BMP("bmp"), GIF("gif");
  
  		private String msVal;
  
  		private IMAGE_FILE_EXTENSIONS(String pVal) {
  			msVal = pVal;
  		}
  
  		public String getValue() {
  			return msVal;
  		}
  	}
  
  	private enum IMAGE_STYLE_OPTIONS_LINUX {
  		// linux (GNOME) usually uses the same name as the value but
  		// not always, so the name of the constant will be used
  		// to coordinate
  		NONE("None"), WALLPAPER("Tiled"), ZOOM("Zoom"), CENTERED("Centered"), SCALED(
  				"Scaled"), STRETCHED("Fill Screen");
  
  		private String msVal;
  
  		private IMAGE_STYLE_OPTIONS_LINUX(String pVal) {
  			msVal = pVal;
  		}
  
  		public String getValue() {
  			return msVal;
  		}
  	}
  
  	private enum IMAGE_STYLE_OPTIONS_WIN32 {
  		// windows stores center, tile and stretch as 0, 1 and 2
  		NONE("None"), CENTER("Center"), TILE("Tile"), STRETCH("Stretch");
  
  		private String msVal;
  
  		private IMAGE_STYLE_OPTIONS_WIN32(String pVal) {
  			msVal = pVal;
  		}
  
  		public String getValue() {
  			return msVal;
  		}
  	}
  
  	private enum PICTURE_DISPLAY_MODE {
  		RANDOM, DATE
  	}
  
  	private static final String PATHS_KEY = "PATHS";
  	private static final String UNABLE_TO_SAVE_PROPERTIES = "Unable to save properties.";
  	private static final String UNABLE_TO_LOAD_PROPERTIES_FILE = "Unable to load properties file.";
  	private static final String REMEMBER_APPLYCHANGES = "Remember to Apply or Cancel your changes.";
  	private static final String APP_TITLE = "Palitan Litrato";
  	private static final String APP_TOOLTIP_TEXT = "Paltan Litrato (TM) - Current background: ";
  	private static final String TRAY_NA_TEXT = "The system tray is not available";
  	private static final String PICTURE_LOCATIONS = "Picture Locations";
  	private static final String PROPS_FILE = "PalitanLitrato.properties";
  	protected static final String SELECTION_MODE_KEY = "SELECTION_MODE";
  	private static final String IMAGE_STYLE_WIN32_KEY = "IMAGE_STYLE_WIN32";
  	private static final String IMAGE_STYLE_LINUX_KEY = "IMAGE_STYLE_LINUX";
  	private static boolean mbLinux = false;
  	private static boolean mbWindows = false;
  	private static boolean mbMac = false;
  	private static boolean mbNIX = false;
  	private List mList = null;
  	private final Display mDisplay = new Display();
  	private final Shell mShell = new Shell(mDisplay);
  	private Label mRememberToApplyLabelLocations = null;
  	private String[] mPaths = null;
  	private final Properties mProps = new Properties();
  	private PICTURE_DISPLAY_MODE mPictureMode = PICTURE_DISPLAY_MODE.RANDOM;
  	private TrayItem mItem = null;
  
  	public PalitanLitrato() {
  		whatOSIsThis();
  		loadProperties();
  		initApp();
  		finalInit();
  	}
  
  	public static void main(String[] args) {
  		PalitanLitrato pl = new PalitanLitrato();
  		pl.runApp();
  	}
  
  	private void loadProperties() {
  		try {
  			File f = new File(PROPS_FILE);
  			if (f.exists()) {
  				InputStream istr = new FileInputStream(PROPS_FILE);
  				mProps.load(istr);
  				istr.close();
  
  				// update selection mode
  				String sMode = mProps.getProperty(SELECTION_MODE_KEY);
  				for (PICTURE_DISPLAY_MODE mode : PICTURE_DISPLAY_MODE.values()) {
  					if (mode.name().equalsIgnoreCase(sMode)) {
  						mPictureMode = mode;
  					}
  				}
  
  				// update style info
  				if (mbLinux) {
  					for (IMAGE_STYLE_OPTIONS_LINUX style : IMAGE_STYLE_OPTIONS_LINUX
  							.values()) {
  						if (style.name().equalsIgnoreCase(
  								mProps.getProperty(IMAGE_STYLE_LINUX_KEY))) {
  							mWallpaperInfo.mStyleLINUX = style;
  
  							break;
  						}
  					}
  
  				} else if (mbWindows) {
  					for (IMAGE_STYLE_OPTIONS_WIN32 style : IMAGE_STYLE_OPTIONS_WIN32
  							.values()) {
  						if (style.name().equalsIgnoreCase(
  								mProps.getProperty(IMAGE_STYLE_WIN32_KEY))) {
  							mWallpaperInfo.mStyleWIN32 = style;
  
  							break;
  						}
  					}
  
  				} else {
  					for (IMAGE_STYLE_OPTIONS_LINUX style : IMAGE_STYLE_OPTIONS_LINUX
  							.values()) {
  						if (style.name().equalsIgnoreCase(
  								mProps.getProperty(IMAGE_STYLE_LINUX_KEY))) {
  							mWallpaperInfo.mStyleLINUX = style;
  
  							break;
  						}
  					}
  				}
  
  			} else {
  				// create it
  				f.createNewFile();
  			}
  
  		} catch (Exception e) {
  			MessageBox msg = new MessageBox(mShell, SWT.ICON_ERROR);
  			msg.setMessage(UNABLE_TO_LOAD_PROPERTIES_FILE);
  			msg.setText(APP_TITLE);
  			msg.open();
  
  			e.printStackTrace();
  		}
  	}
  
  	private void saveProperties() {
  		try {
  			FileOutputStream outstr = new FileOutputStream(PROPS_FILE);
  			mProps.store(outstr, "");
  			outstr.close();
  
  		} catch (Exception e) {
  			MessageBox msg = new MessageBox(mShell, SWT.ICON_ERROR);
  			msg.setMessage(UNABLE_TO_SAVE_PROPERTIES);
  			msg.setText(APP_TITLE);
  			msg.open();
  
  			e.printStackTrace();
  		}
  	}
  
  	private void initApp() {
  		mShell.addKeyListener(new KeyAdapter() {
  			@Override
  			public void keyReleased(KeyEvent e) {
  				if (e.character == SWT.ESC) {
  					closePreferences();
  				}
  			}
  		});
  		mShell.setLayout(new FillLayout());
  		mShell.setImage(SWTResourceManager
  				.getImage(PalitanLitrato.class,
  						"/com/mccomsoft/palitanlitrato/images/emblem-desktop24x24-running.gif"));
  		mShell.addShellListener(new ShellAdapter() {
  			@Override
  			public void shellClosed(final ShellEvent e) {
  				mShell.setVisible(false);
  				e.doit = false;
  			}
  		});
  		mShell.setToolTipText("");
  		mShell.setText(APP_TITLE);
  		mShell.setVisible(false);
  		final Tray tray = mDisplay.getSystemTray();
  		if (tray == null) {
  			System.err.println(TRAY_NA_TEXT);
  			MessageBox msg = new MessageBox(mShell, SWT.ICON_ERROR);
  			msg.setMessage(TRAY_NA_TEXT);
  			msg.setText(APP_TITLE);
  			msg.open();
  			System.exit(-1);
  
  		}
  
  		whatOSIsThis();
  
  		final TrayItem item = new TrayItem(tray, SWT.NONE);
  		mWallpaperInfo = getCurrentWallpaper();
  		item.setToolTipText(APP_TOOLTIP_TEXT + mWallpaperInfo.msCurrentPath);
  		item.setImage(SWTResourceManager.getImage(PalitanLitrato.class,
  				"images/emblem-desktop24x24-running.gif"));
  		mItem = item;
  
  		//
  		// the menus on the pop-up menu
  		//
  		final Menu menu = new Menu(mShell, SWT.POP_UP);
  		MenuItem miNextImage = new MenuItem(menu, SWT.PUSH);
  		miNextImage.addSelectionListener(new SelectionAdapter() {
  			@Override
  			public void widgetSelected(final SelectionEvent e) {
  				findAndChangeWallpaper(mPictureMode);
  			}
  		});
  		item.addListener(SWT.Selection, new Listener() {
  			@Override
  			public void handleEvent(Event event) {
  				// left mouse click
  				findAndChangeWallpaper(mPictureMode);
  			}
  		});
  		miNextImage.setImage(SWTResourceManager.getImage(PalitanLitrato.class,
  				"images/go-next.png"));
  		miNextImage.setText("&Next Image");
  		MenuItem miPrevImage = new MenuItem(menu, SWT.PUSH);
  		miPrevImage.addSelectionListener(new SelectionAdapter() {
  			@Override
  			public void widgetSelected(final SelectionEvent e) {
  				changeWallpaper(mWallpaperInfo.msLastPath);
  			}
  		});
  		miPrevImage.setImage(SWTResourceManager.getImage(PalitanLitrato.class,
  				"images/go-previous.png"));
  		miPrevImage.setText("&Previous Image");
  		MenuItem miPreferences = new MenuItem(menu, SWT.PUSH);
  		miPreferences.addSelectionListener(new SelectionAdapter() {
  			@Override
  			public void widgetSelected(final SelectionEvent e) {
  				// update the mList of saved paths
  				mList.removeAll();
  				if (mPaths != null) {
  					for (String s : mPaths) {
  						if (mPaths.length > 0) {
  							mList.add(s);
  						}
  					}
  				}
  
  				// update the options panel with saved values
  				updateSelectionMode();
  				updateImageStyle();
  
  				// clear the warning messages
  				clearApplyWarningLocations();
  				clearApplyWarningOptions();
  
  				// show the shell which today is also the preferences dialog
  				mShell.open();
  			}
  		});
  		miPreferences.setImage(SWTResourceManager.getImage(
  				PalitanLitrato.class, "images/edit16.png"));
  		miPreferences.setText("P&references");
  		new MenuItem(menu, SWT.SEPARATOR);
  		MenuItem miQuit = new MenuItem(menu, SWT.PUSH);
  		miQuit.addSelectionListener(new SelectionAdapter() {
  			@Override
  			public void widgetSelected(final SelectionEvent e) {
  				mShell.dispose();
  			}
  		});
  		miQuit.setImage(SWTResourceManager.getImage(PalitanLitrato.class,
  				"images/system-log-out.png"));
  		miQuit.setText("&Quit");
  
  		new MenuItem(menu, SWT.SEPARATOR);
  
  		final MenuItem miAbout = new MenuItem(menu, SWT.PUSH);
  		miAbout.addSelectionListener(new SelectionAdapter() {
  			@Override
  			public void widgetSelected(final SelectionEvent e) {
  				MessageBox msg = new MessageBox(mShell, SWT.ICON_INFORMATION);
  				msg.setMessage(PALITAN_LITRATO_ABOUT);
  				msg.setText(APP_TITLE);
  				msg.open();
  			}
  		});
  		miAbout.setImage(SWTResourceManager.getImage(PalitanLitrato.class,
  				"images/help-browser.png"));
  		miAbout.setText("&About");
  
  		// let the menu be shown when the user right clicks on the tray item
  		item.addListener(SWT.MenuDetect, new Listener() {
  			@Override
  			public void handleEvent(Event event) {
  				menu.setVisible(true);
  			}
  		});
  
  		final TabFolder tabFolder = new TabFolder(mShell, SWT.NONE);
  		tabFolder.addKeyListener(new KeyAdapter() {
  			@Override
  			public void keyReleased(KeyEvent e) {
  				if (e.character == SWT.ESC) {
  					closePreferences();
  				}
  			}
  		});
  
  		final TabItem pictureLocationsTabItem = new TabItem(tabFolder, SWT.NONE);
  		pictureLocationsTabItem.setText(PICTURE_LOCATIONS);
  
  		final TabItem optionsTabItem = new TabItem(tabFolder, SWT.NONE);
  		optionsTabItem.setText("Options");
  
  		final Composite composite_1 = new Composite(tabFolder, SWT.NONE);
  		composite_1.setLayout(new FormLayout());
  		optionsTabItem.setControl(composite_1);
  
  		final Group selectionModeGroup = new Group(composite_1, SWT.NONE);
  		final FormData fd_selectionModeGroup = new FormData();
  		fd_selectionModeGroup.bottom = new FormAttachment(0, 69);
  		fd_selectionModeGroup.top = new FormAttachment(0, 10);
  		fd_selectionModeGroup.right = new FormAttachment(0, 221);
  		fd_selectionModeGroup.left = new FormAttachment(0, 10);
  		selectionModeGroup.setLayoutData(fd_selectionModeGroup);
  		selectionModeGroup.setText("Selection Mode");
  
  		comboMode = new Combo(selectionModeGroup, SWT.READ_ONLY);
  		comboMode.addSelectionListener(new SelectionAdapter() {
  			@Override
  			public void widgetSelected(final SelectionEvent e) {
  				setApplyWarningOptions();
  			}
  		});
  		comboMode.select(0);
  		comboMode.setItems(new String[] { "Random",
  				"Collage (Not yet implemented)",
  				"Camouflage (Not yet implemented)",
  				"Party Mask (Not yet implemented)" });
  		comboMode.setBounds(10, 28, 191, 21);
  
  		final Label testLabel_1_1 = new Label(composite_1, SWT.SEPARATOR);
  		final FormData fd_testLabel_1_1 = new FormData();
  		fd_testLabel_1_1.bottom = new FormAttachment(0, 216);
  		fd_testLabel_1_1.top = new FormAttachment(0, 10);
  		fd_testLabel_1_1.left = new FormAttachment(100, -114);
  		fd_testLabel_1_1.right = new FormAttachment(100, -99);
  		testLabel_1_1.setLayoutData(fd_testLabel_1_1);
  		testLabel_1_1.setText("Label");
  
  		final Button applyOptionsButton = new Button(composite_1, SWT.NONE);
  		final FormData fd_applyOptionsButton = new FormData();
  		fd_applyOptionsButton.bottom = new FormAttachment(0, 39);
  		fd_applyOptionsButton.top = new FormAttachment(0, 10);
  		fd_applyOptionsButton.left = new FormAttachment(100, -99);
  		fd_applyOptionsButton.right = new FormAttachment(100, -14);
  		applyOptionsButton.setLayoutData(fd_applyOptionsButton);
  		applyOptionsButton.addMouseListener(new MouseAdapter() {
  			@Override
  			public void mouseUp(final MouseEvent e) {
  				clearApplyWarningOptions();
  
  				// save the options
  				int iIndex1 = comboMode.getSelectionIndex();
  				if (iIndex1 != -1) {
  					String sItem = comboMode.getItem(iIndex1);
  					mProps.setProperty(SELECTION_MODE_KEY, sItem);
  					saveProperties();
  					loadProperties();
  				}
  				int iIndex2 = comboStyle.getSelectionIndex();
  				if (iIndex2 != -1) {
  					String sItem = comboStyle.getItem(iIndex2);
  					if (mbLinux) {
  						for (IMAGE_STYLE_OPTIONS_LINUX style : IMAGE_STYLE_OPTIONS_LINUX
  								.values()) {
  							if (style.getValue().equalsIgnoreCase(sItem)) {
  								mProps.setProperty(IMAGE_STYLE_LINUX_KEY, style
  										.name().toLowerCase());
  							}
  						}
  
  					} else if (mbWindows) {
  						mProps.setProperty(IMAGE_STYLE_WIN32_KEY, sItem);
  						for (IMAGE_STYLE_OPTIONS_WIN32 style : IMAGE_STYLE_OPTIONS_WIN32
  								.values()) {
  							if (style.getValue().equalsIgnoreCase(sItem)) {
  								mProps.setProperty(IMAGE_STYLE_WIN32_KEY, style
  										.name().toLowerCase());
  							}
  						}
  
  					} else {
  						mProps.setProperty(IMAGE_STYLE_LINUX_KEY, sItem);
  						for (IMAGE_STYLE_OPTIONS_LINUX style : IMAGE_STYLE_OPTIONS_LINUX
  								.values()) {
  							if (style.getValue().equalsIgnoreCase(sItem)) {
  								mProps.setProperty(IMAGE_STYLE_LINUX_KEY, style
  										.name().toLowerCase());
  							}
  						}
  
  					}
  					saveProperties();
  					loadProperties();
  				}
  
  				// update the background
  				changeWallpaper(mWallpaperInfo.msCurrentPath);
  			}
  		});
  		applyOptionsButton.setImage(SWTResourceManager.getImage(
  				PalitanLitrato.class,
  				"/com/mccomsoft/palitanlitrato/images/document-save.png"));
  		applyOptionsButton.setText("Apply");
  
  		final Group selectionModeGroup_1 = new Group(composite_1, SWT.NONE);
  		final FormData fd_selectionModeGroup_1 = new FormData();
  		fd_selectionModeGroup_1.bottom = new FormAttachment(0, 138);
  		fd_selectionModeGroup_1.top = new FormAttachment(0, 79);
  		fd_selectionModeGroup_1.right = new FormAttachment(0, 221);
  		fd_selectionModeGroup_1.left = new FormAttachment(0, 10);
  		selectionModeGroup_1.setLayoutData(fd_selectionModeGroup_1);
  		selectionModeGroup_1.setText("Style");
  
  		comboStyle = new Combo(selectionModeGroup_1, SWT.READ_ONLY);
  		comboStyle.setItems(new String[] { "Not implemented yet" });
  		comboStyle.addSelectionListener(new SelectionAdapter() {
  			@Override
  			public void widgetSelected(final SelectionEvent e) {
  				setApplyWarningOptions();
  			}
  		});
  		comboStyle.select(0);
  		comboStyle.setBounds(10, 28, 191, 21);
  
  		final Button closeButtonOption = new Button(composite_1, SWT.NONE);
  		final FormData fd_closeButtonOption = new FormData();
  		fd_closeButtonOption.bottom = new FormAttachment(0, 74);
  		fd_closeButtonOption.top = new FormAttachment(0, 45);
  		fd_closeButtonOption.left = new FormAttachment(100, -99);
  		fd_closeButtonOption.right = new FormAttachment(100, -14);
  		closeButtonOption.setLayoutData(fd_closeButtonOption);
  		closeButtonOption.addMouseListener(new MouseAdapter() {
  			@Override
  			public void mouseUp(final MouseEvent e) {
  				closePreferences();
  			}
  		});
  		closeButtonOption.setImage(SWTResourceManager.getImage(
  				PalitanLitrato.class,
  				"/com/mccomsoft/palitanlitrato/images/system-log-out.png"));
  		closeButtonOption.setText("Close");
  
  		mRememberToApplyLabelOptions = new Label(composite_1, SWT.SHADOW_IN);
  		final FormData fd_mRememberToApplyLabelOptions = new FormData();
  		fd_mRememberToApplyLabelOptions.top = new FormAttachment(100, -28);
  		fd_mRememberToApplyLabelOptions.bottom = new FormAttachment(100, -11);
  		fd_mRememberToApplyLabelOptions.right = new FormAttachment(100, -107);
  		fd_mRememberToApplyLabelOptions.left = new FormAttachment(0, 10);
  		mRememberToApplyLabelOptions
  				.setLayoutData(fd_mRememberToApplyLabelOptions);
  		mRememberToApplyLabelOptions.setText("textWarn2");
  
  		final Composite composite = new Composite(tabFolder, SWT.NONE);
  		composite.setLayout(new FormLayout());
  		pictureLocationsTabItem.setControl(composite);
  
  		final Button addButton = new Button(composite, SWT.NONE);
  		addButton.setImage(SWTResourceManager.getImage(PalitanLitrato.class,
  				"images/go-jump.png"));
  		addButton.addMouseListener(new MouseAdapter() {
  			@Override
  			public void mouseUp(final MouseEvent e) {
  				setApplyWarningLocations();
  				findImagesDialog();
  			}
  		});
  		final FormData fd_addButton = new FormData();
  		fd_addButton.right = new FormAttachment(100, -8);
  		fd_addButton.left = new FormAttachment(100, -93);
  		fd_addButton.top = new FormAttachment(0, 11);
  		fd_addButton.bottom = new FormAttachment(0, 40);
  		addButton.setLayoutData(fd_addButton);
  		addButton.setText("Add");
  
  		Button removeButton;
  		removeButton = new Button(composite, SWT.NONE);
  		removeButton.setImage(SWTResourceManager.getImage(PalitanLitrato.class,
  				"images/remove16.png"));
  		removeButton.addMouseListener(new MouseAdapter() {
  			@Override
  			public void mouseUp(final MouseEvent e) {
  				setApplyWarningLocations();
  				int iIndex = mList.getSelectionIndex();
  				if (iIndex != -1) {
  					mList.remove(iIndex);
  				} else {
  					clearApplyWarningLocations();
  				}
  			}
  		});
  		final FormData fd_removeButton = new FormData();
  		fd_removeButton.left = new FormAttachment(100, -93);
  