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

import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.window.IShellProvider;

import com.patrikdufresne.jface.dialogs.DetailMessageDialog;
import com.patrikdufresne.managers.ManagerException;
import com.patrikdufresne.util.Localized;
import com.planimod.core.PlanimodManagers;
import com.planimod.core.Shift;
import com.planimod.core.TimeRanges;
import com.planimod.ui.PlanimodPolicy;
import com.planimod.ui.theme.Resources;

/**
 * This action allow the remove all the shifts for current week date.
 * 
 * @author Patrik Dufresne
 * 
 */
public class RemoveAllShiftAction extends Action {

	/**
	 * Property name of an action's date (value <code>"date"</code>). The date
	 * property is used to know the time range to be printed by this action.
	 */
	public static final String DATE = "date"; //$NON-NLS-1$
	private IRunnableContext context;

	/**
	 * Define the date value.
	 */
	private Date date;
	private Localized localized = Localized.load(RemoveAllShiftAction.class);
	/**
	 * The managers to use.
	 */
	private PlanimodManagers managers;
	private IShellProvider shellProvider;

	public RemoveAllShiftAction(PlanimodManagers managers,
			IShellProvider shellProvider, IRunnableContext context) {
		super();
		if (shellProvider == null || managers == null || context == null) {
			throw new NullPointerException();
		}
		this.managers = managers;
		this.shellProvider = shellProvider;
		this.context = context;
		setText(this.localized.get("RemoveAllShiftAction.text")); //$NON-NLS-1$
		setToolTipText(this.localized.get("RemoveAllShiftAction.toolTipText")); //$NON-NLS-1$
		setImageDescriptor(Resources
				.getImageDescriptor(Resources.ICON_LIST_REMOVE_ALL_16));
		setEnabled(canRun());
	}

	/**
	 * Returns True if the action can be run.
	 * 
	 * @return
	 */
	protected boolean canRun() {
		return this.date != null;
	}

	/**
	 * Returns the current date state or null if not define.
	 * 
	 * @return the date state or null
	 */
	public Date getDate() {
		return this.date;
	}

	/**
	 * This implementation run the generate planif in a runnable context.
	 */
	@Override
	public void run() {
		// Check the planif and date value
		if (this.date == null) {
			return;
		}

		// Confirmation
		// Confirmation
		DetailMessageDialog dlg = DetailMessageDialog.openDetailYesNoQuestion(
				this.shellProvider.getShell(), this.localized
						.get("RemoveAllShiftAction.confirmRemove.title"), //$NON-NLS-1$
				this.localized
						.get("RemoveAllShiftAction.confirmRemove.message"), //$NON-NLS-1$
				this.localized
						.get("RemoveAllShiftAction.confirmRemove.shortDetail"), //$NON-NLS-1$
				null);
		if (dlg.getReturnCode() != IDialogConstants.YES_ID) {
			// Operation cancel by user
			return;
		}

		try {
			this.context.run(true, true, new IRunnableWithProgress() {
				@Override
				public void run(IProgressMonitor monitor)
						throws InvocationTargetException, InterruptedException {
					runRemove(monitor);
				}
			});
		} catch (InvocationTargetException e) {
			PlanimodPolicy.showException(e);
		} catch (InterruptedException e) {
			PlanimodPolicy.showException(e);
		}
	}

	protected void runRemove(IProgressMonitor monitor) {

		// Start the task
		monitor.beginTask(this.localized.get("RemoveAllShiftAction.beginTask"), //$NON-NLS-1$
				IProgressMonitor.UNKNOWN);

		// Run the copy
		try {
			Date start = TimeRanges.getWeekStart(this.date, this.managers
					.getApplicationSettingManager().getFirstDayOfWeek());
			Date end = TimeRanges.getWeekEnd(this.date, this.managers
					.getApplicationSettingManager().getFirstDayOfWeek());

			List<Shift> shifts = this.managers.getShiftManager().list(start,
					end);
			this.managers.getShiftManager().remove(shifts);

		} catch (ManagerException e) {
			PlanimodPolicy.showException(e);
		}
		monitor.done();

	}

	/**
	 * Sets the date to define the time range to be printed.
	 * 
	 * @param date
	 *            the new date or null
	 */
	public void setDate(Date date) {
		if ((this.date == null && date != null)
				|| (this.date != null && date == null)
				|| (this.date != null && date != null && !date
						.equals(this.date))) {
			Date oldDescription = this.date;
			this.date = date;
			firePropertyChange(DATE, oldDescription, this.date);
			setEnabled(canRun());
		}
	}

}
