using Gtk 4.0;
using Adw 1;

Adw.StatusPage error_page {
  icon-name: "computer-fail-symbolic";
  title: _("Oh, no.");
  description: _("Unable to acquire an OpenGL context for rendering.");

  child: LinkButton {
    label: "https://ghostty.org/docs/help/gtk-opengl-context";
    uri: "https://ghostty.org/docs/help/gtk-opengl-context";
  };
}

Overlay terminal_page {
  focusable: false;
  focus-on-click: false;

  child: Box {
    hexpand: true;
    vexpand: true;

    GLArea gl_area {
      realize => $gl_realize();
      unrealize => $gl_unrealize();
      render => $gl_render();
      resize => $gl_resize();
      hexpand: true;
      vexpand: true;
      focusable: true;
      focus-on-click: true;
      has-stencil-buffer: false;
      has-depth-buffer: false;
      allowed-apis: gl;
    }

    PopoverMenu context_menu {
      closed => $context_menu_closed();
      menu-model: context_menu_model;
      flags: nested;
      halign: start;
      has-arrow: false;
    }

    EventControllerFocus {
      enter => $focus_enter();
      leave => $focus_leave();
    }

    EventControllerKey {
      key-pressed => $key_pressed();
      key-released => $key_released();
    }

    EventControllerScroll {
      scroll => $scroll_vertical();
      scroll-begin => $scroll_vertical_begin();
      scroll-end => $scroll_vertical_end();
      flags: vertical;
    }

    EventControllerScroll {
      scroll => $scroll_horizontal();
      flags: horizontal;
    }

    EventControllerMotion {
      motion => $mouse_motion();
      leave => $mouse_leave();
    }

    GestureClick {
      pressed => $mouse_down();
      released => $mouse_up();
      button: 0;
    }
  };

  [overlay]
  Revealer {
    reveal-child: bind template.readonly;
    transition-type: crossfade;
    transition-duration: 500;
    // Revealers take up the full size, we need this to not capture events.
    can-focus: false;
    can-target: false;
    focusable: false;

    Box readonly_overlay {
      styles [
        "readonly_overlay",
      ]

      // TODO: the tooltip doesn't actually work, but keep it here for now so
      // that we can get the tooltip text translated.
      has-tooltip: true;
      tooltip-text: _("This terminal is in read-only mode. You can still view, select, and scroll through the content, but no input events will be sent to the running application.");
      halign: end;
      valign: start;
      spacing: 6;

      Image {
        icon-name: "changes-prevent-symbolic";
      }

      Label {
        label: _("Read-only");
      }
    }
  }

  [overlay]
  ProgressBar progress_bar_overlay {
    styles [
      "osd",
    ]

    visible: false;
    halign: fill;
    valign: start;
  }

  [overlay]
  // The "border" bell feature is implemented here as an overlay rather than
  // just adding a border to the GLArea or other widget for two reasons.
  // First, adding a border to an existing widget causes a resize of the
  // widget which undesirable side effects. Second, we can make it reactive
  // here in the blueprint with relatively little code.
  Revealer {
    reveal-child: bind $should_border_be_shown(template.config, template.bell-ringing) as <bool>;
    transition-type: crossfade;
    transition-duration: 500;
    // Revealers take up the full size, we need this to not capture events.
    can-focus: false;
    can-target: false;
    focusable: false;

    Box bell_overlay {
      styles [
        "bell-overlay",
      ]

      halign: fill;
      valign: fill;
    }
  }

  [overlay]
  $GhosttySurfaceChildExited child_exited_overlay {
    visible: bind template.child-exited;
    close-request => $child_exited_close();
  }

  [overlay]
  $GhosttyResizeOverlay resize_overlay {}

  [overlay]
  Label url_left {
    styles [
      "background",
      "url-overlay",
    ]

    visible: false;
    halign: start;
    valign: end;
    label: bind template.mouse-hover-url;

    EventControllerMotion url_ec_motion {
      enter => $url_mouse_enter();
      leave => $url_mouse_leave();
    }
  }

  [overlay]
  Label url_right {
    styles [
      "background",
      "url-overlay",
    ]

    visible: false;
    halign: end;
    valign: end;
    label: bind template.mouse-hover-url;
  }

  [overlay]
  $GhosttySearchOverlay search_overlay {
    stop-search => $search_stop();
    search-changed => $search_changed();
    next-match => $search_next_match();
    previous-match => $search_previous_match();
  }

  [overlay]
  $GhosttyKeyStateOverlay key_state_overlay {
    tables: bind template.key-table;
    sequence: bind template.key-sequence;
  }

  [overlay]
  // Apply unfocused-split-fill and unfocused-split-opacity to current surface
  // this is only applied when a tab has more than one surface
  Revealer {
    reveal-child: bind $should_unfocused_split_be_shown(search_overlay.active, template.focused, template.is-split) as <bool>;
    transition-duration: 0;
    // This is all necessary so that the Revealer itself doesn't override
    // any input events from the other overlays. Namely, if you don't have
    // these then the search overlay won't get mouse events.
    can-focus: false;
    can-target: false;
    focusable: false;

    DrawingArea {
      styles [
        "unfocused-split",
      ]
    }
  }

  DropTarget drop_target {
    drop => $drop();
    actions: copy | move;
  }
}

