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

import java.util.Iterator;

import org.eclipse.draw2d.CompoundBorder;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.SnapFeedbackPolicy;

import org.maskat.core.layout.Grid;
import org.maskat.core.layout.GridHeader;
import org.maskat.ui.editors.layout.commands.AddGridHeaderCommand;
import org.maskat.ui.editors.layout.commands.ChangeGridHeaderWidthCommand;
import org.maskat.ui.editors.layout.editpolicies.ComponentXYLayoutEditPolicy;
import org.maskat.ui.editors.layout.editpolicies.FeedBackComponentEditPolicy;
import org.maskat.ui.editors.layout.editpolicies.LabelDirectEditPolicy;
import org.maskat.ui.editors.layout.editpolicies.MaskatComponentEditPolicy;

public class GridHeaderEditPart extends ComponentEditPart
	implements LabelDirectEditable, HorizontalResizable {

	public static final int headerHeight = 20;

	public static final int headerTop = 20;

	public static final int minimalHeaderDisplayWidth = 10;

	protected IFigure createFigure() {
		Label label = new Label();
		label.setBorder(new CompoundBorder(new LineBorder(), new MarginBorder(0)));
		label.setLayoutManager(new XYLayout());
		return label;
	}

	protected void createEditPolicies() {
		int style = FeedBackComponentEditPolicy.getStyle(this);
		installEditPolicy(EditPolicy.COMPONENT_ROLE, new MaskatComponentEditPolicy());
		installEditPolicy(EditPolicy.LAYOUT_ROLE, new ComponentXYLayoutEditPolicy(style));
		installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new LabelDirectEditPolicy());
		installEditPolicy("Snap Feedback", new SnapFeedbackPolicy());
	}

	protected void refreshVisuals() {
		((Label) this.getFigure()).setText(((GridHeader) this.getModel()).getTitle());

		// gridHeaderDefの場合、setLayoutConstraintのconstraintを計算
		GridHeader gridHeader = (GridHeader) getModel();
		int idx = gridHeader.idxInParent();
		Grid grid = (Grid) gridHeader.getParent();
		Iterator headersIt = grid.getHeadersIt();
		if (headersIt != null) {
			int left = 0;
			for (int i = 0; i < idx; i++) {
				int headerWidth = toHeaderDisplayWidth(
						((GridHeader) headersIt.next()).getWidth());
				left += headerWidth;
			}
			Rectangle constraint = new Rectangle(left, headerTop,
					toHeaderDisplayWidth(gridHeader.getWidth()), headerHeight);
			((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(),
					constraint);
		}
	}
	
	/**
	 * gridヘッダー表示用の幅を返す（minimalHeaderDisplayWidth以下であれば、minimalHeaderDisplayWidthを返す）,
	 * つまり、gridヘッダーの表示幅最小限を限定
	 * 
	 * @param headerWidth
	 * @return
	 */
	public static int toHeaderDisplayWidth(int headerWidth) {
		return Math.max(headerWidth, minimalHeaderDisplayWidth);
	}

	public Object getAdapter(Class key) {
		if (key.equals(IdDirectEditable.class)) {
			return null;
		}
		return super.getAdapter(key);
	}

	public String getLabel() {
		return ((GridHeader) getModel()).getTitle();
	}

	public void setLabel(String text) {
		((GridHeader) getModel()).setTitle(text);
	}
	
	public Command createConstrainCommand(Object model, Rectangle constraint) {
		return  new ChangeGridHeaderWidthCommand((GridHeader) model, constraint);
	}

	public Command getCreateCommand(Object parent, Object node) {
		return  new AddGridHeaderCommand((Grid) parent, (GridHeader) node);
	}
}
