/* about.cc
 * This file belongs to Worker, a file manager for UN*X/X11.
 * Copyright (C) 2011-2026 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 "about.hh"
#include <string>
#include "cgpl.h"
#include "aguix/aguix.h"
#include "aguix/utf8.hh"
#include "worker.h"
#include "workerversion.h"
#include "aguix/acontainerbb.h"
#include "aguix/util.h"
#include "aguix/awindow.h"
#include "aguix/button.h"
#include "aguix/fieldlistview.h"
#include "datei.h"
#include "worker_locale.h"

About::About( AGUIX *aguix, Worker &worker ) : m_aguix( aguix ), m_worker( worker )
{
}

#ifdef HAVE_AVFS
static std::string getAVFSVersion()
{
    if ( ! Datei::fileExists( "/#avfsstat/version" ) ) return "";

    Datei f;
    std::string res;

    if ( f.open( "/#avfsstat/version", "r" ) == 0 ) {
        char *str = f.getLine();

        if ( str ) {
            std::string version( str );
            _freesafe( str );

            std::string::size_type pos = version.find( ':' );

            if ( pos != std::string::npos ) {
                if ( pos + 2 < version.length() ) {
                    res = std::string( version, pos + 2 );
                }
            }
        }
    }

    return res;
}
#endif

void About::about()
{
    Button *okb, *licenseb;
    const AWindow *twin = NULL;

    if ( ! m_aguix ) return;

    twin = m_aguix->getTransientWindow();
  
    AWindow *win = new AWindow( m_aguix, 10, 10, 10, 10, catalog.getLocale( 208 ), AWindow::AWINDOW_DIALOG );
    win->create();
    if ( twin != NULL ) {
        win->setTransientForAWindow( twin );
    }

    AContainer *ac1 = win->setContainer( new AContainer( win, 1, 2 ), true );
    ac1->setMinSpace( 0 );
    ac1->setMaxSpace( 0 );
    ac1->setBorderWidth( 5 );

    AContainerBB *ac1_texts = dynamic_cast<AContainerBB*>( ac1->add( new AContainerBB( win, 1, 3 ), 0, 0 ) );
    ac1_texts->setMinSpace( 5 );
    ac1_texts->setMaxSpace( 5 );
    ac1_texts->setBorderWidth( 5 );

    std::string str1 = AGUIXUtils::formatStringToString( "Worker %d.%d.%d%s|Copyright (C) 1998 - 2026 Ralf Hoffmann||Active options:",
                                                         WORKER_MAJOR, WORKER_MINOR, WORKER_PATCH, WORKER_COMMENT );
    win->addMultiLineText( str1, *ac1_texts, 0, 0, NULL, NULL );

    FieldListView *option_lv = dynamic_cast<FieldListView*>( ac1_texts->add( new FieldListView( m_aguix, 0, 0, 100, 100, 0 ),
                                                                             0, 1, AContainer::CO_MIN ) );
    option_lv->setHBarState( 2 );
    option_lv->setVBarState( 2 );
    option_lv->setNrOfFields( 2 );
    option_lv->setGlobalFieldSpace( 5 );

    /* RegEx */
    int row = option_lv->addRow();
    option_lv->setText( row, 0, "Regular expressions for file type patterns:" );
#ifdef HAVE_REGEX
    option_lv->setText( row, 1, "yes" );
#else
    option_lv->setText( row, 1, "no" );
#endif
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );

    /* LFS */
    row = option_lv->addRow();
    option_lv->setText( row, 0, "Large file support:" );
#ifdef WORKER_LFS_SUPPORTED
    option_lv->setText( row, 1, "yes" );
#else
    option_lv->setText( row, 1, "no" );
#endif
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );

    /* AVFS */
    row = option_lv->addRow();
    option_lv->setText( row, 0, "Virtual file system (AVFS) usage:" );
#ifdef HAVE_AVFS
    option_lv->setText( row, 1, "yes" );
#else
    option_lv->setText( row, 1, "no" );
#endif
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );

#ifdef HAVE_AVFS
    row = option_lv->addRow();
    option_lv->setText( row, 0, "  AVFS version:" );
    option_lv->setText( row, 1, getAVFSVersion() );
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );
#endif

    /* UTF8 */
    row = option_lv->addRow();
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );
    option_lv->setText( row, 0, "UTF8 support:" );
#ifdef DISABLE_UTF8_SUPPORT
    option_lv->setText( row, 1, "no" );
#else
    option_lv->setText( row, 1, "yes" );

    row = option_lv->addRow();
    option_lv->setText( row, 0, "  current encoding:" );
    switch ( UTF8::checkSupportedEncodings() ) {
        case UTF8::ENCODING_UTF8:
            option_lv->setText( row, 1, "utf8" );
            break;
        default:
            option_lv->setText( row, 1, "8 bit" );
            break;
    }
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );
#endif

    row = option_lv->addRow();
    option_lv->setText( row, 0, "Font engine:" );
#ifdef HAVE_XFT
    /* XFT */
    option_lv->setText( row, 1, "Xft" );
#else
    option_lv->setText( row, 1, "X11" );
#endif
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );

    /* libmagic */
    row = option_lv->addRow();
    option_lv->setText( row, 0, "File magic support:" );
#ifdef HAVE_LIBMAGIC
    option_lv->setText( row, 1, "yes" );
#else
    option_lv->setText( row, 1, "no" );
#endif
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );

