
#include "wxginkgotoolbar.h"

#include <wx/dcbuffer.h>
#include <wx/menu.h>
#include <wx/aui/aui.h>

enum
{
	wxITEM_CONTROL = wxITEM_MAX,
	wxITEM_LABEL,
	wxITEM_SPACER
};

const int BUTTON_DROPDOWN_WIDTH = 10;

class ToolbarCommandCapture : public wxEvtHandler
{
public:

    ToolbarCommandCapture() { m_lastId = 0; }
    int GetCommandId() const { return m_lastId; }

    bool ProcessEvent(wxEvent& evt)
    {
        if (evt.GetEventType() == wxEVT_MENU)
        {
            m_lastId = evt.GetId();
            return true;
        }

        if (GetNextHandler())
            return GetNextHandler()->ProcessEvent(evt);

        return false;
    }

private:
    int m_lastId;
};

wxGinkgoToolBarArt::wxGinkgoToolBarArt()
{
}

wxGinkgoToolBarArt::wxGinkgoToolBarArt(const wxColor& color)
{
	m_baseColour = color;
}

wxGinkgoToolBarArt::~wxGinkgoToolBarArt()
{
}

void wxGinkgoToolBarArt::SetCustomBaseColor(const wxColor& color)
{
	m_baseColour = color;
}

wxColor wxGinkgoToolBarArt::GetCustomBaseColor()
{
	return m_baseColour;
}

int wxGinkgoToolBarArt::ShowDropDown(wxWindow* wnd, const wxAuiToolBarItemArray& items)
	{
		wxMenu menuPopup;

		size_t items_added = 0;

		size_t i, count = items.GetCount();
		for (i = 0; i < count; ++i)
		{
			wxAuiToolBarItem& item = items.Item(i);

			if (item.GetKind() == wxITEM_NORMAL)
			{
				wxString text = item.GetShortHelp();
				if (text.empty())
					text = item.GetLabel();

				if (text.empty())
					text = wxT(" ");

				wxMenuItem* m =  new wxMenuItem(&menuPopup, item.GetId(), text, item.GetShortHelp());

				m->SetBitmap(item.GetBitmap());
				menuPopup.Append(m);
				items_added++;
			}
			else if (item.GetKind() == wxITEM_SEPARATOR)
			{
				if (items_added > 0)
					menuPopup.AppendSeparator();
			}
		}

		// find out where to put the popup menu of window items
		wxPoint pt = ::wxGetMousePosition();
		pt = wnd->ScreenToClient(pt);

		// find out the screen coordinate at the bottom of the tab ctrl
		wxRect cli_rect = wnd->GetClientRect();
		pt.y = cli_rect.y + cli_rect.height;

		ToolbarCommandCapture* cc = new ToolbarCommandCapture;
		wnd->PushEventHandler(cc);
		wnd->PopupMenu(&menuPopup, pt);
		int command = cc->GetCommandId();
		wnd->PopEventHandler(true);

		return command;
	}

