    /*
 * This file is part of VICE, the Versatile Commodore Emulator.
 * See README for copyright notice.
 *
 *  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 2 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, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 *  02111-1307  USA.
 */

#include "vice.h"

#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <time.h>

#include "lib.h"
#include "log.h"
#include "machine.h"
#include "mainlock.h"
#include "monitor.h"
#include "resources.h"
#include "screenshot.h"
#include "ui.h"
#include "uiactions.h"
#include "vsync.h"

#include "uimedia.h"

/* FIXME: should there be a standard function with this name? */
static video_canvas_t *ui_get_active_canvas(void)
{
    return sdl_active_canvas;
}

/** \brief  Create a string in the format 'yyyymmddHHMMssffffff' of the current time
 *
 * \return  heap-allocated string, owned by VICE, free with lib_free()
 */
static char *create_datetime_string(void)
{
    time_t stamp;
    static time_t stamp_last = 0;
    struct tm *stamp_tm;
    char *t;
    char *str;
    static unsigned int m = 0;

    t = lib_malloc(32);

    stamp = time(NULL);
    stamp_tm = localtime(&stamp);
    if (stamp_tm == NULL ||
        strftime(t, 31, "%Y%m%d%H%M%S", stamp_tm) == 0) {
        return NULL;
    }

    /* FIXME: using a simple counter instead of fractions of seconds. it shouldn't really matter :) */
    if (stamp == stamp_last) {
        m = (m + 1) % 1000000;
    } else {
        m = 0;
    }

    stamp_last = stamp;

    str = lib_msprintf("%s%06u", t, m);

    lib_free(t);

    return str;
}


/** \brief  Create a filename based on the current datetime and \a ext
 *
 * \param[in]   ext file extension (without the dot)
 *
 * \return  heap-allocated string, owned by VICE, free with lib_free()
 */
static char *create_proposed_screenshot_name(const char *ext)
{
    char *date;
    char *filename = NULL;

    date = create_datetime_string();
    if (date) {
        filename = lib_msprintf("vice-screen-%s.%s", date, ext);
        lib_free(date);
    }
    return filename;
}

/** \brief  Callback for vsync_on_vsync_do()
 *
 * Create a screenshot on vsync to avoid tearing.
 *
 * This function is called on the VICE thread, so the canvas is retrieved in
 * ui_media_auto_screenshot() on the UI thread and passed via \a param.
 *
 * \param[in]   param   video canvas
 */
static void auto_screenshot_vsync_callback(void *param)
{
    char *filename;
    video_canvas_t *canvas = param;

    /* no need for locale bullshit */
    filename = create_proposed_screenshot_name("png");
    if ((filename == NULL) || (screenshot_save("PNG", filename, canvas) < 0)) {
        log_error(LOG_ERR, "Failed to autosave screenshot.");
        ui_error("Error autosaving screenshot.");
    }
    lib_free(filename);
}


/** \brief  Create screenshot with autogenerated filename
 *
 * Creates a PNG screenshot with an autogenerated filename with an ISO-8601-ish
 * timestamp:
 * "vice-screenshot-<year><month><day><hour><month><seconds><sec-frac>.png"
 */
void ui_media_auto_screenshot(void)
{
    if (monitor_is_inside_monitor()) {
        /* screenshot immediately if monitor is open */
        auto_screenshot_vsync_callback((void *)ui_get_active_canvas());
    } else {
        /* queue screenshot grab on vsync to avoid tearing */
        vsync_on_vsync_do(auto_screenshot_vsync_callback, (void *)ui_get_active_canvas());
    }
}
