/* wconfig_kvppanel.cc
 * This file belongs to Worker, a file manager for UN*X/X11.
 * Copyright (C) 2025 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_kvppanel.hh"
#include "wconfig.h"
#include "aguix/fieldlistview.h"
#include "aguix/button.h"
#include "worker_locale.h"

KVPPanel::KVPPanel( AWindow &basewin, WConfig &baseconfig ) : WConfigPanel( basewin, baseconfig )
{
}

KVPPanel::~KVPPanel()
{
}

int KVPPanel::create()
{
    std::string str1;
    
    Panel::create();
    
    AContainer *ac1 = setContainer( new AContainer( this, 1, 3 ), true );
    ac1->setBorderWidth( 5 );
    ac1->setMinSpace( 5 );
    ac1->setMaxSpace( 5 );
    
    addMultiLineText( catalog.getLocale( 1602 ),
                      *ac1,
                      0, 0,
                      NULL, NULL );

    m_lv = ac1->addWidget( new FieldListView( _aguix, 0, 0, 10, 10, 0 ),
                           0, 1,
                           AContainer::CO_MIN );
    m_lv->setHBarState( 2 );
    m_lv->setVBarState( 2 );
    m_lv->setNrOfFields( 3 );
    m_lv->setFieldText( 0, catalog.getLocale( 1050 ) );
    m_lv->setFieldText( 1, catalog.getLocale( 1605 ) );
    m_lv->setFieldText( 2, catalog.getLocale( 1605 ) );
    m_lv->setShowHeader( true );
    m_lv->setFieldSpace( 0, 5 );
    m_lv->connect( this );
    m_lv->setConsiderHeaderWidthForDynamicWidth( true );
    m_lv->setFieldWidth( 1, _aguix->getTextWidth( "*" ) );
    m_lv->setFieldTextMerged( 1, true );

    AContainer *ac1_2 = ac1->add( new AContainer( this, 2, 1 ), 0, 2 );
    ac1_2->setBorderWidth( 0 );
    ac1_2->setMinSpace( 0 );
    ac1_2->setMaxSpace( 0 );
    m_edit_b = ac1_2->addWidget( new Button( _aguix, 0, 0, catalog.getLocale( 1606 ), 0 ),
                                 0, 0, AContainer::CO_INCW );
    m_edit_b->connect( this );
    m_default_b = ac1_2->addWidget( new Button( _aguix, 0, 0, catalog.getLocale( 1607 ), 0 ),
                                    1, 0, AContainer::CO_INCW );
    m_default_b->connect( this );

    auto keys = _baseconfig.getKVPPool().getKeys();

    m_entries.clear();

    for ( const auto &k : keys ) {
        int row = m_lv->addRow();
        m_lv->setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );

        auto value = _baseconfig.getKVPPool().getEntry( k );

        m_entries.push_back( value );

        m_lv->setText( row, 0, k );
        updateRow( row );
    }
    
    contMaximize( true );
    return 0;
}

int KVPPanel::saveValues()
{
    WConfigKVPPool kvp;

    for ( size_t r = 0; r < m_entries.size(); r++ ) {
        kvp.setEntry( m_lv->getText( r, 0 ), m_entries[r].value );
    }

    _baseconfig.setKVPPool( kvp );

    return 0;
}

void KVPPanel::run( Widget *elem, const AGMessage &msg )
{
    if ( msg.type == AG_FIELDLV_DOUBLECLICK ) {
        if ( msg.fieldlv.lv == m_lv ) {
            int row = m_lv->getActiveRow();
            if ( m_lv->isValidRow( row ) ) {
                editEntry( row );
            }
        }
    } else if ( msg.type == AG_BUTTONCLICKED ) {
        if ( msg.button.button == m_edit_b ) {
            int row = m_lv->getActiveRow();
            if ( m_lv->isValidRow( row ) ) {
                editEntry( row );
            }
        } else if ( msg.button.button == m_default_b ) {
            int row = m_lv->getActiveRow();
            if ( m_lv->isValidRow( row ) ) {
                resetToDefault( row );
            }
        }
    }
}

std::string KVPPanel::getEntryRepresentation( const WConfigKVPPool::get_entry_result &entry ) const
{
    std::string res;

    switch ( entry.value.type ) {
        case WConfigKVPPool::kvp_entry::KVP_BOOLEAN:
            res = entry.value.bool_value ? "true" : "false";
            break;
        case WConfigKVPPool::kvp_entry::KVP_INT:
            res = AGUIXUtils::formatStringToString( "%d", entry.value.int_value );
            break;
        case WConfigKVPPool::kvp_entry::KVP_STRING:
            res = entry.value.str_value;
            break;
    }

    return res;
}

void KVPPanel::editEntry( int row )
{
    int erg;
    char *str_res = nullptr;
    std::string int_str;
    std::string button_text;

    button_text = catalog.getLocale( 11 );
    button_text += "|";
    button_text += catalog.getLocale( 8 );

    switch ( m_entries[row].value.type ) {
        case WConfigKVPPool::kvp_entry::KVP_BOOLEAN:
            m_entries[row].value.bool_value = !m_entries[row].value.bool_value;
            break;        
        case WConfigKVPPool::kvp_entry::KVP_INT:
            int_str = AGUIXUtils::formatStringToString( "%d", m_entries.at( row ).value.int_value );

            erg = string_request( catalog.getLocale( 123 ),
                                  catalog.getLocale( 1604 ),
                                  int_str.c_str(),
                                  button_text.c_str(),
                                  &str_res );
            if ( erg == 0 && str_res != NULL ) {
                int v = atoi( str_res );
                m_entries.at( row ).value.int_value = v;
            }

            if ( str_res ) _freesafe( str_res );

            break;
        case WConfigKVPPool::kvp_entry::KVP_STRING:
            erg = string_request( catalog.getLocale( 123 ),
                                  catalog.getLocale( 1603 ),
                                  m_entries.at( row ).value.str_value.c_str(),
                                  button_text.c_str(),
                                  &str_res );
            if ( erg == 0 && str_res != NULL ) {
                m_entries.at( row ).value.str_value = str_res;
            }

            if ( str_res ) _freesafe( str_res );

            break;
    }

    updateRow( row );
}

void KVPPanel::resetToDefault( int row )
{
    m_entries.at( row ).value = m_entries.at( row ).default_value;

    updateRow( row );
}

void KVPPanel::updateRow( int row )
{
    bool changed = !( m_entries.at( row ).value == m_entries.at( row ).default_value );

    m_lv->setText( row, 1, changed ? "*" : "" );
    m_lv->setText( row, 2, getEntryRepresentation( m_entries.at( row ) ) );
    m_lv->redraw();
}
