/* PIKA - Photo and Image Kooker Application
 * a rebranding of The GNU Image Manipulation Program (created with heckimp)
 * A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
 *
 * Original copyright, applying to most contents (license remains unchanged): 
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * pikatoolwidget.h
 * Copyright (C) 2017 Michael Natterer <mitch@gimp.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef __PIKA_TOOL_WIDGET_H__
#define __PIKA_TOOL_WIDGET_H__


#include "core/pikaobject.h"


#define PIKA_TOOL_WIDGET_RESPONSE_CONFIRM -1
#define PIKA_TOOL_WIDGET_RESPONSE_CANCEL  -2
#define PIKA_TOOL_WIDGET_RESPONSE_RESET   -3


#define PIKA_TYPE_TOOL_WIDGET            (pika_tool_widget_get_type ())
#define PIKA_TOOL_WIDGET(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PIKA_TYPE_TOOL_WIDGET, PikaToolWidget))
#define PIKA_TOOL_WIDGET_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), PIKA_TYPE_TOOL_WIDGET, PikaToolWidgetClass))
#define PIKA_IS_TOOL_WIDGET(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PIKA_TYPE_TOOL_WIDGET))
#define PIKA_IS_TOOL_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIKA_TYPE_TOOL_WIDGET))
#define PIKA_TOOL_WIDGET_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), PIKA_TYPE_TOOL_WIDGET, PikaToolWidgetClass))


typedef struct _PikaToolWidgetPrivate PikaToolWidgetPrivate;
typedef struct _PikaToolWidgetClass   PikaToolWidgetClass;

struct _PikaToolWidget
{
  PikaObject             parent_instance;

  PikaToolWidgetPrivate *private;
};

struct _PikaToolWidgetClass
{
  PikaObjectClass  parent_class;

  /*  signals  */
  void     (* changed)         (PikaToolWidget        *widget);
  void     (* response)        (PikaToolWidget        *widget,
                                gint                   response_id);
  void     (* snap_offsets)    (PikaToolWidget        *widget,
                                gint                   offset_x,
                                gint                   offset_y,
                                gint                   width,
                                gint                   height);
  void     (* status)          (PikaToolWidget        *widget,
                                const gchar           *status);
  void     (* status_coords)   (PikaToolWidget        *widget,
                                const gchar           *title,
                                gdouble                x,
                                const gchar           *separator,
                                gdouble                y,
                                const gchar           *help);
  void     (* message)         (PikaToolWidget        *widget,
                                const gchar           *message);
  void     (* focus_changed)   (PikaToolWidget        *widget);

  /*  virtual functions  */
  gint     (* button_press)    (PikaToolWidget        *widget,
                                const PikaCoords      *coords,
                                guint32                time,
                                GdkModifierType        state,
                                PikaButtonPressType    press_type);
  void     (* button_release)  (PikaToolWidget        *widget,
                                const PikaCoords      *coords,
                                guint32                time,
                                GdkModifierType        state,
                                PikaButtonReleaseType  release_type);
  void     (* motion)          (PikaToolWidget        *widget,
                                const PikaCoords      *coords,
                                guint32                time,
                                GdkModifierType        state);

  PikaHit  (* hit)             (PikaToolWidget        *widget,
                                const PikaCoords      *coords,
                                GdkModifierType        state,
                                gboolean               proximity);
  void     (* hover)           (PikaToolWidget        *widget,
                                const PikaCoords      *coords,
                                GdkModifierType        state,
                                gboolean               proximity);
  void     (* leave_notify)    (PikaToolWidget        *widget);

  gboolean (* key_press)       (PikaToolWidget        *widget,
                                GdkEventKey           *kevent);
  gboolean (* key_release)     (PikaToolWidget        *widget,
                                GdkEventKey           *kevent);

  void     (* motion_modifier) (PikaToolWidget        *widget,
                                GdkModifierType        key,
                                gboolean               press,
                                GdkModifierType        state);
  void     (* hover_modifier)  (PikaToolWidget        *widget,
                                GdkModifierType        key,
                                gboolean               press,
                                GdkModifierType        state);

  gboolean (* get_cursor)      (PikaToolWidget        *widget,
                                const PikaCoords      *coords,
                                GdkModifierType        state,
                                PikaCursorType        *cursor,
                                PikaToolCursorType    *tool_cursor,
                                PikaCursorModifier    *modifier);

  PikaUIManager *
           (* get_popup)       (PikaToolWidget        *widget,
                                const PikaCoords      *coords,
                                GdkModifierType        state,
                                const gchar          **ui_path);

  gboolean update_on_scale;
  gboolean update_on_scroll;
  gboolean update_on_rotate;
};


