#!/usr/bin/ruby -w
# Encoding: UTF-8
# frozen_string_literal: true
# =========================================================================== #
# === Gtk::CommandlineToAutomaticGUI
#
# This class shall take another class, such as Roebe::Books, as target
# class, then invoke "--help" on it or .show_help().
#
# It will parse this result, and then automatically build a simple GUI
# around it. In other words it will evaluate the --help output.
#
# The class should be as flexible as possible. When there are toggle
# entries then these should be supported too.
#
# For now build it based on "--help". Then improve lateron.
# =========================================================================== #
# require 'gtk_paradise/utility_scripts/commandline_to_automatic_gui.rb'
# =========================================================================== #
module Gtk

class CommandlineToAutomaticGUI # === Gtk::CommandlineToAutomaticGUI

  alias e puts

  require 'colours'
  require 'gtk_paradise/require_gtk3'
  require 'gtk_paradise/requires/require_gtk_runner.rb'
  require 'gtk_paradise/core_classes/label.rb'
  require 'gtk_paradise/core_classes/text_view.rb'
  require 'gtk_paradise/core_classes/scrolled_window.rb'

  begin
    require 'roebe/classes/books/books.rb'
  rescue LoadError; end

  # ========================================================================= #
  # === initialize
  # ========================================================================= #
  def initialize(
      run_already = true
    )
    reset
    run if run_already
  end

  # ========================================================================= #
  # === reset                                                     (reset tag)
  # ========================================================================= #
  def reset
    # ======================================================================= #
    # === @result
    # ======================================================================= #
    @result = ''.dup
    # ======================================================================= #
    # === @main_object
    #
    # This object will receive all commands.
    # ======================================================================= #
    @main_object = nil
    # ======================================================================= #
    # === @results_area
    # ======================================================================= #
    @results_area = ::Gtk.scrolled_window(
      ::Gtk.text_view
    ) { :always }
    @results_area.width_height(500, 300)
    #@results_area.align_to_the_left
    @results_area.font = :hack_10
    # ======================================================================= #
    # === @main_object
    # ======================================================================= #
    @main_object = Roebe::Books.new { :dont_run_yet }
  end

  # ========================================================================= #
  # === restore_stdout
  # ========================================================================= #
  def restore_stdout
    $stdout = STDOUT
  end

  # ========================================================================= #
  # === assign_new_stdout
  # ========================================================================= #
  def assign_new_stdout
    $stdout = StringIO.new
  end

  # ========================================================================= #
  # === assign_the_result_variable_to_the_string_stored_in_stdout
  # ========================================================================= #
  def assign_the_result_variable_to_the_string_stored_in_stdout
    @result = $stdout.string
  end

  # ========================================================================= #
  # === test_class_books
  # ========================================================================= #
  def test_class_books
    @main_object.disable_colours
    @main_object.do_load_the_favourites
    assign_new_stdout
    @main_object.show_help
    assign_the_result_variable_to_the_string_stored_in_stdout
    restore_stdout
    parse_the_result_variable
  end

  # ========================================================================= #
  # === parse_the_result_variable
  # ========================================================================= #
  def parse_the_result_variable(
      i = @result
    )
    use_this_title = 'GUI for Books'
    # ======================================================================= #
    # The outer-vbox will be returned via a Gtk.run instance.
    # ======================================================================= #
    outer_vbox = Gtk.return_custom_generic_widget
    outer_vbox.use_the_default_css_rules
    original_splitted = i.split("\n")
    selection = original_splitted.select {|entry|
      entry.include?('=')
    }
    if selection and !selection.empty?
      selection.each {|this_option|
        short_option = this_option.dup
        text_to_use = ''
        if short_option.include?('#')
          short_option = short_option.split('#')
          text_to_use = ::Gtk.left_aligned_text(
            short_option.last.to_s.dup.strip
          )
          short_option = short_option.first.to_s.strip
        end
        short_option.strip!
        if short_option.include?(' ')
          short_option = short_option.split(' ').last
        end
        # =================================================================== #
        # === Handle entries with = differently
        # =================================================================== #
        if short_option.include?('=')
          splitted = short_option.split('=')
          is_the_second_element_a_numeric_value = false
          if splitted[1] =~ /\d+$/
            is_the_second_element_a_numeric_value = true
          end
          if is_the_second_element_a_numeric_value
            range = (
              splitted[1].to_i .. (splitted[1].to_i+50)
            )
            combo_box_entry = Gtk.combo_box_entry(range.to_a)
            combo_box_entry.pad2px
            if text_to_use.is_a?(String) and text_to_use.empty?
              outer_vbox.minimal(
                combo_box_entry, 2
              )
            else
              outer_vbox.minimal(
                ::Gtk.hbox(
                  text_to_use,
                  combo_box_entry
                ) { :maximal },
                2
              )
            end
          end
        end
      }
    end
    selection = original_splitted.select {|entry|
      !entry.include?('=')
    }.map {|inner_entry| ::Colours.remove_escape_sequence(inner_entry) }

    selection.each {|entry|
      if entry.include? '#'
        splitted = entry.split('#')
        button = Gtk.button(
          splitted.last.strip
        )
        button.on_clicked {
          _ = splitted.first.strip
          if _.include? '--'
            _ = _.split('--').last
          end
          this_command = (
            'do_query_'+_.to_s.strip.delete('-')
          ).to_sym
          assign_new_stdout
          @main_object.send(this_command)
          assign_the_result_variable_to_the_string_stored_in_stdout
          restore_stdout
          @results_area.set_text(
            ::Colours.remove_escape_sequence(
              @result.to_s
            )
          )
        }
        button.clear_background
        button.bblack1
        button.on_hover(:lightblue)
        hbox = ::Gtk.hbox
        hbox.minimal(button, 2)
        hbox.hcenter
        outer_vbox.minimal(hbox, 2)
      else
        unless entry.empty?
          e 'Does not have a # token. Thus it is unhandled.'
          e entry
        end
      end
    }
    outer_vbox.show_all
    outer_vbox.use_this_font = :hack_20
    outer_vbox.pad8px
    runner = Gtk.run
    runner.add(outer_vbox)
    runner.border_width = 4
    runner.show_all
    runner.width_height(1000, 660)
    runner.top_left
    runner.easy_quit
    runner.title = use_this_title
    outer_vbox.do_apply_the_CSS_rules
    outer_vbox.maximal(
      @results_area
    )
    return runner.run
  end

  # ========================================================================= #
  # === run
  # ========================================================================= #
  def run
    test_class_books
  end

end; end

if __FILE__ == $PROGRAM_NAME
  Gtk::CommandlineToAutomaticGUI.new
end # commandlinetoautomaticgui