/* wconfig.h
 * This file belongs to Worker, a file manager for UN*X/X11.
 * Copyright (C) 2001-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
 */

#ifndef WCONFIG_H
#define WCONFIG_H

#include "wdefines.h"
#include "worker_types.h"
#include <vector>
#include <list>
#include <map>
#include "layoutsettings.hh"
#include "aguix/aguix.h"
#include "stringcomparator.hh"
#include "wconfig_types.hh"
#include "wconfig_initial_command.hh"
#include "wconfig_kvp_pool.hh"

class Worker;
class WCPath;
class WCHotkey;
class WCButton;
class WCFiletype;
class WC_Color;
class WCDoubleShortkey;
class FunctionProto;
class Datei;
class FlatTypeList;
class List;

class WConfig
{
public:
  typedef enum { CLOCKBAR_MODE_TIMERAM = 0,
                 CLOCKBAR_MODE_TIME,
                 CLOCKBAR_MODE_VERSION,
                 CLOCKBAR_MODE_EXTERN,
                 CLOCKBAR_MODE_CUSTOM } clockbar_mode_t;

  WConfig(Worker *);
  ~WConfig();
  WConfig( const WConfig &other );
  WConfig &operator=( const WConfig &other );

  WConfig *duplicate();
  void setLang( const char* );
  void setTerminalBin(const char*);
  void setRows(unsigned int);
  void setColumns(unsigned int);
  void setCacheSize(unsigned int);
  void setHBarTop(int,bool);
  void setVBarLeft(int,bool);
  void setHBarHeight(int,unsigned int);
  void setVBarWidth(int,unsigned int);
  void setVisCols( int side, const std::vector<WorkerTypes::listcol_t> *nv );
  char *getLang();
  char *getTerminalBin();
  unsigned int getRows();
  unsigned int getColumns();
  unsigned int getCacheSize();
  bool getHBarTop(int);
  bool getVBarLeft(int);
  unsigned int getHBarHeight(int);
  unsigned int getVBarWidth(int);
  const std::vector<WorkerTypes::listcol_t> *getVisCols( int side ) const;
  void setStartDir(int,const char*);
  char *getStartDir(int);
  void setFont(int,const char*);
  std::string getFont( int );
  void setPaths(List*);
  List *getPaths();
  void setFiletypes(List*);
  List *getFiletypes();
  void setHotkeys(List*);
  List *getHotkeys();
  void setButtons(List*);
  List *getButtons();
  void setColors(List*);
  List *getColors();
  void setColor( int nr, int red, int green, int blue );
  void resetColors();
  void cleanUpPaths();
  void cleanUpButtons();
  void setOwnerstringtype(int);
  int getOwnerstringtype();
  void setClockbarMode(clockbar_mode_t);
  clockbar_mode_t getClockbarMode();
  void setClockbarUpdatetime(int);
  int getClockbarUpdatetime();
    void setClockbarCommand( const std::string & );
    const std::string &getClockbarCommand() const;
    void setClockbarCustom( const std::string &, uint8_t variant );
    const std::string &getClockbarCustom( uint8_t variant ) const;
  void setClockbarHints( bool );
  bool getClockbarHints();

    void setDontCheckDirs( const std::list< WConfigTypes::dont_check_dir > &l );
    const std::list< WConfigTypes::dont_check_dir > &getDontCheckDirs() const;

  void setDontCheckVirtual( bool );
  bool getDontCheckVirtual() const;
  void setShowStringForDirSize(bool nv);
  bool getShowStringForDirSize();
  void setStringForDirSize(const char *nv);
  const char *getStringForDirSize();

  void applyColorList(List *);

  bool configure( const std::string &panel = "" );

  int palette();
  int palette(int);
  bool save();
  bool saveas( const std::string &file );
  bool load();
  bool loadfrom( const std::string &file );
  
  WCFiletype *getnotyettype();
  WCFiletype *getdirtype();
  WCFiletype *getvoidtype();
  WCFiletype *getunknowntype();
  void applyLanguage();
  
  const char *getTerminalStr();
  int getStringForDirSizeLen();

  void setDateFormat( int nv );
  int getDateFormat();
  void setDateFormatString( const char *nv );
  const char *getDateFormatString();
  void setDateSubst( bool nv );
  bool getDateSubst();
  void setTimeFormat( int nv );
  int getTimeFormat();
  void setTimeFormatString( const char *nv );
  const char *getTimeFormatString();
  void setDateBeforeTime( bool nv );
  bool getDateBeforeTime();
  
  void setShowHeader( int side, bool nv );
  bool getShowHeader( int side ) const;

