/*
 * Copyright (c) 2011, Patrik Dufresne. All rights reserved.
 * Patrik Dufresne PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.planimod.ui.views;

import java.util.Arrays;
import java.util.List;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.IShellProvider;

import com.patrikdufresne.jface.dialogs.DetailMessageDialog;
import com.patrikdufresne.managers.ManagedObject;
import com.patrikdufresne.managers.ManagerException;
import com.patrikdufresne.util.Localized;
import com.planimod.core.PlanimodManagers;
import com.planimod.ui.MessageUtils;
import com.planimod.ui.theme.Resources;

/**
 * Action to remove object using managers.
 * <p>
 * The confirmation message displayed by this action can be personalized using
 * the {@link #setConfirmationMessage(String)} and
 * {@link #setConfirmationShortDetail(String)}.
 * 
 * @author Patrik Dufresne
 * 
 */
public class RemoveAction extends Action {
	/**
	 * Property name of this action object (value <code>"object"</code>). The
	 * object property define the entity to be delete.
	 */
	public static final String OBJECT = "object"; //$NON-NLS-1$

	/**
	 * Property name of this action objects (value <code>"objects"</code>). The
	 * objects property define the entities to be deleted.
	 */
	public static final String OBJECTS = "objects"; //$NON-NLS-1$

	/**
	 * Managers used to remove the objects.
	 */
	private PlanimodManagers managers;

	/**
	 * The confirmation message to be displayed.
	 */
	private String message;

	/**
	 * The list of object to be removed.
	 */
	private List<ManagedObject> objects;

	/**
	 * Shell provider.
	 */
	private IShellProvider shellProvider;

	/**
	 * A short detail message.
	 */
	private String shortDetail;

	/**
	 * Create the action
	 * 
	 * @param provider
	 *            the selection provider
	 * @param shellProvider
	 *            the shell provider
	 */
	public RemoveAction(PlanimodManagers managers, IShellProvider shellProvider) {
		if (managers == null || shellProvider == null) {
			throw new NullPointerException();
		}
		this.managers = managers;
		this.shellProvider = shellProvider;
		setText(Localized.get(RemoveAction.class, "RemoveAction.text")); //$NON-NLS-1$
		setToolTipText(Localized.get(RemoveAction.class,
				"RemoveAction.toolTipText")); //$NON-NLS-1$
		setImageDescriptor(Resources
				.getImageDescriptor(Resources.ICON_LIST_REMOVE_16));
		setEnabled(canRun());
	}

	/**
	 * Check if this action can be run.
	 * 
	 * @return
	 */
	protected boolean canRun() {
		return this.objects != null && this.objects.size() > 0;
	}

	/**
	 * Return the confirmation message value or null if unset.
	 * 
	 * @return the message
	 */
	public String getConfirmationMessage() {
		return this.message;
	}

	/**
	 * Return the short detail confirmation message.
	 * 
	 * @return
	 */
	public String getConfirmationShortDetail() {
		return this.shortDetail;
	}

	public ManagedObject getObject() {
		if (this.objects == null || this.objects.size() == 0) {
			return null;
		}
		return this.objects.get(0);
	}

	public List<ManagedObject> getObjects() {
		return this.objects;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.action.Action#run()
	 */
	@Override
	public void run() {

		if (this.objects == null || this.objects.size() == 0) {
			return;
		}

		// Confirmation
		DetailMessageDialog dlg = new DetailMessageDialog(
				this.shellProvider.getShell(),
				Localized.get(RemoveAction.class,
						"RemoveAction.confirmRemove.title"), //$NON-NLS-1$
				null,
				this.message != null ? this.message : Localized.get(
						RemoveAction.class,
						"RemoveAction.confirmRemove.message"), //$NON-NLS-1$
				this.shortDetail != null ? this.shortDetail : Localized.get(
						RemoveAction.class,
						"RemoveAction.confirmRemove.shortDetail"), null, //$NON-NLS-1$
				MessageDialog.QUESTION,
				new String[] { IDialogConstants.YES_LABEL,
						IDialogConstants.NO_LABEL }, 1, // no is the default
				null, false);
		if (dlg.open() != IDialogConstants.YES_ID) {
			return;
		}

		// Proceed with removal
		try {
			this.managers.removeAll(this.objects);
		} catch (ClassCastException e) {
			MessageUtils.openWarning(this.shellProvider.getShell(), Localized
					.get(RemoveAction.class, "RemoveAction.cantRemoveObject"), //$NON-NLS-1$
					Localized.get(RemoveAction.class,
							"RemoveAction.invalidObject"), //$NON-NLS-1$
					e);
			return;
		} catch (ManagerException e) {
			MessageUtils.openWarning(this.shellProvider.getShell(), Localized
					.get(RemoveAction.class, "RemoveAction.cantRemoveObject"), //$NON-NLS-1$
					Localized.get(RemoveAction.class,
							"RemoveAction.errorOccurred"), //$NON-NLS-1$
					e);
		}

	}

	/**
	 * Sets the confirmation to be displayed when the user run this action.
	 * 
	 * @param message
	 *            the messagevalue or null to use the default message.
	 */
	public void setConfirmationMessage(String message) {
		this.message = message;
	}

	/**
	 * Sets the short detail confirmation message.
	 * 
	 * @param message
	 */
	public void setConfirmationShortDetail(String message) {
		this.shortDetail = message;
	}

	/**
	 * Sets the object to be deleted.
	 * 
	 * @param object
	 *            the object
	 */
	public void setObject(ManagedObject object) {
		firePropertyChange(OBJECT, getObject(),
				this.objects = (object == null ? null : Arrays.asList(object)));
		setEnabled(canRun());
	}

	public void setObjects(List<ManagedObject> objects) {
		this.objects = objects;
		setEnabled(canRun());
	}

}
