/*
  ==============================================================================

   This file is part of the JUCE library - "Jules' Utility Class Extensions"
   Copyright 2004-6 by Raw Material Software ltd.

  ------------------------------------------------------------------------------

   JUCE can be redistributed and/or modified under the terms of the
   GNU General Public License, as published by the Free Software Foundation;
   either version 2 of the License, or (at your option) any later version.

   JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
   Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
   Boston, MA 02111-1307 USA

  ------------------------------------------------------------------------------

   If you'd like to release a closed-source product which uses JUCE, commercial
   licenses are also available: visit www.rawmaterialsoftware.com/juce for
   more information.

  ==============================================================================
*/

#ifndef __JUCE_TABBEDCOMPONENT_JUCEHEADER__
#define __JUCE_TABBEDCOMPONENT_JUCEHEADER__

#include "juce_TabbedButtonBar.h"


//==============================================================================
/**
    A component with a TabbedButtonBar along one of its sides.

    This makes it easy to create a set of tabbed pages - just overload the
    createPanelComponentForTab() method to create the component you want,
    add a bunch of tabs with addTab(), and this will take care of showing the
    pages for you when the user clicks on a different tab.

    @see TabbedButtonBar
*/
class JUCE_API  TabbedComponent  : public Component
{
public:
    //==============================================================================
    /** Creates a TabbedComponent, specifying where the tabs should be placed.

        Once created, add some tabs with the addTab() method.
    */
    TabbedComponent (const TabbedButtonBar::Orientation orientation);

    /** Destructor. */
    ~TabbedComponent();

    //==============================================================================
    /** Changes the placement of the tabs.

        This will rearrange the layout to place the tabs along the appropriate
        side of this component, and will shift the content component accordingly.

        @see TabbedButtonBar::setOrientation
    */
    void setOrientation (const TabbedButtonBar::Orientation orientation);

    /** Returns the current tab placement.

        @see setOrientation, TabbedButtonBar::getOrientation
    */
    const TabbedButtonBar::Orientation getOrientation() const throw();

    /** Specifies how many pixels wide or high the tab-bar should be.

        If the tabs are placed along the top or bottom, this specified the height
        of the bar; if they're along the left or right edges, it'll be the width
        of the bar.
    */
    void setTabBarDepth (const int newDepth);

    /** Returns the current thickness of the tab bar.

        @see setTabBarDepth
    */
    int getTabBarDepth() const throw()                          { return tabDepth; }

    /** Specifies an outline that should be drawn around the entire content component.

        If this thickness is > 0, a line of the specified colour will be drawn around
        the three sides of the content component which don't touch the tab-bar, and
        the content component will be inset by this amount.
    */
    void setOutline (const Colour& newOutlineColour,
                     const int newThickness);

    /** Specifies a gap to leave around the edge of the content component.

        Each edge of the content component will be indented by the given number of pixels.
    */
    void setIndent (const int indentThickness);

    //==============================================================================
    /** Removes all the tabs from the bar.

        @see TabbedButtonBar::clearTabs
    */
    void clearTabs();

    /** Adds a tab to the tab-bar.

        Your createPanelComponentForTab() will have to be able to create a suitable
        component for each tab that's added.

        @see TabbedButtonBar::addTab
    */
    void addTab (const String& tabName,
                 const Colour& tabBackgroundColour);

    /** Changes the name of one of the tabs. */
    void setTabName (const int tabIndex,
                     const String& newName);

    /** Gets rid of one of the tabs. */
    void removeTab (const int tabIndex);

    /** Returns the number of tabs in the bar. */
    int getNumTabs() const;

    /** Returns a list of all the tab names in the bar. */
    const StringArray getTabNames() const;

    /** Changes the currently-selected tab.

        This will cause a new content component to be created by your createPanelComponentForTab()
        and added to the panel.

        To deselect all the tabs, pass -1 as the index.

        @see TabbedButtonBar::setCurrentTabIndex
    */
    void setCurrentTabIndex (const int newTabIndex);

    /** Returns the index of the currently selected tab.

        @see addTab, TabbedButtonBar::getCurrentTabIndex()
    */
    int getCurrentTabIndex() const;

    /** Returns the name of the currently selected tab.

        @see addTab, TabbedButtonBar::getCurrentTabName()
    */
    const String& getCurrentTabName() const;

    /** Returns the current component that's filling the panel.

        This will return 0 if there isn't one.
    */
    Component* getCurrentContentComponent() const throw()       { return panelComponent; }

    //==============================================================================
    /** A subclass must implement this method to create the content components
        that represent each of the tabs.

        Your subclass should return a new object here, which will then be added
        and repositioned in this panel.

        If you want the TabbedComponent to automatically delete your new component
        when it's no longer required, set the componentCanBeDeleted parameter
        to true.

        If you set componentCanBeDeleted to false, your component will be removed
        from the TabbedComonent when no longer being shown, but it won't be deleted,
        so this lets you re-use the same component rather than creating a new instance
        each time the user changes tab.
    */
    virtual Component* createPanelComponentForTab (const int tabIndex,
                                                   const String& tabName,
                                                   bool& componentCanBeDeleted) = 0;


    /** Callback method to indicate the selected tab has been changed.

        @see setCurrentTabIndex
    */
    virtual void currentTabChanged (const int newCurrentTabIndex,
                                    const String& newCurrentTabName);

    /** Callback method to indicate that the user has right-clicked on a tab.

        (Or ctrl-clicked on the Mac)
    */
    virtual void popupMenuClickOnTab (const int tabIndex,
                                      const String& tabName);


    //==============================================================================
    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void resized();

    juce_UseDebuggingNewOperator

protected:
    //==============================================================================
    TabbedButtonBar* tabs;

private:
    //==============================================================================
    Component* panelComponent;
    int tabDepth;
    bool componentCanBeDeleted;
    Colour outlineColour;
    int outlineThickness, edgeIndent;

    friend class TabCompButtonBar;
    void changeCallback (const int newCurrentTabIndex, const String& newTabName);

    TabbedComponent (const TabbedComponent&);
    const TabbedComponent& operator= (const TabbedComponent&);
};


#endif   // __JUCE_TABBEDCOMPONENT_JUCEHEADER__