  void setPathEntryOnTop( int side, bool nv );
  bool getPathEntryOnTop( int side ) const;

  int writeDateToString( std::string &str, struct tm *timeptr );
  
  bool checkForNewerConfig();
  time_t getFileConfigMod();
  
  void clearVisCols( int side );
  void addListCol( int side, WorkerTypes::listcol_t nv );
  
    void setLayoutOrders( const std::list< LayoutSettings::layoutID_t > &nl );
    const std::list< LayoutSettings::layoutID_t > &getLayoutOrders() const;
    void setLayoutButtonVert( bool nv );
    bool getLayoutButtonVert() const;
    void setLayoutListviewVert( bool nv );
    bool getLayoutListviewVert() const;
    void clearLayoutOrders();
    void layoutAddEntry( LayoutSettings::layoutID_t nv );
    void setLayoutListViewWeight( int nv );
    int getLayoutListViewWeight() const;
    void setLayoutWeightRelToActive( bool nv );
    bool getLayoutWeightRelToActive() const;

    std::unique_ptr< FlatTypeList > getFlatTypeList() const;
  typedef enum { MOUSECONF_NORMAL_MODE,
		 MOUSECONF_ALT_MODE } mouseconf_method_t;
  void setMouseSelectButton( int nv );
  void setMouseActivateButton( int nv );
  void setMouseScrollButton( int nv );
  void setMouseContextButton( int nv );
  void setMouseSelectMethod( mouseconf_method_t nv );
  int getMouseSelectButton() const;
  int getMouseActivateButton() const;
  int getMouseScrollButton() const;
  int getMouseContextButton() const;
  mouseconf_method_t getMouseSelectMethod() const;
  void setMouseActivateMod( int nv );
  void setMouseScrollMod( int nv );
  void setMouseContextMod( int nv );
  int getMouseActivateMod() const;
  int getMouseScrollMod() const;
  int getMouseContextMod() const;
    void setMouseContextMenuWithDelayedActivate( bool nv );
    bool getMouseContextMenuWithDelayedActivate() const;

  bool configureButtonIndex( int index );
  bool configurePathIndex( int index );
  bool configureHotkeyIndex( int index );
  bool configureFiletype(WCFiletype*, int default_panel = 0);

  static bool isCorrectTerminalBin(const char*);
  int loadImportConfig( const char *filename,
                        bool &import_buttons,
                        bool &import_hotkeys,
                        bool &import_filetypes,
                        const std::string &info_text,
                        WConfig **return_config );
  int cfg_export( const char *filename );

  int addButtons( List *bl );
  int addHotkeys( List *hl );
  int addFiletypes( List *fl, bool init_fix_types = false );

  static bool getAlwaysKeepOldKey();
  static void setAlwaysKeepOldKey( bool nv );
  static int fixDoubleKeys( List *bl, List *pl, List *hl, WCButton *im_b1, WCHotkey *im_h1 );
  static int fixDoubleKeys( List *bl, List *pl, List *hl, List *button_check, List *hotkey_check );

  static int getNrOfPreDates();
  static int getNrOfPreTimes();
  static const char *getPreDate( int pos );
  static const char *getPreTime( int pos );

  class ColorDef
  {
  public:
      ColorDef();
      ~ColorDef();
      ColorDef &operator=( const ColorDef &other );

      typedef struct _label_colors_t {
          _label_colors_t() : normal_fg( 1 ),
                              normal_bg( 0 ),
                              active_fg( 1 ),
                              active_bg( 0 ) {}
          
          int normal_fg, normal_bg;
          int active_fg, active_bg;
          bool only_exact_path = false;
      } label_colors_t;

      void setLabelColors( const std::map<std::string, label_colors_t> &cols );
      const std::map<std::string, label_colors_t> &getLabelColors() const;
      const label_colors_t &getLabelColor( const std::string &label ) const;
      void addLabelColor( const std::string &label,
                          const label_colors_t &col );
      void removeLabelColor( const std::string &label );
  private:
      std::map<std::string, label_colors_t> m_label_colors;
  };

  void setColorDefs( const ColorDef &cols );
  const ColorDef &getColorDefs() const;

  int getAllCustomNames( std::vector<std::string> &custom_names ) const;

  void setSaveWorkerStateOnExit( bool nv );
  bool getSaveWorkerStateOnExit() const;

  void setUseStringCompareMode( StringComparator::string_comparator_modes nv );
  StringComparator::string_comparator_modes getUseStringCompareMode() const;

  void setPathJumpStoreFilesAlways( bool nv );
  bool getPathJumpStoreFilesAlways() const;

  void setApplyWindowDialogType( bool nv );
  bool getApplyWindowDialogType() const;