GType              pika_tool_widget_get_type          (void) G_GNUC_CONST;

PikaDisplayShell * pika_tool_widget_get_shell         (PikaToolWidget  *widget);
PikaCanvasItem   * pika_tool_widget_get_item          (PikaToolWidget  *widget);

void               pika_tool_widget_set_visible       (PikaToolWidget  *widget,
                                                       gboolean         visible);
gboolean           pika_tool_widget_get_visible       (PikaToolWidget  *widget);

void               pika_tool_widget_set_focus         (PikaToolWidget  *widget,
                                                       gboolean         focus);
gboolean           pika_tool_widget_get_focus         (PikaToolWidget  *widget);

/*  for subclasses, to notify the handling tool
 */
void               pika_tool_widget_changed           (PikaToolWidget  *widget);

void               pika_tool_widget_response          (PikaToolWidget  *widget,
                                                       gint             response_id);

void               pika_tool_widget_set_snap_offsets  (PikaToolWidget  *widget,
                                                       gint             offset_x,
                                                       gint             offset_y,
                                                       gint             width,
                                                       gint             height);
void               pika_tool_widget_get_snap_offsets  (PikaToolWidget  *widget,
                                                       gint            *offset_x,
                                                       gint            *offset_y,
                                                       gint            *width,
                                                       gint            *height);

void               pika_tool_widget_set_status        (PikaToolWidget  *widget,
                                                       const gchar     *status);
void               pika_tool_widget_set_status_coords (PikaToolWidget  *widget,
                                                       const gchar     *title,
                                                       gdouble          x,
                                                       const gchar     *separator,
                                                       gdouble          y,
                                                       const gchar     *help);

void               pika_tool_widget_message           (PikaToolWidget  *widget,
                                                       const gchar     *format,
                                                       ...) G_GNUC_PRINTF (2, 3);
void               pika_tool_widget_message_literal   (PikaToolWidget  *widget,
                                                       const gchar     *message);

/*  for subclasses, to add and manage their items
 */
void               pika_tool_widget_add_item         (PikaToolWidget  *widget,
                                                      PikaCanvasItem  *item);
void               pika_tool_widget_remove_item      (PikaToolWidget  *widget,
                                                      PikaCanvasItem  *item);

PikaCanvasGroup  * pika_tool_widget_add_group        (PikaToolWidget  *widget);
PikaCanvasGroup  * pika_tool_widget_add_stroke_group (PikaToolWidget  *widget);
PikaCanvasGroup  * pika_tool_widget_add_fill_group   (PikaToolWidget  *widget);

void               pika_tool_widget_push_group       (PikaToolWidget  *widget,
                                                      PikaCanvasGroup *group);
void               pika_tool_widget_pop_group        (PikaToolWidget  *widget);

/*  for subclasses, convenience functions to add specific items
 */
PikaCanvasItem * pika_tool_widget_add_line      (PikaToolWidget       *widget,
                                                 gdouble               x1,
                                                 gdouble               y1,
                                                 gdouble               x2,
                                                 gdouble               y2);
PikaCanvasItem * pika_tool_widget_add_rectangle (PikaToolWidget       *widget,
                                                 gdouble               x,
                                                 gdouble               y,
                                                 gdouble               width,
                                                 gdouble               height,
                                                 gboolean              filled);
PikaCanvasItem * pika_tool_widget_add_arc       (PikaToolWidget       *widget,
                                                 gdouble               center_x,
                                                 gdouble               center_y,
                                                 gdouble               radius_x,
                                                 gdouble               radius_y,
                                                 gdouble               start_angle,
                                                 gdouble               slice_angle,
                                                 gboolean              filled);
PikaCanvasItem * pika_tool_widget_add_limit     (PikaToolWidget       *widget,
                                                 PikaLimitType         type,
                                                 gdouble               x,
                                                 gdouble               y,
                                                 gdouble               radius,
                                                 gdouble               aspect_ratio,
                                                 gdouble               angle,
                                                 gboolean              dashed);
