/*
 * Copyright (c) Stefano Sabatini 2011
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * cellular automaton video source, based on Stephen Wolfram "experimentus crucis"
 */

/* #define DEBUG */

#include "libavutil/file.h"
#include "libavutil/internal.h"
#include "libavutil/lfg.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
#include "libavutil/random_seed.h"
#include "libavutil/avstring.h"
#include "avfilter.h"
#include "internal.h"
#include "formats.h"
#include "video.h"

typedef struct {
    const AVClass *class;
    int w, h;
    char *filename;
    char *rule_str;
    uint8_t *file_buf;
    size_t file_bufsize;
    uint8_t *buf;
    int buf_prev_row_idx, buf_row_idx;
    uint8_t rule;
    uint64_t pts;
    AVRational frame_rate;
    double   random_fill_ratio;
    uint32_t random_seed;
    int stitch, scroll, start_full;
    int64_t generation;         ///< the generation number, starting from 0
    AVLFG lfg;
    char *pattern;
} CellAutoContext;

#define OFFSET(x) offsetof(CellAutoContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM

static const AVOption cellauto_options[] = {
    { "filename", "read initial pattern from file", OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
    { "f",        "read initial pattern from file", OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
    { "pattern",  "set initial pattern", OFFSET(pattern), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
    { "p",        "set initial pattern", OFFSET(pattern), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
    { "rate",     "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },
    { "r",        "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },
    { "size",     "set video size", OFFSET(w),    AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, FLAGS },
    { "s",        "set video size", OFFSET(w),    AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, FLAGS },
    { "rule",     "set rule",       OFFSET(rule), AV_OPT_TYPE_INT,    {.i64 = 110},  0, 255, FLAGS },
    { "random_fill_ratio", "set fill ratio for filling initial grid randomly", OFFSET(random_fill_ratio), AV_OPT_TYPE_DOUBLE, {.dbl = 1/M_PHI}, 0, 1, FLAGS },
    { "ratio",             "set fill ratio for filling initial grid randomly", OFFSET(random_fill_ratio), AV_OPT_TYPE_DOUBLE, {.dbl = 1/M_PHI}, 0, 1, FLAGS },
    { "random_seed", "set the seed for filling the initial grid randomly", OFFSET(random_seed), AV_OPT_TYPE_INT, {.i64 = -1}, -1, UINT32_MAX, FLAGS },
    { "seed",        "set the seed for filling the initial grid randomly", OFFSET(random_seed), AV_OPT_TYPE_INT, {.i64 = -1}, -1, UINT32_MAX, FLAGS },
    { "scroll",      "scroll pattern downward", OFFSET(scroll), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, FLAGS },
    { "start_full",  "start filling the whole video", OFFSET(start_full), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS },
    { "full",        "start filling the whole video", OFFSET(start_full), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, FLAGS },
    { "stitch",      "stitch boundaries", OFFSET(stitch), AV_OPT_TYPE_INT,    {.i64 = 1},   0, 1, FLAGS },
    { NULL }
};

AVFILTER_DEFINE_CLASS(cellauto);

#ifdef DEBUG
static void show_cellauto_row(AVFilterContext *ctx)
{
    CellAutoContext *cellauto = ctx->priv;
    int i;
    uint8_t *row = cellauto->buf + cellauto->w * cellauto->buf_row_idx;
    char *line = av_malloc(cellauto->w + 1);
    if (!line)
        return;

    for (i = 0; i < cellauto->w; i++)
        line[i] = row[i] ? '@' : ' ';
    line[i] = 0;
    av_log(ctx, AV_LOG_DEBUG, "generation:%"PRId64" row:%s|\n", cellauto->generation, line);
    av_free(line);
}
#endif

static int init_pattern_from_string(AVFilterContext *ctx)
{
    CellAutoContext *cellauto = ctx->priv;
    char *p;
    int i, w = 0;

    w = strlen(cellauto->pattern);
    av_log(ctx, AV_LOG_DEBUG, "w:%d\n", w);

    if (cellauto->w) {
        if (w > cellauto->w) {
            av_log(ctx, AV_LOG_ERROR,
                   "The specified width is %d which cannot contain the provided string width of %d\n",
                   cellauto->w, w);
            return AVERROR(EINVAL);
        }
    } else {
        /* width was not specified, set it to width of the provided row */
        cellauto->w = w;
        cellauto->h = (double)cellauto->w * M_PHI;
    }

    cellauto->buf = av_mallocz_array(sizeof(uint8_t) * cellauto->w, cellauto->h);
    if (!cellauto->buf)
        return AVERROR(ENOMEM);

    /* fill buf */
    p = cellauto->pattern;
    for (i = (cellauto->w - w)/2;; i++) {
        av_log(ctx, AV_LOG_DEBUG, "%d %c\n", i, *p == '\n' ? 'N' : *p);
        if (*p == '\n' || !*p)
            break;
        else
            cellauto->buf[i] = !!av_isgraph(*(p++));
    }

    return 0;
}

static int init_pattern_from_file(AVFilterContext *ctx)
{
    CellAutoContext *cellauto = ctx->priv;
    int ret;

    ret = av_file_map(cellauto->filename,
                      &cellauto->file_buf, &cellauto->file_bufsize, 0, ctx);
    if (ret < 0)
        return ret;

    /* create a string based on the read file */
    cellauto->pattern = av_malloc(cellauto->file_bufsize + 1);
    if (!cellauto->pattern)
        return AVERROR(ENOMEM);
    memcpy(cellauto->pattern, cellauto->file_buf, cellauto->file_bufsize);
    cellauto->pattern[cellauto->file_bufsize] = 0;

    return init_pattern_from_string(ctx);
}

static av_cold int init(AVFilterContext *ctx)
{
    CellAutoContext *cellauto = ctx->priv;
    int ret;

    if (!cellauto->w && !cellauto->filename && !cellauto->pattern)
        av_opt_set(cellauto, "size", "320x518", 0);

    if (cellauto->filename && cellauto->pattern) {
        av_log(ctx, AV_LOG_ERROR, "Only one of the filename or pattern options can be used\n");
        return AVERROR(EINVAL);
    }

    if (cellauto->filename) {
        if ((ret = init_pattern_from_file(ctx)) < 0)
            return ret;
    } else if (cellauto->pattern) {
        if ((ret = init_pattern_from_string(ctx)) < 0)
            return ret;
    } else {
        /* fill the first row randomly */
        int i;

        cellauto->buf = av_mallocz_array(sizeof(uint8_t) * cellauto->w, cellauto->h);
        if (!cellauto->buf)
            return AVERROR(ENOMEM);
        if (cellauto->random_seed == -1)
            cellauto->random_seed = av_get_random_seed();

        av_lfg_init(&cellauto->lfg, cellauto->random_seed);

        for (i = 0; i < cellauto->w; i++) {
            double r = (double)av_lfg_get(&cellauto->lfg) / UINT32_MAX;
            if (r <= cellauto->random_fill_ratio)
                cellauto->buf[i] = 1;
        }
    }

    av_log(ctx, AV_LOG_VERBOSE,
           "s:%dx%d r:%d/%d rule:%d stitch:%d scroll:%d full:%d seed:%u\n",
           cellauto->w, cellauto->h, cellauto->frame_rate.num, cellauto->frame_rate.den,
           cellauto->rule, cellauto->stitch, cellauto->scroll, cellauto->start_full,
           cellauto->random_seed);
    return 0;
}

static av_cold void uninit(AVFilterContext *ctx)
{
    CellAutoContext *cellauto = ctx->priv;

    av_file_unmap(cellauto->file_buf, cellauto->file_bufsize);
    av_freep(&cellauto->buf);
    av_freep(&cellauto->pattern);
}

static int config_props(AVFilterLink *outlink)
{
    CellAutoContext *cellauto = outlink->src->priv;

    outlink->w = cellauto->w;
    outlink->h = cellauto->h;
    outlink->time_base = av_inv_q(cellauto->frame_rate);

    return 0;
}

static void evolve(AVFilterContext *ctx)
{
    CellAutoContext *cellauto = ctx->priv;
    int i, v, pos[3];
    uint8_t *row, *prev_row = cellauto->buf + cellauto->buf_row_idx * cellauto->w;
    enum { NW, N, NE };

    cellauto->buf_prev_row_idx = cellauto->buf_row_idx;
    cellauto->buf_row_idx      = cellauto->buf_row_idx == cellauto->h-1 ? 0 : cellauto->buf_row_idx+1;
    row = cellauto->buf + cellauto->w * cellauto->buf_row_idx;

    for (i = 0; i < cellauto->w; i++) {
        if (cellauto->stitch) {
            pos[NW] = i-1 < 0 ? cellauto->w-1 : i-1;
            pos[N]  = i;
            pos[NE] = i+1 == cellauto->w ? 0  : i+1;
            v = prev_row[pos[NW]]<<2 | prev_row[pos[N]]<<1 | prev_row[pos[NE]];
        } else {
            v = 0;
            v|= i-1 >= 0          ? prev_row[i-1]<<2 : 0;
            v|=                     prev_row[i  ]<<1    ;
            v|= i+1 < cellauto->w ? prev_row[i+1]    : 0;
        }
        row[i] = !!(cellauto->rule & (1<<v));
        ff_dlog(ctx, "i:%d context:%c%c%c -> cell:%d\n", i,
                v&4?'@':' ', v&2?'@':' ', v&1?'@':' ', row[i]);
    }

    cellauto->generation++;
}

static void fill_picture(AVFilterContext *ctx, AVFrame *picref)
{
    CellAutoContext *cellauto = ctx->priv;
    int i, j, k, row_idx = 0;
    uint8_t *p0 = picref->data[0];

    if (cellauto->scroll && cellauto->generation >= cellauto->h)
        /* show on top the oldest row */
        row_idx = (cellauto->buf_row_idx + 1) % cellauto->h;

    /* fill the output picture with the whole buffer */
    for (i = 0; i < cellauto->h; i++) {
        uint8_t byte = 0;
        uint8_t *row = cellauto->buf + row_idx*cellauto->w;
        uint8_t *p = p0;
        for (k = 0, j = 0; j < cellauto->w; j++) {
            byte |= row[j]<<(7-k++);
            if (k==8 || j == cellauto->w-1) {
                k = 0;
                *p++ = byte;
                byte = 0;
            }
        }
        row_idx = (row_idx + 1) % cellauto->h;
        p0 += picref->linesize[0];
    }
}

static int request_frame(AVFilterLink *outlink)
{
    CellAutoContext *cellauto = outlink->src->priv;
    AVFrame *picref = ff_get_video_buffer(outlink, cellauto->w, cellauto->h);
    if (!picref)
        return AVERROR(ENOMEM);
    picref->sample_aspect_ratio = (AVRational) {1, 1};
    if (cellauto->generation == 0 && cellauto->start_full) {
        int i;
        for (i = 0; i < cellauto->h-1; i++)
            evolve(outlink->src);
    }
    fill_picture(outlink->src, picref);
    evolve(outlink->src);

    picref->pts = cellauto->pts++;

#ifdef DEBUG
    show_cellauto_row(outlink->src);
#endif
    return ff_filter_frame(outlink, picref);
}

static int query_formats(AVFilterContext *ctx)
{
    static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_NONE };
    AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
    if (!fmts_list)
        return AVERROR(ENOMEM);
    return ff_set_common_formats(ctx, fmts_list);
}

static const AVFilterPad cellauto_outputs[] = {
    {
        .name          = "default",
        .type          = AVMEDIA_TYPE_VIDEO,
        .request_frame = request_frame,
        .config_props  = config_props,
    },
    { NULL }
};

AVFilter ff_vsrc_cellauto = {
    .name          = "cellauto",
    .description   = NULL_IF_CONFIG_SMALL("Create pattern generated by an elementary cellular automaton."),
    .priv_size     = sizeof(CellAutoContext),
    .priv_class    = &cellauto_class,
    .init          = init,
    .uninit        = uninit,
    .query_formats = query_formats,
    .inputs        = NULL,
    .outputs       = cellauto_outputs,
};
