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

import java.util.ArrayList;

import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.util.Geometry;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.swt.widgets.Shell;

/**
 * A JFace window is an object that has no visual representation (no widgets)
 * until it is told to open.
 * <p>
 * Creating a window involves the following steps:
 * <ul>
 * <li>creating an instance of a concrete subclass of <code>Window</code>
 * </li>
 * <li>creating the window's shell and widget tree by calling
 * <code>create</code> (optional)</li>
 * <li>assigning the window to a window manager using
 * <code>WindowManager.add</code> (optional)</li>
 * <li>opening the window by calling <code>open</code></li>
 * </ul>
 * Opening the window will create its shell and widget tree if they have not
 * already been created. When the window is closed, the shell and widget tree
 * are disposed of and are no longer referenced, and the window is automatically
 * removed from its window manager. A window may be reopened.
 * </p>
 * <p>
 * The JFace window framework (this package) consists of this class,
 * <code>Window</code>, the abstract base of all windows, and one concrete
 * window classes (<code>ApplicationWindow</code>) which may also be
 * subclassed. Clients may define additional window subclasses as required.
 * </p>
 * <p>
 * The <code>Window</code> class provides methods that subclasses may 
 * override to configure the window, including:
 * <ul>
 * <li><code>close</code>- extend to free other SWT resources</li>
 * <li><code>configureShell</code>- extend or reimplement to set shell
 * properties before window opens</li>
 * <li><code>createContents</code>- extend or reimplement to create controls
 * before window opens</li>
 * <li><code>getInitialSize</code>- reimplement to give the initial size for
 * the shell</li>
 * <li><code>getInitialLocation</code>- reimplement to give the initial
 * location for the shell</li>
 * <li><code>getShellListener</code>- extend or reimplement to receive shell
 * events</li>
 * <li><code>handleFontChange</code>- reimplement to respond to font changes
 * </li>
 * <li><code>handleShellCloseEvent</code>- extend or reimplement to handle
 * shell closings</li>
 * </ul>
 * </p>
 */
public abstract class Window implements IShellProvider {

	/**
	 * Standard return code constant (value 0) indicating that the window was
	 * opened.
	 * 
	 * @see #open
	 */
	public static final int OK = 0;

	/**
	 * Standard return code constant (value 1) indicating that the window was
	 * canceled.
	 * 
	 * @see #open
	 */
	public static final int CANCEL = 1;

	/**
	 * An array of images to be used for the window. It is expected that the
	 * array will contain the same icon rendered at different resolutions.
	 */
	private static Image[] defaultImages;

	/**
	 * This interface defines a Exception Handler which can be set as a global
	 * handler and will be called if an exception happens in the event loop.
	 */
	public static interface IExceptionHandler {
		/**
		 * Handle the exception.
		 * 
		 * @param t
		 *            The exception that occured.
		 */
		public void handleException(Throwable t);
	}

	/**
	 * Defines a default exception handler.
	 */
	private static class DefaultExceptionHandler implements IExceptionHandler {
		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.window.Window.IExceptionHandler#handleException(java.lang.Throwable)
		 */
		public void handleException(Throwable t) {
			if (t instanceof ThreadDeath) {
				// Don't catch ThreadDeath as this is a normal occurrence when
				// the thread dies
				throw (ThreadDeath) t;
			}
			// Try to keep running.
			t.printStackTrace();
		}
	}

	/**
	 * The exception handler for this application.
	 */
	private static IExceptionHandler exceptionHandler = new DefaultExceptionHandler();
	
	/**
	 * The default orientation of the window. By default
	 * it is SWT#NONE but it can also be SWT#LEFT_TO_RIGHT
	 * or SWT#RIGHT_TO_LEFT
	 */
	private static int orientation = SWT.NONE;

    /**
     * Object used to locate the default parent for modal shells
     */
    private static IShellProvider defaultModalParent = new IShellProvider() {
        public Shell getShell() {
            Display d = Display.getCurrent();
            
            if (d == null) {
                return null;
            }

            Shell parent = d.getActiveShell();
            
            // Make sure we don't pick a parent that has a modal child (this can lock the app)
            if (parent == null) {
                // If this is a top-level window, then there must not be any open modal windows.
                parent = getModalChild(Display.getCurrent().getShells());
            } else {
                // If we picked a parent with a modal child, use the modal child instead
                Shell modalChild = getModalChild(parent.getShells());
                if (modalChild != null) {
                    parent = modalChild;
                }
            }
            
            return parent;
        }
    };
    
