#ifndef _CORE_H_
#define _CORE_H_

#include "ujpeg.h"

/* easing curves */
typedef enum _easing_curve {
    EC_LINEAR = 0,                  /* linear */
    EC_SMOOTH,                      /* cubic smooth */
    EC_ACCELERATE,                  /* cubic smooth, slow start, accelerating */
    EC_DECELERATE                   /* cubic smooth, fast start, decelerating */
} easing_curve_t;

/* transition types */
typedef enum _trans_type {
    TRANS_CROSSFADE = 0,            /* simple crossfade */
    TRANS_MAP = 1,                  /* use JPEG file for map (black -> white) */
    TRANS_HORIZONTAL,               /* horizontal left -> right */
    TRANS_VERTICAL,                 /* vertical top -> down */
    TRANS_CIRCULAR,                 /* circular inner -> outer */
    TRANS_DIAGONAL,                 /* diagonal top-left -> bottom-right */
    TRANS_DIAGONAL_ALT,             /* diagonal top-right -> bottom-left */
    TRANS_HORIZONTAL_CENTER_OUT,    /* horizontal center -> left+right edges */
    TRANS_VERTICAL_CENTER_OUT       /* vertical center -> top+bottom edges */
} trans_type_t;

/* animation start and end key parameters */
typedef struct _key {               /* key information structure */
    int flags;                      /* key flags (see below) */
    float sx, sy;                   /* scale or size */
    float px, py;                   /* position (absolute or relative) */
} key_t;
#define KF_VALID     (1 << 0)       /* this key is set to valid values */
#define KF_ABS_SCALE (1 << 1)       /* 0: sx/sy = relative scale;
                                     * 1: sx/sy = absolute size in pixels */
#define KF_ABS_POS   (1 << 2)       /* 0: px/py = relative position;
                                     * 1: px/py = absolute position in pixels */
#define KF_AUTOANIM  (1 << 3)       /* 1: auto-animate this key */

/* slide data structure */
typedef struct _slide {
    /* config parameters */
    const char *filename;           /* JPEG file name; NULL = solid color */
    unsigned long background;       /* background color (BGR24 -> 0xBBGGRR) */
    float core_duration;            /* core duration in seconds */
    key_t start, end;               /* start and end parameters for animation */
    easing_curve_t curve;           /* easing curve for animation */

    /* transition parameters */
    struct {
        trans_type_t type;          /* transition type */
        const char *mapfile;        /* name of JPEG file to use for map */
        float duration;             /* transition duration in seconds */
        easing_curve_t time_curve;  /* easing curve for time */
        float map_band_size;        /* map band size (0..1) */
        easing_curve_t map_curve;   /* easing curve for transition band */
        int map_invert;             /* 1 = invert map */
    } trans;

    /* derived parameters (do not change!) */
    int num;                        /* slide number (1-based) */
    int width, height;              /* width and height of the input image */
    float vp_width, vp_height;      /* aspect-adjusted viewport size */
    float total_duration;           /* total display duration (incl. trans) */
    float total_start;              /* display starting time */
    float core_start;               /* core starting time (i.e. end of trans) */

    /* run-time values (DO NOT CHANGE!) */
    ujImage image;                  /* JPEG image handle */
    unsigned char *scaled_img;      /* RGB image, scaled to output size */
    struct _slide *next;            /* pointer to next slide */
} slide_t;

/* Global variables for output settings.
 * These values MUST NOT be changed after finish_slide_setup() has been called! */
extern int output_width, output_height;
extern float output_sar;

/* Global variables for automatic animation. */
extern int autoanim_isotropic;      /* 1 = force isotropic positions: don't move 
                                     * the crop area further away from the
                                     * center as is possible for the _minimum_
                                     * of both directions (X/Y);
                                     * 0 = accept any position */
extern float autoanim_scale_limit;  /* minimum (if < 1.0) or maximum (if > 1.0)
                                     * relative scale */

/* Global variable for quality control. */
extern int low_quality;             /* 1 = low quality scaling,
                                     * 0 = high quality scaling (default) */

/* new_slide(): add a new slide
 * filename: name of the JPEG file
 * slide_template: slide template to copy parameters from (may be NULL)
 * returns: pointer to the slide structure of the new slide, or NULL on error */
extern slide_t* new_slide(const char *filename, const slide_t *slide_template);

/* new_trans(): add a new transition
 * trans_template: slide template to copy parameters from (may be NULL)
 * returns: pointer to the slide structure of the slide containing the new
 *          transition, or NULL on error */
extern slide_t* new_trans(const slide_t *trans_template);

/* trans_set_map(): use a map file for a transition
 * slide: pointer to the slide structure containing the transition to modity
 * mapfile: name of the JPEG file to use as a map file
 * returns: 0 on error, 1 on success */
extern int trans_set_map(slide_t* slide, const char *mapfile);

/* finish_slide_setup(): must be called after adding all slides and transitions
 * returns: the total duration of the slideshow, in seconds */
extern float finish_slide_setup(void);

/* count_slides(): return number of slides
 * trans_only: if 0, count all slides; if 1, count slides with transitions only */
extern int count_slides(int trans_only);

/* dump_slides(): dump slideshow "playlist" to stdout */
extern void dump_slides(void);

/* render_frame(): render a frame of the slideshow
 * t: the time, in seconds, of the frame to render, must be between 0.0f and
 *    the total slideshow duration;
 *    note that the function is heavily optimized to be called with
 *    monotonously ascending timestamps
 * output: a pointer to an array variable to receive the address of the output
 *         buffer (note that the returned address may vary)
 * returns: the current slide number; if negative, the transition to the next
 *          slide is in progress; on error, 0 is returned */
extern int render_frame(float t, unsigned char **output);

/* core_cleanup(): free all memory allocated by core.c */
extern void core_cleanup(void);

#endif//_CORE_H_
