### ----------------------------------------------------
### -- Gnome::Gtk3
### -- Licenses: Artistic-2.0
### -- Authors: Marcel Timmerman
### -- File: t/ShortcutsWindow.rakutest
### ----------------------------------------------------
use v6;
use NativeCall;
use Test;

use Gnome::Gtk3::Main:api<1>;
use Gnome::Gtk3::Enums:api<1>;
use Gnome::Gtk3::Builder:api<1>;
use Gnome::Gtk3::ShortcutsWindow:api<1>;
use Gnome::Gtk3::ShortcutsSection:api<1>;
use Gnome::Gtk3::ShortcutsGroup:api<1>;
use Gnome::Gtk3::ShortcutsShortcut:api<1>;

use Gnome::N::GlibToRakuTypes:api<1>;
#use Gnome::N::X:api<1>;
#Gnome::N::debug(:on);

#-------------------------------------------------------------------------------
my Gnome::Gtk3::Main $main .= new;
my Gnome::Gtk3::ShortcutsWindow() $sw;
my Gnome::Gtk3::ShortcutsSection() $ss;
my Gnome::Gtk3::ShortcutsGroup() $sg;
my Gnome::Gtk3::ShortcutsShortcut() $scut1;
my Gnome::Gtk3::ShortcutsShortcut() $scut2;
#-------------------------------------------------------------------------------
#subtest 'ISA test', {
#  $sw .= new;
#  isa-ok $sw, Gnome::Gtk3::ShortcutsWindow, '.new()';
#}

#-------------------------------------------------------------------------------
# set environment variable 'raku-test-all' if rest must be tested too.
unless %*ENV<raku_test_all>:exists {
  done-testing;
  exit;
}

#-------------------------------------------------------------------------------
subtest 'Manipulations', {
  my Str $build-xml = Q:q:to/END_BUILDXML/;
    <?xml version="1.0" encoding="UTF-8"?>
    <interface>
      <object class="GtkShortcutsWindow" id="shortcuts-clocks">
        <property name="modal">1</property>
        <child>
          <object class="GtkShortcutsSection" id="shortcuts-section">
            <property name="section-name">shortcuts</property>
            <property name="max-height">10</property>
            <child>
              <object class="GtkShortcutsGroup" id="shortcuts-group">
                <property name="title" translatable="yes">General</property>
                <child>
                  <object class="GtkShortcutsShortcut" id="scut1">
                    <property name="accelerator">&lt;ctrl&gt;Page_Down</property>
                    <property name="title" translatable="yes">Go to the next section</property>
                  </object>
                </child>
                <child>
                  <object class="GtkShortcutsShortcut" id="scut2">
                    <property name="accelerator">&lt;ctrl&gt;Page_Up</property>
                    <property name="title" translatable="yes">Go to the previous section</property>
                  </object>
                </child>
                <child>
                  <object class="GtkShortcutsShortcut">
                    <property name="accelerator">&lt;alt&gt;Q</property>
                    <property name="title" translatable="yes">Quit</property>
                  </object>
                </child>
                <child>
                  <object class="GtkShortcutsShortcut">
                    <property name="accelerator">&lt;alt&gt;Right</property>
                    <property name="direction">ltr</property>
                    <property name="title" translatable="yes">Forward</property>
                  </object>
                </child>
                <child>
                  <object class="GtkShortcutsShortcut">
                    <property name="accelerator">&lt;ctrl&gt;Left</property>
                    <property name="direction">ltr</property>
                    <property name="title" translatable="yes">Back</property>
                  </object>
                </child>
                <child>
                  <object class="GtkShortcutsShortcut">
                    <property name="accelerator">&lt;alt&gt;Left</property>
                    <property name="direction">rtl</property>
                    <property name="title" translatable="yes">Forward</property>
                  </object>
                </child>
                <child>
                  <object class="GtkShortcutsShortcut">
                    <property name="accelerator">&lt;ctrl&gt;Right</property>
                    <property name="direction">rtl</property>
                    <property name="title" translatable="yes">Back</property>
                  </object>
                </child>
              </object>
            </child>
            <child>
              <object class="GtkShortcutsGroup">
                <property name="view">world</property>
                <property name="title" translatable="yes">World Clocks</property>
                <child>
                  <object class="GtkShortcutsShortcut">
                    <property name="accelerator">&lt;ctrl&gt;N</property>
                    <property name="title" translatable="yes">Add a world clock</property>
                  </object>
                </child>
                <child>
                  <object class="GtkShortcutsShortcut">
                    <property name="accelerator">&lt;ctrl&gt;S</property>
                    <property name="title" translatable="yes">Select world clocks</property>
                  </object>
                </child>
              </object>
            </child>
            <child>
              <object class="GtkShortcutsGroup">
                <property name="view">alarm</property>
                <property name="title" translatable="yes">Alarm</property>
                <child>
                  <object class="GtkShortcutsShortcut">
                    <property name="accelerator">&lt;ctrl&gt;N</property>
                    <property name="title" translatable="yes">Add an alarm</property>
                  </object>
                </child>
                <child>
                  <object class="GtkShortcutsShortcut">
                    <property name="accelerator">&lt;ctrl&gt;S</property>
                    <property name="title" translatable="yes">Select alarms</property>
                  </object>
                </child>
              </object>
            </child>
            <child>
              <object class="GtkShortcutsGroup">
                <property name="view">stopwatch</property>
                <property name="title" translatable="yes">Stopwatch</property>
                <child>
                  <object class="GtkShortcutsShortcut">
                    <property name="accelerator">Return space</property>
                    <property name="title" translatable="yes">Start / Stop / Continue</property>
                  </object>
                </child>
                <child>
                  <object class="GtkShortcutsShortcut">
                    <property name="accelerator">L</property>
                    <property name="title" translatable="yes">Lap</property>
                  </object>
                </child>
                <child>
                  <object class="GtkShortcutsShortcut">
                    <property name="accelerator">Delete</property>
                    <property name="title" translatable="yes">Reset</property>
                  </object>
                </child>
              </object>
            </child>
            <child>
              <object class="GtkShortcutsGroup">
                <property name="view">timer</property>
                <property name="title" translatable="yes">Timer</property>
                <child>
                  <object class="GtkShortcutsShortcut">
                    <property name="accelerator">Return space</property>
                    <property name="title" translatable="yes">Start / Stop / Pause</property>
                  </object>
                </child>
                <child>
                  <object class="GtkShortcutsShortcut">
                    <property name="accelerator">Delete</property>
                    <property name="title" translatable="yes">Reset</property>
                  </object>
                </child>
              </object>
            </child>
          </object>
        </child>
      </object>
    </interface>
    END_BUILDXML

  my Gnome::Gtk3::Builder $builder .= new(:string($build-xml));
  $sw = $builder.get-object('shortcuts-clocks');
  $ss = $builder.get-object('shortcuts-section');
  $sg = $builder.get-object('shortcuts-group');
  $scut1 = $builder.get-object('scut1');
  $scut2 = $builder.get-object('scut2');
#  diag $sg.gist;

  # must show before changing properties, section name cannot change before
  $sw.show-all;
  $ss.show;
}

