//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.authoring.ui.wizards;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.library.ui.wizards.BaseWizardPage;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.PlatformUI;


/**
 * A wizard page that lists the currently open editors and prompts the user to
 * save them before performing an import or export operation.
 * 
 * @author Jeff Hardy
 * @author Kelvin Low
 * @since 1.0
 */
public class SaveAllEditorsPage extends BaseWizardPage {

	private static final String SAVE_AND_CLOSE_PAGE_TITLE = AuthoringUIResources.AuthoringUIPlugin_SaveAllEditorsPage_saveAndClosePageTitle; //$NON-NLS-1$

	private static final String SAVE_AND_CLOSE_PAGE_DESC = AuthoringUIResources.AuthoringUIPlugin_SaveAllEditorsPage_saveAndClosePageDescription; //$NON-NLS-1$

	private static final String SAVE_PAGE_TITLE = AuthoringUIResources.AuthoringUIPlugin_SaveAllEditorsPage_saveTitle; //$NON-NLS-1$

	private static final String SAVE_PAGE_DESC = AuthoringUIResources.AuthoringUIPlugin_SaveAllEditorsPage_saveDescription; //$NON-NLS-1$

	private boolean doClose;

	private CheckboxTableViewer ctrl_chkboxTableViewer;

	private Button selectAll;

	private Button deselectAll;

	/**
	 * Adds this wizard page to a wizard only when necessary.
	 * 
	 * @param wizard
	 *            The wizard which this page might be added.
	 * @param doClose
	 *            If <code>true</code>, this page will be added iff there are
	 *            open editors. If <code>false</code>, this page will be
	 *            added iff there are dirty editors.
	 * @return <code>true</code> if the page will be added to the wizard.
	 */
	public static boolean addPageIfNeeded(Wizard wizard, boolean doClose) {
		boolean anEditorIsDirty = false;
		IEditorReference[] list = PlatformUI.getWorkbench()
				.getActiveWorkbenchWindow().getActivePage()
				.getEditorReferences();
		for (int i = 0; i < list.length; i++) {
			if (list[i].isDirty()) {
				anEditorIsDirty = true;
				break;
			}
		}

		if (anEditorIsDirty || doClose && list.length > 0) {
			wizard.addPage(new SaveAllEditorsPage(doClose));
			return true;
		} else
			return false;

	}

	/**
	 * Adds this wizard page to a wizard only when necessary.
	 * 
	 * @param wizard
	 *            The wizard which this page might be added.
	 * @param doClose
	 *            If <code>true</code>, this page will be added iff there are
	 *            open editors. If <code>false</code>, this page will be
	 *            added iff there are dirty editors.
	 * @return <code>true</code> if the page will be added to the wizard.
	 */
	public static boolean addPageIfNeeded(Wizard wizard, boolean doClose,
			String title, String description, ImageDescriptor image) {
		boolean anEditorIsDirty = false;
		IEditorReference[] list = PlatformUI.getWorkbench()
				.getActiveWorkbenchWindow().getActivePage()
				.getEditorReferences();
		for (int i = 0; i < list.length; i++) {
			if (list[i].isDirty()) {
				anEditorIsDirty = true;
				break;
			}
		}

		if (anEditorIsDirty || doClose && list.length > 0) {
			SaveAllEditorsPage page = new SaveAllEditorsPage(doClose);
			if (title != null) {
				page.setTitle(title);
			}
			if (description != null) {
				page.setDescription(description);
			}
			if (image != null) {
				page.setImageDescriptor(image);
			}
			wizard.addPage(page);
			return true;
		} else
			return false;
	}

	/**
	 * Creates a new intance.
	 */
	public SaveAllEditorsPage(boolean close) {
		super(SAVE_PAGE_TITLE);
		this.doClose = close;
		if (doClose) {
			setTitle(SAVE_AND_CLOSE_PAGE_TITLE);
			setDescription(SAVE_AND_CLOSE_PAGE_DESC);
		} else {
			setTitle(SAVE_PAGE_TITLE);
			setDescription(SAVE_PAGE_DESC);
		}
	}

