/*
 *  Copyright 1994-2022 Olivier Girondel
 *
 *  This file is part of lebiniou.
 *
 *  lebiniou 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 2 of the License, or
 *  (at your option) any later version.
 *
 *  lebiniou 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 lebiniou. If not, see <http://www.gnu.org/licenses/>.
 */

#include "globals.h"
#include "sequence.h"
#include "images.h"
#include "colormaps.h"


static int
Sequence_write_json(Context_t *ctx, const Sequence_t *s, const char *filename, const uint8_t full)
{
  json_t *sequence_j = Sequence_to_json(ctx, s, full, 1, NULL);
  int ret = json_dump_file(sequence_j, filename, JSON_INDENT(4));

  if (!ret) {
    printf("[s] Saved sequence %s\n", filename);
  } else {
    printf("[s] ERROR: could not save sequence %s\n", filename);
  }
  json_decref(sequence_j);

  return ret;
}


void
Sequence_save(struct Context_s *ctx, uint8_t overwrite,
              const uint8_t bare, const char auto_colormaps, const char auto_images)
{
  Sequence_t *store = NULL;
  Sequence_t *s = ctx->sm->cur;

  if (g_list_length(s->layers) == 0) {
    printf("[!] *NOT* saving an empty sequence !\n");
    return;
  }

  if (s->broken) {
    printf("[!] Sequence is broken, won't save !\n");
    return;
  }

  if (overwrite && (s->id == 0)) {
    printf("[!] Overwriting a NEW sequence == saving\n");
    overwrite = 0;
  }

  uint64_t old_id = s->id; // to restore if Sequence_write_json() fails
  char *old_name = (NULL != s->name) ? strdup(s->name) : NULL; // ditto

  if (!overwrite) {
    xfree(s->name);
    // sequence ids are now in milliseconds
    s->id = g_get_real_time() / 1000;
  }

  if (NULL == s->name) {
    s->name = g_strdup_printf("%"PRIu64, s->id);
  }

  const gchar *blah = Sequences_get_dir();
  g_mkdir_with_parents(blah, DIRECTORY_MODE);

  /* set auto_colormaps from context if needed */
  if (s->auto_colormaps == -1) {
    s->auto_colormaps = auto_colormaps;
  }
  /* set auto_images from context if needed */
  if (s->auto_images == -1) {
    s->auto_images = auto_images;
  }

  // override if auto colormaps or images are not allowed
  if (!ctx->allow_auto_colormaps) {
    s->auto_colormaps = 0;
  }
  if (!ctx->allow_auto_images) {
    s->auto_images = 0;
  }

  // set 3D parameters from context
  if (NULL != s->params3d) {
    json_decref(s->params3d);
  }
  s->params3d = Params3d_to_json(&ctx->params3d);

  gchar *filename_json = NULL;
  if (overwrite) {
    filename_json = g_strdup_printf("%s/%s.json", blah, s->name);
  } else {
    filename_json = g_strdup_printf("%s/%"PRIu64".json", blah, s->id);
  }

  if (!Sequence_write_json(ctx, s, filename_json, bare)) {
    xfree(old_name);
  } else { // saving failed, restore old id/name
    s->id = old_id;
    s->name = old_name;
  }
  g_free(filename_json);

  s->changed = 0;

  if (overwrite) {
    GList *oldp = g_list_find_custom(sequences->seqs, (gpointer)s, Sequence_sort_func);
    Sequence_t *old;

    if (NULL != oldp) {
      old = (Sequence_t *)oldp->data;
      Sequence_copy(ctx, s, old);
    } else {
      overwrite = 0;
    }
  }

  if (overwrite == 0) {
    /* new sequence */
    store = Sequence_new(0);
    Sequence_copy(ctx, s, store);

    sequences->seqs = g_list_append(sequences->seqs, (gpointer)store);
    sequences->size++;
  }
}