	/**
	 * Object that returns the parent shell.
	 */
	private IShellProvider parentShell;

	/**
	 * Shell style bits.
	 * 
	 * @see #setShellStyle
	 */
	private int shellStyle = SWT.SHELL_TRIM;

	/**
	 * Window manager, or <code>null</code> if none.
	 * 
	 * @see #setWindowManager
	 */
	private WindowManager windowManager;

	/**
	 * Window shell, or <code>null</code> if none.
	 */
	private Shell shell;

	/**
	 * Top level SWT control, or <code>null</code> if none
	 */
	private Control contents;

	/**
	 * Window return code; initially <code>OK</code>.
	 * 
	 * @see #setReturnCode
	 */
	private int returnCode = OK;

	/**
	 * <code>true</code> if the <code>open</code> method should not return
	 * until the window closes, and <code>false</code> if the
	 * <code>open</code> method should return immediately; initially
	 * <code>false</code> (non-blocking).
	 * 
	 * @see #setBlockOnOpen
	 */
	private boolean block = false;

	/**
	 * Internal class for informing this window when fonts change.
	 */
	private class FontChangeListener implements IPropertyChangeListener {
		public void propertyChange(PropertyChangeEvent event) {
			handleFontChange(event);
		}
	}

	/**
	 * Internal font change listener.
	 */
	private FontChangeListener fontChangeListener;

	/**
	 * Internal fields to detect if shell size has been set
	 */
	private boolean resizeHasOccurred = false;

	private Listener resizeListener;
 
	/**
	 * Creates a window instance, whose shell will be created under the given
	 * parent shell. Note that the window will have no visual representation
	 * until it is told to open. By default, <code>open</code> does not block.
	 * 
	 * @param parentShell
	 *            the parent shell, or <code>null</code> to create a top-level
	 *            shell. Try passing "(Shell)null" to this method instead of "null"
     *            if your compiler complains about an ambiguity error.
	 * @see #setBlockOnOpen
	 * @see #getDefaultOrientation()
	 */
	protected Window(Shell parentShell) {
        this(new SameShellProvider(parentShell));
        
        if(parentShell == null) {
			setShellStyle(getShellStyle() | getDefaultOrientation());
		}
	}
    
    /**
     * Creates a new window which will create its shell as a child of whatever
     * the given shellProvider returns.
     * 
     * @param shellProvider object that will return the current parent shell. Not null.
     * 
     * @since 3.1
     */
    protected Window(IShellProvider shellProvider) {
        Assert.isNotNull(shellProvider);
        this.parentShell = shellProvider;   
    }

	/**
	 * Determines if the window should handle the close event or do nothing.
	 * <p>
	 * The default implementation of this framework method returns
	 * <code>true</code>, which will allow the
	 * <code>handleShellCloseEvent</code> method to be called. Subclasses may
	 * extend or reimplement.
	 * </p>
	 * 
	 * @return whether the window should handle the close event.
	 */
	protected boolean canHandleShellCloseEvent() {
		return true;
	}

	/**
	 * Closes this window, disposes its shell, and removes this window from its
	 * window manager (if it has one).
	 * <p>
	 * This framework method may be extended (<code>super.close</code> must
	 * be called).
	 * </p>
	 * <p>
	 *  Note that in order to prevent recursive calls to this method 
	 *  it does not call <code>Shell#close()</code>. As a result <code>ShellListener</code>s 
	 *  will not receive a <code>shellClosed</code> event.
	 *  </p>
	 * 
	 * @return <code>true</code> if the window is (or was already) closed, and
	 *         <code>false</code> if it is still open
	 */
	public boolean close() {
		
		// stop listening for font changes
		if (fontChangeListener != null) {
			JFaceResources.getFontRegistry().removeListener(fontChangeListener);
			fontChangeListener = null;
		}
		
		// remove this window from a window manager if it has one
		if (windowManager != null) {
			windowManager.remove(this);
			windowManager = null;
		}

		if (shell == null || shell.isDisposed()) {
			return true;
		}

		// If we "close" the shell recursion will occur.
		// Instead, we need to "dispose" the shell to remove it from the
		// display.
		shell.dispose();
		shell = null;
		contents = null;

		return true;
	}

