package cnp.ew.list;

import java.awt.*;
import java.util.*;

import cnp.ew.util.*;
import cnp.ew.misc.*;
import cnp.ew.displayer.*;
import cnp.ew.lightweight.*;
import cnp.ew.layout.*;
import cnp.ew.button.*;
import cnp.ew.image.*;
import cnp.ew.properties.*;
import cnp.ew.text.*;

public class CpDropDownListLc extends CpAbstractLc implements CpEditor
{

    static int downArrowId;

    static {
        downArrowId = CpToolkit.registerImageName("darrow12.gif");
    }

    Vector choices;

    CpLabeledImageButtonLc downButton;
    CpReadOnlyTextAreaLc text;
    CpListboxLc pop, popLc;

    boolean dontPopup = false;

    public CpDropDownListLc()
    {
        CpAttachmentsLayout layout = new CpAttachmentsLayout();
        setLayout(layout);

        setBorderStyle(BORDER_INWARD3D);

        downButton = new CpLabeledImageButtonLc(CpToolkit.getImage(downArrowId));
        downButton.setUsesFocus(false);
        ((CpButtonBorderDisplayer)downButton.getBorderDisplayer()).setReverse3D(true);
        downButton.addObserver(this);
        CpAttachments attachments = new CpAttachments(-1, 0, 0, 0);
        layout.setAttachments(downButton, attachments);
        add(downButton);

        text = new CpReadOnlyTextAreaLc("");
        text.setBorderMargin(1, 1);
        text.setSelectionStyle(CpReadOnlyTextAreaLc.SELECT_CELL);
        text.setSelectionExpansion(1);
        text.setBackground(Color.white);
        text.setVerticalAlignment(CpAlignable.ALIGN_CENTER);
        attachments = new CpAttachments(0, 0, -1, 0);
        attachments.setRightAttachment(0, downButton);
        layout.setAttachments(text, attachments);
        add(text);

    }

    public void setItems(Vector v)
    {
        choices = v;
        if (!choices.isEmpty()) {
            setObject(choices.elementAt(0));
        }
        popLc = null;
    }

    public void removeAllItems()
    {
        choices = new Vector();
        popLc = null;
    }

    public void addItem(Object o)
    {
        if (choices == null) {
            choices = new Vector();
        }
        choices.addElement(o);
        if (choices.size() == 1) {
            setObject(o);
        }
        popLc = null;
    }

    public Dimension preferredSize()
    {
        int totalWidth = 0;
        FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(text.getFont());
        for (int i = 0; i < choices.size(); i++) {
            totalWidth = Math.max(totalWidth, fm.stringWidth(((String)choices.elementAt(i))));
        }
        Dimension d = new Dimension(10 + totalWidth + downButton.preferredSize().width, Math.max(text.preferredSize().height - 3, downButton.preferredSize().height));
        return borderedPreferredSize(d);
    }

    public void setObject(Object o)
    {
        text.setText((String)o);
    }

    public Object getObject()
    {
        return text.getText();
    }

    public String getSelectedItem()
    {
        return text.getText();
    }

    public int getSelectedIndex()
    {
        return choices.indexOf(getObject());
    }

    public void select(String s)
    {
        setObject(s);
    }

    public void select(int i)
    {
        select((String)choices.elementAt(i));
    }

    public boolean keyDown(Event e, int key)
    {
        int selectedIndex;
        // TBD: this doesn't work in windows; if the alt key's down, we don't get keys, I guess.
        if ((key == Event.UP || key == Event.DOWN) && e.metaDown()) {
            popUpList();
            return true;
        }

        switch (key) {
        case Event.LEFT:
        case Event.UP:
            selectedIndex = getSelectedIndex();
            if (selectedIndex > 0) {
                select(selectedIndex - 1);
           	    notifyObservers(OBJECT_CHANGING);
           	    notifyObservers(OBJECT_CHANGED);
            }
            return true;
        case Event.RIGHT:
        case Event.DOWN:
            selectedIndex = getSelectedIndex();
            if (selectedIndex < choices.size() - 1) {
                select(selectedIndex + 1);
           	    notifyObservers(OBJECT_CHANGING);
           	    notifyObservers(OBJECT_CHANGED);
            }
            return true;
        default:
            return false;
        }

    }

    public boolean mouseDown(Event e, int x, int y)
    {
        update(null, BUTTON_PRESS, null);
        return false;
    }

    CpListboxLc getPopLc()
    {
        if (popLc == null) {
            popLc = new CpListboxLc(false, false);
            popLc.setBorderStyle(BORDER_LINE);
            popLc.setBackground(Color.white);
            popLc.listPane.setSelectionDisplayStyle(CpGeneralStringDisplayer.SELECT_CELL);
            popLc.listPane.setSelectionExpansion(1);
            popLc.setItems(choices);
            popLc.addObserver(this);
        }
        return popLc;
    }

    public void update(CpObservable o, int facet, Object arg)
    {
        switch (facet) {
            case LC_POPPED_DOWN : {
                pop = null;
                Point mouseLoc = mouseLocation();
                Rectangle rect = new Rectangle(0, 0, size().width, size().height);
                if (!rect.inside(mouseLoc.x, mouseLoc.y)) {
                    dontPopup = false;
                }
                requestFocus();
                break;
            }
            case BUTTON_PRESS : {
                if (dontPopup == true) {
                    dontPopup = false;
                    break;
                }
                popUpList();
                break;
            }
            case OBJECT_CHANGED : {
               // System.out.println("Got an obj changed from " + o);
               // System.out.println("Selected: " + pop.getSelectedItem());
           	    setObject(pop.getSelectedItem());
           	    popDownPoppedUpLc();
           	    notifyObservers(OBJECT_CHANGING);
           	    notifyObservers(OBJECT_CHANGED);
            }
        }
    }

    void popUpList()
    {
        if (pop == null) {
            dontPopup = true;
            pop = getPopLc();
            popUpLcAt(pop, new Rectangle(0, size().height, size().width, pop.preferredSize().height));
            pop.requestFocus();
        }
    }

    /********** Default stuff for cpeditor ******/

    public int getVerticalAlignment()
    {
        return ALIGN_TOP;
    }

    public void setVerticalAlignment(int verticalAlignment) {}

    public int getHorizontalAlignment()
    {
        return ALIGN_LEFT;
    }

    public void setHorizontalAlignment(int horizontalAlignment) {}

    public boolean usesFocus()
    {
        return true;
    }

    public boolean gotFocus()
    {
        enableDamageRepair(false);
        text.setShowFocus(true);
        text.setIsSelected(true);
        enableDamageRepair(true);
        repairDamage();
        return true;
    }

    public boolean lostFocus()
    {
        enableDamageRepair(false);
        text.setShowFocus(false);
        text.setIsSelected(false);
        enableDamageRepair(true);
        repairDamage();
        return true;
    }
}


