package jp.hasc.hasctool.ui.bdeditor2.model;

import java.util.ArrayList;
import java.util.List;

import jp.hasc.hasctool.core.blockdiagram.model.Comment;
import jp.hasc.hasctool.core.blockdiagram.model.Shape;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;

/**
 * @author iwasaki
 */
public abstract class ShapeElement extends ModelElement{
	/** logger for this class */
	private final static org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
			.getLog(ShapeElement.class);
	private static final long serialVersionUID = 1;

	protected BlockDiagramElement bdg_;
	
	public static final String LOCATION_PROP = "Shape.Location";
	public static final String SIZE_PROP = "Shape.Size";
	private static final String XPOS_PROP = "Shape.xPos";
	private static final String YPOS_PROP = "Shape.yPos";
	private static final String WIDTH_PROP = "Shape.Width";
	private static final String HEIGHT_PROP = "Shape.Height";
	
	@Override
	public IPropertyDescriptor[] getPropertyDescriptors() {
		ArrayList<IPropertyDescriptor> descriptors=new ArrayList<IPropertyDescriptor>();
		setupPropertyDescriptors(descriptors);
		return descriptors.toArray(new IPropertyDescriptor[descriptors.size()]);
	}
	
	protected void setupPropertyDescriptors(
			List<IPropertyDescriptor> descriptors) {
		descriptors.add(new TextPropertyDescriptor(XPOS_PROP, "X"));
		descriptors.add(new TextPropertyDescriptor(YPOS_PROP, "Y"));
		descriptors.add(new TextPropertyDescriptor(WIDTH_PROP, "Width"));
		descriptors.add(new TextPropertyDescriptor(HEIGHT_PROP, "Height"));
	}
	
	public Point getLocation() {
		return new Point(getShape().getViewPosition().getX(), getShape().getViewPosition().getY());
	}
	
	public void setLocation(Point newLocation, boolean snapToGrid) {
		getShape().setViewPosition(BlockDiagramElement.toModelPosition(newLocation, snapToGrid));
		firePropertyChange(LOCATION_PROP, null, getLocation());
	}
	
	public Dimension getSize() {
		return new Dimension(getShape().getViewSize().getX(), getShape().getViewSize().getY());
	}
	
	public void setSize(Dimension newSize, boolean snapToGrid) {
		getShape().setViewSize(BlockDiagramElement.toModelPosition(newSize, snapToGrid));
		firePropertyChange(SIZE_PROP, null, getSize());
	}
	
	public abstract Shape getShape();

	public static ShapeElement newInstance(BlockDiagramElement bdg, Shape s) {
		if (s instanceof Comment) {
			return new CommentElement((Comment)s);
		}else{
			throw new RuntimeException();
		}
	}
	
	@Override
	public Object getPropertyValue(Object id) {
		if (XPOS_PROP.equals(id)) {
			return Integer.toString(getLocation().x);
		}else if (YPOS_PROP.equals(id)) {
			return Integer.toString(getLocation().y);
		}else if (WIDTH_PROP.equals(id)) {
			return Integer.toString(getSize().width);
		}else if (HEIGHT_PROP.equals(id)) {
			return Integer.toString(getSize().height);
		}
		return super.getPropertyValue(id);
	}

	@Override
	public void setPropertyValue(Object id, Object value) {
		LOG.debug("setPropertyValue: "+id+"="+value);
		if (XPOS_PROP.equals(id)) {
			int x = Integer.parseInt((String) value);
			setLocation(new Point(x, getLocation().y),false);
		} else if (YPOS_PROP.equals(id)) {
			int y = Integer.parseInt((String) value);
			setLocation(new Point(getLocation().x, y),false);
		} else if (WIDTH_PROP.equals(id)) {
			int iv = Integer.parseInt((String) value);
			setSize(new Dimension(iv, getSize().height),false);
		} else if (HEIGHT_PROP.equals(id)) {
			int iv = Integer.parseInt((String) value);
			setSize(new Dimension(getSize().width, iv),false);
		}
	}
}
