/***************************************************************************
 *   Copyright (C) 2005 by Thierry CHARLES   *
 *   thierry@les-charles.net   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it 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.                                   *
 *                                                                         *
 *   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.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "tlabel.h"

#include <wx/dcclient.h>
#include <wx/settings.h>
#include <wx/pen.h>
#include <wx/brush.h>

#include "lib/lib_logging.h"

#define DEFAULT_BORDER_MARGIN 2

IMPLEMENT_DYNAMIC_CLASS(TLabel,wxControl);

BEGIN_EVENT_TABLE(TLabel,wxControl)
        EVT_PAINT(TLabel::onPaint)
        EVT_SIZE(TLabel::onResize)
END_EVENT_TABLE()

TLabel::TLabel(wxWindow * parent, long iStyle)
    : wxControl(parent, -1, wxDefaultPosition, wxDefaultSize, iStyle),
                sText(wxT("")), align(Left)
{
}

TLabel::~TLabel()
{
}

/** defini le texte du bouton */
void TLabel::setText(const wxString & s)
{
    this->sText = s;
    this->Refresh();
}

/** defini l'alignement du texte */
void TLabel::setAlignment(const TextAlignment align)
{
    this->align = align;
    this->Refresh();
}

/** calcule la taille optimale du bouton */
wxSize TLabel::DoGetBestSize() const
{
    // Do not return any arbitrary default value...
    wxASSERT_MSG( m_widget, wxT("TGenButton::DoGetBestSize called before creation") );

    // calcul de l'encombrement du texte
    if(this->sText.length())
    {
        int iTextWidth, iTextHeight;
        wxPaintDC dc(const_cast<TLabel*>(this));
        dc.SetFont(this->GetFont());
        dc.GetTextExtent(this->sText, &iTextWidth, &iTextHeight);
        return wxSize(iTextWidth + 2*DEFAULT_BORDER_MARGIN, iTextHeight + 2*DEFAULT_BORDER_MARGIN);
    }
    else
    {
        return wxSize( 2*DEFAULT_BORDER_MARGIN, 2*DEFAULT_BORDER_MARGIN);
    }
}

void TLabel::onPaint(wxPaintEvent& event)
{
    wxPaintDC dc(this);

    if(this->HasTransparentBackground())
    {
        dc.SetBackgroundMode(wxTRANSPARENT);
    }

    dc.SetTextForeground ( (this->IsEnabled()) ?
                this->GetForegroundColour() : wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT) );
    dc.SetTextBackground ( this->GetBackgroundColour() );
    dc.SetFont(this->GetFont());

    wxSize txtSize(this->DoGetBestSize());
    int iRealWidth, iRealHeight;
    this->GetClientSize( &iRealWidth, &iRealHeight );

    int iLeft;
    switch(this->align)
    {
        case Left:
            iLeft = DEFAULT_BORDER_MARGIN;
            break;
        case Center:
            if(txtSize.GetWidth() > iRealWidth)
                iLeft = DEFAULT_BORDER_MARGIN;
            else
                iLeft = (iRealWidth - txtSize.GetWidth()) / 2;
            break;
        case Right:
            iLeft = iRealWidth - txtSize.GetWidth() - DEFAULT_BORDER_MARGIN;
    }

    dc.DrawText(this->sText, iLeft, DEFAULT_BORDER_MARGIN);
}

void TLabel::onResize(wxSizeEvent & WXUNUSED(event))
{
    this->Refresh();
}

bool TLabel::SetBackgroundColour(const wxColour& colour)
{
    bool b = wxControl::SetBackgroundColour(colour);
    this->Refresh();
    return b;
}