#-------------------------------------------------------------------------------
subtest 'Properties ...', {
  while $main.gtk-events-pending() { $main.iteration-do(False); }
  sleep 1;

  my @r = $sw.get-properties( 'section-name', Str, 'view-name', Str);
  is @r[0], 'internal-search', 'SC Window: section-name';
  is @r[1], '', 'SC Window: view-name';

  $sw.set-properties( :section-name<shortcuts>, :view-name<stopwatch>);
  @r = $sw.get-properties( 'section-name', Str, 'view-name', Str);
  is @r[0], 'shortcuts', 'SC Window: section-name';
  is @r[1], 'stopwatch', 'SC Window: view-name';

  # this show is needed to update the window for selected section and view
  # $sw.show-all() will show everything while $ss.show() shows the selected
  # view only.
  $ss.show;

  @r = $ss.get-properties(
    'max-height', UInt, 'section-name', Str, 'title', Str, 'view-name', Str
  );
  is @r[0], 10, 'max-height';
  is @r[1], 'shortcuts', 'SC Section: section-name';
  is @r[2], '', 'SC Section: title';
  is @r[3], 'stopwatch', 'SC Section: view-name';

  $sg.show;
#TODO won't set;  $sg.set-properties(:view<stopwatch>);
  @r = $sg.get-properties( 'height', UInt, 'title', Str, 'view', Str);
  ok @r[0] > 1, 'SC Group: height';
  is @r[1], 'General', 'SC Group: title';
#  is @r[3], 'stopwatch', 'view';
  is @r[3], Any, 'view';

  @r = $scut1.get-properties( 'accelerator', Str);
  is @r[0], '<ctrl>Page_Down', 'SC Shortcut 1: accelerator';
  @r = $scut2.get-properties(
    'accelerator', Str, 'action-name', Str, 'direction', GEnum,
    'icon-set', gboolean, 'subtitle', Str, 'subtitle-set', gboolean,
    'title', Str
  );
  is @r[0], '<ctrl>Page_Up', 'SC Shortcut 2: accelerator';
  is @r[1], '', 'SC Shortcut 2: action-name';
  is GtkTextDirection(@r[2]), GTK_TEXT_DIR_NONE, 'SC Shortcut 2: direction';
  is @r[3], 0, 'SC Shortcut 2: icon-set';
  is @r[4], '', 'SC Shortcut 2: subtitle';
  is @r[5], 0, 'SC Shortcut 2: subtitle-set';
  is @r[6], 'Go to the previous section', 'SC Shortcut 2: title';
#note @r.gist;

  while $main.gtk-events-pending() { $main.iteration-do(False); }
  sleep 1;
  while $main.gtk-events-pending() { $main.iteration-do(False); }
  sleep 1;
  while $main.gtk-events-pending() { $main.iteration-do(False); }
  sleep 5;
}

