package cnp.ew.spin;

import cnp.ew.util.*;
import cnp.ew.displayer.*;
import cnp.ew.converter.*;
import java.awt.*;
import java.util.*;

public class CpStringListSpinFieldLc extends CpAbstractSpinFieldLc
{

    Dimension cachedPreferredSize;

    CpPrefixMatcher prefixMatcher = new CpPrefixMatcher();

    public CpModelSelectableDisplayable buildDisplayer()
    {
        return new CpPrefixedStringDisplayer();
    }

    public CpToStringConverter buildConverter()
    {
        return CpDefaultToStringConverter.converterFor(getModel());
    }

    public void update(CpObservable o, int facet, Object arg)
    {
        // Questionable...
        if (arg instanceof Vector) {
            prefixMatcher.setStringList(getModel().getStringList());
            cachedPreferredSize = null;
        }
        prefixMatcher.setSelectionIndex(getModel().getSelectionIndex());
        ((CpPrefixedStringDisplayer)getDisplayer()).setPrefixString(prefixMatcher.getPrefixString());
        super.update(o, facet, arg);
    }

    public boolean keyDown(Event e, int key)
    {
        prefixMatcher.processKey(key);

        if (prefixMatcher.wasNoMatch()) {
           //beep();
        }
        if (prefixMatcher.selectionChanged()) {
            getModel().setSelectionIndex(prefixMatcher.getSelectionIndex());
            return true;
        } else if (prefixMatcher.prefixChanged()) {
            ((CpPrefixedStringDisplayer)getDisplayer()).setPrefixString(prefixMatcher.getPrefixString());
            repaint();
            return true;
        }
        return false;
    }

    public Dimension preferredSize()
    {
        // TBD: stringlist model should return an enumeration directly

        if (cachedPreferredSize != null) {
            return cachedPreferredSize;
        }

        Enumeration e = getModel().getStringList().elements();
        String string, savedString;
        Object savedModel;

        savedModel = getDisplayer().getModel();
        if (e.hasMoreElements()) {
            getDisplayer().setModel(e.nextElement());
            cachedPreferredSize = getDisplayer().preferredSize(getSpinEditor());
        } else {
            return new Dimension(0,0);
        }

        while (e.hasMoreElements()) {
            getDisplayer().setModel(e.nextElement());
            cachedPreferredSize.width = Math.max(cachedPreferredSize.width, getDisplayer().preferredSize(getSpinEditor()).width);
        }
        if (savedModel != null) {
            getDisplayer().setModel(savedModel);
        }

        return cachedPreferredSize;
    }

    public void increment()
    {
        getModel().increment();
    }

    public void decrement()
    {
        getModel().decrement();
    }

    public boolean canIncrementAndDecrement()
    {
        return true;
    }

    CpStringListAndSelectionModel getModel()
    {
        return (CpStringListAndSelectionModel)getSpinEditor().getModel();
    }
}