void wxGinkgoToolBarArt::DrawDropDownButton(
		wxDC& dc,
		wxWindow* /*wnd*/,
		const wxAuiToolBarItem& item,
		const wxRect& rect)
{
	const int BUTTON_DROPDOWN_WIDTH = 10;
	static const unsigned char DISABLED_TEXT_GREY_HUE = wxColour::AlphaBlend(0, 255, 0.4);
	const wxColour DISABLED_TEXT_COLOR(DISABLED_TEXT_GREY_HUE, DISABLED_TEXT_GREY_HUE, DISABLED_TEXT_GREY_HUE);

	int textWidth = 0, textHeight = 0, textX = 0, textY = 0;
	int bmpX = 0, bmpY = 0, dropBmpX = 0, dropBmpY = 0;

	wxRect buttonRect = wxRect(rect.x,
		rect.y,
		rect.width-BUTTON_DROPDOWN_WIDTH,
		rect.height);
	wxRect dropDownRect = wxRect(rect.x+rect.width-BUTTON_DROPDOWN_WIDTH-1,
		rect.y,
		BUTTON_DROPDOWN_WIDTH+1,
		rect.height);

	if (m_flags & wxAUI_TB_TEXT)
	{
		dc.SetFont(m_font);

		int tx, ty;
		if (m_flags & wxAUI_TB_TEXT)
		{
			dc.GetTextExtent(wxT("ABCDHgj"), &tx, &textHeight);
			textWidth = 0;
		}

		dc.GetTextExtent(item.GetLabel(), &textWidth, &ty);
	}

	dropBmpX = dropDownRect.x +
		(dropDownRect.width/2) -
		(m_buttonDropDownBmp.GetWidth()/2);
	dropBmpY = dropDownRect.y +
		(dropDownRect.height/2) -
		(m_buttonDropDownBmp.GetHeight()/2);

	if (m_textOrientation == wxAUI_TBTOOL_TEXT_BOTTOM)
	{
		bmpX = buttonRect.x +
			(buttonRect.width/2) -
			(item.GetBitmap().GetWidth()/2);
		bmpY = buttonRect.y +
			((buttonRect.height-textHeight)/2) -
			(item.GetBitmap().GetHeight()/2);

		textX = rect.x + (rect.width/2) - (textWidth/2) + 1;
		textY = rect.y + rect.height - textHeight - 1;
	}
	else if (m_textOrientation == wxAUI_TBTOOL_TEXT_RIGHT)
	{
		bmpX = rect.x + 3;

		bmpY = rect.y +
			(rect.height/2) -
			(item.GetBitmap().GetHeight()/2);

		textX = bmpX + 3 + item.GetBitmap().GetWidth();
		textY = rect.y +
			(rect.height/2) -
			(textHeight/2);
	}


	if (item.GetState() & wxAUI_BUTTON_STATE_PRESSED)
	{
		dc.SetPen(wxPen(m_highlightColour));
		dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(140)));
		dc.DrawRectangle(buttonRect);

		dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(170)));
		dc.DrawRectangle(dropDownRect);
	}
	else if (item.GetState() & wxAUI_BUTTON_STATE_HOVER ||
		item.IsSticky())
	{
		dc.SetPen(wxPen(m_highlightColour));
		dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(170)));
		dc.DrawRectangle(buttonRect);
		dc.DrawRectangle(dropDownRect);
	}
	else if (item.GetState() & wxAUI_BUTTON_STATE_CHECKED)
	{
		// Notice that this branch must come after the hover one to ensure the
		// correct appearance when the mouse hovers over a checked item.m_
		dc.SetPen(wxPen(m_highlightColour));
		dc.SetBrush(wxBrush(m_highlightColour.ChangeLightness(170)));
		dc.DrawRectangle(buttonRect);
		dc.DrawRectangle(dropDownRect);
	}

	wxBitmap bmp;
	wxBitmap dropbmp;
	if (item.GetState() & wxAUI_BUTTON_STATE_DISABLED)
	{
		bmp = item.GetDisabledBitmap();
		dropbmp = m_disabledButtonDropDownBmp;
	}
	else
	{
		bmp = item.GetBitmap();
		dropbmp = m_buttonDropDownBmp;
	}

	if (!bmp.IsOk())
		return;

	dc.DrawBitmap(bmp, bmpX, bmpY, true);
	dc.DrawBitmap(dropbmp, dropBmpX, dropBmpY, true);

	// set the item's text color based on if it is disabled
	dc.SetTextForeground(*wxBLACK);
	if (item.GetState() & wxAUI_BUTTON_STATE_DISABLED)
		dc.SetTextForeground(DISABLED_TEXT_COLOR);

	if ( (m_flags & wxAUI_TB_TEXT) && !item.GetLabel().empty() )
	{
		dc.DrawText(item.GetLabel(), textX, textY);
	}
}

void wxGinkgoToolBarArt::DrawButton(
		wxDC& dc,
		wxWindow* wnd,
		const wxAuiToolBarItem& item,
		const wxRect& rect)
	{
		if (item.HasDropDown()) {
			//we have modified default draw function to draw checked + drop down (not supported in wxWidgets)
			DrawDropDownButton(dc, wnd, item, rect);
		} else {
			wxAuiDefaultToolBarArt::DrawButton(dc, wnd, item, rect);
		}
}

//==================================================================================