#-------------------------------------------------------------------------------
done-testing;

=finish


#-------------------------------------------------------------------------------
subtest 'Inherit Gnome::Gtk3::ShortcutsWindow', {
  class MyClass is Gnome::Gtk3::ShortcutsWindow {
    method new ( |c ) {
      self.bless( :GtkShortcutsWindow, |c);
    }

    submethod BUILD ( *%options ) {

    }
  }

  my MyClass $mgc .= new;
  isa-ok $mgc, Gnome::Gtk3::ShortcutsWindow, 'MyClass.new()';
}

#-------------------------------------------------------------------------------
subtest 'Interface ...', {
}

#-------------------------------------------------------------------------------
subtest 'Properties ...', {
  use Gnome::GObject::Value:api<1>;
  use Gnome::GObject::Type:api<1>;

  #my Gnome::Gtk3::ShortcutsWindow $sw .= new;

  sub test-property (
    $type, Str $prop, Str $routine, $value,
    Bool :$approx = False, Bool :$is-local = False
  ) {
    my Gnome::GObject::Value $gv .= new(:init($type));
    $sw.get-property( $prop, $gv);
    my $gv-value = $gv."$routine"();
    if $approx {
      is-approx $gv-value, $value,
        "property $prop, value: " ~ $gv-value;
    }

    # dependency on local settings might result in different values
    elsif $is-local {
      if $gv-value ~~ /$value/ {
        like $gv-value, /$value/, "property $prop, value: " ~ $gv-value;
      }

      else {
        ok 1, "property $prop, value: " ~ $gv-value;
      }
    }

    else {
      is $gv-value, $value,
        "property $prop, value: " ~ $gv-value;
    }
    $gv.clear-object;
  }

  # example calls
  #test-property( G_TYPE_BOOLEAN, 'homogeneous', 'get-boolean', False);
  #test-property( G_TYPE_STRING, 'label', 'get-string', '...');
  #test-property( G_TYPE_FLOAT, 'xalign', 'get-float', 23e-2, :approx);
}

#-------------------------------------------------------------------------------
subtest 'Themes ...', {
}

#-------------------------------------------------------------------------------
subtest 'Signals ...', {
  use Gnome::Gtk3::Main:api<1>;
  use Gnome::N::GlibToRakuTypes:api<1>;

  my Gnome::Gtk3::Main $main .= new;

  class SignalHandlers {
    has Bool $!signal-processed = False;

    method ... (
      'any-args',
      Gnome::Gtk3::ShortcutsWindow() :_native-object($_widget), gulong :$_handler-id
      # --> ...
    ) {

      isa-ok $_widget, Gnome::Gtk3::ShortcutsWindow;
      $!signal-processed = True;
    }

    method signal-emitter ( Gnome::Gtk3::ShortcutsWindow :$widget --> Str ) {

      while $main.gtk-events-pending() { $main.iteration-do(False); }

      $widget.emit-by-name(
        'signal',
      #  'any-args',
      #  :return-type(int32),
      #  :parameters([int32,])
      );
      is $!signal-processed, True, '\'...\' signal processed';

      while $main.gtk-events-pending() { $main.iteration-do(False); }

      #$!signal-processed = False;
      #$widget.emit-by-name(
      #  'signal',
      #  'any-args',
      #  :return-type(int32),
      #  :parameters([int32,])
      #);
      #is $!signal-processed, True, '\'...\' signal processed';

      while $main.gtk-events-pending() { $main.iteration-do(False); }
      sleep(0.4);
      $main.gtk-main-quit;

      'done'
    }
  }

  my Gnome::Gtk3::ShortcutsWindow $sw .= new;

  #my Gnome::Gtk3::Window $w .= new;
  #$w.add($m);

  my SignalHandlers $sh .= new;
  $sw.register-signal( $sh, 'method', 'signal');

  my Promise $p = $sw.start-thread(
    $sh, 'signal-emitter',
    # :!new-context,
    # :start-time(now + 1)
  );

  is $main.gtk-main-level, 0, "loop level 0";
  $main.gtk-main;
  #is $main.gtk-main-level, 0, "loop level is 0 again";

  is $p.result, 'done', 'emitter finished';
}