  void setUseExtendedRegEx( bool nv );
  bool getUseExtendedRegEx() const;

  typedef enum {
      FONT_X11_GLOBAL,
      FONT_X11_BUTTONS,
      FONT_X11_LEFT,
      FONT_X11_RIGHT,
      FONT_X11_TEXTVIEW,
      FONT_X11_STATEBAR,
      FONT_X11_TEXTVIEW_ALT,
      FONT_XFT_GLOBAL,
      FONT_XFT_BUTTONS,
      FONT_XFT_LEFT,
      FONT_XFT_RIGHT,
      FONT_XFT_TEXTVIEW,
      FONT_XFT_STATEBAR,
      FONT_XFT_TEXTVIEW_ALT
  } font_type_t;

  void setFontName( font_type_t fonttype, const std::string &name );
  std::string getFontName( font_type_t fonttype );

    void setVMMountCommand( const std::string &cmd );
    std::string getVMMountCommand() const;
    void setVMUnmountCommand( const std::string &cmd );
    std::string getVMUnmountCommand() const;
    void setVMFStabFile( const std::string &filename );
    std::string getVMFStabFile() const;
    void setVMMtabFile( const std::string &filename );
    std::string getVMMtabFile() const;
    void setVMPartitionFile( const std::string &filename );
    std::string getVMPartitionFile() const;
    void setVMRequestAction( bool nv );
    bool getVMRequestAction() const;
    void setVMEjectCommand( const std::string &cmd );
    std::string getVMEjectCommand() const;
    void setVMCloseTrayCommand( const std::string &cmd );
    std::string getVMCloseTrayCommand() const;
    void setVMPreferredUdisksVersion( int version );
    int getVMPreferredUdisksVersion() const;

    void setPathJumpAllowDirs( const std::list< std::string > &l );
    const std::list< std::string > &getPathJumpAllowDirs();

    void setFaceDB( const FaceDB &facedb );
    const FaceDB &getFaceDB() const;
    FaceDB getFaceDB();

    void applyNewFacesFromList( const std::list< std::pair< std::string, int > > &faces );

    void setLoadedVersion( int major,
                           int minor,
                           int patch );
    void getLoadedVersion( int &major,
                           int &minor,
                           int &patch );

    Worker *getWorker();

    typedef enum {
        RESTORE_TABS_NEVER = 0 ,
        RESTORE_TABS_ALWAYS,
        RESTORE_TABS_ASK
    } restore_tabs_mode_t;

    typedef enum {
        STORE_TABS_NEVER = 0 ,
        STORE_TABS_ALWAYS,
        STORE_TABS_AS_EXIT_STATE,
        STORE_TABS_ASK
    } store_tabs_mode_t;

    void setRestoreTabsMode( restore_tabs_mode_t );
    restore_tabs_mode_t getRestoreTabsMode() const;

    void setStoreTabsMode( store_tabs_mode_t );
    store_tabs_mode_t getStoreTabsMode() const;

    void setTerminalReturnsEarly( bool nv );
    bool getTerminalReturnsEarly() const;

    void setDirectoryPresets( const std::map< std::string, struct directory_presets > &presets );
    const std::map< std::string, struct directory_presets > &getDirectoryPresets() const;

    void setInitialCommand( const WConfigInitialCommand &cmd );

    void setDisableBGCheckPrefix( const std::string &prefix );
    const std::string getDisableBGCheckPrefix() const;

    std::string queryNewActionName() const;

    const WConfigKVPPool &getKVPPool() const;
    void setKVPPool( const WConfigKVPPool &kvp );

    void applyKVPPool();
protected:
  char *lang;
  unsigned int rows,columns;
  unsigned int cachesize;
  List *colors;
  bool hbar_top[2];
  bool vbar_left[2];
  unsigned int hbar_height[2];
  unsigned int vbar_width[2];
  std::vector<WorkerTypes::listcol_t> viscols[2];
  char *dir[2];  // left=0, right=1
  List *paths;  // Elemente sind WCPath
  List *filetypes; // Elemente sind WCFiletype
  List *hotkeys; // Elemente sind WCHotkey
  List *buttons; // Elemente sind WCButton
  clockbar_mode_t clockbar_mode;
  int clockbar_updatetime;
    std::string clockbar_command;
    std::string m_clockbar_custom[2];
  bool m_clockbar_hints;

    std::list< WConfigTypes::dont_check_dir > m_dont_check_dirs;
    bool dontcheckvirtual;
  
    LayoutSettings m_layout_conf;

  struct {
    int select_button, activate_button, scroll_button, context_button;
    mouseconf_method_t select_method;
    int activate_mod, scroll_mod, context_mod;
      bool context_menu_with_delayed_activate;
  } mouseConf;
  
