package org.jcon.df.edit.screen.std;

import org.jcon.df.edit.screen.WidgetDef;
import org.jcon.df.edit.screen.WidgetDefEvent;
import org.jcon.df.edit.screen.WidgetDefEventListener;
import org.jcon.param.Param;
import org.jcon.param.ParamDrivenInfo;
import org.jcon.param.ParamDrivenSupply;
import org.jcon.param.ParamSupplier;
import java.util.Vector;

/**
* This class defines a single widget, which is a
* Control or Module.
*
* @author Jack Harich
*/
public class WidgetDefStd
    implements WidgetDef, ParamDrivenSupply {

//---------- Private Fields ------------------------------
// Properties
private ParamSupplier paramSupplier;
private Param         param;
private String        widgetName;
// Internal
private Vector        listeners = new Vector();

//---------- WidgetDef Implementation --------------------
/**
* Returns a shallow copy of the instance.
*/
public Object clone() {
    WidgetDefStd def = new WidgetDefStd();
    def.paramSupplier = paramSupplier;
    def.param = param;
    def.widgetName = widgetName;
    def.listeners = listeners;
    return def;
}
/**
* Sets the widget name. If this method is used it will
* override the widget name in the Param. 
* The name CANNOT be changed once set.
* The advantage to using this method to set the name and
* not the Param is the Param load can be delayed.
*/
public void setWidgetName(String name) {
    //print(".setWidgetName() - name = " + name);
    widgetName = name;
}
/**
* Returns the name of the widget, which must be unique
* per view. This uses the setWidgetName() or "WidgetName"
* from the Param. The name CANNOT be changed once set.
*/
public String getWidgetName() {
    if (widgetName != null) {
        //print(".getWidgetName() - Returning name = " + widgetName);
        return widgetName;
    } else {
        getParam();
        //print(".getWidgetName() - Returning name from Param = " + param.getString("WidgetName"));        
        return param.getString("WidgetName");
    }
}
/**
* The position defines the position of the widget in the
* view. The position must already exist in the view.
*/
public Object getWidgetPosition() {
    getParam();
    return param.getString("WidgetPosition");
}
/**
* See interface for doc.
*/
public Object getWidgetSubPosition() {
    getParam();
    return param.getString("WidgetSubPosition");
}
/**
* Returns the Param used to create the widget.
*/
public Param getWidgetParam() {
    getParam();
    return param.getParam("WidgetParam");
}
/**
* Adds the listener for WidgetDefEvents.
*/
public void addWidgetDefListener(WidgetDefEventListener listener) {
    listeners.addElement(listener);
}
/**
* Removes the listener for WidgetDefEvents.
*/
public void removeWidgetDefListener(WidgetDefEventListener listener) {
    listeners.removeElement(listener);
}
//---------- ParamDriven Implementation ------------------
public void setParam(Param param) {
    this.param = param;
}
public Param getParam() {
    if (param == null) {
        paramSupplier.supplyParam(this);
        paramSupplier = null;
    }
    return param;
}
/**
* This causes WidgetDefEvent.CHANGED to be fired.
*/
public boolean applyNewParam(Param newParam) {

    // Create event
    WidgetDefEvent evt = new WidgetDefEvent(WidgetDefEvent.CHANGED);
    evt.setOldWidgetDef((WidgetDef)this.clone());
    this.param = newParam;
    evt.setNewWidgetDef(this);
    
    // Send event to listeners
    Vector list = new Vector();
    synchronized(this) {
        list = (Vector)listeners.clone();
    }
    for (int i = 0; i < listeners.size(); i++) {
        WidgetDefEventListener listener = 
            (WidgetDefEventListener)listeners.elementAt(i);
        listener.processWidgetDefEvent(evt);
        print(".applyNewParam() - Event sent");
    }
    return true; // Successful
}
public ParamDrivenInfo getParamDrivenInfo() {
    return null;
}
public void setParamSupplier(ParamSupplier paramSupplier) {
    this.paramSupplier = paramSupplier;
}
//---------- Private Methods -----------------------------
//--- Std
private static void print(String text) {
    System.out.println("WidgetDefStd" + text);
}

} // End class
