/*
 * marker.c
 * Copyright (C) 2021 Zwarf <zwarf@mail.de>
 *
 * 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 <http://www.gnu.org/licenses/>.
 */


/*
 * Code mainly taken from https://gitlab.gnome.org/GNOME/libshumate/-/blob/main/shumate/shumate-marker.c
 * This is a copy of the 'ShumateMarker' class adjusted for the needs of PicPlanner
 *
 * TODO:
 * Comment more what is happening inside the functions.
 */

#include "marker.h"

typedef struct
{
  double x;
  double y;
  double x_offset;
  double y_offset;

  GtkWidget *child;
} PicplannerMarkerPrivate;

static void buildable_interface_init (GtkBuildableIface *iface);

G_DEFINE_TYPE_WITH_CODE (PicplannerMarker, picplanner_marker, GTK_TYPE_WIDGET,
    G_ADD_PRIVATE (PicplannerMarker)
    G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, buildable_interface_init));

static GtkBuildableIface *parent_buildable_iface;

void
picplanner_marker_set_location (PicplannerMarker *marker,
                                double           x,
                                double           y,
                                double           x_offset,
                                double           y_offset)
{
  PicplannerMarkerPrivate *priv = picplanner_marker_get_instance_private (marker);

  priv->x = x;
  priv->y = y;
  priv->x_offset = x_offset;
  priv->y_offset = y_offset;
}


double
picplanner_marker_get_x (PicplannerMarker *marker)
{
  PicplannerMarkerPrivate *priv = picplanner_marker_get_instance_private (marker);

  return priv->x;
}


double
picplanner_marker_get_y (PicplannerMarker *marker)
{
  PicplannerMarkerPrivate *priv = picplanner_marker_get_instance_private (marker);

  return priv->y;
}

double
picplanner_marker_get_x_offset (PicplannerMarker *marker)
{
  PicplannerMarkerPrivate *priv = picplanner_marker_get_instance_private (marker);

  return priv->x_offset;
}


double
picplanner_marker_get_y_offset (PicplannerMarker *marker)
{
  PicplannerMarkerPrivate *priv = picplanner_marker_get_instance_private (marker);

  return priv->y_offset;
}

static void
picplanner_marker_add_child (GtkBuildable *buildable,
                             GtkBuilder   *builder,
                             GObject      *child,
                             const char   *type)
{
  if (GTK_IS_WIDGET (child))
    picplanner_marker_set_child (PICPLANNER_MARKER (buildable), GTK_WIDGET (child));
  else
    parent_buildable_iface->add_child (buildable, builder, child, type);
}


static void
picplanner_marker_dispose (GObject *object)
{
  PicplannerMarker *marker = PICPLANNER_MARKER (object);

  picplanner_marker_set_child (marker, NULL);

  G_OBJECT_CLASS (picplanner_marker_parent_class)->dispose (object);
}

static void
picplanner_marker_class_init (PicplannerMarkerClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);

  object_class->dispose = picplanner_marker_dispose;

  gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
  gtk_widget_class_set_css_name (widget_class, "map-marker");
}

static void
picplanner_marker_init (PicplannerMarker *self)
{
  PicplannerMarkerPrivate *priv = picplanner_marker_get_instance_private (self);

  priv->x = 0;
  priv->y = 0;
}

static void
buildable_interface_init (GtkBuildableIface *iface)
{
  parent_buildable_iface = g_type_interface_peek_parent (iface);
  iface->add_child = picplanner_marker_add_child;
}

PicplannerMarker *
picplanner_marker_new (void)
{
  return PICPLANNER_MARKER (g_object_new (PICPLANNER_TYPE_MARKER, NULL));
}

GtkWidget *
picplanner_marker_get_child (PicplannerMarker *marker)
{
  PicplannerMarkerPrivate *priv = picplanner_marker_get_instance_private (marker);

  g_return_val_if_fail (PICPLANNER_IS_MARKER (marker), NULL);

  return priv->child;
}


void
picplanner_marker_set_child (PicplannerMarker *marker,
                             GtkWidget        *child)
{
  PicplannerMarkerPrivate *priv = picplanner_marker_get_instance_private (marker);

  g_return_if_fail (PICPLANNER_IS_MARKER (marker));

  if (priv->child == child)
    return;

  g_clear_pointer (&priv->child, gtk_widget_unparent);

  priv->child = child;

  if (priv->child)
    gtk_widget_set_parent (priv->child, GTK_WIDGET (marker));
}