#ifdef HAVE_HAL_DBUS
    /* HAL */
    row = option_lv->addRow();
    option_lv->setText( row, 0, "HAL support:" );
    option_lv->setText( row, 1, "yes" );
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );
#elif defined(HAVE_DBUS)
    /* udisks */
    row = option_lv->addRow();
    option_lv->setText( row, 0, "UDisks support:" );
    option_lv->setText( row, 1, "yes" );
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );

    row = option_lv->addRow();
    option_lv->setText( row, 0, "  UDisks available:" );
    if ( m_worker.getVolumeManager().getUDisksAvailable() == true ) {
        option_lv->setText( row, 1, "yes (version 1)" );
    } else if ( m_worker.getVolumeManager().getUDisks2Available() == true ) {
        option_lv->setText( row, 1, "yes (version 2)" );
    } else {
        option_lv->setText( row, 1, "no" );
    }
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );
#else
    row = option_lv->addRow();
    option_lv->setText( row, 0, "HAL support:" );
    option_lv->setText( row, 1, "no" );
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );

    row = option_lv->addRow();
    option_lv->setText( row, 0, "UDisks support:" );
    option_lv->setText( row, 1, "no" );
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );
#endif

    /* EXE_STRING_LEN */
    row = option_lv->addRow();
    option_lv->setText( row, 0, "Maximum length of command lines:" );

    str1 = AGUIXUtils::formatStringToString( "%d", EXE_STRING_LEN );

    option_lv->setText( row, 1, str1 );
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );

    /* inotify */
    row = option_lv->addRow();
    option_lv->setText( row, 0, "Inotify support:" );
#ifdef HAVE_INOTIFY
    option_lv->setText( row, 1, "yes" );
#else
    option_lv->setText( row, 1, "no" );
#endif
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );

    /* XIM mode */
    row = option_lv->addRow();
    option_lv->setText( row, 0, "XIM mode:" );
    if ( m_aguix->getOverrideXIM() ) { 
        option_lv->setText( row, 1, "fallback" );
    } else {
        option_lv->setText( row, 1, "default" );
    }
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );

    /* LUA */
    row = option_lv->addRow();
    option_lv->setText( row, 0, "LUA support:" );
#ifdef HAVE_LUA
    option_lv->setText( row, 1, "yes" );
#else
    option_lv->setText( row, 1, "no" );
#endif
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );

#ifdef DEVELOPER
    row = option_lv->addRow();
    option_lv->setText( row, 0, "Developer version:" );
    option_lv->setText( row, 1, "yes" );
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );
#endif

#ifdef DEBUG
    row = option_lv->addRow();
    option_lv->setText( row, 0, "Debug version:" );
    option_lv->setText( row, 1, "yes" );
    option_lv->setPreColors( row, FieldListView::PRECOLOR_NOTSELORACT );
#endif

    str1 = "|Homepage: http://www.boomerangsworld.de/worker|EMail: Ralf Hoffmann <ralf@boomerangsworld.de>";
    str1 += "||Released under the GNU General Public License:||";
    str1 += "This program is free software; you can redistribute it and/or modify|";
    str1 += "it under the terms of the GNU General Public License as published by|";
    str1 += "the Free Software Foundation; either version 2 of the License, or|";
    str1 += "(at your option) any later version.||";
    str1 += "This program is distributed in the hope that it will be useful,|";
    str1 += "but WITHOUT ANY WARRANTY; without even the implied warranty of|";
    str1 += "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the|";
    str1 += "GNU General Public License for more details.";

    win->addMultiLineText( str1, *ac1_texts, 0, 2, NULL, NULL );

    AContainer *ac1_buttons = NULL;

    ac1_buttons = ac1->add( new AContainer( win, 2, 1 ), 0, 1 );
    ac1_buttons->setMinSpace( 5 );
    ac1_buttons->setMaxSpace( -1 );
    ac1_buttons->setBorderWidth( 0 );

    licenseb = (Button*)ac1_buttons->add( new Button( m_aguix, 0, 0, catalog.getLocale( 508 ), 0 ),
                                          0, 0, AContainer::CO_FIX );
    okb = (Button*)ac1_buttons->add( new Button( m_aguix, 0, 0, catalog.getLocale( 11 ), 0 ),
                                     1, 0, AContainer::CO_FIX );
    okb->takeFocus();

    win->setDoTabCycling( true );
    win->contMaximize( true, false );
    win->useStippleBackground();
    win->centerScreen();
    win->show();

    AGMessage *msg;
    int endmode = -1;
    for (; endmode == -1; ) {
        msg = m_aguix->WaitMessage( win );
        if ( msg != NULL ) {
            switch ( msg->type ) {
                case AG_CLOSEWINDOW:
                    if ( msg->closewindow.window == win->getWindow() ) {
                        endmode = 1;
                    }
                    break;
                case AG_BUTTONCLICKED:
                    if ( msg->button.button == okb ) {
                        endmode = 1;
                        break;
                    } else if ( msg->button.button == licenseb ) {
                        showLicense( win );
                    }
                    break;
                case AG_KEYPRESSED:
                    if ( win->isParent( msg->key.window, false ) == true ) {
                        switch ( msg->key.key ) {
                            case XK_KP_Enter:
                            case XK_Return:
                                if ( okb->getHasFocus() == true ) endmode = 0;
                                else if ( licenseb->getHasFocus() == true ) showLicense( win );
                                break;
                            case XK_Escape:
                                endmode = 1;
                                break;
                        }
                    }
                    break;
            }
            m_aguix->ReplyMessage( msg );
        }
    }
    delete win;
}

void About::showLicense( AWindow *transient_window )
{
    if ( ! m_aguix ) return;

    RefCount<AFontWidth> lencalc( new AFontWidth( m_aguix, NULL ) );
    auto ts = std::make_shared< TextStorageString >( cgpl, lencalc );
    Worker::getRequester()->request( catalog.getLocale( 509 ), ts, catalog.getLocale( 11 ),
                                     transient_window, Requester::REQUEST_NONE );
}
