;; -*- mode: scheme; coding: utf-8 -*-

;;;;
;;;; Copyright (C) 2016 - 2025
;;;; Free Software Foundation, Inc.

;;;; This file is part of GNU G-Golf

;;;; GNU G-Golf is free software; you can redistribute it and/or modify
;;;; it under the terms of the GNU Lesser General Public License as
;;;; published by the Free Software Foundation; either version 3 of the
;;;; License, or (at your option) any later version.

;;;; GNU G-Golf 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
;;;; Lesser General Public License for more details.

;;;; You should have received a copy of the GNU Lesser General Public
;;;; License along with GNU G-Golf.  If not, see
;;;; <https://www.gnu.org/licenses/lgpl.html>.
;;;;

;;; Commentary:

;;; Code:


;; useless in guile-2.2, we have to declare #:duplicates in each module
;; we keep it in case things change in the future, who knows...
#;(eval-when (expand load eval)
  (use-modules (oop goops))
  (default-duplicate-binding-handler
    '(merge-generics replace warn-override-core warn last)))


(define-module (g-golf)
  #:use-module (oop goops)
  #:use-module (oop goops describe)
  #:use-module (ice-9 match)
  #:use-module (ice-9 receive)  
  #:use-module (ice-9 binary-ports)
  #:use-module (rnrs bytevectors)
  #:use-module (rnrs arithmetic bitwise)
  #:use-module (system foreign)
  #:use-module ((srfi srfi-1) #:hide (map remove))
  #:use-module (g-golf support libg-golf)
  #:use-module (g-golf support const)
  #:use-module (g-golf support float)
  #:use-module (g-golf support module)
  #:use-module (g-golf support goops)
  #:use-module (g-golf support g-export)
  #:use-module (g-golf support utils)
  #:use-module (g-golf support push)
  #:use-module (g-golf support keyword)
  #:use-module (g-golf support enum)
  #:use-module (g-golf support flags)
  #:use-module (g-golf support struct)
  #:use-module (g-golf support union)
  #:use-module (g-golf support bytevector)
  #:use-module (g-golf support ffi)
  #:use-module (g-golf support sxml)
  #:use-module (g-golf support color)
  #:use-module (g-golf init)
  #:use-module (g-golf glib version-information)
  #:use-module (g-golf glib mem-alloc)
  #:use-module (g-golf glib main-event-loop)
  #:use-module (g-golf glib io-channels)
  #:use-module (g-golf glib misc-util-funcs)
  #:use-module (g-golf glib unix-utils)
  #:use-module (g-golf glib glist)
  #:use-module (g-golf glib gslist)
  #:use-module (g-golf glib byte-arrays)
  #:use-module (g-golf glib quarks)
  #:use-module (g-golf glib simple-xml-subset-parser)
  #:use-module (g-golf glib date-and-time-functions)
  #:use-module (g-golf glib type-conversion)
  #:use-module (g-golf gobject type-info)
  #:use-module (g-golf gobject gobject)
  #:use-module (g-golf gobject enum-flags)
  #:use-module (g-golf gobject boxed-types)
  #:use-module (g-golf gobject generic-values)
  #:use-module (g-golf gobject params-vals)
  #:use-module (g-golf gobject param-spec)
  #:use-module (g-golf gobject closures)
  #:use-module (g-golf gobject signals)
  #:use-module (g-golf gi utils)
  #:use-module (g-golf gi cache-gi)
  #:use-module (g-golf gi cache-others)
  #:use-module (g-golf gi repository)
  #:use-module (g-golf gi typelib)
  #:use-module (g-golf gi version)
  #:use-module (g-golf gi common-types)
  #:use-module (g-golf gi base-info)
  #:use-module (g-golf gi callable-info)
  #:use-module (g-golf gi function-info)
  #:use-module (g-golf gi signal-info)
  #:use-module (g-golf gi vfunc-info)
  #:use-module (g-golf gi registered-type-info)
  #:use-module (g-golf gi enum-info)
  #:use-module (g-golf gi struct-info)
  #:use-module (g-golf gi union-info)
  #:use-module (g-golf gi object-info)
  #:use-module (g-golf gi interface-info)
  #:use-module (g-golf gi arg-info)
  #:use-module (g-golf gi constant-info)
  #:use-module (g-golf gi field-info)
  #:use-module (g-golf gi property-info)
  #:use-module (g-golf gi type-info)
  #:use-module (g-golf gi gir-ffi)
  #:use-module (g-golf gdk events)
  #:use-module (g-golf hl-api n-decl)
  #:use-module (g-golf hl-api ccc)
  #:use-module (g-golf hl-api argument)
  #:use-module (g-golf hl-api gtype)
  #:use-module (g-golf hl-api gparam)
  #:use-module (g-golf hl-api iface)
  #:use-module (g-golf hl-api gobject)
  #:use-module (g-golf hl-api events)
  #:use-module (g-golf hl-api callable)
  #:use-module (g-golf hl-api callback)
  #:use-module (g-golf hl-api function)
  #:use-module (g-golf hl-api vfunc)
  #:use-module (g-golf hl-api object)
  #:use-module (g-golf hl-api closure)
  #:use-module (g-golf hl-api signal)
  #:use-module (g-golf hl-api glib)
  #:use-module (g-golf hl-api import)
  #:use-module (g-golf hl-api utils)
  #:use-module (g-golf override override)
  #:use-module (g-golf override gdk)
  #:use-module (g-golf override gtk)

  #:duplicates (merge-generics
		replace
		warn-override-core
		warn
		last))


