+/////////////////////////////////////////////////////////////////////////////
+// Name:        src/generic/buttonbar.cpp
+// Purpose:     wxButtonToolBar implementation
+// Author:      Julian Smart, after Robert Roebling, Vadim Zeitlin, SciTech
+// Modified by:
+// Created:     2006-04-13
+// Id:          $Id$
+// Copyright:   (c) Julian Smart, Robert Roebling, Vadim Zeitlin,
+//              SciTech Software, Inc. 
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#if wxUSE_TOOLBAR && wxUSE_BMPBUTTON
+
+#ifndef WX_PRECOMP
+    #include "wx/utils.h"
+    #include "wx/app.h"
+#endif
+
+#include "wx/generic/buttonbar.h"
+#include "wx/frame.h"
+#include "wx/image.h"
+#include "wx/log.h"
+
+// ----------------------------------------------------------------------------
+// wxButtonToolBarTool: our implementation of wxToolBarToolBase
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxButtonToolBarTool : public wxToolBarToolBase
+{
+public:
+    wxButtonToolBarTool(wxButtonToolBar *tbar,
+                  int id,
+                  const wxString& label,
+                  const wxBitmap& bmpNormal,
+                  const wxBitmap& bmpDisabled,
+                  wxItemKind kind,
+                  wxObject *clientData,
+                  const wxString& shortHelp,
+                  const wxString& longHelp)
+        : wxToolBarToolBase(tbar, id, label, bmpNormal, bmpDisabled, kind,
+                            clientData, shortHelp, longHelp)
+    {
+        m_x = m_y = wxDefaultCoord;
+        m_width =
+        m_height = 0;
+        
+        m_button = NULL;
+    }
+
+    wxButtonToolBarTool(wxButtonToolBar *tbar, wxControl *control)
+        : wxToolBarToolBase(tbar, control)
+    {
+        m_x = m_y = wxDefaultCoord;
+        m_width =
+        m_height = 0;
+        m_button = NULL;
+    }
+
+    wxBitmapButton* GetButton() const { return m_button; }
+    void SetButton(wxBitmapButton* button) { m_button = button; }
+
+public:
+    // the tool position (for controls)
+    wxCoord m_x;
+    wxCoord m_y;
+    wxCoord m_width;
+    wxCoord m_height;
+
+private:
+    // the control representing the button
+    wxBitmapButton* m_button;
+};
+
+// ============================================================================
+// wxButtonToolBar implementation
+// ============================================================================
+
+IMPLEMENT_DYNAMIC_CLASS(wxButtonToolBar, wxControl)
+
+BEGIN_EVENT_TABLE(wxButtonToolBar, wxControl)
+    EVT_BUTTON(wxID_ANY, wxButtonToolBar::OnCommand)
+END_EVENT_TABLE()
+
+// ----------------------------------------------------------------------------
+// wxButtonToolBar creation
+// ----------------------------------------------------------------------------
+
+void wxButtonToolBar::Init()
+{
+    // no tools yet
+    m_needsLayout = false;
+
+    // unknown widths for the tools and separators
+    m_widthSeparator = wxDefaultCoord;
+
+    m_maxWidth =
+    m_maxHeight = 0;
+}
+
+bool wxButtonToolBar::Create(wxWindow *parent,
+                       wxWindowID id,
+                       const wxPoint& pos,
+                       const wxSize& size,
+                       long style,
+                       const wxString& name)
+{
+    if ( !wxToolBarBase::Create(parent, id, pos, size, style,
+                                wxDefaultValidator, name) )
+    {
+        return false;
+    }
+
+    return true;
+}
+
+wxButtonToolBar::~wxButtonToolBar()
+{
+}
+
+// ----------------------------------------------------------------------------
+// wxButtonToolBar tool-related methods
+// ----------------------------------------------------------------------------
+
+wxToolBarToolBase *wxButtonToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
+{
+    // check the "other" direction first: it must be inside the toolbar or we
+    // don't risk finding anything
+    if ( IsVertical() )
+    {
+        if ( x < 0 || x > m_maxWidth )
+            return NULL;
+
+        // we always use x, even for a vertical toolbar, this makes the code
+        // below simpler
+        x = y;
+    }
+    else // horizontal
+    {
+        if ( y < 0 || y > m_maxHeight )
+            return NULL;
+    }
+
+    for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
+          node;
+          node = node->GetNext() )
+    {
+        wxButtonToolBarTool *tool =  (wxButtonToolBarTool*) node->GetData();
+        wxRect rectTool = GetToolRect(tool);
+
+        wxCoord startTool, endTool;
+        GetRectLimits(rectTool, &startTool, &endTool);
+
+        if ( x >= startTool && x <= endTool )
+        {
+            // don't return the separators from here, they don't accept any
+            // input anyhow
+            return tool->IsSeparator() ? NULL : tool;
+        }
+    }
+
+    return NULL;
+}
+
+void wxButtonToolBar::GetRectLimits(const wxRect& rect,
+                              wxCoord *start,
+                              wxCoord *end) const
+{
+    wxCHECK_RET( start && end, _T("NULL pointer in GetRectLimits") );
+
+    if ( IsVertical() )
+    {
+        *start = rect.GetTop();
+        *end = rect.GetBottom();
+    }
+    else // horizontal
+    {
+        *start = rect.GetLeft();
+        *end = rect.GetRight();
+    }
+}
+
+
+void wxButtonToolBar::SetToolShortHelp(int id, const wxString& help)
+{
+    wxToolBarToolBase *tool = FindById(id);
+
+    wxCHECK_RET( tool, _T("SetToolShortHelp: no such tool") );
+
+    // TODO: set tooltip/short help
+    tool->SetShortHelp(help);
+}
+
+bool wxButtonToolBar::DoInsertTool(size_t WXUNUSED(pos),
+                             wxToolBarToolBase * WXUNUSED(tool))
+{
+    return true;
+}
+
+bool wxButtonToolBar::DoDeleteTool(size_t WXUNUSED(pos),
+                             wxToolBarToolBase * WXUNUSED(tool))
+{
+    // TODO
+    return true;
+}
+
+void wxButtonToolBar::DoEnableTool(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(enable))
+{
+    // TODO
+}
+
+void wxButtonToolBar::DoToggleTool(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
+{
+    // TODO
+}
+
+void wxButtonToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
+{
+    // TODO
+}
+
+wxToolBarToolBase *wxButtonToolBar::CreateTool(int id,
+                                         const wxString& label,
+                                         const wxBitmap& bmpNormal,
+                                         const wxBitmap& bmpDisabled,
+                                         wxItemKind kind,
+                                         wxObject *clientData,
+                                         const wxString& shortHelp,
+                                         const wxString& longHelp)
+{
+    return new wxButtonToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind,
+                             clientData, shortHelp, longHelp);
+}
+
+wxToolBarToolBase *wxButtonToolBar::CreateTool(wxControl *control)
+{
+    return new wxButtonToolBarTool(this, control);
+}
+
+// ----------------------------------------------------------------------------
+// wxButtonToolBar geometry
+// ----------------------------------------------------------------------------
+
+wxRect wxButtonToolBar::GetToolRect(wxToolBarToolBase *toolBase) const
+{
+    const wxButtonToolBarTool *tool = (wxButtonToolBarTool *)toolBase;
+
+    wxRect rect;
+
+    wxCHECK_MSG( tool, rect, _T("GetToolRect: NULL tool") );
+
+    // ensure that we always have the valid tool position
+    if ( m_needsLayout )
+    {
+        wxConstCast(this, wxButtonToolBar)->DoLayout();
+    }
+
+    rect.x = tool->m_x - m_xMargin;
+    rect.y = tool->m_y - m_yMargin;
+
+    if ( IsVertical() )
+    {
+        if (tool->IsButton())
+        {
+            rect.width = m_defaultWidth;
+            rect.height = m_defaultHeight;
+            if (tool->GetButton())
+                rect.SetSize(tool->GetButton()->GetSize());
+        }
+        else if (tool->IsSeparator())
+        {
+            rect.width = m_defaultWidth;
+            rect.height = m_widthSeparator;
+        }
+        else // control
+        {
+            rect.width = tool->m_width;
+            rect.height = tool->m_height;
+        }
+    }
+    else // horizontal
+    {
+        if (tool->IsButton())
+        {
+            rect.width = m_defaultWidth;
+            rect.height = m_defaultHeight;
+            if (tool->GetButton())
+                rect.SetSize(tool->GetButton()->GetSize());
+        }
+        else if (tool->IsSeparator())
+        {
+            rect.width = m_widthSeparator;
+            rect.height = m_defaultHeight;
+        }
+        else // control
+        {
+            rect.width = tool->m_width;
+            rect.height = tool->m_height;
+        }
+    }
+
+    rect.width += 2*m_xMargin;
+    rect.height += 2*m_yMargin;
+
+    return rect;
+}
+
+bool wxButtonToolBar::Realize()
+{
+    if ( !wxToolBarBase::Realize() )
+        return false;
+    
+    m_needsLayout = true;
+    DoLayout();
+    
+    SetBestSize(wxSize(m_maxWidth, m_maxHeight));
+
+    return true;
+}
+
+void wxButtonToolBar::DoLayout()
+{
+    m_needsLayout = false;
+
+    wxCoord x = m_xMargin,
+            y = m_yMargin;
+
+    int maxHeight = 0;
+
+    const wxCoord widthTool = IsVertical() ? m_defaultHeight : m_defaultWidth;
+    wxCoord margin = IsVertical() ? m_xMargin : m_yMargin;
+    wxCoord *pCur = IsVertical() ? &y : &x;
+
+    // calculate the positions of all elements
+    for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
+          node;
+          node = node->GetNext() )
+    {
+        wxButtonToolBarTool *tool = (wxButtonToolBarTool *) node->GetData();
+
+        tool->m_x = x;
+        tool->m_y = y;
+        
+        if (tool->IsButton())
+        {
+            if (!tool->GetButton())
+            {
+                wxBitmapButton* bmpButton = new wxBitmapButton(this, tool->GetId(), tool->GetNormalBitmap(), wxPoint(tool->m_x, tool->m_y), wxDefaultSize,
+                    wxBU_AUTODRAW);
+                
+                tool->SetButton(bmpButton);
+            }
+            else
+            {
+                tool->GetButton()->Move(wxPoint(tool->m_x, tool->m_y));
+            }
+            
+            int w = widthTool;
+            if (tool->GetButton())
+            {
+                wxSize sz = tool->GetButton()->GetSize();
+                w = sz.x;
+
+                maxHeight = wxMax(maxHeight, sz.y);
+            }
+
+            *pCur += (w + GetToolPacking());
+        }
+        else if (tool->IsSeparator())
+        {
+            *pCur += m_widthSeparator;
+        }
+        else if (!IsVertical()) // horizontal control
+        {
+            wxControl *control = tool->GetControl();
+            wxSize size = control->GetSize();
+            tool->m_y += (m_defaultHeight - size.y)/2;
+            tool->m_width = size.x;
+            tool->m_height = size.y;
+
+            *pCur += tool->m_width;
+
+            maxHeight = wxMax(maxHeight, size.y);
+        }
+        *pCur += margin;
+    }
+
+    // calculate the total toolbar size
+    m_maxWidth = x + 2*m_xMargin;
+    m_maxHeight = maxHeight + 2*m_yMargin;
+}
+
+wxSize wxButtonToolBar::DoGetBestClientSize() const
+{
+    return wxSize(m_maxWidth, m_maxHeight);
+}
+
+// receives button commands
+void wxButtonToolBar::OnCommand(wxCommandEvent& event)
+{
+    wxButtonToolBarTool* tool = (wxButtonToolBarTool*) FindById(event.GetId());
+    if (!tool)
+    {
+        event.Skip();
+        return;
+    }
+
+    // TODO: handle toggle items
+    OnLeftClick(event.GetId(), false);    
+}
+
+#endif // wxUSE_TOOLBAR && wxUSE_BMPBUTTON
+