	/**
	 * Configures the given shell in preparation for opening this window in it.
	 * <p>
	 * The default implementation of this framework method sets the shell's
	 * image and gives it a grid layout. Subclasses may extend or reimplement.
	 * </p>
	 * 
	 * @param newShell
	 *            the shell
	 */
	protected void configureShell(Shell newShell) {

		// The single image version of this code had a comment related to bug
		// 46624,
		// and some code that did nothing if the stored image was already
		// disposed.
		// The equivalent in the multi-image version seems to be to remove the
		// disposed images from the array passed to the shell.
		if (defaultImages != null && defaultImages.length > 0) {
			ArrayList nonDisposedImages = new ArrayList(defaultImages.length);
			for (int i = 0; i < defaultImages.length; ++i) {
				if (defaultImages[i] != null && !defaultImages[i].isDisposed()) {
					nonDisposedImages.add(defaultImages[i]);
				}
			}

			if (nonDisposedImages.size() <= 0) {
				System.err.println("Window.configureShell: images disposed"); //$NON-NLS-1$
			} else {
				Image[] array = new Image[nonDisposedImages.size()];
				nonDisposedImages.toArray(array);
				newShell.setImages(array);
			}
		}

		Layout layout = getLayout();
		if (layout != null) {
			newShell.setLayout(layout);
		}
	}

	/**
	 * Creates the layout for the shell. The layout created here will be
	 * attached to the composite passed into createContents. The default
	 * implementation returns a GridLayout with no margins. Subclasses that
	 * change the layout type by overriding this method should also override
	 * createContents.
	 * 
	 * <p>
	 * A return value of null indicates that no layout should be attached to the
	 * composite. In this case, the layout may be attached within
	 * createContents.
	 * </p>
	 * 
	 * @return a newly created Layout or null if no layout should be attached.
	 * @since 3.0
	 */
	protected Layout getLayout() {
		GridLayout layout = new GridLayout();
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		return layout;
	}

	/**
	 * Constrain the shell size to be no larger than the display bounds.
	 * 
	 * @since 2.0
	 */
	protected void constrainShellSize() {
		// limit the shell size to the display size
		Rectangle bounds = shell.getBounds();
		Rectangle constrained = getConstrainedShellBounds(bounds);
		if (!bounds.equals(constrained)) {
			shell.setBounds(constrained);
		}
	}

	/**
	 * Creates this window's widgetry in a new top-level shell.
	 * <p>
	 * The default implementation of this framework method creates this window's
	 * shell (by calling <code>createShell</code>), and its controls (by
	 * calling <code>createContents</code>), then initializes this window's
	 * shell bounds (by calling <code>initializeBounds</code>).
	 * </p>
	 */
	public void create() {
		shell = createShell();
		contents = createContents(shell);

		//initialize the bounds of the shell to that appropriate for the
		// contents
		initializeBounds();
	}

	/**
	 * Creates and returns this window's contents. Subclasses may attach any
	 * number of children to the parent. As a convenience, the return value of
	 * this method will be remembered and returned by subsequent calls to
	 * getContents(). Subclasses may modify the parent's layout if they overload
	 * getLayout() to return null.
	 * 
	 * <p>
	 * It is common practise to create and return a single composite that
	 * contains the entire window contents.
	 * </p>
	 * 
	 * <p>
	 * The default implementation of this framework method creates an instance
	 * of <code>Composite</code>. Subclasses may override.
	 * </p>
	 * 
	 * @param parent
	 *            the parent composite for the controls in this window. The type
	 *            of layout used is determined by getLayout()
	 * 
	 * @return the control that will be returned by subsequent calls to
	 *         getContents()
	 */
	protected Control createContents(Composite parent) {
		// by default, just create a composite
		return new Composite(parent, SWT.NONE);
	}