(eval-when (expand load eval)
  (re-export-and-replace! (current-module)
                          connect
                          delete
                          member
                          map
                          for-each
                          remove
                          list-index)
  (re-export-public-interface (oop goops)
                              (oop goops describe)
			      (ice-9 match)
                              (ice-9 receive)
			      (ice-9 binary-ports)
			      (rnrs bytevectors)
			      (rnrs arithmetic bitwise)
			      (system foreign)
			      (srfi srfi-1)
                              (g-golf support const)
                              (g-golf support float)
                              (g-golf support module)
			      (g-golf support goops)
			      (g-golf support g-export)
			      (g-golf support utils)
                              (g-golf support push)
			      (g-golf support keyword)
			      (g-golf support enum)
                              (g-golf support flags)
                              (g-golf support struct)
                              (g-golf support union)
                              (g-golf support bytevector)
                              (g-golf support ffi)
                              (g-golf support sxml)
                              (g-golf support color)
			      (g-golf init)
                              (g-golf glib version-information)
			      (g-golf glib mem-alloc)
                              (g-golf glib main-event-loop)
                              (g-golf glib io-channels)
                              (g-golf glib misc-util-funcs)
                              (g-golf glib unix-utils)
                              (g-golf glib glist)
                              (g-golf glib gslist)
                              (g-golf glib byte-arrays)
                              (g-golf glib quarks)
                              (g-golf glib simple-xml-subset-parser)
                              (g-golf glib date-and-time-functions)
                              (g-golf glib type-conversion)
			      (g-golf gobject type-info)
                              (g-golf gobject gobject)
			      (g-golf gobject enum-flags)
                              (g-golf gobject boxed-types)
			      (g-golf gobject generic-values)
                              (g-golf gobject params-vals)
			      (g-golf gobject param-spec)
			      (g-golf gobject closures)
                              (g-golf gobject signals)
			      (g-golf gi utils)
                              (g-golf gi cache-gi)
                              (g-golf gi cache-others)
			      (g-golf gi repository)
                              (g-golf gi typelib)
                              (g-golf gi version)
                              (g-golf gi common-types)
  			      (g-golf gi base-info)
			      (g-golf gi callable-info)
                              (g-golf gi function-info)
                              (g-golf gi signal-info)
                              (g-golf gi vfunc-info)
			      (g-golf gi registered-type-info)
			      (g-golf gi enum-info)
                              (g-golf gi struct-info)
                              (g-golf gi union-info)
			      (g-golf gi object-info)
                              (g-golf gi interface-info)
			      (g-golf gi arg-info)
                              (g-golf gi constant-info)
                              (g-golf gi field-info)
			      (g-golf gi property-info)
			      (g-golf gi type-info)
                              (g-golf gi gir-ffi)
                              (g-golf gdk events)
                              (g-golf hl-api n-decl)
                              (g-golf hl-api ccc)
                              (g-golf hl-api argument)
                              (g-golf hl-api gtype)
                              (g-golf hl-api gparam)
                              (g-golf hl-api iface)
                              (g-golf hl-api gobject)
                              (g-golf hl-api events)
                              (g-golf hl-api callable)
                              (g-golf hl-api callback)
                              (g-golf hl-api function)
                              (g-golf hl-api vfunc)
                              (g-golf hl-api object)
                              (g-golf hl-api closure)
                              (g-golf hl-api signal)
                              (g-golf hl-api glib)
                              (g-golf hl-api import)
                              (g-golf hl-api utils)
                              (g-golf override override)
                              (g-golf override gdk)
                              (g-golf override gtk)))


;;;
;;; Mandatory selective imports
;;;

(eval-when (load eval)
  (for-each (lambda (i-spec)
              (match i-spec
                ((name force? with-methods?)
                 (gi-import-by-name "GLib" name
                                    #:force? force?
                                    #:with-methods? with-methods?))))
      '(("Error" #t #f)
        ("IOChannel" #t #f)
        ("SpawnFlags" #t #f)
        ("VariantClass" #t #f)
        ("Variant" #t #t)
        ("VariantType" #t #t)))

  ;; Some (if not all) GObject subclasses re subclasses of
  ;; GInitiallyUnowned.
  (for-each (lambda (i-spec)
              (match i-spec
                ((name force? with-methods?)
                 (gi-import-by-name "GObject" name
                                    #:force? force?
                                    #:with-methods? with-methods?))))
      '(("InitiallyUnowned" #t #f)
        ;; Although at this stage, G-Golf would properly import
        ;; "GObject" "ParamSpec", it's ok to manually import it here
        ;; anyway: (a) some namespace define classes that inherit from
        ;; it, like "Clutter" "ParamSpecUnit" and (b) it is the returned
        ;; type of some gtk class methods, like
        ;; gtk-container-class-find-child-property.

        ;; In all use cases - see (g-golf hl-api argument)
        ;; gi-argument->scm - G-Golf never creates <g-param> instances,
        ;; and 'blindingly' receive and pass GParamSpec pointers from/to
        ;; GObject (just like opaque structures).

        ;; Finally, note that the base info name is "ParamSpec" but the
        ;; registered type name is "GParam", hence the class is imported
        ;; as <g-param>.
        ("ParamSpec" #t #f)
        ("Binding" #t #f) ;; needs to be true ?
        ("BindingFlags" #t #f)
        ("TypeFlags" #t #f)))

  (let* ((module (resolve-module '(g-golf hl-api object)))
         (gi-import-object-methods
          (module-ref module 'gi-import-object-methods))
         (g-object-info
          (g-irepository-find-by-name "GObject" "Object"))
         (class-struct
          (g-object-info-get-class-struct g-object-info)))
    (mslot-set! <gobject>
                'info g-object-info
                'g-struct-fields (gi-struct-field-desc class-struct))
    (gi-import-object-methods g-object-info #:force? #t)))


;;;
;;; populate the color dictionary
;;;

(eval-when (expand load eval)
  ((@@ (g-golf support color) populate-color-dictionary)))
