#!/usr/bin/ruby -w
# Encoding: UTF-8
# frozen_string_literal: true
# =========================================================================== #
# require 'gtk_paradise/toplevel_methods/css.rb'
# Gtk.return_default_css
# =========================================================================== #
module Gtk

  require 'gtk_paradise/project/project.rb'
  require 'gtk_paradise/constants/constants.rb'
  # ========================================================================= #
  # The next line is useful for ruby-gtk3 and ruby-gtk4. It is not so
  # useful on ruby-gtk2.
  # ========================================================================= #
  require 'gtk_paradise/core_classes/style_context.rb'

  # ========================================================================= #
  # === @string_additional_css_rules
  # ========================================================================= #
  @string_additional_css_rules = ''.dup

  # ========================================================================= #
  # === Gtk.css_rules?
  # ========================================================================= #
  def self.css_rules?
    @string_additional_css_rules
  end; self.instance_eval { alias css_rules_to_apply? css_rules? } # === Gtk.css_rules_to_apply?
       self.instance_eval { alias toplevel_CSS?       css_rules? } # === Gtk.toplevel_CSS?

  # ========================================================================= #
  # === @provider
  # ========================================================================= #
  @provider = nil

  # ========================================================================= #
  # === Gtk.css_provider
  #
  # This method is not allowed to have a default dataset.
  #
  # Be careful when using this, though, because it will set @provider
  # globally, which may not always be what you want to have.
  # ========================================================================= #
  def self.css_provider(
      dataset_to_use
    )
    # ======================================================================= #
    # === @provider
    # ======================================================================= #
    @provider = ::Gtk::CssProvider.new
    @provider.load(data: dataset_to_use)
    # ======================================================================= #
    # The next method will work for both ruby-gtk3 and ruby-gtk4. It will
    # not work for ruby-gtk2.
    # ======================================================================= #
    style_context_provider(@provider)
    return @provider # Return it just in case.
  end; self.instance_eval { alias add_these_css_rules css_provider } # === Gtk.add_these_css_rules

  # ========================================================================= #
  # === @css_classes
  #
  # This variable will keep track of all CSS classes in use. The user
  # can not modify this Array directly - at the least not via a
  # guaranteed API.
  # ========================================================================= #
  @css_classes = []

  # ========================================================================= #
  # === Gtk.reset_css_rules
  #
  # This method will reset the toplevel-defined CSS rules.
  # ========================================================================= #
  def self.reset_css_rules
    # ======================================================================= #
    # === @string_additional_css_rules
    # ======================================================================= #
    @string_additional_css_rules = ''.dup
    # ======================================================================= #
    # === @css_classes
    # ======================================================================= #
    @css_classes = [] # The Array will be reset as well.
  end

  # ========================================================================= #
  # === Gtk.return_default_CSS_rules
  #
  # This method will return all CSS rules that the gtk-paradise gem
  # uses, as a String.
  # ========================================================================= #
  def self.return_default_CSS_rules(
      i = :project_internal_files
    )
    dataset = ''.dup # This is the dataset that will be returned.
    case i
    # ======================================================================= #
    # === :project_internal_files
    #
    # All gtk-paradise internal CSS files should be listed here. This
    # provides the general entry point for CSS files used in the
    # gtk-paradise gem.
    # ======================================================================= #
    when :project_internal_files,
         :default
      i = ARRAY_CSS_FILES
    end
    # ======================================================================= #
    # Operate on an Array always.
    # ======================================================================= #
    [i].flatten.compact.each {|this_css_file|
      if File.exist? this_css_file # Must check whether the file exists first.
        dataset << File.read(this_css_file)
        dataset << "\n"
      end
    }
    return dataset
  end; self.instance_eval { alias return_gtk_paradise_css_rules return_default_CSS_rules } # === Gtk.return_gtk_paradise_css_rules

  # ========================================================================= #
  # === Gtk.append_css
  # ========================================================================= #
  def self.append_css(i)
    case i
    # ======================================================================= #
    # === :project_internal_files
    # ======================================================================= #
    when :project_internal_files,
         :append_onto_the_CSS_rules,
         :append_project_css_file
      i = ::Gtk.return_default_CSS_rules
    end
    if i.is_a? Array
      i.each {|entry| append_css(entry) }
    else
      if i.start_with?('.') or i.start_with?('#')
        _ = i.dup
        # =================================================================== #
        # '.border12 {'
        # =================================================================== #
        if _.include? '{'
          _ = _.split('{').first.strip
        end
        this_CSS_class_was_found = _.delete('.#')
        # =================================================================== #
        # Only some CSS classes are added.
        # =================================================================== #
        @css_classes << this_CSS_class_was_found
      end
      @string_additional_css_rules << i
    end
  end; self.instance_eval { alias register_this_css_class_is_in_use append_css } # === Gtk.register_this_css_class_is_in_use
       self.instance_eval { alias add_to_the_toplevel_CSS_string    append_css } # === Gtk.add_to_the_toplevel_CSS_string
       self.instance_eval { alias append_these_css_rules            append_css } # === Gtk.append_these_css_rules
       self.instance_eval { alias append_onto_the_CSS_rules         append_css } # === Gtk.append_onto_the_CSS_rules

  # ========================================================================= #
  # === Gtk.css_classes_in_use?
  # ========================================================================= #
  def self.css_classes_in_use?
    @css_classes
  end

  # ========================================================================= #
  # === Gtk.initialize_default_css_provider
  #
  # This method will basically make the two files "project.css" and
  # "colours.css" available. These two files are distributed within
  # the gtk_paradise gem.
  #
  # This method is thus useful as a quick convenience method, when you
  # want to quickly add CSS-support into the ruby-gtk3 application at
  # hand, but don't want to write or define your own CSS file.
  # ========================================================================= #
  def self.initialize_default_css_provider(
      i = :project_internal_files
    )
    case i
    # ======================================================================= #
    # === :project_internal_files
    # ======================================================================= #
    when :project_internal_files,
         :default
      i = ARRAY_CSS_FILES
    end
    dataset = ''.dup
    # ======================================================================= #
    # Operate on an Array always.
    # ======================================================================= #
    [i].flatten.compact.each {|this_css_file|
      dataset << File.read(this_css_file)
      dataset << "\n" # And a newline for visual beauty.
    }
    Gtk.css_provider(dataset)
  end; self.instance_eval { alias project_css_file                  initialize_default_css_provider } # === Gtk.project_css_file
       self.instance_eval { alias gtk_paradise_css_file             initialize_default_css_provider } # === Gtk.gtk_paradise_css_file
       self.instance_eval { alias enable_default_css                initialize_default_css_provider } # === Gtk.enable_default_css
       self.instance_eval { alias use_gtk_paradise_project_css_file initialize_default_css_provider } # === Gtk.use_gtk_paradise_project_css_file

  # ========================================================================= #
  # === Gtk.infer_the_name_of_the_project_based_on_this_directory
  #
  # This method will take a String input, such as:
  #
  #   /usr/lib/ruby/site_ruby/2.7.0/gtk_paradise/widgets/shared_code/shell
  #
  # and return exactly the string "gtk_paradise". This is necessary
  # so that we can then infer the path to the default .css file
  # that projects are, assumingly, using.
  # ========================================================================= #
  def self.infer_the_name_of_the_project_based_on_this_directory(
      i
    )
    sitelibdir = RbConfig::CONFIG['sitelibdir']+'/'
    i = i.dup
    if i.include? '/home/x/programming/ruby/src/'
      use_this_regex = /#{Regexp.quote('/home/x/programming/ruby/src/')}/
    else
      use_this_regex = /#{Regexp.quote(sitelibdir)}/
    end
    i.sub!(use_this_regex, '')
    i = File.dirname(i)
    i = i.split('/').first if i.include? '/'
    return i
  end

  # ========================================================================= #
  # === Gtk.return_path_to_the_default_css_file
  #
  # This method will return the path to the project.css file.
  # ========================================================================= #
  def self.return_path_to_the_default_css_file
    "#{PROJECT_BASE_DIRECTORY}css/project.css"
  end

  # ========================================================================= #
  # === Gtk.css_provider?
  # ========================================================================= #
  def self.css_provider?
    @provider
  end

  # ========================================================================= #
  # === Gtk.return_default_css_content
  #
  # This method will return the default .css content for the gtk-paradise
  # project, as a String. That way the user can use this for a given
  # application, to provide some "default" css.
  # ========================================================================= #
  def self.return_default_css_content(
      use_this_path_for_the_css_file = 
        "#{::Gtk.project_base_directory?}css_files/project.css"
    )
    _ = ''.dup # This variable will be returned, as a String.
    if File.exist? use_this_path_for_the_css_file
      # ===================================================================== #
      # Ok the file exists, so read it.
      # ===================================================================== #
      _ = File.read(use_this_path_for_the_css_file)
    end
    return _ # Return the result here.
  end

  # ========================================================================= #
  # === Gtk.load_css_engine_for_gtk4
  #
  # This method can be specifically used for ruby-gtk4 support of
  # CSS. The API changed between ruby-gtk3 and ruby-gtk4, so
  # this method here was added on an ad-hoc basis.
  #
  # Right now this method only supports a String as main input.
  # The CSS rules should be passed as a String to this method.
  #
  # Usage example:
  #
  #   Gtk.load_css_engine_for_gtk4(use_these_css_rules)
  #
  # ========================================================================= #
  def self.load_css_engine_for_gtk4(
      use_these_css_rules = ::Gtk.css_rules?.to_s
    )
    css_provider = ::Gtk::CssProvider.new
    css_provider.load(data: use_these_css_rules)
    ::Gtk::StyleContext.add_provider_for_display(
      Gdk::Display.default,
      css_provider,
      ::Gtk::StyleProvider::PRIORITY_APPLICATION
    )
    return css_provider # Return it here just in case.
  end

  # ========================================================================= #
  # === Gtk.turn_this_font_symbol_into_its_corresponding_CSS_rule
  # ========================================================================= #
  def self.turn_this_font_symbol_into_its_corresponding_CSS_rule(i)
    if i.is_a? Symbol
      string = i.to_s.tr('_',' ')
      splitted = string.split(' ') # dejavu_condensed_20
      font_size = splitted.last
      splitted[0] = splitted[0].capitalize
      first_part = splitted[0 .. -2].join(' ')
      return '
      .use_this_font {
        font-family: '+first_part+';
        font-size: '+font_size.to_s+'pt;
      }'
    end
  end

end

if __FILE__ == $PROGRAM_NAME
  require 'colours/autoinclude'
  alias e puts
  e
  e "#{Gtk.project_base_directory?}cascading_style_sheets/project.css"
  e
  result = Gtk.return_default_css_content
  e
  e 'The default css is:'
  e
  e Colours.steelblue(result)
  e
end