	/**
	 * Creates and returns this window's shell.
	 * <p>
	 * The default implementation of this framework method creates a new shell
	 * and configures it using <code/>configureShell</code>. Rather than
	 * override this method, subclasses should instead override
	 * <code/>configureShell</code>.
	 * </p>
	 * 
	 * @return the shell
	 */
	protected final Shell createShell() {

		Shell newParent = getParentShell();
		if(newParent != null &&  newParent.isDisposed()){
			parentShell = new SameShellProvider(null);
			newParent = getParentShell();//Find a better parent
		}
		
		//Create the shell
		Shell newShell = new Shell(newParent, getShellStyle());

		resizeListener = new Listener() {
			public void handleEvent(Event e) {
				resizeHasOccurred = true;
			}
		};

		newShell.addListener(SWT.Resize, resizeListener);
		newShell.setData(this);

		//Add a listener
		newShell.addShellListener(getShellListener());

		//Set the layout
		configureShell(newShell);

		//Register for font changes
		if (fontChangeListener == null) {
			fontChangeListener = new FontChangeListener();
		}
		JFaceResources.getFontRegistry().addListener(fontChangeListener);

		return newShell;
	}

	/**
	 * Returns the top level control for this window. The parent of this control
	 * is the shell.
	 * 
	 * @return the top level control, or <code>null</code> if this window's
	 *         control has not been created yet
	 */
	protected Control getContents() {
		return contents;
	}

	/**
	 * Returns the default image. This is the image that will be used for
	 * windows that have no shell image at the time they are opened. There is no
	 * default image unless one is installed via <code>setDefaultImage</code>.
	 * 
	 * @return the default image, or <code>null</code> if none
	 * @see #setDefaultImage
	 */
	public static Image getDefaultImage() {
		return (defaultImages == null || defaultImages.length < 1) ? null
				: defaultImages[0];
	}

	/**
	 * Returns the array of default images to use for newly opened windows. It
	 * is expected that the array will contain the same icon rendered at
	 * different resolutions.
	 * 
	 * @see org.eclipse.swt.widgets.Decorations#setImages(org.eclipse.swt.graphics.Image[])
	 * 
	 * @return the array of images to be used when a new window is opened
	 * @see #setDefaultImages
	 * @since 3.0
	 */
	public static Image[] getDefaultImages() {
		return (defaultImages == null ? new Image[0] : defaultImages);
	}

	/**
	 * Returns the initial location to use for the shell. The default
	 * implementation centers the shell horizontally (1/2 of the difference to
	 * the left and 1/2 to the right) and vertically (1/3 above and 2/3 below)
	 * relative to the parent shell, or display bounds if there is no parent
	 * shell.
	 * 
	 * @param initialSize
	 *            the initial size of the shell, as returned by
	 *            <code>getInitialSize</code>.
	 * @return the initial location of the shell
	 */
	protected Point getInitialLocation(Point initialSize) {
		Composite parent = shell.getParent();

		Monitor monitor = shell.getDisplay().getPrimaryMonitor();
		if (parent != null) {
			monitor = parent.getMonitor();
		}

		Rectangle monitorBounds = monitor.getClientArea();
		Point centerPoint;
		if (parent != null) {
			centerPoint = Geometry.centerPoint(parent.getBounds());
		} else {
			centerPoint = Geometry.centerPoint(monitorBounds);
		}

		return new Point(centerPoint.x - (initialSize.x / 2), Math.max(
				monitorBounds.y, Math.min(centerPoint.y
						- (initialSize.y * 2 / 3), monitorBounds.y
						+ monitorBounds.height - initialSize.y)));
	}

	/**
	 * Returns the initial size to use for the shell. The default implementation
	 * returns the preferred size of the shell, using
	 * <code>Shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true)</code>.
	 * 
	 * @return the initial size of the shell
	 */
	protected Point getInitialSize() {
		return shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
	}

    /**
     * Returns the most specific modal child from the given list of Shells. 
     * 
     * @param toSearch shells to search for modal children
     * @return the most specific modal child, or null if none
     * 
     * @since 3.1
     */
    private static Shell getModalChild(Shell[] toSearch) {
        int modal = SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL | SWT.PRIMARY_MODAL;
        
        for (int i = toSearch.length - 1; i >= 0; i--) {
            Shell shell = toSearch[i];
            
            // Check if this shell has a modal child
            Shell[] children = shell.getShells();
            Shell modalChild = getModalChild(children);
            if (modalChild != null) {
                return modalChild;
            }
            
            // If not, check if this shell is modal itself
            if (shell.isVisible() && (shell.getStyle() & modal) != 0) {
                return shell;
            }
        }
        
        return null;
    }
    
