/**
 * @file lv_snapshot.h
 *
 */

#ifndef LV_SNAPSHOT_H
#define LV_SNAPSHOT_H

#ifdef __cplusplus
extern "C" {
#endif

/*********************
 *      INCLUDES
 *********************/
#include <stdint.h>
#include <stddef.h>

#include "../../core/lv_obj.h"

/*********************
 *      DEFINES
 *********************/

#if LV_USE_SNAPSHOT
/**********************
 *      TYPEDEFS
 **********************/

/**********************
 * GLOBAL PROTOTYPES
 **********************/

/**
 * Take snapshot for object with its children, create the draw buffer as needed.
 * @param obj   the object to generate snapshot.
 * @param cf    color format for generated image.
 * @return      a pointer to an draw buffer containing snapshot image, or NULL if failed.
 */
lv_draw_buf_t * lv_snapshot_take(lv_obj_t * obj, lv_color_format_t cf);

/**
 * Create a draw buffer to store the snapshot image for object.
 * @param obj   the object to generate snapshot.
 * @param cf    color format for generated image.
 * @return      a pointer to an draw buffer ready for taking snapshot, or NULL if failed.
 */
lv_draw_buf_t * lv_snapshot_create_draw_buf(lv_obj_t * obj, lv_color_format_t cf);

/**
 * Reshape the draw buffer to prepare for taking snapshot for obj.
 * This is usually used to check if the existing draw buffer is enough for
 * obj snapshot. If return LV_RESULT_INVALID, you should create a new one.
 * @param draw_buf  the draw buffer to reshape.
 * @param obj       the object to generate snapshot.
 */
lv_result_t lv_snapshot_reshape_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_buf);

/**
 * Take snapshot for object with its children, save image info to provided buffer.
 * @param obj       the object to generate snapshot.
 * @param cf        color format for new snapshot image.
 *                  It could differ with cf of `draw_buf` as long as the new cf will fit in.
 * @param draw_buf  the draw buffer to store the image result. It's reshaped automatically.
 * @return          LV_RESULT_OK on success, LV_RESULT_INVALID on error.
 */
lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, lv_draw_buf_t * draw_buf);

/**
 * @deprecated Use `lv_draw_buf_destroy` instead.
 *
 * Free the snapshot image returned by @ref lv_snapshot_take
 * @param dsc   the image descriptor generated by lv_snapshot_take.
 */
static inline void lv_snapshot_free(lv_image_dsc_t * dsc)
{
    LV_LOG_WARN("Deprecated API, use lv_draw_buf_destroy directly.");
    lv_draw_buf_destroy((lv_draw_buf_t *)dsc);
}

/**
 * Take snapshot for object with its children, save image info to provided buffer.
 * @param obj       the object to generate snapshot.
 * @param cf        color format for generated image.
 * @param dsc       image descriptor to store the image result.
 * @param buf       the buffer to store image data. It must meet align requirement.
 * @param buf_size  provided buffer size in bytes.
 * @return          LV_RESULT_OK on success, LV_RESULT_INVALID on error.
 * @deprecated      Use lv_snapshot_take_to_draw_buf instead.
 */
static inline lv_result_t lv_snapshot_take_to_buf(lv_obj_t * obj, lv_color_format_t cf, lv_image_dsc_t * dsc,
                                                  void * buf,
                                                  uint32_t buf_size)
{
    lv_draw_buf_t draw_buf;
    LV_LOG_WARN("Deprecated API, use lv_snapshot_take_to_draw_buf instead.");
    lv_draw_buf_init(&draw_buf, 1, 1, cf, buf_size, buf, buf_size);
    lv_result_t res = lv_snapshot_take_to_draw_buf(obj, cf, &draw_buf);
    if(res == LV_RESULT_OK) {
        lv_memcpy((void *)dsc, &draw_buf, sizeof(lv_image_dsc_t));
    }
    return res;
}

/**********************
 *      MACROS
 **********************/
#endif /*LV_USE_SNAPSHOT*/

#ifdef __cplusplus
} /*extern "C"*/
#endif

#endif
