/*
 * 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.beans.PropertyChangeEvent;
import java.util.List;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.editpolicies.SnapFeedbackPolicy;

import org.maskat.core.MaskatElement;
import org.maskat.core.layout.custom.DynaComponent;
import org.maskat.core.layout.custom.DynaComponentClass;
import org.maskat.ui.editors.layout.editpolicies.ComponentXYLayoutEditPolicy;
import org.maskat.ui.editors.layout.editpolicies.DataBindingEditPolicy;
import org.maskat.ui.editors.layout.editpolicies.FeedBackComponentEditPolicy;
import org.maskat.ui.editors.layout.editpolicies.LabelDirectEditPolicy;
import org.maskat.ui.editors.layout.editpolicies.MaskatComponentEditPolicy;
import org.maskat.ui.editors.layout.figures.DynaComponentFigure;
import org.maskat.ui.editors.layout.figures.IFigureFactory;

public class DynaComponentEditPart extends ComponentEditPart {
	
	private int width = 10;
	
	private int height = 10;

	private DynaComponentClass dynaClass;
	
	private IFigureFactory figureFactory;

	public void setWidth(int width) {
		this.width = width;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public void setFigureFactory(IFigureFactory figureFactory) {
		this.figureFactory = figureFactory;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editparts.AbstractEditPart#setModel(java.lang.Object)
	 */
	public void setModel(Object model) {
		super.setModel(model);
		dynaClass = (DynaComponentClass) ((DynaComponent) model).getDynaClass();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.maskat.ui.editors.layout.editparts.ComponentEditPart#createFigure()
	 */
	protected IFigure createFigure() {
		DynaComponent component = (DynaComponent) getModel(); 
		if (figureFactory != null) {
			return figureFactory.createFigure(component);
		}

		String name = component.getName();
		if (name == null) {
			name = dynaClass.getName();	
		}
		if (dynaClass.isContainer()) {
			return new DynaComponentFigure(name, PositionConstants.LEFT);
		}
		return new DynaComponentFigure(name);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.maskat.ui.editors.layout.editparts.ComponentEditPart#createEditPolicies()
	 */
	protected void createEditPolicies() {
		DynaComponent component = (DynaComponent) getModel();
		DynaComponentClass dynaClass = (DynaComponentClass) component.getDynaClass();

		int style = FeedBackComponentEditPolicy.NONRESIZE;
		if (dynaClass.isWidthResizable()) {
			style |= FeedBackComponentEditPolicy.HORIZONTAL;
		}
		if (dynaClass.isHeightResizable()) {
			style |= FeedBackComponentEditPolicy.VERTICAL;
		}

		installEditPolicy(EditPolicy.COMPONENT_ROLE, new MaskatComponentEditPolicy());
		installEditPolicy(EditPolicy.LAYOUT_ROLE, new ComponentXYLayoutEditPolicy(style));
		installEditPolicy("Snap Feedback", new SnapFeedbackPolicy());
		installEditPolicy(DataBindingEditPolicy.ROLE, new DataBindingEditPolicy());
		installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new LabelDirectEditPolicy());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.maskat.ui.editors.layout.editparts.ComponentEditPart#refreshVisuals()
	 */
	protected void refreshVisuals() {
		DynaComponent component = (DynaComponent) getModel();
		Rectangle constraint = new Rectangle(
				component.getLeft(),
				component.getTop(),
				dynaClass.isWidthResizable() ? component.getWidth() : width,
				dynaClass.isHeightResizable() ? component.getHeight() : height);
		
		((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(), constraint);
	}
	
	public void propertyChange(PropertyChangeEvent evt) {
		if ("addChild".equals(evt.getPropertyName()) ||
			"removeChild".equals(evt.getPropertyName())) {
			refresh();
		}
		super.propertyChange(evt);
	}
	
	protected List getModelChildren() {
		List result = null;
		if (getModel() instanceof MaskatElement) {
			result = ((MaskatElement) getModel()).getUnmodifiableChildren();
		}
		return (result != null) ? result : super.getModelChildren(); 
	}
}
