/*
 ============================================================================
 xoblite -> an alternative shell based on Blackbox for Windows
 Copyright  2002-2005 Karl-Henrik Henriksson [qwilk]
 Copyright  2001-2004 The Blackbox for Windows Development Team
 http://xoblite.net/ - #bb4win on irc.freenode.net
 ============================================================================

  Blackbox for Windows is free software, released under the
  GNU General Public License (GPL version 2 or later), with an extension
  that allows linking of proprietary modules under a controlled interface.
  What this means is that plugins etc. are allowed to be released
  under any license the author wishes. Please note, however, that the
  original Blackbox gradient math code used in Blackbox for Windows
  is available under the BSD license.

  http://www.fsf.org/licenses/gpl.html
  http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
  http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5

  This program 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.

  For additional license information, please read the included license.html

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

#include "MenuItem.h" 
#include "Painter.h" 
#include "MenuMaker.h" 
#include "Menu.h" 
#include "../Settings.h" 
#include "../Toolbar.h" 

extern MenuMaker *pMenuMaker;
extern Settings *pSettings;
extern Toolbar *pToolbar;

int MenuItem::m_nAlignment = DT_LEFT;
int MenuItem::m_nTitleAlignment = DT_LEFT;
int MenuItem::m_nIndent = 0;
int MenuItem::m_nRightIndent = 0;

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

MenuItem::MenuItem()
{
        m_pParent = NULL;
        m_nWidth = 0;
        m_nHeight = 0;

        m_pForeground = NULL;
        m_pBackground = NULL;

        m_pActiveForeground = NULL;
        m_pActiveBackground = NULL;

        m_bActive = false;

        m_nSortPriority = 1; // 0?
}

MenuItem::~MenuItem()
{
}

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

void MenuItem::Paint(HDC hDC)
{
        SetBkMode(hDC, TRANSPARENT); // To do: Move to a painter...
        // Paint the background
        if(m_bActive && m_pActiveBackground) m_pActiveBackground->Paint(this, hDC);
        else if (m_pBackground) m_pBackground->Paint(this, hDC);
}

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

// Execute the command that is associated with the menu item
void MenuItem::Invoke(int button)
{
        // First we set focus to the toolbar to prevent
        // the focus from going back to the previous task
        // after the menu is closed...
        if (pSettings->followActive) SetForegroundWindow(pToolbar->hToolbarWnd);

        // Default implementation is a NOP
        for (int n=0; n < (int)pMenuMaker->m_RootMenus.size(); ++n)
        {
                Menu *pMenu = pMenuMaker->m_RootMenus[n];
                if (pMenu->HasMoved()) break;
                pMenuMaker->Hide();
                ShowWindow(pMenu->GetWindow(), SW_HIDE);
        }
}

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

// Mouse commands...
void MenuItem::Mouse(UINT nMsg, int x, int y)
{
        RECT r;
        m_mousePos.x = x;
        m_mousePos.y = y;
        GetItemRect(&r);

        if (PtInRect(&r, m_mousePos))
        {
                switch (nMsg)
                {
                        case WM_LBUTTONUP:
                        case WM_NCLBUTTONUP:
                                Invoke(1);
                                break;
                        case WM_RBUTTONUP:
                        case WM_NCRBUTTONUP:
                                Invoke(2);
                                break;
                        case WM_MBUTTONUP:
                        case WM_NCMBUTTONUP:
                                Invoke(3);
                                break;
                        case WM_MOUSEMOVE:
                        case WM_NCMOUSEMOVE:
                                Active(true);
                                break;
                        default:
                                break;
                }
        }
        else Active(false);
}

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

void MenuItem::Timer(int nTimer)
{
        // Execute timer messages...
}

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

int MenuItem::IsOver(int x, int y)
{
        if ((x >= 0) && (x <= GetWidth()) && (y >= m_nTop) &&  (y <= m_nTop + GetHeight()))
                return true;
        else
                return false;
}

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

void MenuItem::Attached(Menu* pMenu)
{
        m_pParent = pMenu;
}

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

bool MenuItem::Active(bool bActive)
{
        if (GetSortPriority() == 255) return false; // Header items

        RECT r;

        if (m_bActive != bActive)
        {
                // Only redraw the window if the state changes...
                m_bActive = bActive;
                GetItemRect(&r);

                RedrawWindow(m_pParent->GetWindow(), &r, NULL, RDW_INVALIDATE);
        }

        return m_bActive;
}

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

void MenuItem::GetItemRect(LPRECT lpRect)
{
        lpRect->top = m_nTop;
        lpRect->left = 0;
        lpRect->right = lpRect->left + GetWidth();
        lpRect->bottom = lpRect->top + GetHeight();
}

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

void MenuItem::SetPainter(Painter* pBackground)
{
        m_pBackground = pBackground;
}

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

void MenuItem::SetActivePainter(Painter* pBackground)
{
        m_pActiveBackground = pBackground;
}

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

HWND MenuItem::GetWindow()
{
        if(m_pParent)
                return m_pParent->GetWindow();
        else
                return NULL;
}

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

LRESULT MenuItem::Command(WPARAM wParam, LPARAM lParam)
{
        return 0;
}

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

// Returns true if m1 < m2
bool MenuItem::Compare(MenuItem* m1,MenuItem* m2)
{
        int m1_sort = m1->GetSortPriority();
        int m2_sort = m2->GetSortPriority();

        if(m1_sort == m2_sort)
                return stricmp(m1->GetSortString(), m2->GetSortString()) < 0;
        else
                return m1_sort > m2_sort;
}

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





syntax highlighting by

w e b c p p
web c plus plus