#!/usr/bin/ruby -w
# Encoding: UTF-8
# frozen_string_literal: true
# =========================================================================== #
# Do note that the code in this file only works on gtk3 - gtk2 does not
# have Gtk::Application defined. We could in theory also define such a
# class for gtk2, but for the time being (January 2020) we won't do so;
# it does not seem to be necessary to use it.
# =========================================================================== #
# require 'gtk_paradise/core_classes/application.rb'
# app = Gtk.application('org.gtk.button_box_example')
# =========================================================================== #
module Gtk

  require 'gtk_paradise/core_classes/application_window.rb'

  # ========================================================================= #
  # === Gtk.application
  #
  # This is essentially the same as:
  #
  #   Gtk::Application.new("org.gtk.example", :flags_none)
  #
  # If a block is given then this will be assumed to mean that
  # we want to evaluate that block within the given application.
  #
  # Usage example for the latter use case:
  #
  #   application = Gtk.default_application('interactive.caesar.cipher') {{
  #     widget_to_use: Roebe::InteractiveCaesarCipher.new
  #   }}
  #
  # Simpler usageexample:
  #
  #   application = Gtk.default_application(:infer) {{
  #     widget_to_use: Roebe::InteractiveCaesarCipher.new
  #   }}
  #
  # The namespace should be something like 'org.gtk.example_application'.
  # If no '.' is included then Gtk::Application will complain.
  # ========================================================================= #
  def self.application(
      namespace       = :infer,
      use_these_flags = :flags_none,
      &block
    )
    # ======================================================================= #
    # The namespace may be a Symbol, such as :infer. Either way if it is
    # a Symbol it must be sanitized.
    # ======================================================================= #
    if namespace.is_a? Symbol
      case namespace
      # ===================================================================== #
      # === :infer
      #
      # In this case we will infer the name from $PROGRAM_NAME.
      # ===================================================================== #
      when :infer
        program_name = $PROGRAM_NAME.dup
        program_name = File.basename(program_name) if program_name.include?('/')
        program_name = program_name.delete_suffix(File.extname(program_name)).dup
        program_name.tr!('_','.') if program_name.include? '_'
        namespace = program_name
      end
    end
    # ======================================================================= #
    # Check that the namespace has at the least one '.' character.
    # ======================================================================= #
    unless namespace.include? '.'
      e 'Note that the namespace must include . such as '\
        'in org.gnome.foobar_application'
    end
    application = ::Gtk::Application.new(namespace, use_these_flags)
    # ======================================================================= #
    # === Handle blocks next
    # ======================================================================= #
    if block_given?
      yielded = yield
      # ===================================================================== #
      # === Handle Hashes next
      # ===================================================================== #
      if yielded.is_a? Hash
        # =================================================================== #
        # === :widget_to_use
        # =================================================================== #
        if yielded.has_key? :widget_to_use
          add_this_widget = yielded[:widget_to_use]
          application.signal_connect(:activate) { |app|
            # =============================================================== #
            # Construct a new application-window next:
            # =============================================================== #
            application_window = ::Gtk::ApplicationWindow.new(app)
            if add_this_widget.respond_to?(:title?)
              application_window.title = add_this_widget.title?
            end
            # =============================================================== #
            # Handle width and height settings automatically if the
            # child widget responds to the methods width? and height?
            # next:
            # =============================================================== #
            if add_this_widget.respond_to?(:width?) and
               add_this_widget.respond_to?(:height?)
              application_window.set_default_size(
                add_this_widget.width?.to_i,
                add_this_widget.height?.to_i
              )
            else
              application_window.set_default_size(1200, 800)
            end
            application_window << add_this_widget
            application_window.show
          }
          application.run
        end
      end
    end
    return application
  end; self.instance_eval { alias default_application application } # === Gtk.default_application

end