template $GhosttySurface: Adw.Bin {
  styles [
    "surface",
  ]

  notify::config => $notify_config();
  notify::error => $notify_error();
  notify::mouse-hover-url => $notify_mouse_hover_url();
  notify::mouse-hidden => $notify_mouse_hidden();
  notify::mouse-shape => $notify_mouse_shape();
  notify::vadjustment => $notify_vadjustment();
  // Some history: we used to use a Stack here and swap between the
  // terminal and error pages as needed. But a Stack doesn't play nice
  // with our SplitTree and Gtk.Paned usage[^1]. Replacing this with
  // a manual programmatic child swap fixed this. So if you ever change
  // this, be sure to test many splits!
  //
  // [^1]: https://github.com/ghostty-org/ghostty/issues/8533
  child: terminal_page;
}

IMMulticontext im_context {
  input-purpose: terminal;
  preedit-start => $im_preedit_start();
  preedit-changed => $im_preedit_changed();
  preedit-end => $im_preedit_end();
  commit => $im_commit();
}

menu context_menu_model {
  section {
    item {
      label: _("Copy");
      action: "win.copy";
    }

    item {
      label: _("Paste");
      action: "win.paste";
    }

    item {
      label: _("Notify on Next Command Finish");
      action: "surface.notify-on-next-command-finish";
    }
  }

  section {
    item {
      label: _("Clear");
      action: "win.clear";
    }

    item {
      label: _("Reset");
      action: "win.reset";
    }
  }

  section {
    submenu {
      label: _("Split");

      item {
        label: _("Change Title…");
        action: "surface.prompt-title";
      }

      item {
        label: _("Split Up");
        action: "split-tree.new-split";
        target: "up";
      }

      item {
        label: _("Split Down");
        action: "split-tree.new-split";
        target: "down";
      }

      item {
        label: _("Split Left");
        action: "split-tree.new-split";
        target: "left";
      }

      item {
        label: _("Split Right");
        action: "split-tree.new-split";
        target: "right";
      }
    }

    submenu {
      label: _("Tab");

      item {
        label: _("Change Tab Title…");
        action: "tab.prompt-tab-title";
      }

      item {
        label: _("New Tab");
        action: "win.new-tab";
      }

      item {
        label: _("Close Tab");
        action: "tab.close";
        target: "this";
      }
    }

    submenu {
      label: _("Window");

      item {
        label: _("New Window");
        action: "win.new-window";
      }

      item {
        label: _("Close Window");
        action: "win.close";
      }
    }
  }

  section {
    submenu {
      label: _("Config");

      item {
        label: _("Open Configuration");
        action: "app.open-config";
      }

      item {
        label: _("Reload Configuration");
        action: "app.reload-config";
      }
    }
  }
}
