package net.sourceforge.ganttproject.gui.options.model;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public abstract class GPAbstractOption implements GPOption, ChangeValueDispatcher {
    private final String myID;

    protected boolean isLocked;

    private List myListeners = new ArrayList();

    private PropertyChangeSupport myPropertyChangeSupport = new PropertyChangeSupport(this);

    private boolean isWritable = true;
    
    private Map<Class,UIHint> myClass_Hint;
    
    protected GPAbstractOption(String id) {
        myID = id;
    }

    public String getID() {
        return myID;
    }

    public void lock() {
        if (isLocked) {
            throw new IllegalStateException("Already locked");
        }
        isLocked = true;
    }

    public void commit() {
        if (!isLocked()) {
            throw new IllegalStateException("Can't commit not locked option");
        }
        setLocked(false);

    }

    public void rollback() {
        if (!isLocked()) {
            throw new IllegalStateException("Can't rollback not locked option");
        }
        setLocked(false);
    }

    protected boolean isLocked() {
        return isLocked;
    }

    protected void setLocked(boolean isLocked) {
        this.isLocked = isLocked;
    }
    
    public void addChangeValueListener(ChangeValueListener listener) {
        myListeners.add(listener);
    }

    protected void fireChangeValueEvent(ChangeValueEvent event) {
        Iterator it = myListeners.iterator();
        while (it.hasNext()) {
            ((ChangeValueListener) it.next()).changeValue(event);
        }
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        myPropertyChangeSupport.addPropertyChangeListener(listener);
    }
    public void removePropertyChangeListener(PropertyChangeListener listener) {
        myPropertyChangeSupport.removePropertyChangeListener(listener);
    }

    public boolean isWritable() {
        return isWritable;
    }


    public void setWritable(boolean isWritable) {
        this.isWritable = isWritable;
        myPropertyChangeSupport.firePropertyChange("isWritable", Boolean.valueOf(!isWritable), Boolean.valueOf(isWritable));
    }

    public UIHint getUIHint(Class hintClass) {
        return myClass_Hint==null ? null : myClass_Hint.get(hintClass);
    }
    
    protected void addHint(Class hintClass, UIHint hint) {
        if (myClass_Hint==null) {
            myClass_Hint = new HashMap<Class, UIHint>();
        }
        myClass_Hint.put(hintClass, hint);
    }
    

}
