/*
 * Copyright (c) 2006-2008 Maskat Project.
 *
 * 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:
 *     Maskat Project - initial API and implementation
 */
package org.maskat.ui.editors.layout.commands;

import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.commands.Command;

import org.maskat.core.layout.DivSplit;
import org.maskat.core.layout.Component;
import org.maskat.core.layout.Container;
import org.maskat.core.layout.Popup;
import org.maskat.ui.Messages;

public class ChangeConstraintCommand extends Command {
	
	private Component nodeElement;

	private Rectangle newConstraint;
	
	private Rectangle oldConstraint;

	public ChangeConstraintCommand(Component node, Rectangle newConstraint) {
		super(node.getName() + Messages.getString("layout.cmd.constraint.msg")); //$NON-NLS-1$
		this.nodeElement = node;
		this.newConstraint = newConstraint;
	}

	/*
	 * (非 Javadoc)
	 * 
	 * @see org.eclipse.gef.commands.Command#execute()
	 */
	public void execute() {
		doExecute();
	}

	private void doExecute() {
		
		// 制約の変更
		if (nodeElement instanceof DivSplit) {
			
			// ここではnewConstraint.heightあるいはwidthはDivSplitDefのheightとwidthである
			// parentのSplitterDefのheightとwidthではなく
			// だから、nodeElementの相対座標変化を計算して、SplitterDefの座標を計算する

			int deltaX = newConstraint.x - nodeElement.getLeft();
			int deltaY = newConstraint.y - nodeElement.getTop();
			int deltaWidth = newConstraint.width - nodeElement.getWidth();
			int deltaHeight = newConstraint.height - nodeElement.getHeight();

			Container parent = nodeElement.getContainer();
			if (parent.getContainer() instanceof Popup) {
				deltaY = (parent.getTop() + deltaY) < 0 ? -parent.getTop() : deltaY;
			}

			this.oldConstraint = new Rectangle(parent.getLeft(), parent.getTop(), 
					parent.getWidth(), parent.getHeight());
			parent.setConstraint(parent.getLeft() + deltaX, parent.getTop() + deltaY,
					parent.getWidth() + deltaWidth, parent.getHeight() + deltaHeight);
		} else {
			this.oldConstraint = new Rectangle(nodeElement.getLeft(), nodeElement
					.getTop(), nodeElement.getWidth(), nodeElement.getHeight());

			nodeElement.setConstraint(newConstraint.x, newConstraint.y, newConstraint.width,
					newConstraint.height);
		}
	}

	public boolean canUndo() {
		return true;
	}

	/*
	 * (非 Javadoc)
	 * 
	 * @see org.eclipse.gef.commands.Command#undo()
	 */
	public void undo() {
		
		// 制約を元にもどす
		if (nodeElement instanceof DivSplit) {
			nodeElement.getContainer().setConstraint(oldConstraint.x, oldConstraint.y,
					oldConstraint.width, oldConstraint.height);
		} else {
			nodeElement.setConstraint(oldConstraint.x, oldConstraint.y,
					oldConstraint.width, oldConstraint.height);
		}
	}

}