	/**
	 * Returns parent shell, under which this window's shell is created.
	 * 
	 * @return the parent shell, or <code>null</code> if there is no parent
	 *         shell
	 */
	protected Shell getParentShell() {
        Shell parent = parentShell.getShell();
        
        int modal = SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL | SWT.PRIMARY_MODAL;
        
        if ((getShellStyle() & modal) != 0) {
            // If this is a modal shell with no parent, pick a shell using defaultModalParent.
            if (parent == null) {
                parent = defaultModalParent.getShell();
            }
        }
        
        return parent;
	}

	/**
	 * Returns this window's return code. A window's return codes are
	 * window-specific, although two standard return codes are predefined:
	 * <code>OK</code> and <code>CANCEL</code>.
	 * 
	 * @return the return code
	 */
	public int getReturnCode() {
		return returnCode;
	}

	/**
	 * Returns this window's shell.
	 * 
	 * @return this window's shell, or <code>null</code> if this window's
	 *         shell has not been created yet
	 */
	public Shell getShell() {
		return shell;
	}

	/**
	 * Returns a shell listener. This shell listener gets registered with this
	 * window's shell.
	 * <p>
	 * The default implementation of this framework method returns a new
	 * listener that makes this window the active window for its window manager
	 * (if it has one) when the shell is activated, and calls the framework
	 * method <code>handleShellCloseEvent</code> when the shell is closed.
	 * Subclasses may extend or reimplement.
	 * </p>
	 * 
	 * @return a shell listener
	 */
	protected ShellListener getShellListener() {
		return new ShellAdapter() {
			public void shellClosed(ShellEvent event) {
				event.doit = false; // don't close now
				if (canHandleShellCloseEvent()) {
					handleShellCloseEvent();
				}
			}
		};
	}

	/**
	 * Returns the shell style bits.
	 * <p>
	 * The default value is <code>SWT.CLOSE|SWT.MIN|SWT.MAX|SWT.RESIZE</code>.
	 * Subclassers should call <code>setShellStyle</code> to change this
	 * value, rather than overriding this method.
	 * </p>
	 * 
	 * @return the shell style bits
	 */
	protected int getShellStyle() {
		return shellStyle;
	}

	/**
	 * Returns the window manager of this window.
	 * 
	 * @return the WindowManager, or <code>null</code> if none
	 */
	public WindowManager getWindowManager() {
		return windowManager;
	}

	/**
	 * Notifies of a font property change.
	 * <p>
	 * The default implementation of this framework method does nothing.
	 * Subclasses may reimplement.
	 * </p>
	 * 
	 * @param event
	 *            the property change event detailing what changed
	 */
	protected void handleFontChange(PropertyChangeEvent event) {
		// do nothing
	}

	/**
	 * Notifies that the window's close button was pressed, the close menu was
	 * selected, or the ESCAPE key pressed.
	 * <p>
	 * The default implementation of this framework method sets the window's
	 * return code to <code>CANCEL</code> and closes the window using
	 * <code>close</code>. Subclasses may extend or reimplement.
	 * </p>
	 */
	protected void handleShellCloseEvent() {
		setReturnCode(CANCEL);
		close();
	}

	/**
	 * Initializes the location and size of this window's SWT shell after it has
	 * been created.
	 * <p>
	 * This framework method is called by the <code>create</code> framework
	 * method. The default implementation calls <code>getInitialSize</code>
	 * and <code>getInitialLocation</code> and passes the results to
	 * <code>Shell.setBounds</code>. This is only done if the bounds of the
	 * shell have not already been modified. Subclasses may extend or
	 * reimplement.
	 * </p>
	 */
	protected void initializeBounds() {
		if (resizeListener != null) {
			shell.removeListener(SWT.Resize, resizeListener);
		}
		if (resizeHasOccurred) { // Check if shell size has been set already.
			return;
		}

		Point size = getInitialSize();
		Point location = getInitialLocation(size);
		shell.setBounds(getConstrainedShellBounds(new Rectangle(location.x,
				location.y, size.x, size.y)));
	}