wxGinkgoToolBar::wxGinkgoToolBar(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style) : wxAuiToolBar(parent, id, pos, size, style)
{
	SetToolBitmapSize(wxSize(16,16));
	wxAuiDefaultToolBarArt* pToolArt= new wxGinkgoToolBarArt();
	SetArtProvider(pToolArt);

	Connect(wxEVT_PAINT, wxPaintEventHandler(wxGinkgoToolBar::OnPaint), NULL, this);
	Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(wxGinkgoToolBar::OnLeftDown), NULL, this);
	Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(wxGinkgoToolBar::OnLeftDown), NULL, this);
	Connect(wxEVT_LEFT_UP, wxMouseEventHandler(wxGinkgoToolBar::OnLeftUp), NULL, this);
	Connect(wxEVT_MOTION, wxMouseEventHandler(wxGinkgoToolBar::OnMotion), NULL, this);
	Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler( wxGinkgoToolBar ::OnEraseBackground ) );
}

wxGinkgoToolBar::wxGinkgoToolBar(wxWindow* pParent, const wxColor& color, int style) : wxAuiToolBar(pParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, style|wxAUI_TB_DEFAULT_STYLE)
{
	SetToolBitmapSize(wxSize(16,16));
	wxAuiDefaultToolBarArt* pToolArt= new wxGinkgoToolBarArt(color);
	SetArtProvider(pToolArt);
	Connect(wxEVT_PAINT, wxPaintEventHandler(wxGinkgoToolBar::OnPaint), NULL, this);
	Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(wxGinkgoToolBar::OnLeftDown), NULL, this);
	Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(wxGinkgoToolBar::OnLeftDown), NULL, this);
	Connect(wxEVT_LEFT_UP, wxMouseEventHandler(wxGinkgoToolBar::OnLeftUp), NULL, this);
	Connect(wxEVT_MOTION, wxMouseEventHandler(wxGinkgoToolBar::OnMotion), NULL, this);
	Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler( wxGinkgoToolBar ::OnEraseBackground ) );
}

wxGinkgoToolBar::wxGinkgoToolBar(wxWindow* pParent, const wxColor& color, wxFont& fontBar) : wxAuiToolBar(pParent,wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_TB_DEFAULT_STYLE)
{
	SetToolBitmapSize(wxSize(16,16));
	wxAuiDefaultToolBarArt* pToolArt= new wxGinkgoToolBarArt(color);
	pToolArt->SetFont(fontBar);
	SetArtProvider(pToolArt);
	Connect(wxEVT_PAINT, wxPaintEventHandler(wxGinkgoToolBar::OnPaint), NULL, this);
	Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(wxGinkgoToolBar::OnLeftDown), NULL, this);
	Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(wxGinkgoToolBar::OnLeftDown), NULL, this);
	Connect(wxEVT_LEFT_UP, wxMouseEventHandler(wxGinkgoToolBar::OnLeftUp), NULL, this);
	Connect(wxEVT_MOTION, wxMouseEventHandler(wxGinkgoToolBar::OnMotion), NULL, this);
	Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler( wxGinkgoToolBar ::OnEraseBackground ) );
}

wxGinkgoToolBar::~wxGinkgoToolBar()
{
	Disconnect(wxEVT_MOTION, wxMouseEventHandler(wxGinkgoToolBar::OnMotion), NULL, this);
	Disconnect(wxEVT_LEFT_UP, wxMouseEventHandler(wxGinkgoToolBar::OnLeftUp), NULL, this);
	Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(wxGinkgoToolBar::OnLeftDown), NULL, this);
	Disconnect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(wxGinkgoToolBar::OnLeftDown), NULL, this);
	Disconnect(wxEVT_PAINT, wxPaintEventHandler(wxGinkgoToolBar::OnPaint), NULL, this);
	Disconnect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler( wxGinkgoToolBar ::OnEraseBackground ) );
}

void wxGinkgoToolBar::ForceToggleTool(int tool_id, bool state)
{
	wxAuiToolBarItem* tool = FindTool(tool_id);

	if (tool)
	{
		if (tool->GetKind() == wxITEM_RADIO)
		{
			int i, idx, count;
			idx = GetToolIndex(tool_id);
			count = (int)m_items.GetCount();

			if (idx >= 0 && idx < count)
			{
				for (i = idx + 1; i < count; ++i)
				{
					if (m_items[i].GetKind() != wxITEM_RADIO)
						break;
					m_items[i].SetState(m_items[i].GetState() & ~wxAUI_BUTTON_STATE_CHECKED);
				}
				for (i = idx - 1; i >= 0; i--)
				{
					if (m_items[i].GetKind() != wxITEM_RADIO)
						break;
					m_items[i].SetState(m_items[i].GetState() & ~wxAUI_BUTTON_STATE_CHECKED);
				}
			}

			tool->SetState(tool->GetState() | wxAUI_BUTTON_STATE_CHECKED);
		}
		else
		{
			if (state == true) {
				tool->SetState(tool->GetState() | wxAUI_BUTTON_STATE_CHECKED);
			}
			else {
				tool->SetState(tool->GetState() & ~wxAUI_BUTTON_STATE_CHECKED);
			}
		}
	}
}

