package cnp.ew.notebook;

import cnp.ew.util.*;
import java.awt.*;
import java.util.*;
import cnp.ew.displayer.*;
import cnp.ew.lightweight.*;

public abstract class CpAbstractNotebookTabsLc extends CpAbstractLc
implements CpTabsLc
{
    Vector tabs = new Vector(5);

    CpTabLc selectedTab=null;

    CpTabDisplayable tabDisplayer;

    public CpAbstractNotebookTabsLc(CpTabDisplayable newTabDisplayer)
    {
        super();
        tabDisplayer = newTabDisplayer;
    }

    public void addTab(String s)
    {
        addTab(new CpGeneralStringDisplayer(s));
    }

    public void addTab(CpDisplayable innerDisplayer)
    {
        CpTabLc newTab = new CpTabLc(tabDisplayer, innerDisplayer);
        newTab.setIsGroupStart(false);
        tabs.addElement(newTab);
        add(newTab);

        newTab.addObserver(this);

        if (selectedTab == null) {
            selectTab(newTab);
        }

        // allow subclasses to do something
        tabAdded();
    }

    public void update(CpObservable o, int facet, Object arg)
    {
        if (facet == TAB_SELECTED) {
            basicSelectTab((CpTabLc)o, true);
        }
    }

    void tabAdded()
    {
    }


    public void selectTab(CpTabLc tab)
    {
        basicSelectTab(tab, false);
    }

    void basicSelectTab(CpTabLc tab, boolean wasClick)
    {
        if (selectedTab == tab) {
            return;
        }

        if (selectedTab != null) {
            selectedTab.setIsSelected(false);
            selectedTab.setIsTabStop(false);
        }
        tab.setIsSelected(true);
        tab.setIsTabStop(isTabStop());
        selectedTab = tab;

        selectedTabChanged(wasClick);
        repaint();
        notifyObservers(TAB_CHANGED);
    }

    public void setSelectedTabIndex(int index)
    {
        CpTabLc tab = (CpTabLc)tabs.elementAt(index);
        selectTab(tab);
    }


    public int getSelectedTabIndex()
    {
        for (int i = 0; i < tabs.size(); i++) {
            if (selectedTab == tabs.elementAt(i)) {
                return i;
            }
        }
        return -1;
    }

    CpTabLc getSelectedTab()
    {
        return selectedTab;
    }

    public boolean gotFocus()
    {
        selectedTab.requestFocus();
        return true;
    }

        /**
     * Special case: need to handle shifting directly, since our z-order gets reordered
     * each time a tab is selected. Ugh.
     */
    public boolean wantsLeftAndRightArrows()
    {
        return true;
    }

    public boolean keyDown(Event e, int key)
    {
        switch (key) {
        case Event.LEFT:
        case Event.UP:
            shiftFocusToPreviousTab();
            return true;
        case Event.RIGHT:
        case Event.DOWN:
            shiftFocusToNextTab();
            return true;
        default:
            return false;
        }
    }

    void shiftFocusToNextTab()
    {
        enableDamageRepair(false);
        int index = tabs.indexOf(selectedTab);
        if (index < tabs.size() - 1) {
            ((CpTabLc)tabs.elementAt(index + 1)).requestFocus();
        }
        enableDamageRepair(true);
        repairDamage();
    }

    void shiftFocusToPreviousTab()
    {
        enableDamageRepair(false);
        int index = tabs.indexOf(selectedTab);
        if (index > 0) {
            ((CpTabLc)tabs.elementAt(index - 1)).requestFocus();
        }
        enableDamageRepair(true);
        repairDamage();
    }

    /**
     * subclasses should do something with this (e.g. cause layout to happen)
     * The boolean value tells whether this was from user input or a programmatic change.
     */
    void selectedTabChanged(boolean wasClick)
    {
    }


    /*
     * may want to subclass selectedTabChanged() and tabAdded()
     */

}
