/*
 * widgets/ButtonWidget.cc:
 *
 * Copyright (C) 2000 John Watson, jwatson@tempusmud.com
 * 
 * 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 "WidgetEvents.h"
#include "Widget.h"
#include "ButtonWidget.h"
#include "LabelWidget.h"
#include "LookAndFeel.h"

/** 
 * default message = 0
 */

ButtonWidget::ButtonWidget( int width, int height, const char * message ) : Widget( width, height ) {

        _isPressed    = false;
        _isToggleable = false;
        _isSelected   = false;
        _isCheckbox   = false;

        _drawBottomHighlight = true;

        setOpaque( true );

        // reset colors to defaults
        setButtonColors( 0, 0, 0 );

        _name = "ButtonWidget";

        if ( message ) {
                _label = new LabelWidget( _size[0], _size[1], message );

                _label->setFGColor4fv( getLookAndFeel()->getBlackColor() );

                
                _label->setPaintBase( false );

                add( _label, 0, 0 );
        }
        else {
                _label = 0;
        }
}

ButtonWidget::~ButtonWidget() {
        if ( _label )
                delete _label;
}

void ButtonWidget::setButtonColors( const GLfloat * unsel, const GLfloat *sel, const GLfloat *press ) {
        _unselectedBGColor =
                ( unsel ? unsel : getLookAndFeel()->getSecondaryColor( COLOR_THREE ) );
        _selectedBGColor   = 
                ( sel ? sel : getLookAndFeel()->getSecondaryColor( COLOR_TWO ) );
        _pressedBGColor    = 
                ( press ? press : getLookAndFeel()->getPrimaryColor( COLOR_THREE ) );

        setBGColor4fv( isPressed() ? _pressedBGColor : 
                       ( isSelected() ? _selectedBGColor : _unselectedBGColor ) );

}

void ButtonWidget::paint() {

        Widget::paint();
        /*
        glColor3fv( getBGColor4fv() );
        glBegin( GL_QUADS );
        {
                glVertex2d( 2,            2 );
                glVertex2d( _size[0] - 2, 2 );
                glVertex2d( _size[0] - 2, _size[1] - 2 );
                glVertex2d( 2,            _size[1] - 2 );
        }
        glEnd();
        */
        
        if ( isFocused() && isEnabled() ) {
                glColor4fv( getLookAndFeel()->getHighlightColor() );
        }
        else {
                glColor4fv( getLookAndFeel()->getSecondaryColor( COLOR_ONE ) );
        }
        
        glBegin( GL_LINE_LOOP );
        {
                glVertex2f( 0,            1 );
                glVertex2f( _size[0] - 2, 1 );
                glVertex2f( _size[0] - 2, _size[1] - 1 );
                glVertex2f( 0,            _size[1] - 1 );

        }
        glEnd();

        if ( isPressed() || isSelected() ) {
                glColor4fv( getLookAndFeel()->getSecondaryColor( COLOR_ONE ) );

                glBegin( GL_LINE_STRIP );
                {
                        glVertex2f( _size[0] - 2, _size[1] - 2 );
                        glVertex2f( 1,            _size[1] - 2 );     
                        glVertex2f( 1,            1 );
                }
                glEnd();
        }

        if ( drawBottomHighlight() || ( ! isSelected() && ! isPressed() ) ) {
                glColor4fv( getLookAndFeel()->getWhiteColor() );
                
                glBegin( GL_LINE_STRIP );
                {
                        
                        if ( drawBottomHighlight() ) {
                                glVertex2f( 1,            0 );
                                glVertex2f( _size[0] - 1, 0 );
                        }
                        
                        glVertex2f( _size[0] - 1, _size[1] - 2 );

                        if ( ! _isSelected && ! _isPressed ) {
                                glVertex2f( 1,            _size[1] - 2 );
                                glVertex2f( 1,            1 );
                        }
                        
                }
                glEnd();
        }
        

        if ( _isCheckbox && _isSelected ) {
                glColor4fv( getLookAndFeel()->getBlackColor() );

                glBegin( GL_LINES );
                {
                        glVertex2f( 3,                        3 );
                        glVertex2f( _size[0] - 4,             _size[1] - 4 );

                        glVertex2f( 3,                        _size[1] - 4 );
                        glVertex2f( _size[0] - 4,             3 );

                }
                glEnd();
        }
}


bool ButtonWidget::mouseReleased( SDL_MouseButtonEvent * evt ) { 

        if ( ! _isPressed )
                return false;

        _isPressed = false;

        if ( _isToggleable ) {
                setSelected( ! _isSelected );
        }
        else {
                setBGColor4fv( _unselectedBGColor );
                notifyActionListeners( this, "button clicked" );
        }

        return true;
}

bool ButtonWidget::mousePressed( SDL_MouseButtonEvent * evt ) { 
        if ( isEnabled() == false )
                return true;

        setBGColor4fv( _pressedBGColor );
        _isPressed = true;
        return true;
}

bool ButtonWidget::mouseExited( SDL_MouseMotionEvent * evt ) { 
        Widget::mouseExited( evt );

        _isPressed = false;
        
        setBGColor4fv( _isSelected ? _selectedBGColor : _unselectedBGColor );

        return true;
}

void ButtonWidget::setSelected( bool selected ) {
        if ( selected != _isSelected ) {
                _isSelected = selected;
                
                if ( _isSelected ) {
                        setBGColor4fv( _selectedBGColor );
                }
                else {
                        setBGColor4fv( 0 );
                }
                notifyActionListeners( this, "button toggled" );
        }
}

void ButtonWidget::setDrawBottomHighlight( bool draw ) {
        _drawBottomHighlight = draw;
}

void ButtonWidget::setToggleable( bool togg ) {
        _isToggleable = togg;
}

void ButtonWidget::setCheckbox( bool check ) {
        _isCheckbox = check;
        setToggleable( check );
}

const char * ButtonWidget::getLabelText() const {
        return ( _label ? _label->getText() : 0 );
}
