/*
 * Copyright (c) 2012 Clément Bœsch
 *
 * 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
 * VPlayer subtitles format demuxer
 */

#include "avformat.h"
#include "internal.h"
#include "subtitles.h"

typedef struct {
    FFDemuxSubtitlesQueue q;
} VPlayerContext;

static int vplayer_probe(AVProbeData *p)
{
    char c;
    const unsigned char *ptr = p->buf;

    if (sscanf(ptr, "%*d:%*d:%*d.%*d%c", &c) == 1 && strchr(": =", c))
        return AVPROBE_SCORE_MAX;
    return 0;
}

static int64_t read_ts(char **line)
{
    char c;
    int hh, mm, ss, ms, len;

    if (sscanf(*line, "%d:%d:%d.%d%c%n",
               &hh, &mm, &ss, &ms, &c, &len) >= 5) {
        *line += len;
        return (hh*3600LL + mm*60LL + ss) * 100LL + ms;
    }
    return AV_NOPTS_VALUE;
}

static int vplayer_read_header(AVFormatContext *s)
{
    VPlayerContext *vplayer = s->priv_data;
    AVStream *st = avformat_new_stream(s, NULL);

    if (!st)
        return AVERROR(ENOMEM);
    avpriv_set_pts_info(st, 64, 1, 100);
    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
    st->codec->codec_id   = AV_CODEC_ID_VPLAYER;

    while (!url_feof(s->pb)) {
        char line[4096];
        char *p = line;
        const int64_t pos = avio_tell(s->pb);
        int len = ff_get_line(s->pb, line, sizeof(line));
        int64_t pts_start;

        if (!len)
            break;

        line[strcspn(line, "\r\n")] = 0;

        pts_start = read_ts(&p);
        if (pts_start != AV_NOPTS_VALUE) {
            AVPacket *sub;

            sub = ff_subtitles_queue_insert(&vplayer->q, p, strlen(p), 0);
            if (!sub)
                return AVERROR(ENOMEM);
            sub->pos = pos;
            sub->pts = pts_start;
            sub->duration = -1;
        }
    }

    ff_subtitles_queue_finalize(&vplayer->q);
    return 0;
}

static int vplayer_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    VPlayerContext *vplayer = s->priv_data;
    return ff_subtitles_queue_read_packet(&vplayer->q, pkt);
}

static int vplayer_read_seek(AVFormatContext *s, int stream_index,
                             int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
{
    VPlayerContext *vplayer = s->priv_data;
    return ff_subtitles_queue_seek(&vplayer->q, s, stream_index,
                                   min_ts, ts, max_ts, flags);
}

static int vplayer_read_close(AVFormatContext *s)
{
    VPlayerContext *vplayer = s->priv_data;
    ff_subtitles_queue_clean(&vplayer->q);
    return 0;
}

AVInputFormat ff_vplayer_demuxer = {
    .name           = "vplayer",
    .long_name      = NULL_IF_CONFIG_SMALL("VPlayer subtitles"),
    .priv_data_size = sizeof(VPlayerContext),
    .read_probe     = vplayer_probe,
    .read_header    = vplayer_read_header,
    .read_packet    = vplayer_read_packet,
    .read_seek2     = vplayer_read_seek,
    .read_close     = vplayer_read_close,
    .extensions     = "txt",
};