  char *terminalbin;
  
  int ownerstringtype;
  
  bool showStringForDirSize;
  char *stringForDirSize;
  int stringForDirSizeLen;
  bool showHeader[2];
  bool m_path_entry_on_top[2];
  
  WCFiletype *notyettype; // Nur zum schnelleren Auslesen, muss nicht abgespeichert werden
  WCFiletype *dirtype; // Nur zum schnelleren Auslesen, muss nicht abgespeichert werden
  WCFiletype *voidtype; // Nur zum schnelleren Auslesen, muss nicht abgespeichert werden
  WCFiletype *unknowntype; // Nur zum schnelleren Auslesen, muss nicht abgespeichert werden
  
  Worker *worker;

  bool changeTypes( bool allowRemoveUnique );
  bool changeHotkeys();
  bool changeButtons();
  bool changeDisplaySets(int);
  
  bool configurePath(WCPath*);
  int grabKey( const char *title, const char *text, KeySym *return_key, unsigned int *return_mod );
  int getDoubleShortkey( bool doublek,
                         const WCButton *ignore_b,
                         const WCHotkey *ignore_h,
                         const WCPath *ignore_p,
                         WCDoubleShortkey **return_dk);
  static int findDoubleShortkey( WCDoubleShortkey *dk,
                                 List *button_list,
                                 List *path_list,
                                 List *hotkey_list,
                                 WCButton **return_button,
                                 WCPath **return_path,
                                 WCHotkey **return_hotkey );
  int addButton( List *bl, WCButton *b );
  int addHotkey( List *hl, WCHotkey *h );
  int addFiletype( List *fl, WCFiletype *f );

  static bool always_keep_old_key;

  bool configureHotkey(WCHotkey*);
  std::shared_ptr< FunctionProto > requestCommand( bool &dontConfigure );
  static int requestCommand_sf(void*,void*);

  bool configureButton(WCButton*);
  //bool configureFiletype(WCFiletype*);
    void showFTActions( const char*, WCFiletype*, FieldListView*, command_list_t *return_list, std::string &write_back_name );
  bool changeFiledesc(WCFiletype*);
  char *getStr4Char(int,short);
  int WCEditByte(int ch);
  bool FTautocreate(WCFiletype *);
  void initFixTypes();
  void setDefaultConfig();

  int export2file( bool export_buttons,
                   bool export_hotkeys,
                   bool export_types,
                   const char *filename );
  int configureForImport( int nrb,
                          bool &import_buttons,
                          bool &import_hotkeys,
                          bool &import_filetypes,
                          const std::string &info_text );
  void insertFileTypeFlag( StringGadget *sg, WCFiletype *ft );
  
  int date_format;  // -1 = user-defined
                    // >=0 any of the predefined
  char *date_formatstring;
  bool date_subst;
  
  int time_format; // as above
  char *time_formatstring;
  
  bool date_before_time;
  
  int configureButtonSize[2];
  int changeTypesSize[2];
  int changeHotkeysSize[2];
  int configureFiletypeSize[2];
  int configureHotkeySize[2];
  char *lastRequestCommand;
  time_t currentConfigTime;
  
  ColorDef _color_defs;
  
  bool m_save_worker_state_on_exit;

  std::map< font_type_t, std::string > m_font_names;
  void setFontNames( const std::map< font_type_t, std::string > &font_names );
  std::map< font_type_t, std::string > getFontNames() const;

    struct {
        std::string mount_command;
        std::string unmount_command;
        std::string fstab_file;
        std::string mtab_file;
        std::string part_file;
        bool request_action;
        std::string eject_command;
        std::string closetray_command;
        int preferred_udisks_version;
    } m_vm_settings;

    StringComparator::string_comparator_modes m_use_string_compare_mode;
    bool m_apply_window_dialog_type;
    bool m_use_extended_regex;
    std::list< std::string > m_pathjump_allow_dirs;
    bool m_pathjump_store_files_always;

    FaceDB m_facedb;

    int m_loaded_major_version;
    int m_loaded_minor_version;
    int m_loaded_patch_version;

    restore_tabs_mode_t m_restore_tabs_mode;
    store_tabs_mode_t m_store_tabs_mode;

    bool m_terminal_returns_early;

    std::map< std::string, struct directory_presets > m_directory_presets;

    WConfigInitialCommand m_initial_command;

    std::string m_disable_bg_check_prefix;

    std::shared_ptr< WConfigKVPPool > m_kvp_pool;
};

extern WConfig *wconfig;

#endif

/* Local Variables: */
/* mode:c++ */
/* End: */