bool wxGinkgoToolBar::ForceGetToolToggled(int tool_id) const
{
	wxAuiToolBarItem* tool = FindTool(tool_id);

	if (tool)
	{
		return (tool->GetState() & wxAUI_BUTTON_STATE_CHECKED) ? true : false;
	}

	return false;
}

void wxGinkgoToolBar::ForceSetToolDropDown(int tool_id, bool dropdown)
{
	wxAuiToolBarItem* item = FindTool(tool_id);
	if (!item)
		return;

	if (item->GetKind() != wxITEM_NORMAL) {
		int kind = item->GetKind(); // Hack
		item->SetKind(wxITEM_NORMAL);
		item->SetHasDropDown(dropdown);
		item->SetKind(kind);
	}
	else {
		item->SetHasDropDown(dropdown);
	}
}

void wxGinkgoToolBar::ForceSetOrientation(int orientation)
{
	wxAuiToolBar::SetOrientation(orientation);
}

void wxGinkgoToolBar::OnPaint(wxPaintEvent& WXUNUSED(evt))
{
	wxAutoBufferedPaintDC dc(this);
	wxRect cli_rect(wxPoint(0,0), GetClientSize());

	bool horizontal = m_orientation == wxHORIZONTAL;

	if (m_windowStyle & wxAUI_TB_PLAIN_BACKGROUND)
		m_art->DrawPlainBackground(dc, this, cli_rect);
	else
		m_art->DrawBackground(dc, this, cli_rect);

	int gripperSize = m_art->GetElementSize(wxAUI_TBART_GRIPPER_SIZE);
	int dropdown_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);

	// paint the gripper
	if (gripperSize > 0 && m_gripperSizerItem)
	{
		wxRect gripper_rect = m_gripperSizerItem->GetRect();
		if (horizontal)
			gripper_rect.width = gripperSize;
		else
			gripper_rect.height = gripperSize;
		m_art->DrawGripper(dc, this, gripper_rect);
	}

	// calculated how far we can draw items
	int last_extent;
	if (horizontal)
		last_extent = cli_rect.width;
	else
		last_extent = cli_rect.height;
	if (m_overflowVisible)
		last_extent -= dropdown_size;

	// paint each individual tool
	size_t i, count = m_items.GetCount();
	for (i = 0; i < count; ++i)
	{
		wxAuiToolBarItem& item = m_items.Item(i);

		if (!item.GetSizerItem())
			continue;

		wxRect item_rect = item.GetSizerItem()->GetRect();


		if ((horizontal  && item_rect.x + item_rect.width >= last_extent) ||
			(!horizontal && item_rect.y + item_rect.height >= last_extent))
		{
			break;
		}

		switch ( item.GetKind() )
		{
		case wxITEM_CHECK:
		case wxITEM_NORMAL:
			m_art->DrawButton(dc, this, item, item_rect);
			break;
		case wxITEM_RADIO:
			// draw a toggle button
			m_art->DrawButton(dc, this, item, item_rect);
			break;

		case wxITEM_SEPARATOR:
			// draw a separator
			m_art->DrawSeparator(dc, this, item_rect);
			break;
		case wxITEM_LABEL:
			// draw a text label only
			m_art->DrawLabel(dc, this, item, item_rect);
			break;

		case wxITEM_CONTROL:
			// draw the control's label
			m_art->DrawControlLabel(dc, this, item, item_rect);
			break;
		}

		// fire a signal to see if the item wants to be custom-rendered
		OnCustomRender(dc, item, item_rect);
	}

	// paint the overflow button
	if (dropdown_size > 0 && m_overflowSizerItem)
	{
		wxRect dropDownRect = GetOverflowRect();
		m_art->DrawOverflowButton(dc, this, dropDownRect, m_overflowState);
	}
}