	/**
	 * Opens this window, creating it first if it has not yet been created.
	 * <p>
	 * If this window has been configured to block on open (
	 * <code>setBlockOnOpen</code>), this method waits until the window is
	 * closed by the end user, and then it returns the window's return code;
	 * otherwise, this method returns immediately. A window's return codes are
	 * window-specific, although two standard return codes are predefined:
	 * <code>OK</code> and <code>CANCEL</code>.
	 * </p>
	 * 
	 * @return the return code
	 * 
	 * @see #create()
	 */
	public int open() {
        
		if (shell == null || shell.isDisposed()) {
            shell = null;
			// create the window
			create();
		}

		// limit the shell size to the display size
		constrainShellSize();

		// open the window
		shell.open();

		// run the event loop if specified
		if (block) {
			runEventLoop(shell);
		}

		return returnCode;
	}

	/**
	 * Runs the event loop for the given shell.
	 * 
	 * @param loopShell
	 *            the shell
	 */
	private void runEventLoop(Shell loopShell) {

		//Use the display provided by the shell if possible
		Display display;
		if (shell == null) {
			display = Display.getCurrent();
		} else {
			display = loopShell.getDisplay();
		}

		while (loopShell != null && !loopShell.isDisposed()) {
			try {
				if (!display.readAndDispatch()) {
					display.sleep();
				}
			} catch (Throwable e) {
				exceptionHandler.handleException(e);
			}
		}
		display.update();
	}

	/**
	 * Sets whether the <code>open</code> method should block until the window
	 * closes.
	 * 
	 * @param shouldBlock
	 *            <code>true</code> if the <code>open</code> method should
	 *            not return until the window closes, and <code>false</code>
	 *            if the <code>open</code> method should return immediately
	 */
	public void setBlockOnOpen(boolean shouldBlock) {
		block = shouldBlock;
	}

	/**
	 * Sets the default image. This is the image that will be used for windows
	 * that have no shell image at the time they are opened. There is no default
	 * image unless one is installed via this method.
	 * 
	 * @param image
	 *            the default image, or <code>null</code> if none
	 */
	public static void setDefaultImage(Image image) {
		defaultImages = image == null ? null : new Image[] { image };
	}

	/**
	 * Sets the array of default images to use for newly opened windows. It is
	 * expected that the array will contain the same icon rendered at different
	 * resolutions.
	 * 
	 * @see org.eclipse.swt.widgets.Decorations#setImages(org.eclipse.swt.graphics.Image[])
	 * 
	 * @param images
	 *            the array of images to be used when this window is opened
	 * @since 3.0
	 */
	public static void setDefaultImages(Image[] images) {
		Image[] newArray = new Image[images.length];
		System.arraycopy(images, 0, newArray, 0, newArray.length);
		defaultImages = newArray;
	}
	
	/**
     * Changes the parent shell. This is only safe to use when the shell is not
     * yet realized (i.e., created). Once the shell is created, it must be
     * disposed (i.e., closed) before this method can be called.
     * 
     * @param newParentShell
     *            The new parent shell; this value may be <code>null</code> if
     *            there is to be no parent.
     * @since 3.1
     */
    protected void setParentShell(final Shell newParentShell) {
        Assert.isTrue((shell == null), "There must not be an existing shell."); //$NON-NLS-1$
        parentShell = new SameShellProvider(newParentShell);
    }

	/**
	 * Sets this window's return code. The return code is automatically returned
	 * by <code>open</code> if block on open is enabled. For non-blocking
	 * opens, the return code needs to be retrieved manually using
	 * <code>getReturnCode</code>.
	 * 
	 * @param code
	 *            the return code
	 */
	protected void setReturnCode(int code) {
		returnCode = code;
	}

	/**
	 * Returns the monitor whose client area contains the given point. If no
	 * monitor contains the point, returns the monitor that is closest to the
	 * point. If this is ever made public, it should be moved into a separate
	 * utility class.
	 * 
	 * @param toSearch
	 *            point to find (display coordinates)
	 * @param toFind
	 *            point to find (display coordinates)
	 * @return the montor closest to the given point
	 */
	private static Monitor getClosestMonitor(Display toSearch, Point toFind) {
		int closest = Integer.MAX_VALUE;

		Monitor[] monitors = toSearch.getMonitors();
		Monitor result = monitors[0];

		for (int idx = 0; idx < monitors.length; idx++) {
			Monitor current = monitors[idx];

			Rectangle clientArea = current.getClientArea();

			if (clientArea.contains(toFind)) {
				return current;
			}

			int distance = Geometry.distanceSquared(Geometry
					.centerPoint(clientArea), toFind);
			if (distance < closest) {
				closest = distance;
				result = current;
			}
		}

		return result;
	}

