//------------------------------------------------------------------------------
// 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.library.edit.command;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.common.command.AbstractCommand;
import org.eclipse.epf.library.edit.util.Misc;
import org.eclipse.epf.library.edit.util.SectionList;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Section;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.util.UmaUtil;

/**
 * This command is used to reorder a section within a section list.
 * 
 * @author Shashidhar Kannoori
 * @since 1.0
 */
public class MoveInSectionListCommand extends AbstractCommand implements
		IResourceAwareCommand {

	private ContentElement contentElement;

	private SectionList sectionList;

	private List<? extends Section> elementsList;

	private ContentElement usedContentElement = null;

	private Collection modifiedResources;

	private static int UP = 1;

	private static int Down = 0;

	private int direction = -1;

	private boolean moved;

	/**
	 * @deprecated
	 */
	public MoveInSectionListCommand() {
		super();
	}

	public MoveInSectionListCommand(ContentElement contentElement,
			List<? extends Section> elementsList, SectionList sectionList, int direction) {
		this.contentElement = contentElement;
		this.sectionList = sectionList;
		this.elementsList = elementsList;
		this.direction = direction;

		modifiedResources = new HashSet();
	}

	protected boolean prepare() {
		return true;
	}

	/**
	 * @param label
	 */
	public MoveInSectionListCommand(String label) {
		super(label);
	}

	/**
	 * @param label
	 * @param description
	 */
	public MoveInSectionListCommand(String label, String description) {
		super(label, description);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.command.IResourceAwareCommand#getModifiedResources()
	 */
	public Collection getModifiedResources() {
		if (contentElement.getPresentation() != null) {
			modifiedResources.add(contentElement.getPresentation().eResource());
		}
		return modifiedResources;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.Command#execute()
	 */
	public void execute() {
		MethodPlugin taskPlugin = UmaUtil.getMethodPlugin(contentElement);
		MethodPlugin elementPlugin = UmaUtil
				.getMethodPlugin((MethodElement) elementsList.get(0));

		if (taskPlugin != elementPlugin
				&& Misc.isBaseOf(taskPlugin, elementPlugin)) {
			for (Iterator iter = TngUtil.getContributors(contentElement); iter
					.hasNext();) {
				VariabilityElement ve = (VariabilityElement) iter.next();
				if (ve instanceof ContentElement
						&& UmaUtil.getMethodPlugin(ve) == elementPlugin) {
					usedContentElement = (ContentElement) ve;
					break;
				}
			}
		}
		if (usedContentElement == null) {
			usedContentElement = contentElement;
		}

		redo();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.command.Command#redo()
	 */
	public void redo() {
		if (usedContentElement == null)
			return;
		int size = elementsList.size();
		for (Section object : elementsList) {
			int index = sectionList.indexOf(object);
			if (direction == UP) {
				if (index > 0)
					sectionList.move(index - 1, object);
			} else if (direction == Down) {
				if (index < sectionList.size())
					sectionList.move(index + size, object);
			}
			moved = true;
		}
		sectionList.apply();

	}

	public void undo() {
		if (moved) {
			int size = elementsList.size();
			for (Section object : elementsList) {
				int index = sectionList.indexOf(object);
				if (direction == UP) {
					if (index < sectionList.size())
						sectionList.move(index + size, object);
				} else if (direction == Down) {
					if (index > 0)
						sectionList.move(index - 1, object);
				}
				moved = true;
			}
			sectionList.apply();
			moved = false;
		}
	}

	public Collection getAffectedObjects() {
		return Collections.singletonList(usedContentElement);
	}

}
