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

#include "wdefines.h"
#include "functionproto.h"
#include <memory>
#include "ajson.hh"

class FlatTypeList;
class AWindow;
class PersistentStringList;
class ChooseButton;
class Button;
class ListerMode;

class StartProgOp:public FunctionProto
{
public:
  StartProgOp();
  virtual ~StartProgOp();
  StartProgOp( const StartProgOp &other );
  StartProgOp &operator=( const StartProgOp &other );

  StartProgOp *duplicate() const override;
  bool isName(const char *) override;
  const char *getName() override;
  int run( std::shared_ptr< WPUContext > wpu, ActionMessage* ) override;
  bool save(Datei*) override;
  const char *getDescription() override;
  int configure() override;
  
  int doconfigure();

  typedef enum {STARTPROGOP_START_NORMAL=0,
                STARTPROGOP_START_IN_TERMINAL,
                STARTPROGOP_START_IN_TERMINAL_AND_WAIT4KEY,
                STARTPROGOP_SHOW_OUTPUT,
                STARTPROGOP_SHOW_OUTPUT_INT,
                STARTPROGOP_SHOW_OUTPUT_OTHER_SIDE,
                STARTPROGOP_SHOW_OUTPUT_CUSTOM_ATTRIBUTE } startprogstart_t;
  void setStart(startprogstart_t);
  void setGlobal(bool);
  void setRequestFlags(bool);
  void setInBackground( bool );
  void setViewStr( std::string );
  void setDontCD( bool );
    void setFollowActive( bool );
    void setWatchFile( bool );
    void setSeparateEachEntry( bool nv );
  void setGUIMsg( std::string msg );
protected:
  static const char *name;
  // Infos to save

  startprogstart_t startprogstart;

  std::string view_str;
  bool global;
  bool inbackground;
  bool dontcd;
    bool m_follow_active = false;
    bool m_watch_file = false;
    bool m_separate_each_entry = false;
  
  // temp variables
  Lister *startlister,*endlister;
  
  int startprog( std::shared_ptr< WPUContext > wpu, ActionMessage *am );

  class SettingsWidgets
  {
  public:
      SettingsWidgets( class AContainer *sg_ac,
                       class StringGadget *sg,
                       class CycleButton *cyb,
                       ChooseButton *gcb,
                       ChooseButton *ibcb,
                       ChooseButton *dcdcb,
                       ChooseButton *follow_active_cb,
                       ChooseButton *watch_file_cb,
                       ChooseButton *separate_each_entry_cb );
    SettingsWidgets( const SettingsWidgets &other );
    SettingsWidgets &operator=( const SettingsWidgets &other );
    int validate();
      void updateVisibility();
      class AContainer *m_sg_ac;
    class StringGadget *_sg;
    class CycleButton *m_cyb;
    ChooseButton *_gcb;
    ChooseButton *_ibcb;
    ChooseButton *_dcdcb;
      ChooseButton *m_follow_active_cb;
      ChooseButton *m_watch_file_cb;
      ChooseButton *m_separate_each_entry_cb;
  };
    std::unique_ptr< SettingsWidgets > buildW( AWindow *win );

  class FiletypeWindow
  {
  public:
    FiletypeWindow( class FieldListView *lv,
                    StringGadget *sg,
                    std::unique_ptr< FlatTypeList > flatlist );
    ~FiletypeWindow();
    FiletypeWindow( const FiletypeWindow &other );
    FiletypeWindow &operator=( const FiletypeWindow &other );
    class FieldListView *_lv;
    StringGadget *m_filter_sg;
    std::unique_ptr< FlatTypeList > _flatlist;

      void updateView();
  };
  std::unique_ptr< FiletypeWindow > buildFTWindow( AWindow *win );

  class ArchiveWindow
  {
  public:
    ArchiveWindow( class FieldListView *lv, class StringGadget *sg );
    ArchiveWindow( const ArchiveWindow &other );
    ArchiveWindow &operator=( const ArchiveWindow &other );
    class FieldListView *_lv;
    class StringGadget *_sg;
    std::vector<std::string> _arclist;
  };
  std::unique_ptr< ArchiveWindow > buildArcWindow( AWindow *win );

  class StartSettings
  {
  public:
    StartSettings();
    StartSettings( const StartSettings &other ) = default;
      StartSettings &operator=( const StartSettings &other ) = default;
    enum StartModes { CANCEL, STARTPROG, HANDLE_TYPE, HANDLE_ARCHIVE } _startmode;
    std::string _command;
    class WCFiletype *_type;
    std::string _archive;

    startprogstart_t _start;
    std::string _view_str;
    bool _global;
    bool _inbackground;
    bool _dontcd;
      bool m_follow_active = false;
      bool m_watch_file = false;
      bool m_separate_each_entry = false;
  };
  std::unique_ptr< StartSettings > showGUI();

    void updateCompletionList( const std::string &base,
                               PersistentStringList &history,
                               std::shared_ptr< AJSON::JSONType > &filetype_history );
    void updateSGFromComplete( StringGadget *sg,
                               PersistentStringList &history,
                               std::shared_ptr< AJSON::JSONType > &filetype_history,
                               FieldListView *lv,
                               SettingsWidgets &sw );
    void updateSGFromRow( int row,
                          PersistentStringList &history,
                          std::shared_ptr< AJSON::JSONType > &filetype_history,
                          SettingsWidgets &sw );
    void updateFiletypeHistory( std::shared_ptr< AJSON::JSONType > &filetype_history,
                                const std::string &base,
                                const StartSettings &settings );
    void set_history_json( std::shared_ptr< AJSON::JSONObject > &jobj,
                           const std::string &base,
                           const StartSettings &settings );
    int parse_history_json( std::shared_ptr< AJSON::JSONObject > &jobj,
                            StartSettings &settings );
    void apply_settings( const StartSettings &settings,
                         SettingsWidgets &sw );

  std::string default_file;
  std::string m_default_file_filetype;
  std::string m_default_file_mime_type;
  bool m_default_file_unknown = false;
  
  std::string gui_msg;

    enum completion_type {
                          FILETYPE_COMPLETION,
                          MIMETYPE_COMPLETION,
                          ANY_COMPLETION
    };
    
    std::list< std::pair< completion_type, StartSettings > > m_current_completions;
    std::string m_current_original_file;
    bool m_completion_enabled;
    std::string m_previous_sg_content;

    StringGadget *m_cmd_sg;
    FieldListView *m_completion_lv;
    Button *m_cmd_flag_b;
};

#endif

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