void wxGinkgoToolBar::OnLeftDown(wxMouseEvent& evt)
{
	//very important to prevent trap because of capturemouse reentering
	if (HasCapture()) {
		ReleaseMouse();
        return;
	}
    wxRect cli_rect(wxPoint(0,0), GetClientSize());

    if (m_gripperSizerItem)
    {
        wxRect gripper_rect = m_gripperSizerItem->GetRect();
        if (gripper_rect.Contains(evt.GetX(), evt.GetY()))
        {
            // find aui manager
            wxAuiManager* manager = wxAuiManager::GetManager(this);
            if (!manager)
                return;

            int x_drag_offset = evt.GetX() - gripper_rect.GetX();
            int y_drag_offset = evt.GetY() - gripper_rect.GetY();

            // gripper was clicked
            manager->StartPaneDrag(this, wxPoint(x_drag_offset, y_drag_offset));
            return;
        }
    }

    if (m_overflowSizerItem)
    {
        wxRect overflow_rect = GetOverflowRect();

        if (m_art &&
            m_overflowVisible &&
            overflow_rect.Contains(evt.m_x, evt.m_y))
        {
            wxAuiToolBarEvent e(wxEVT_AUITOOLBAR_OVERFLOW_CLICK, -1);
            e.SetEventObject(this);
            e.SetToolId(-1);
            e.SetClickPoint(wxPoint(evt.GetX(), evt.GetY()));
            bool processed = GetEventHandler()->ProcessEvent(e);

            if (processed)
            {
                DoIdleUpdate();
            }
            else
            {
                size_t i, count;
                wxAuiToolBarItemArray overflow_items;


                // add custom overflow prepend items, if any
                count = m_customOverflowPrepend.GetCount();
                for (i = 0; i < count; ++i)
                    overflow_items.Add(m_customOverflowPrepend[i]);

                // only show items that don't fit in the dropdown
                count = m_items.GetCount();
                for (i = 0; i < count; ++i)
                {
                    if (!GetToolFitsByIndex(i))
                        overflow_items.Add(m_items[i]);
                }

                // add custom overflow append items, if any
                count = m_customOverflowAppend.GetCount();
                for (i = 0; i < count; ++i)
                    overflow_items.Add(m_customOverflowAppend[i]);

                int res = m_art->ShowDropDown(this, overflow_items);
                m_overflowState = 0;
                Refresh(false);
                if (res != -1)
                {
                    wxCommandEvent event(wxEVT_MENU, res);
                    event.SetEventObject(this);
                    GetParent()->GetEventHandler()->ProcessEvent(event);
                }
            }

            return;
        }
    }

    m_dragging = false;
    m_actionPos = wxPoint(evt.GetX(), evt.GetY());
    m_actionItem = FindToolByPosition(evt.GetX(), evt.GetY());

    if (m_actionItem)
    {
		if (m_actionItem->GetState() & wxAUI_BUTTON_STATE_DISABLED)
        {
            m_actionPos = wxPoint(-1,-1);
            m_actionItem = NULL;
            return;
        }

        UnsetToolTip();

        // fire the tool dropdown event
		wxAuiToolBarEvent e(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, m_actionItem->GetId());
        e.SetEventObject(this);
        e.SetToolId(m_actionItem->GetId());

        int mouse_x = evt.GetX();
		wxRect rect = m_actionItem->GetSizerItem()->GetRect();
		const bool dropDownHit = m_actionItem->HasDropDown() &&
                                 mouse_x >= (rect.x+rect.width-BUTTON_DROPDOWN_WIDTH-1) &&
                                 mouse_x < (rect.x+rect.width);
        e.SetDropDownClicked(dropDownHit);

        e.SetClickPoint(evt.GetPosition());
        e.SetItemRect(rect);

        // we only set the 'pressed button' state if we hit the actual button
        // and not just the drop-down
        SetPressedItem(dropDownHit ? 0 : m_actionItem);

        if(dropDownHit)
        {
            m_actionPos = wxPoint(-1,-1);
            m_actionItem = NULL;
        }

		if(!GetEventHandler()->ProcessEvent(e) || e.GetSkipped()) {
			CaptureMouse();
		}

        // Ensure hovered item is really ok, as mouse may have moved during
        //  event processing
        wxPoint cursor_pos_after_evt = ScreenToClient(wxGetMousePosition());
        SetHoverItem(FindToolByPosition(cursor_pos_after_evt.x, cursor_pos_after_evt.y));

        DoIdleUpdate();
    }
}

