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

   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.

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

#include "../../../../juce_core/basics/juce_StandardHeader.h"

BEGIN_JUCE_NAMESPACE

#include "juce_TabbedComponent.h"
#include "../../graphics/geometry/juce_RectangleList.h"


//==============================================================================
class TabCompButtonBar  : public TabbedButtonBar
{
public:
    TabCompButtonBar (TabbedComponent* const owner_,
                      const TabbedButtonBar::Orientation orientation)
        : TabbedButtonBar (orientation),
          owner (owner_)
    {
    }

    ~TabCompButtonBar()
    {
    }

    void currentTabChanged (const int newCurrentTabIndex,
                            const String& newTabName)
    {
        owner->changeCallback (newCurrentTabIndex, newTabName);
    }

    void popupMenuClickOnTab (const int tabIndex,
                              const String& tabName)
    {
        owner->popupMenuClickOnTab (tabIndex, tabName);
    }

    const Colour getTabBackgroundColour (const int tabIndex)
    {
        return owner->tabs->getTabBackgroundColour (tabIndex);
    }

    juce_UseDebuggingNewOperator

private:
    TabbedComponent* const owner;

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


TabbedComponent::TabbedComponent (const TabbedButtonBar::Orientation orientation)
    : panelComponent (0),
      tabDepth (30),
      componentCanBeDeleted (false),
      outlineColour (Colours::grey),
      outlineThickness (1),
      edgeIndent (0)
{
    addAndMakeVisible (tabs = new TabCompButtonBar (this, orientation));
}

TabbedComponent::~TabbedComponent()
{
    if (panelComponent != 0)
    {
        if (componentCanBeDeleted)
            delete panelComponent;
        else
            removeChildComponent (panelComponent);

        panelComponent = 0;
    }

    delete tabs;
}

//==============================================================================
void TabbedComponent::setOrientation (const TabbedButtonBar::Orientation orientation)
{
    tabs->setOrientation (orientation);
    resized();
}

const TabbedButtonBar::Orientation TabbedComponent::getOrientation() const throw()
{
    return tabs->getOrientation();
}

void TabbedComponent::setTabBarDepth (const int newDepth)
{
    if (tabDepth != newDepth)
    {
        tabDepth = newDepth;
        resized();
    }
}

//==============================================================================
void TabbedComponent::clearTabs()
{
    tabs->clearTabs();
}

void TabbedComponent::addTab (const String& tabName,
                              const Colour& tabBackgroundColour)
{
    tabs->addTab (tabName, tabBackgroundColour);
}

void TabbedComponent::setTabName (const int tabIndex,
                                  const String& newName)
{
    tabs->setTabName (tabIndex, newName);
}

void TabbedComponent::removeTab (const int tabIndex)
{
    tabs->removeTab (tabIndex);
}

int TabbedComponent::getNumTabs() const
{
    return tabs->getNumTabs();
}

const StringArray TabbedComponent::getTabNames() const
{
    return tabs->getTabNames();
}

void TabbedComponent::setCurrentTabIndex (const int newTabIndex)
{
    tabs->setCurrentTabIndex (newTabIndex);
}

int TabbedComponent::getCurrentTabIndex() const
{
    return tabs->getCurrentTabIndex();
}

const String& TabbedComponent::getCurrentTabName() const
{
    return tabs->getCurrentTabName();
}

void TabbedComponent::setOutline (const Colour& colour, int thickness)
{
    outlineColour = colour;
    outlineThickness = thickness;
    repaint();
}

void TabbedComponent::setIndent (const int indentThickness)
{
    edgeIndent = indentThickness;
}

void TabbedComponent::paint (Graphics& g)
{
    const TabbedButtonBar::Orientation o = getOrientation();

    int x = 0;
    int y = 0;
    int r = getWidth();
    int b = getHeight();

    if (o == TabbedButtonBar::TabsAtTop)
        y += tabDepth;
    else if (o == TabbedButtonBar::TabsAtBottom)
        b -= tabDepth;
    else if (o == TabbedButtonBar::TabsAtLeft)
        x += tabDepth;
    else if (o == TabbedButtonBar::TabsAtRight)
        r -= tabDepth;

    g.reduceClipRegion (x, y, r - x, b - y);
    g.fillAll (tabs->getTabBackgroundColour (getCurrentTabIndex()));

    if (outlineThickness > 0)
    {
        if (o == TabbedButtonBar::TabsAtTop)
            --y;
        else if (o == TabbedButtonBar::TabsAtBottom)
            ++b;
        else if (o == TabbedButtonBar::TabsAtLeft)
            --x;
        else if (o == TabbedButtonBar::TabsAtRight)
            ++r;

        g.setColour (outlineColour);
        g.drawRect (x, y, r - x, b - y, outlineThickness);
    }
}

void TabbedComponent::resized()
{
    const TabbedButtonBar::Orientation o = getOrientation();
    const int indent = edgeIndent + outlineThickness;
    BorderSize indents (indent);

    if (o == TabbedButtonBar::TabsAtTop)
    {
        tabs->setBounds (0, 0, getWidth(), tabDepth);
        indents.setTop (tabDepth + edgeIndent);
    }
    else if (o == TabbedButtonBar::TabsAtBottom)
    {
        tabs->setBounds (0, getHeight() - tabDepth, getWidth(), tabDepth);
        indents.setBottom (tabDepth + edgeIndent);
    }
    else if (o == TabbedButtonBar::TabsAtLeft)
    {
        tabs->setBounds (0, 0, tabDepth, getHeight());
        indents.setLeft (tabDepth + edgeIndent);
    }
    else if (o == TabbedButtonBar::TabsAtRight)
    {
        tabs->setBounds (getWidth() - tabDepth, 0, tabDepth, getHeight());
        indents.setRight (tabDepth + edgeIndent);
    }

    if (panelComponent != 0)
        panelComponent->setBoundsInset (indents);
}

void TabbedComponent::changeCallback (const int newCurrentTabIndex,
                                      const String& newTabName)
{
    if (panelComponent != 0)
    {
        if (componentCanBeDeleted)
            delete panelComponent;
        else
            removeChildComponent (panelComponent);

        panelComponent = 0;
    }

    if (getCurrentTabIndex() >= 0)
    {
        componentCanBeDeleted = false;

        panelComponent = createPanelComponentForTab (getCurrentTabIndex(),
                                                     getCurrentTabName(),
                                                     componentCanBeDeleted);

        if (panelComponent != 0)
            addAndMakeVisible (panelComponent);
    }

    resized();

    currentTabChanged (newCurrentTabIndex, newTabName);
}

void TabbedComponent::currentTabChanged (const int, const String&)
{
}

void TabbedComponent::popupMenuClickOnTab (const int, const String&)
{
}

END_JUCE_NAMESPACE
