/*
 * Copyright (C) 2019 Alexandros Theodotou <alex at zrythm dot org>
 *
 * This file is part of Zrythm
 *
 * Zrythm is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Zrythm 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Zrythm.  If not, see <https://www.gnu.org/licenses/>.
 */

#include <stdlib.h>

#include "audio/marker_track.h"
#include "audio/track.h"
#include "project.h"
#include "utils/arrays.h"
#include "utils/flags.h"
#include "utils/objects.h"

#include <gtk/gtk.h>
#include <glib/gi18n.h>

/**
 * Inits the marker track.
 */
void
marker_track_init (
  Track * self)
{
  self->type = TRACK_TYPE_MARKER;

  gdk_rgba_parse (&self->color, "#A3289a");
}

/**
 * Creates the default marker track.
 */
MarkerTrack *
marker_track_default ()
{
  Track * self =
    track_new (
      TRACK_TYPE_MARKER, _("Markers"),
      F_WITHOUT_LANE);

  /* add start and end markers */
  Marker * marker;
  Position pos;
  marker =
    marker_new (_("start"), 1);
  position_set_to_bar (&pos, 1);
  marker_set_pos (
    marker, &pos, AO_UPDATE_ALL);
  marker->type = MARKER_TYPE_START;
  marker_track_add_marker (
    self, marker);
  marker =
    marker_new (_("end"), 1);
  position_set_to_bar (&pos, 129);
  marker_set_pos (
    marker, &pos, AO_UPDATE_ALL);
  marker->type = MARKER_TYPE_END;
  marker_track_add_marker (
    self, marker);

  return self;
}

/**
 * Returns the start marker.
 */
Marker *
marker_track_get_start_marker (
  const Track * track)
{
  g_return_val_if_fail (
    track->type == TRACK_TYPE_MARKER, NULL);

  Marker * marker;
  for (int i = 0; i < track->num_markers; i++)
    {
      marker = track->markers[i];
      if (marker->type == MARKER_TYPE_START)
        return marker;
    }
  g_return_val_if_reached (NULL);
}

/**
 * Returns the end marker.
 */
Marker *
marker_track_get_end_marker (
  const Track * track)
{
  g_return_val_if_fail (
    track->type == TRACK_TYPE_MARKER, NULL);

  Marker * marker;
  for (int i = 0; i < track->num_markers; i++)
    {
      marker = track->markers[i];
      if (marker->type == MARKER_TYPE_END)
        return marker;
    }
  g_return_val_if_reached (NULL);
}

/**
 * Adds a Marker to the Track.\
 *
 * @gen_widget Generates a widget for the Marker.
 */
void
marker_track_add_marker (
  MarkerTrack * track,
  Marker *      marker)
{
  g_warn_if_fail (
    track->type == TRACK_TYPE_MARKER && marker);
  g_warn_if_fail (
    marker->obj_info.counterpart ==
      AOI_COUNTERPART_MAIN);
  g_warn_if_fail (
    marker->obj_info.main &&
    marker->obj_info.main_trans &&
    marker->obj_info.lane &&
    marker->obj_info.lane_trans);

  marker_set_track (marker, track);
  array_double_size_if_full (
    track->markers, track->num_markers,
    track->markers_size, Marker *);
  array_append (track->markers,
                track->num_markers,
                marker);

  EVENTS_PUSH (ET_MARKER_CREATED, marker);
}

/**
 * Removes a marker, optionally freeing it.
 */
void
marker_track_remove_marker (
  MarkerTrack * self,
  Marker *      marker,
  int           free)
{
  /* deselect */
  timeline_selections_remove_marker (
    TL_SELECTIONS, marker);

  array_delete (self->markers,
                self->num_markers,
                marker);

  if (free)
    free_later (marker, marker_free);

  EVENTS_PUSH (ET_MARKER_REMOVED, self);
}

void
marker_track_free (MarkerTrack * self)
{
  /* TODO free Marker's */

}
