/*
 * DirectShow capture interface
 * Copyright (c) 2010 Ramiro Polla
 *
 * 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
 */

#include "dshow_capture.h"

DECLARE_QUERYINTERFACE(libAVFilter,
    { {&IID_IUnknown,0}, {&IID_IBaseFilter,0} })
DECLARE_ADDREF(libAVFilter)
DECLARE_RELEASE(libAVFilter)

long WINAPI
libAVFilter_GetClassID(libAVFilter *this, CLSID *id)
{
    dshowdebug("libAVFilter_GetClassID(%p)\n", this);
    /* I'm not creating a ClassID just for this. */
    return E_FAIL;
}
long WINAPI
libAVFilter_Stop(libAVFilter *this)
{
    dshowdebug("libAVFilter_Stop(%p)\n", this);
    this->state = State_Stopped;
    return S_OK;
}
long WINAPI
libAVFilter_Pause(libAVFilter *this)
{
    dshowdebug("libAVFilter_Pause(%p)\n", this);
    this->state = State_Paused;
    return S_OK;
}
long WINAPI
libAVFilter_Run(libAVFilter *this, REFERENCE_TIME start)
{
    dshowdebug("libAVFilter_Run(%p) %"PRId64"\n", this, start);
    this->state = State_Running;
    this->start_time = start;
    return S_OK;
}
long WINAPI
libAVFilter_GetState(libAVFilter *this, DWORD ms, FILTER_STATE *state)
{
    dshowdebug("libAVFilter_GetState(%p)\n", this);
    if (!state)
        return E_POINTER;
    *state = this->state;
    return S_OK;
}
long WINAPI
libAVFilter_SetSyncSource(libAVFilter *this, IReferenceClock *clock)
{
    dshowdebug("libAVFilter_SetSyncSource(%p)\n", this);

    if (this->clock != clock) {
        if (this->clock)
            IReferenceClock_Release(this->clock);
        this->clock = clock;
        if (clock)
            IReferenceClock_AddRef(clock);
    }

    return S_OK;
}
long WINAPI
libAVFilter_GetSyncSource(libAVFilter *this, IReferenceClock **clock)
{
    dshowdebug("libAVFilter_GetSyncSource(%p)\n", this);

    if (!clock)
        return E_POINTER;
    if (this->clock)
        IReferenceClock_AddRef(this->clock);
    *clock = this->clock;

    return S_OK;
}
long WINAPI
libAVFilter_EnumPins(libAVFilter *this, IEnumPins **enumpin)
{
    libAVEnumPins *new;
    dshowdebug("libAVFilter_EnumPins(%p)\n", this);

    if (!enumpin)
        return E_POINTER;
    new = libAVEnumPins_Create(this->pin, this);
    if (!new)
        return E_OUTOFMEMORY;

    *enumpin = (IEnumPins *) new;
    return S_OK;
}
long WINAPI
libAVFilter_FindPin(libAVFilter *this, const wchar_t *id, IPin **pin)
{
    libAVPin *found = NULL;
    dshowdebug("libAVFilter_FindPin(%p)\n", this);

    if (!id || !pin)
        return E_POINTER;
    if (!wcscmp(id, L"In")) {
        found = this->pin;
        libAVPin_AddRef(found);
    }
    *pin = (IPin *) found;
    if (!found)
        return VFW_E_NOT_FOUND;

    return S_OK;
}
long WINAPI
libAVFilter_QueryFilterInfo(libAVFilter *this, FILTER_INFO *info)
{
    dshowdebug("libAVFilter_QueryFilterInfo(%p)\n", this);

    if (!info)
        return E_POINTER;
    if (this->info.pGraph)
        IFilterGraph_AddRef(this->info.pGraph);
    *info = this->info;

    return S_OK;
}
long WINAPI
libAVFilter_JoinFilterGraph(libAVFilter *this, IFilterGraph *graph,
                            const wchar_t *name)
{
    dshowdebug("libAVFilter_JoinFilterGraph(%p)\n", this);

    this->info.pGraph = graph;
    if (name)
        wcscpy(this->info.achName, name);

    return S_OK;
}
long WINAPI
libAVFilter_QueryVendorInfo(libAVFilter *this, wchar_t **info)
{
    dshowdebug("libAVFilter_QueryVendorInfo(%p)\n", this);

    if (!info)
        return E_POINTER;
    return E_NOTIMPL; /* don't have to do anything here */
}

static int
libAVFilter_Setup(libAVFilter *this, void *priv_data, void *callback,
                  enum dshowDeviceType type)
{
    IBaseFilterVtbl *vtbl = this->vtbl;
    SETVTBL(vtbl, libAVFilter, QueryInterface);
    SETVTBL(vtbl, libAVFilter, AddRef);
    SETVTBL(vtbl, libAVFilter, Release);
    SETVTBL(vtbl, libAVFilter, GetClassID);
    SETVTBL(vtbl, libAVFilter, Stop);
    SETVTBL(vtbl, libAVFilter, Pause);
    SETVTBL(vtbl, libAVFilter, Run);
    SETVTBL(vtbl, libAVFilter, GetState);
    SETVTBL(vtbl, libAVFilter, SetSyncSource);
    SETVTBL(vtbl, libAVFilter, GetSyncSource);
    SETVTBL(vtbl, libAVFilter, EnumPins);
    SETVTBL(vtbl, libAVFilter, FindPin);
    SETVTBL(vtbl, libAVFilter, QueryFilterInfo);
    SETVTBL(vtbl, libAVFilter, JoinFilterGraph);
    SETVTBL(vtbl, libAVFilter, QueryVendorInfo);

    this->pin = libAVPin_Create(this);

    this->priv_data = priv_data;
    this->callback  = callback;
    this->type      = type;

    return 1;
}
static int
libAVFilter_Cleanup(libAVFilter *this)
{
    libAVPin_Release(this->pin);
    return 1;
}
DECLARE_CREATE(libAVFilter, libAVFilter_Setup(this, priv_data, callback, type),
               void *priv_data, void *callback, enum dshowDeviceType type)
DECLARE_DESTROY(libAVFilter, libAVFilter_Cleanup)