	/**
	 * Given the desired position of the window, this method returns an adjusted
	 * position such that the window is no larger than its monitor, and does not
	 * extend beyond the edge of the monitor. This is used for computing the
	 * initial window position, and subclasses can use this as a utility method
	 * if they want to limit the region in which the window may be moved.
	 * 
	 * @param preferredSize
	 *            the preferred position of the window
	 * @return a rectangle as close as possible to preferredSize that does not
	 *         extend outside the monitor
	 * 
	 * @since 3.0
	 */
	protected Rectangle getConstrainedShellBounds(Rectangle preferredSize) {
		Rectangle result = new Rectangle(preferredSize.x, preferredSize.y,
				preferredSize.width, preferredSize.height);

		Monitor mon = getClosestMonitor(getShell().getDisplay(), Geometry
				.centerPoint(result));

		Rectangle bounds = mon.getClientArea();

		if (result.height > bounds.height) {
			result.height = bounds.height;
		}

		if (result.width > bounds.width) {
			result.width = bounds.width;
		}

		result.x = Math.max(bounds.x, Math.min(result.x, bounds.x
				+ bounds.width - result.width));
		result.y = Math.max(bounds.y, Math.min(result.y, bounds.y
				+ bounds.height - result.height));

		return result;
	}

	/**
	 * Sets the shell style bits. This method has no effect after the shell is
	 * created.
	 * <p>
	 * The shell style bits are used by the framework method
	 * <code>createShell</code> when creating this window's shell.
	 * </p>
	 * 
	 * @param newShellStyle
	 *            the new shell style bits
	 */
	protected void setShellStyle(int newShellStyle) {
		shellStyle = newShellStyle;
	}

	/**
	 * Sets the window manager of this window.
	 * <p>
	 * Note that this method is used by <code>WindowManager</code> to maintain
	 * a backpointer. Clients must not call the method directly.
	 * </p>
	 * 
	 * @param manager
	 *            the window manager, or <code>null</code> if none
	 */
	public void setWindowManager(WindowManager manager) {
		windowManager = manager;

		// Code to detect invalid usage

		if (manager != null) {
			Window[] windows = manager.getWindows();
			for (int i = 0; i < windows.length; i++) {
				if (windows[i] == this) {
					return;
				}
			}
			manager.add(this);
		}
	}

	/**
	 * Sets the exception handler for this application.
	 * <p>
	 * Note that the handler may only be set once.  Subsequent calls to this method will be
	 * ignored.
	 * <p>
	 * 
	 * @param handler
	 *            the exception handler for the application.
	 */
	public static void setExceptionHandler(IExceptionHandler handler) {
		if (exceptionHandler instanceof DefaultExceptionHandler) {
			exceptionHandler = handler;
		}
	}
    
    /**
     * Sets the default parent for modal Windows. This will be used to locate
     * the parent for any modal Window constructed with a null parent.
     * 
     * @param provider shell provider that will be used to locate the parent shell
     * whenever a Window is created with a null parent
     * @since 3.1
     */
    public static void setDefaultModalParent(IShellProvider provider) {
        defaultModalParent = provider;
    }
    
	/**
	 * Gets the default orientation for windows. If it is not
	 * set the default value will be unspecified (SWT#NONE).
	 * 
	 * 
	 * @return SWT#NONE, SWT.RIGHT_TO_LEFT or SWT.LEFT_TO_RIGHT
	 * @see SWT#RIGHT_TO_LEFT
	 * @see SWT#LEFT_TO_RIGHT
	 * @see SWT#NONE
	 * @since 3.1
	 */
	public static int getDefaultOrientation() {
		return orientation;

	}

	/**
	 * Sets the default orientation of windows.
	 * @param defaultOrientation one of 
	 * 	SWT#RIGHT_TO_LEFT, SWT#LEFT_TO_RIGHT ,SWT#NONE
	 * @see SWT#RIGHT_TO_LEFT
	 * @see SWT#LEFT_TO_RIGHT
	 * @see SWT#NONE
	 * @since 3.1
	 */
	public static void setDefaultOrientation(int defaultOrientation) {
		orientation = defaultOrientation;
		
	}

}