	/**
	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(Composite)
	 */
	public void createControl(Composite parent) {
		Composite container = new Composite(parent, SWT.NONE);
		container.setLayout(new GridLayout(2, false));

		IEditorReference[] allEditors = PlatformUI.getWorkbench()
				.getActiveWorkbenchWindow().getActivePage()
				.getEditorReferences();
		List dirtyEditors = new ArrayList();
		for (int i = 0; i < allEditors.length; i++) {
			if (allEditors[i].isDirty())
				dirtyEditors.add(allEditors[i]);
		}

		ctrl_chkboxTableViewer = CheckboxTableViewer.newCheckList(container,
				SWT.BORDER | SWT.FILL | SWT.HORIZONTAL);
		ctrl_chkboxTableViewer.getTable().setLayoutData(
				new GridData(SWT.FILL, SWT.FILL, true, true));

		ctrl_chkboxTableViewer.setLabelProvider(new LabelProvider() {
			public String getText(Object element) {
				IEditorReference ref = (IEditorReference) element;
				return ref.getEditor(false).getTitle();
			}

			public Image getImage(Object element) {
				IEditorReference ref = (IEditorReference) element;
				return ref.getEditor(false).getTitleImage();
			}
		});
		ctrl_chkboxTableViewer.setContentProvider(new ArrayContentProvider());
		ctrl_chkboxTableViewer.setInput(dirtyEditors.toArray());
		ctrl_chkboxTableViewer.setAllChecked(true);

		Composite buttonContainer = new Composite(container, SWT.NONE);
		buttonContainer.setLayout(new GridLayout(1, true));
		buttonContainer.setLayoutData(new GridData(SWT.DEFAULT, SWT.BEGINNING,
				false, true));

		selectAll = new Button(buttonContainer, SWT.PUSH);
		selectAll
				.setText(AuthoringUIResources.AuthoringUIPlugin_SaveAllEditorsPage_SelectAllButtonLabel); //$NON-NLS-1$
		selectAll.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, false,
				true));

		deselectAll = new Button(buttonContainer, SWT.PUSH);
		deselectAll
				.setText(AuthoringUIResources.AuthoringUIPlugin_SaveAllEditorsPage_DeselectAllButtonLabel); //$NON-NLS-1$
		deselectAll.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, false,
				true));

		if (dirtyEditors.size() == 0) {
			ctrl_chkboxTableViewer.getControl().setEnabled(false);
			selectAll.setEnabled(false);
			deselectAll.setEnabled(false);
		}

		addListeners();

		setControl(container);
		setPageComplete(true);
	}

	private void addListeners() {
		selectAll.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				ctrl_chkboxTableViewer.setAllChecked(true);
			}

			public void widgetDefaultSelected(SelectionEvent e) {
				widgetSelected(e);
			}

		});

		deselectAll.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				ctrl_chkboxTableViewer.setAllChecked(false);
			}

			public void widgetDefaultSelected(SelectionEvent e) {
				widgetSelected(e);
			}

		});
	}

	public boolean canFlipToNextPage() {
		return true;
	}

	/**
	 * Perform our save (and possibly close) operation
	 */
	public IWizardPage getNextPage() {
		Object[] checkedArray = ctrl_chkboxTableViewer.getCheckedElements();
		for (int i = 0; i < checkedArray.length; i++) {
			PlatformUI.getWorkbench().getActiveWorkbenchWindow()
					.getActivePage().saveEditor(
							((IEditorReference) checkedArray[i])
									.getEditor(false), false);
		}
		if (doClose)
			PlatformUI.getWorkbench().getActiveWorkbenchWindow()
					.getActivePage().closeAllEditors(false);

		return super.getNextPage();
	}

}