PikaCanvasItem * pika_tool_widget_add_polygon   (PikaToolWidget       *widget,
                                                 PikaMatrix3          *transform,
                                                 const PikaVector2    *points,
                                                 gint                  n_points,
                                                 gboolean              filled);
PikaCanvasItem * pika_tool_widget_add_polygon_from_coords
                                                (PikaToolWidget       *widget,
                                                 PikaMatrix3          *transform,
                                                 const PikaCoords     *points,
                                                 gint                  n_points,
                                                 gboolean              filled);
PikaCanvasItem * pika_tool_widget_add_path      (PikaToolWidget       *widget,
                                                 const PikaBezierDesc *desc);

PikaCanvasItem * pika_tool_widget_add_handle    (PikaToolWidget       *widget,
                                                 PikaHandleType        type,
                                                 gdouble               x,
                                                 gdouble               y,
                                                 gint                  width,
                                                 gint                  height,
                                                 PikaHandleAnchor      anchor);
PikaCanvasItem * pika_tool_widget_add_corner    (PikaToolWidget       *widget,
                                                 gdouble               x,
                                                 gdouble               y,
                                                 gdouble               width,
                                                 gdouble               height,
                                                 PikaHandleAnchor      anchor,
                                                 gint                  corner_width,
                                                 gint                  corner_height,
                                                 gboolean              outside);

PikaCanvasItem * pika_tool_widget_add_rectangle_guides
                                                (PikaToolWidget       *widget,
                                                 gdouble               x,
                                                 gdouble               y,
                                                 gdouble               width,
                                                 gdouble               height,
                                                 PikaGuidesType        type);
PikaCanvasItem * pika_tool_widget_add_transform_guides
                                                (PikaToolWidget       *widget,
                                                 const PikaMatrix3    *transform,
                                                 gdouble               x1,
                                                 gdouble               y1,
                                                 gdouble               x2,
                                                 gdouble               y2,
                                                 PikaGuidesType        type,
                                                 gint                  n_guides,
                                                 gboolean              clip);

/*  for tools, to be called from the respective PikaTool method
 *  implementations
 */
gint       pika_tool_widget_button_press    (PikaToolWidget        *widget,
                                             const PikaCoords      *coords,
                                             guint32                time,
                                             GdkModifierType        state,
                                             PikaButtonPressType    press_type);
void       pika_tool_widget_button_release  (PikaToolWidget        *widget,
                                             const PikaCoords      *coords,
                                             guint32                time,
                                             GdkModifierType        state,
                                             PikaButtonReleaseType  release_type);
void       pika_tool_widget_motion          (PikaToolWidget        *widget,
                                             const PikaCoords      *coords,
                                             guint32                time,
                                             GdkModifierType        state);

PikaHit    pika_tool_widget_hit             (PikaToolWidget        *widget,
                                             const PikaCoords      *coords,
                                             GdkModifierType        state,
                                             gboolean               proximity);
void       pika_tool_widget_hover           (PikaToolWidget        *widget,
                                             const PikaCoords      *coords,
                                             GdkModifierType        state,
                                             gboolean               proximity);
void       pika_tool_widget_leave_notify    (PikaToolWidget        *widget);

gboolean   pika_tool_widget_key_press       (PikaToolWidget        *widget,
                                             GdkEventKey           *kevent);
gboolean   pika_tool_widget_key_release     (PikaToolWidget        *widget,
                                             GdkEventKey           *kevent);

void       pika_tool_widget_motion_modifier (PikaToolWidget        *widget,
                                             GdkModifierType        key,
                                             gboolean               press,
                                             GdkModifierType        state);
void       pika_tool_widget_hover_modifier  (PikaToolWidget        *widget,
                                             GdkModifierType        key,
                                             gboolean               press,
                                             GdkModifierType        state);

gboolean   pika_tool_widget_get_cursor      (PikaToolWidget        *widget,
                                             const PikaCoords      *coords,
                                             GdkModifierType        state,
                                             PikaCursorType        *cursor,
                                             PikaToolCursorType    *tool_cursor,
                                             PikaCursorModifier    *modifier);

PikaUIManager *
           pika_tool_widget_get_popup       (PikaToolWidget        *widget,
                                             const PikaCoords      *coords,
                                             GdkModifierType        state,
                                             const gchar          **ui_path);

#endif /* __PIKA_TOOL_WIDGET_H__ */
