/*
 * 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.util.Arrays;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Shell;

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

/**
 * Action to edit a non-availability event.
 * 
 * @author Patrik Dufresne
 * 
 */
public class EditShiftAction extends Action {
	/**
	 * Property name for shift (value <code>"shift"</code> ).
	 */
	public static final String SHIFT = "shift"; //$NON-NLS-1$

	/**
	 * Static function to edit a shift event.
	 * 
	 * @param managers
	 *            the managers
	 * @param shell
	 *            the parent shell
	 * @param event
	 *            the calendar event to edit
	 */
	public static void edit(PlanimodManagers managers, Shell shell, Shift event) {
		// Open the dialog
		ShiftDialog dlg = new ShiftDialog(shell, managers, ShiftDialog.EDIT);
		dlg.setStart(event.getStartDate());
		dlg.setEnd(event.getEndDate());
		dlg.setShift(event.getTeam());
		if (dlg.open() != Window.OK) {
			// Cancel by user
			return;
		}

		// Validation
		if (dlg.getShift() == null || dlg.getStart() == null
				|| dlg.getEnd() == null
				|| dlg.getStart().compareTo(dlg.getEnd()) > 0) {
			return;
		}

		event.setTeam(dlg.getShift());
		event.setStartDate(dlg.getStart());
		event.setEndDate(dlg.getEnd());

		// Save the event
		try {
			managers.getShiftManager().update(Arrays.asList(event));
		} catch (ManagerException e) {
			PlanimodPolicy.showException(e);
			return;
		}
	}

	/**
	 * Managers to use
	 */
	private PlanimodManagers managers;
	/**
	 * Shell provider.
	 */
	private IShellProvider shellProvider;

	/**
	 * The shift event to be edited.
	 */
	private Shift shift;

	/**
	 * Create a new action.
	 * 
	 * @param managers
	 * @param provider
	 * @param selectionProvider
	 */
	public EditShiftAction(PlanimodManagers managers, IShellProvider provider) {
		this.managers = managers;
		this.shellProvider = provider;
		setText(Localized.get(EditShiftAction.class, "EditShiftAction.text")); //$NON-NLS-1$
		setToolTipText(Localized.get(EditShiftAction.class,
				"EditShiftAction.tooltipText")); //$NON-NLS-1$
		setImageDescriptor(Resources.getImageDescriptor(Resources.ICON_EDIT_16));
		setEnabled(canRun());
	}

	/**
	 * This function is used to determine if the action can be run.
	 * 
	 * @return True if the shift event are define.
	 */
	protected boolean canRun() {
		return this.shift != null;
	}

	public Shift getShift() {
		return this.shift;
	}

	/**
	 * This implementation open a dialog to edit the event.
	 */
	@Override
	public void run() {
		// Retrieve calendar event
		if (this.shift == null) {
			return;
		}
		edit(this.managers, this.shellProvider.getShell(), this.shift);
	}

	/**
	 * Sets the shift event value for this action.
	 * 
	 * @param shift
	 */
	public void setShift(Shift shift) {
		if ((this.shift == null && shift != null)
				|| (this.shift != null && shift == null)
				|| (this.shift != null && shift != null && !shift
						.equals(this.shift))) {
			Object oldDescription = this.shift;
			this.shift = shift;
			firePropertyChange(SHIFT, oldDescription, this.shift);
			setEnabled(canRun());
		}
	}
}