void wxGinkgoToolBar::OnLeftUp(wxMouseEvent& evt)
{
	//process only if this control has registered capture
	if (!HasCapture())
        return;

    SetPressedItem(NULL);

    wxAuiToolBarItem* hitItem;
    hitItem = FindToolByPosition(evt.GetX(), evt.GetY());
    SetHoverItem(hitItem);

    if (m_dragging)
    {
        // TODO: it would make sense to send out an 'END_DRAG' event here,
        // otherwise a client would never know what to do with the 'BEGIN_DRAG'
        // event

        // OnCaptureLost() will be called now and this will reset all our state
        // tracking variables
        ReleaseMouse();
    }
    else
    {
        if (m_actionItem && hitItem == m_actionItem)
        {
            UnsetToolTip();

			wxCommandEvent e(wxEVT_MENU, m_actionItem->GetId());
			e.SetEventObject(this);

			if (hitItem->GetKind() == wxITEM_CHECK || hitItem->GetKind() == wxITEM_RADIO)
            {
				const bool toggle = !(m_actionItem->GetState() & wxAUI_BUTTON_STATE_CHECKED);

				ForceToggleTool(m_actionItem->GetId(), toggle);

                // repaint immediately
                Refresh(false);
                Update();

                e.SetInt(toggle);
            }

            // we have to release the mouse *before* sending the event, because
            // we don't know what a handler might do. It could open up a popup
            // menu for example and that would make us lose our capture anyway.

            ReleaseMouse();

            GetEventHandler()->ProcessEvent(e);

            // Ensure hovered item is really ok, as mouse may have moved during
            // event processing
            wxPoint cursor_pos_after_evt = ScreenToClient(wxGetMousePosition());
            SetHoverItem(FindToolByPosition(cursor_pos_after_evt.x, cursor_pos_after_evt.y));

            DoIdleUpdate();
        }
        else
            ReleaseMouse();
    }
}

void wxGinkgoToolBar::OnMotion(wxMouseEvent& evt)
{
    const bool button_pressed = HasCapture();

    // start a drag event
	if (m_actionItem && !m_dragging && button_pressed &&
        abs(evt.GetX() - m_actionPos.x) + abs(evt.GetY() - m_actionPos.y) > 5)
    {
        // TODO: sending this event only makes sense if there is an 'END_DRAG'
        // event sent sometime in the future (see OnLeftUp())
        wxAuiToolBarEvent e(wxEVT_AUITOOLBAR_BEGIN_DRAG, GetId());
        e.SetEventObject(this);
		e.SetToolId(m_actionItem->GetId());
		
        m_dragging = GetEventHandler()->ProcessEvent(e) && !e.GetSkipped();

        DoIdleUpdate();
    }

    if(m_dragging)
        return;

    wxAuiToolBarItem* hitItem = FindToolByPosition(evt.GetX(), evt.GetY());
    if(button_pressed)
    {
        // if we have a button pressed we want it to be shown in 'depressed'
        // state unless we move the mouse outside the button, then we want it
        // to show as just 'highlighted'
        if (hitItem == m_actionItem)
            SetPressedItem(m_actionItem);
        else
        {
            SetPressedItem(NULL);
            SetHoverItem(m_actionItem);
        }
    }
    else
    {
        SetHoverItem(hitItem);

        // tooltips handling
        wxAuiToolBarItem* packingHitItem;
        packingHitItem = FindToolByPositionWithPacking(evt.GetX(), evt.GetY());
        if (packingHitItem)
        {
            if (packingHitItem != m_tipItem)
            {
                m_tipItem = packingHitItem;

				if ( !packingHitItem->GetShortHelp().empty() )
					SetToolTip(packingHitItem->GetShortHelp());
                else
                    UnsetToolTip();
            }
        }
        else
        {
            UnsetToolTip();
            m_tipItem = NULL;
        }

        // figure out the dropdown button state (are we hovering or pressing it?)
        RefreshOverflowState();
    }
}

void wxGinkgoToolBar::OnEraseBackground( wxEraseEvent& event ) 
{
	event.Skip(false);
}
