/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2 -*-
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 * SPDX-FileCopyrightText: Michael Terry
 */

using GLib;

[GtkTemplate (ui = "/org/gnome/DejaDup/OperationStatusPage.ui")]
public class OperationStatusPage : Adw.Bin
{
  public void connect_to_operation(DejaDup.Operation operation)
  {
    stack.set_visible_child_full("spinner", Gtk.StackTransitionType.NONE);

    wrapper = new OperationWrapper(operation, this);

    wrapper.bind_property("summary", spinner_label, "label", BindingFlags.SYNC_CREATE);
    wrapper.bind_property("summary", summary, "label", BindingFlags.SYNC_CREATE);
    wrapper.bind_property("button-label", button, "label", BindingFlags.SYNC_CREATE);

    wrapper.notify["button-label"].connect(handle_button_label_change);
    wrapper.notify["button-suggested"].connect(handle_button_suggested_change);
    wrapper.notify["error-mode"].connect(handle_error_mode_change);

    wrapper.notify["active"].connect(handle_pulsing_change);
    wrapper.notify["pulsing"].connect(handle_pulsing_change);

    wrapper.done.connect(handle_done);
  }

  // Use this for errors that occur outside of the operation lifecycle.
  // The message will be shown with a retry button.
  public void set_error_state(string message)
  {
    wrapper = null;
    summary.label = message;
    summary.add_css_class("error");
    button.visible = false;
    stack.set_visible_child_full("action", Gtk.StackTransitionType.NONE);
  }

  [GtkChild]
  unowned Gtk.Stack stack;
  [GtkChild]
  unowned Gtk.Label spinner_label;
  [GtkChild]
  unowned Gtk.Label summary;
  [GtkChild]
  unowned Gtk.Button button;

  OperationWrapper wrapper;

  construct {
    realize.connect(handle_realize);
  }

  // #############
  // Helpers
  // #############

  void handle_realize()
  {
    var window = this.root as Gtk.Window;
    window.close_request.connect(handle_close_request);
  }

  bool handle_close_request()
  {
    // Because this class only operates on "temporary" operations, shut it down
    if (wrapper != null && wrapper.operation != null)
      wrapper.operation.stop();
    return false;
  }

  [GtkCallback]
  void on_button_clicked()
  {
    wrapper.click();
  }

  void handle_done()
  {
    wrapper.clear();
  }

  void handle_button_label_change()
  {
    button.visible = wrapper.button_label != "";
  }

  void handle_button_suggested_change()
  {
    if (wrapper.button_suggested)
      button.add_css_class("suggested-action");
    else
      button.remove_css_class("suggested-action");
  }

  void handle_error_mode_change()
  {
    if (wrapper.error_mode)
      summary.add_css_class("error");
    else
      summary.remove_css_class("error");
  }

  void handle_pulsing_change()
  {
    if (wrapper.pulsing || !wrapper.active)
      stack.visible_child_name = "spinner";
    else
      stack.visible_child_name = "action";
  }
}
