/** BEGIN COPYRIGHT BLOCK
 * Copyright (C) 2001 Sun Microsystems, Inc.  Used by permission.
 * Copyright (C) 2005 Red Hat, Inc.
 * All rights reserved.
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 2
 * of the License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 * END COPYRIGHT BLOCK **/
package com.netscape.management.admserv.config;

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import com.netscape.management.client.util.*;

/**
  *
  * @version 0.1 11/26/97
  * @author miodrag@netscape.com
  */

public class EditMonitor implements ActionListener, ChangeListener,
DocumentListener, ItemListener, ListDataListener {

    boolean _isDirty = false;

    boolean _isRunning = false;

    /** Dirty flag listeners */
    Vector _listeners;

    /** Components to be enabled when dirty flag is true */
    Vector _enableComponents;

    /** Components to be disable when dirty flag is true */
    Vector _disableComponents;


    /**
     * Constructors
    */
    public EditMonitor() {
        _enableComponents = new Vector(5);
        _disableComponents = new Vector(5);
        _listeners = new Vector(5);
    }

    /** Start processing change events */
    void start() {
        _isRunning = true;
    }

    /** Do not process change events */
    void stop() {
        _isRunning = false;
    }

    /**
      * Change listeners when dirty flag is modified
     */

    public void addChangeListener(ChangeListener l) {
        _listeners.addElement(l);
    }

    public void removeChangeListener(ChangeListener l) {
        _listeners.removeElement(l);
    }

    protected void fireChangeEvent() {
        for (int i = 0; i < _listeners.size(); i++) {
            ChangeListener l = (ChangeListener)_listeners.elementAt(i);
            l.stateChanged(new ChangeEvent(new Boolean(_isDirty)));
        }
    }

    /**
      * Getter / Setter methods
     */
    public void setEnableComponets(Vector enableComponents) {
        _enableComponents = new Vector();
    }

    public void setDisableComponets(Vector disableComponents) {
        _disableComponents = new Vector();
    }

    public void addEnableComponent(Component c) {
        //Debug.println("addEnableComponent" + c.getClass().getName());
        _enableComponents.addElement(c);
        c.setEnabled(_isDirty);
    }

    public void addDisableComponent(Component c) {
        //Debug.println("addDisableComponent" + c.getClass().getName());
        _disableComponents.addElement(c);
        c.setEnabled(!_isDirty);
    }


    private void setComponentsEnabledState(boolean flag) {
        for (int i = 0; i < _enableComponents.size(); i++) {
            Component c = (Component)_enableComponents.elementAt(i);
            c.setEnabled(flag);
        }
        for (int i = 0; i < _disableComponents.size(); i++) {
            Component c = (Component)_disableComponents.elementAt(i);
            c.setEnabled(!flag);
        }

    }

    public void setDirtyFlag(boolean flag) {
        //Thread.currentThread().dumpStack();
        //Debug.println("dirtyFlag="+flag);
        if (_isRunning) {
            boolean modified = (flag != _isDirty);
            _isDirty = flag;
            setComponentsEnabledState(_isDirty);
            if (modified) {
                fireChangeEvent();
            }
        }
    }

    public boolean getDirtyFlag() {
        return _isDirty;
    }

    /**
      *  Subscription methods for monitoring changes
     */
    public void monitor(JTextComponent text) {
        text.getDocument().addDocumentListener(this);
    }

    public void monitor(JList list) {
        list.getModel().addListDataListener(this);
    }

    public void monitor(ListModel model) {
        model.addListDataListener(this);
    }

    public void monitor(JToggleButton toggle) {
        toggle.addActionListener(this);
    }

    public void monitor(JComboBox comboChoice) {
        comboChoice.addItemListener(this);
    }

    /**
      *   Listener interface implementation
     */

    // Action
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() instanceof Component) {
            Component c = (Component) e.getSource();
            if (c.isEnabled()) {
                setDirtyFlag(true);
            }
        } else {
            setDirtyFlag(true);
        }
    }

    // Change
    public void stateChanged(ChangeEvent e) {
        setDirtyFlag(true);
    }

    // Document
    public void changedUpdate(DocumentEvent e) {
        setDirtyFlag(true);
    }
    public void insertUpdate(DocumentEvent e) {
        setDirtyFlag(true);
    }
    public void removeUpdate(DocumentEvent e) {
        setDirtyFlag(true);
    }

    // Item
    public void itemStateChanged(ItemEvent e) {
        if (e.getSource() instanceof Component) {
            Component c = (Component) e.getSource();
            if (c.isEnabled()) {
                setDirtyFlag(true);
            }
        } else {
            setDirtyFlag(true);
        }
    }

    // List Data
    public void contentsChanged(ListDataEvent e) {
        setDirtyFlag(true);
    }
    public void intervalAdded(ListDataEvent e) {
        setDirtyFlag(true);
    }
    public void intervalRemoved(ListDataEvent e) {
        setDirtyFlag(true);
    }

    public String toString() {
        return "EditMonitor[dirty=" + _isDirty + ", running=" +
                _isRunning + "]";
    }
}
