/* wconfig_bookmarkcolor.cc
 * This file belongs to Worker, a file manager for UN*X/X11.
 * Copyright (C) 2008-2024 Ralf Hoffmann.
 * You can contact me at: ralf@boomerangsworld.de
 *   or http://www.boomerangsworld.de/worker
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "wconfig_bookmarkcolor.hh"
#include "wconfig.h"
#include "worker.h"
#include "worker_locale.h"
#include "aguix/bevelbox.h"
#include "aguix/choosebutton.h"
#include "aguix/fieldlistview.h"
#include "aguix/button.h"
#include "aguix/stringgadget.h"

BookmarkColorPanel::BookmarkColorPanel( AWindow &basewin, WConfig &baseconfig ) : WConfigPanel( basewin, baseconfig )
{
    m_lv = NULL;
    m_label_lv = NULL;
    m_norm_b[0] = NULL;
    m_norm_b[1] = NULL;
    m_act_b[0] = NULL;
    m_act_b[1] = NULL;
    m_add_label_b = NULL;
    m_label_sg = NULL;
    m_del_label_b = NULL;

    m_label_colors = _baseconfig.getColorDefs().getLabelColors();
}

BookmarkColorPanel::~BookmarkColorPanel()
{
}

int BookmarkColorPanel::create()
{
    int trow;
    
    Panel::create();

    AContainer *ac1 = setContainer( new AContainer( this, 1, 4 ), true );
    ac1->setMinSpace( 5 );
    ac1->setMaxSpace( 5 );
    
    addMultiLineText( catalog.getLocale( 825 ),
                      *ac1,
                      0, 0,
                      NULL, NULL );

    ac1->add( new BevelBox( _aguix, 0, 0, 10, 2, 0 ), 0, 1, AContainer::CO_INCW );
    ac1->add( new Text( _aguix, 0, 0, catalog.getLocale( 826 ) ), 0, 2, AContainer::CO_INCW );

    AContainer *ac1_0 = ac1->add( new AContainer( this, 2, 1 ), 0, 3 );
    ac1_0->setBorderWidth( 0 );
    ac1_0->setMinSpace( 5 );
    ac1_0->setMaxSpace( 5 );

    AContainer *ac1_0_1 = ac1_0->add( new AContainer( this, 1, 2 ), 0, 0 );
    ac1_0_1->setBorderWidth( 0 );
    ac1_0_1->setMinSpace( 0 );
    ac1_0_1->setMaxSpace( 0 );

    m_label_lv = (FieldListView*)ac1_0_1->add( new FieldListView( _aguix, 0, 0, 100, 100, 0 ),
                                               0, 0, AContainer::CO_INCW );
    m_label_lv->setHBarState( 2 );
    m_label_lv->setVBarState( 2 );
    m_label_lv->setAcceptFocus( true );
    m_label_lv->setDisplayFocus( true );

    std::map<std::string, WConfig::ColorDef::label_colors_t>::const_iterator label_it;

    for ( label_it = m_label_colors.begin(); label_it != m_label_colors.end(); ++label_it ) {
        trow = m_label_lv->addRow();
        m_label_lv->setText( trow, 0, label_it->first );
        m_label_lv->setPreColors( trow, FieldListView::PRECOLOR_ONLYACTIVE );
    }
    m_label_lv->connect( this );

    AContainer *ac1_0_1_1 = ac1_0_1->add( new AContainer( this, 3, 1 ), 0, 1 );
    ac1_0_1_1->setBorderWidth( 0 );
    ac1_0_1_1->setMinSpace( 0 );
    ac1_0_1_1->setMaxSpace( 0 );

    m_add_label_b = (Button*)ac1_0_1_1->add( new Button( _aguix, 0, 0, catalog.getLocale( 827 ), 0 ),
                                             0, 0, AContainer::CO_FIX );
    m_add_label_b->connect( this );

    m_label_sg = dynamic_cast<StringGadget*>( ac1_0_1_1->add( new StringGadget( _aguix,
                                                                                0, 0,
                                                                                100,
                                                                                "",
                                                                                0 ), 1, 0, AContainer::CO_INCW ) );
    m_label_sg->connect( this );
    m_del_label_b = (Button*)ac1_0_1_1->add( new Button( _aguix, 0, 0, catalog.getLocale( 828 ), 0 ),
                                             2, 0, AContainer::CO_FIX );
    m_del_label_b->connect( this );

    AContainer *cont_1x2_at_1x0 = ac1_0->add( new AContainer( this, 1, 2 ), 1, 0 );
    cont_1x2_at_1x0->setBorderWidth( 0 );
    cont_1x2_at_1x0->setMinSpace( 5 );
    cont_1x2_at_1x0->setMaxSpace( 5 );

    AContainer *ac1_1 = cont_1x2_at_1x0->add( new AContainer( this, 2, 1 ), 0, 0 );
    ac1_1->setBorderWidth( 0 );
    ac1_1->setMinSpace( 5 );
    ac1_1->setMaxSpace( 5 );

    m_lv = (FieldListView*)ac1_1->add( new FieldListView( _aguix, 0, 0, 50, 50, 0 ),
                                       0, 0, AContainer::CO_INCW );
    m_lv->setHBarState(0);
    m_lv->setVBarState(0);
    m_lv->setShowHeader( true );
    m_lv->setFieldText( 0, catalog.getLocale( 555 ) );
    m_lv->setHeaderFG( _baseconfig.getFaceDB().getColor( "dirview-header-fg" ) );
    m_lv->setHeaderBG( _baseconfig.getFaceDB().getColor( "dirview-header-bg" ) );

    trow = m_lv->addRow();
    m_lv->setText( trow, 0, catalog.getLocale( 607 ) );
    setLVColors( trow, 0, 0 );
    
    trow = m_lv->addRow();
    m_lv->setText( trow, 0, catalog.getLocale( 609 ) );
    setLVColors( trow, 0, 0 );
    
    m_lv->maximizeY();
    m_lv->maximizeX();
    m_lv->redraw();
    ac1_1->readLimits();
    
    AContainer *ac1_1_1 = ac1_1->add( new AContainer( this, 2, 3 ), 1, 0 );
    ac1_1_1->setBorderWidth( 0 );
    ac1_1_1->setMinSpace( 0 );
    ac1_1_1->setMaxSpace( 0 );

    ac1_1_1->setMinHeight( 0, 0, m_lv->getHeaderHeight() );

    m_norm_b[0] = (Button*)ac1_1_1->add( new Button( _aguix, 0, 0, catalog.getLocale( 32 ), 0 ),
                                         0, 1, AContainer::CO_FIX );
    m_norm_b[0]->resize( m_norm_b[0]->getWidth(), m_lv->getRowHeight() );
        
    m_norm_b[1] = (Button*)ac1_1_1->add( new Button( _aguix, 0, 0, catalog.getLocale( 33 ), 0 ),
                                         1, 1, AContainer::CO_FIX );
    m_norm_b[1]->resize( m_norm_b[1]->getWidth(), m_lv->getRowHeight() );
    
    m_act_b[0] = (Button*)ac1_1_1->add( new Button( _aguix, 0, 0, catalog.getLocale( 32 ), 0 ),
                                         0, 2, AContainer::CO_FIX );
    m_act_b[0]->resize( m_act_b[0]->getWidth(), m_lv->getRowHeight() );
        
    m_act_b[1] = (Button*)ac1_1_1->add( new Button( _aguix, 0, 0, catalog.getLocale( 33 ), 0 ),
                                         1, 2, AContainer::CO_FIX );
    m_act_b[1]->resize( m_act_b[1]->getWidth(), m_lv->getRowHeight() );
    
    ac1_1_1->readLimits();

    m_only_exact_path = cont_1x2_at_1x0->addWidget( new ChooseButton( _aguix, 0, 0, false,
                                                                      catalog.getLocale( 1561 ),
                                                                      LABEL_LEFT, 0 ), 0, 1, AContainer::CO_FIXNR );
    
    m_norm_b[0]->connect( this );
    m_norm_b[1]->connect( this );
    m_act_b[0]->connect( this );
    m_act_b[1]->connect( this );

    m_only_exact_path->connect( this );

    contMaximize( true );
    return 0;
}

int BookmarkColorPanel::saveValues()
{
    WConfig::ColorDef current_cols = _baseconfig.getColorDefs();
    current_cols.setLabelColors( m_label_colors );
    _baseconfig.setColorDefs( current_cols );
    return 0;
}

WConfigPanel::panel_action_t BookmarkColorPanel::setColors( List *colors )
{
    if ( colors != _baseconfig.getColors() ) {
        _baseconfig.setColors( colors );
    }
    return PANEL_NOACTION;
}

void BookmarkColorPanel::run( Widget *elem, const AGMessage &msg )
{
    int col;

    if ( msg.type == AG_BUTTONCLICKED ) {
        if ( msg.button.button == m_add_label_b ) {
            std::map<std::string, WConfig::ColorDef::label_colors_t>::const_iterator label_it;

            label_it = m_label_colors.find( m_label_sg->getText() );
            if ( label_it == m_label_colors.end() ) {
                WConfig::ColorDef::label_colors_t cols;
                m_label_colors[m_label_sg->getText()] = cols;
                
                int row = m_label_lv->addRow();
                m_label_lv->setText( row, 0, m_label_sg->getText() );
                m_label_lv->setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );

                updateLV();
                m_label_lv->redraw();
            }
        } else if ( msg.button.button == m_del_label_b ) {
            int row = m_label_lv->getActiveRow();
            
            if ( m_label_lv->isValidRow( row ) == true ) {
                std::string label = m_label_lv->getText( row, 0 );
                std::map<std::string, WConfig::ColorDef::label_colors_t>::iterator label_it;
        
                label_it = m_label_colors.find( label );
                if ( label_it != m_label_colors.end() ) {
                    m_label_colors.erase( label_it );
                    m_label_lv->deleteRow( row );

                    updateLV();
                    m_label_lv->redraw();
                }
            }
        } else {
            int row = m_label_lv->getActiveRow();
            
            if ( m_label_lv->isValidRow( row ) == true ) {
                std::string label = m_label_lv->getText( row, 0 );
                if ( m_label_colors.count( label ) > 0 ) {
                    if ( msg.button.button == m_norm_b[0] ) {
                        col = _baseconfig.palette( m_lv->getFG( 0, FieldListView::CC_NORMAL ) );
                        if ( col >= 0 ) {
                            m_label_colors[label].normal_fg = col;
                        }
                    } else if ( msg.button.button == m_norm_b[1] ) {
                        col = _baseconfig.palette( m_lv->getBG( 0, FieldListView::CC_NORMAL ) );
                        if ( col >= 0 ) {
                            m_label_colors[label].normal_bg = col;
                        }
                    } else if ( msg.button.button == m_act_b[0] ) {
                        col = _baseconfig.palette( m_lv->getFG( 1, FieldListView::CC_NORMAL ) );
                        if ( col >= 0 ) {
                            m_label_colors[label].active_fg = col;
                        }
                    } else if ( msg.button.button == m_act_b[1] ) {
                        col = _baseconfig.palette( m_lv->getBG( 1, FieldListView::CC_NORMAL ) );
                        if ( col >= 0 ) {
                            m_label_colors[label].active_bg = col;
                        }
                    }
                    updateLV();
                }
            }
        }
    } else if ( msg.type == AG_STRINGGADGET_CONTENTCHANGE ) {
        int row = 0;
        for ( row = 0; m_label_lv->isValidRow( row ) == true; row++ ) {
            if ( m_label_lv->getText( row, 0 ) == m_label_sg->getText() ) {
                break;
            }
        }
        if ( m_label_lv->isValidRow( row ) == true ) {
                m_label_lv->setActiveRow( row );
        } else {
                m_label_lv->setActiveRow( -1 );
        }
        updateLV();
    } else if ( msg.type == AG_FIELDLV_ONESELECT || msg.type == AG_FIELDLV_MULTISELECT  ) {
        int row = m_label_lv->getActiveRow();
        if ( m_label_lv->isValidRow( row ) == true ) {
            m_label_sg->setText( m_label_lv->getText( row, 0 ).c_str() );
        }
        updateLV();
    } else if ( msg.type == AG_CHOOSECLICKED ) {
        if ( msg.choose.button == m_only_exact_path ) {
            int row = m_label_lv->getActiveRow();
            
            if ( m_label_lv->isValidRow( row ) == true ) {
                std::string label = m_label_lv->getText( row, 0 );
                if ( m_label_colors.count( label ) > 0 ) {
                    m_label_colors[label].only_exact_path = msg.choose.state;
                }
            }
        }
    }
}

void BookmarkColorPanel::setLVColors( int row, int fg, int bg )
{
    m_lv->setFG( row, FieldListView::CC_NORMAL, fg );
    m_lv->setFG( row, FieldListView::CC_SELECT, fg );
    m_lv->setFG( row, FieldListView::CC_ACTIVE, fg );
    m_lv->setFG( row, FieldListView::CC_SELACT, fg );
    m_lv->setBG( row, FieldListView::CC_NORMAL, bg );
    m_lv->setBG( row, FieldListView::CC_SELECT, bg );
    m_lv->setBG( row, FieldListView::CC_ACTIVE, bg );
    m_lv->setBG( row, FieldListView::CC_SELACT, bg );
}

void BookmarkColorPanel::updateLV()
{
    int row = m_label_lv->getActiveRow();

    if ( m_label_lv->isValidRow( row ) == true ) {
        std::map<std::string, WConfig::ColorDef::label_colors_t>::const_iterator label_it;
        
        label_it = m_label_colors.find( m_label_lv->getText( row, 0 ) );
        if ( label_it != m_label_colors.end() ) {
            setLVColors( 0, label_it->second.normal_fg, label_it->second.normal_bg );
            setLVColors( 1, label_it->second.active_fg, label_it->second.active_bg );

            m_only_exact_path->setState( label_it->second.only_exact_path );
        }
    } else {
        setLVColors( 0, 0, 0 );
        setLVColors( 1, 0, 0 );
        m_only_exact_path->setState( false );
    }

    m_lv->redraw();
}
