/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package APStudio.models;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.PropertyDescriptor;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;


abstract public class BasicSubpart
	extends BasicElement
{


protected Hashtable inputs = new Hashtable (7);

protected Point location = new Point(0,0);
protected Vector  outputs  = new Vector (4,4);
static final long serialVersionUID = 1;
protected Dimension size = new Dimension(-1,-1);

protected static IPropertyDescriptor[] descriptors = null;
public static String ID_SIZE = "size";         //$NON-NLS-1$
public static String ID_LOCATION = "location"; //$NON-NLS-1$
public static String ID_NAME="Name";
protected String Name;
static{
	descriptors = new IPropertyDescriptor[]{
		new PropertyDescriptor(ID_SIZE, "Size"),
		new PropertyDescriptor(ID_LOCATION,"Location"),
		new TextPropertyDescriptor(ID_NAME,"Name")
	};
}


public BasicSubpart() {
	
}

public void connectInput(Connector w) {
	inputs.put(w.getID(), w);
	update();
	fireStructureChange(INPUTS, w);
}

public void connectOutput(Connector w) {
	outputs.addElement(w);
	update();
	fireStructureChange(OUTPUTS, w);
}

public void disconnectInput(Connector w) {
	String s  = w.getTargetTerminal();
	if(s != null){
	
	inputs.remove(w.getID());
	update();
	fireStructureChange(INPUTS,w);
	}
}

public void disconnectOutput(Connector w) {
	outputs.removeElement(w);
	update();
	fireStructureChange(OUTPUTS,w);
}

public Vector getOutputs(){
	return outputs;
}

public Vector getConnections() {
	Vector v = (Vector)outputs.clone();
	Enumeration ins = inputs.elements();
	while (ins.hasMoreElements())
		v.addElement(ins.nextElement());
	return v;
}

public Image getIcon() {
	return getIconImage();
}

abstract public Image getIconImage();



protected boolean getInput(String terminal) {
	Connector w = (Connector)inputs.get(terminal);
	return (w == null) ? false : w.getValue();
}

public Point getLocation() {
	return location;
}



/**
 * Returns useful property descriptors for the use
 * in property sheets. this supports location ,
 * size and Name.
 *
 * @return  Array of property descriptors.
 */
public IPropertyDescriptor[] getPropertyDescriptors() {
	return descriptors;
}


/**
 * Returns an Object which represents the appropriate
 * value for the property name supplied.
 *
 * @param propName  Name of the property for which the
 *                  the values are needed.
 * @return  Object which is the value of the property.
 */
public Object getPropertyValue(Object propName) {
	if (ID_SIZE.equals(propName))
		return new DimensionPropertySource(getSize());
	else if( ID_LOCATION.equals(propName))
		return new LocationPropertySource(getLocation());
	else if(ID_NAME.equals(propName))
		return new String(getName());
	return null;
}

public Dimension getSize() {
	return size;
}

public Vector getSourceConnections() {
	return (Vector)outputs.clone();
}

public Vector getTargetConnections() {
	Enumeration enum = inputs.elements();
	Vector v = new Vector(inputs.size());
	while (enum.hasMoreElements())
		v.addElement(enum.nextElement());
	return v;
}

/**
 * 
 */
public boolean isPropertySet(){
	return true;	
}

/*
 * Does nothing for the present, but could be
 * used to reset the properties of this to 
 * whatever values are desired.
 *
 * @param id  Parameter which is to be reset.
 *
public void resetPropertyValue(Object id){
	if(ID_SIZE.equals(id)){;}
	if(ID_LOCATION.equals(id)){;}
}*/



public void setLocation(Point p) {
	if (location.equals(p)) return;
	location = p;
	firePropertyChange("location", null, p);  //$NON-NLS-1$
}

protected void setOutput(String terminal, boolean val) {
	Enumeration enum = outputs.elements();
	Connector w;
	while (enum.hasMoreElements()) {
		w = (Connector) enum.nextElement();
		if (w.getSourceTerminal().equals(terminal) && this.equals(w.getSource()))
			w.setValue(val);
	}
}

/**
 * Sets the value of a given property with the value
 * supplied. Also fires a property change if necessary.
 * 
 * @param id  Name of the parameter to be changed.
 * @param value  Value to be set to the given parameter.
 */
public void setPropertyValue(Object id, Object value){
	if (ID_SIZE.equals(id)){
		DimensionPropertySource dimPS = (DimensionPropertySource)value;
		setSize(new Dimension(dimPS.getValue()));
	}
	else if (ID_LOCATION.equals(id)){
		LocationPropertySource locPS = (LocationPropertySource)value;
		setLocation(new Point(locPS.getValue()));
	}
	else if(ID_NAME.equals(id)){
		setName((String)value);
	}
}

public void setSize(Dimension d) {
	if (size.equals(d)) return;
	size = d;
	firePropertyChange("size", null, size);  //$NON-NLS-1$
}

public void setName(String newName ){
		if(Name.equals(newName)) return;
		String oldName = Name;
		Name = newName;
		firePropertyChange("Name",oldName,newName);
	}
	
public String getName(){
		return Name;
	}
}
