/*
 * Generic Implementation of strmbase video classes
 *
 * Copyright 2012 Aric Stewart, CodeWeavers
 *
 * This library 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.
 *
 * This library 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 this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define COBJMACROS

#include <assert.h>
#include "dshow.h"
#include "uuids.h"
#include "vfwmsgs.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "wine/strmbase.h"

WINE_DEFAULT_DEBUG_CHANNEL(strmbase);

static inline BaseControlVideo *impl_from_IBasicVideo(IBasicVideo *iface)
{
    return CONTAINING_RECORD(iface, BaseControlVideo, IBasicVideo_iface);
}

HRESULT WINAPI BaseControlVideo_Init(BaseControlVideo *pControlVideo, const IBasicVideoVtbl *lpVtbl, BaseFilter *owner, CRITICAL_SECTION *lock, BasePin* pPin, const BaseControlVideoFuncTable* pFuncsTable)
{
    pControlVideo->IBasicVideo_iface.lpVtbl = lpVtbl;
    pControlVideo->pFilter = owner;
    pControlVideo->pInterfaceLock = lock;
    pControlVideo->pPin = pPin;
    pControlVideo->pFuncsTable = pFuncsTable;

    BaseDispatch_Init(&pControlVideo->baseDispatch, &IID_IBasicVideo);

    return S_OK;
}

HRESULT WINAPI BaseControlVideo_Destroy(BaseControlVideo *pControlVideo)
{
    return BaseDispatch_Destroy(&pControlVideo->baseDispatch);
}

HRESULT WINAPI BaseControlVideoImpl_GetTypeInfoCount(IBasicVideo *iface, UINT *pctinfo)
{
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    return BaseDispatchImpl_GetTypeInfoCount(&This->baseDispatch, pctinfo);
}

HRESULT WINAPI BaseControlVideoImpl_GetTypeInfo(IBasicVideo *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    return BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, &IID_NULL, iTInfo, lcid, ppTInfo);
}

HRESULT WINAPI BaseControlVideoImpl_GetIDsOfNames(IBasicVideo *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    return BaseDispatchImpl_GetIDsOfNames(&This->baseDispatch, riid, rgszNames, cNames, lcid, rgDispId);
}

HRESULT WINAPI BaseControlVideoImpl_Invoke(IBasicVideo *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, UINT *puArgErr)
{
    BaseControlVideo *This = impl_from_IBasicVideo(iface);
    HRESULT hr = S_OK;
    ITypeInfo *pTypeInfo;

    hr = BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, riid, 1, lcid, &pTypeInfo);
    if (SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke(pTypeInfo, &This->IBasicVideo_iface, dispIdMember, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
        ITypeInfo_Release(pTypeInfo);
    }

    return hr;
}

HRESULT WINAPI BaseControlVideoImpl_get_AvgTimePerFrame(IBasicVideo *iface, REFTIME *pAvgTimePerFrame)
{
    VIDEOINFOHEADER *vih;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    if (!This->pPin->pConnectedTo)
        return VFW_E_NOT_CONNECTED;

    TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame);

    vih = This->pFuncsTable->pfnGetVideoFormat(This);
    *pAvgTimePerFrame = vih->AvgTimePerFrame;
    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_get_BitRate(IBasicVideo *iface, LONG *pBitRate)
{
    VIDEOINFOHEADER *vih;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%p)\n", This, iface, pBitRate);

    if (!This->pPin->pConnectedTo)
        return VFW_E_NOT_CONNECTED;

    vih = This->pFuncsTable->pfnGetVideoFormat(This);
    *pBitRate = vih->dwBitRate;
    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_get_BitErrorRate(IBasicVideo *iface, LONG *pBitErrorRate)
{
    VIDEOINFOHEADER *vih;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%p)\n", This, iface, pBitErrorRate);

    if (!This->pPin->pConnectedTo)
        return VFW_E_NOT_CONNECTED;

    vih = This->pFuncsTable->pfnGetVideoFormat(This);
    *pBitErrorRate = vih->dwBitErrorRate;
    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_get_VideoWidth(IBasicVideo *iface, LONG *pVideoWidth)
{
    VIDEOINFOHEADER *vih;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth);

    vih = This->pFuncsTable->pfnGetVideoFormat(This);
    *pVideoWidth = vih->bmiHeader.biWidth;

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_get_VideoHeight(IBasicVideo *iface, LONG *pVideoHeight)
{
    VIDEOINFOHEADER *vih;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight);

    vih = This->pFuncsTable->pfnGetVideoFormat(This);
    *pVideoHeight = abs(vih->bmiHeader.biHeight);

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_put_SourceLeft(IBasicVideo *iface, LONG SourceLeft)
{
    RECT SourceRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%d)\n", This, iface, SourceLeft);
    This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
    SourceRect.left = SourceLeft;
    This->pFuncsTable->pfnSetSourceRect(This, &SourceRect);

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_get_SourceLeft(IBasicVideo *iface, LONG *pSourceLeft)
{
    RECT SourceRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft);
    This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
    *pSourceLeft = SourceRect.left;

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_put_SourceWidth(IBasicVideo *iface, LONG SourceWidth)
{
    RECT SourceRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%d)\n", This, iface, SourceWidth);
    This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
    SourceRect.right = SourceRect.left + SourceWidth;
    This->pFuncsTable->pfnSetSourceRect(This, &SourceRect);

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_get_SourceWidth(IBasicVideo *iface, LONG *pSourceWidth)
{
    RECT SourceRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth);
    This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
    *pSourceWidth = SourceRect.right - SourceRect.left;

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_put_SourceTop(IBasicVideo *iface, LONG SourceTop)
{
    RECT SourceRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%d)\n", This, iface, SourceTop);
    This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
    SourceRect.top = SourceTop;
    This->pFuncsTable->pfnSetSourceRect(This, &SourceRect);

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_get_SourceTop(IBasicVideo *iface, LONG *pSourceTop)
{
    RECT SourceRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop);
    This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
    *pSourceTop = SourceRect.top;

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_put_SourceHeight(IBasicVideo *iface, LONG SourceHeight)
{
    RECT SourceRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%d)\n", This, iface, SourceHeight);
    This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);
    SourceRect.bottom = SourceRect.top + SourceHeight;
    This->pFuncsTable->pfnSetSourceRect(This, &SourceRect);

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_get_SourceHeight(IBasicVideo *iface, LONG *pSourceHeight)
{
    RECT SourceRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight);
    This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);

    *pSourceHeight = SourceRect.bottom - SourceRect.top;

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_put_DestinationLeft(IBasicVideo *iface, LONG DestinationLeft)
{
    RECT DestRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%d)\n", This, iface, DestinationLeft);
    This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
    DestRect.left = DestinationLeft;
    This->pFuncsTable->pfnSetTargetRect(This, &DestRect);

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_get_DestinationLeft(IBasicVideo *iface, LONG *pDestinationLeft)
{
    RECT DestRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft);
    This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
    *pDestinationLeft = DestRect.left;

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_put_DestinationWidth(IBasicVideo *iface, LONG DestinationWidth)
{
    RECT DestRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%d)\n", This, iface, DestinationWidth);
    This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
    DestRect.right = DestRect.left + DestinationWidth;
    This->pFuncsTable->pfnSetTargetRect(This, &DestRect);

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_get_DestinationWidth(IBasicVideo *iface, LONG *pDestinationWidth)
{
    RECT DestRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth);
    This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
    *pDestinationWidth = DestRect.right - DestRect.left;

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_put_DestinationTop(IBasicVideo *iface, LONG DestinationTop)
{
    RECT DestRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%d)\n", This, iface, DestinationTop);
    This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
    DestRect.top = DestinationTop;
    This->pFuncsTable->pfnSetTargetRect(This, &DestRect);

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_get_DestinationTop(IBasicVideo *iface, LONG *pDestinationTop)
{
    RECT DestRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop);
    This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
    *pDestinationTop = DestRect.top;

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_put_DestinationHeight(IBasicVideo *iface, LONG DestinationHeight)
{
    RECT DestRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%d)\n", This, iface, DestinationHeight);
    This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
    DestRect.right = DestRect.left + DestinationHeight;
    This->pFuncsTable->pfnSetTargetRect(This, &DestRect);

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_get_DestinationHeight(IBasicVideo *iface, LONG *pDestinationHeight)
{
    RECT DestRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight);
    This->pFuncsTable->pfnGetTargetRect(This, &DestRect);
    *pDestinationHeight = DestRect.right - DestRect.left;

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_SetSourcePosition(IBasicVideo *iface, LONG Left, LONG Top, LONG Width, LONG Height)
{
    RECT SourceRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height);
    SourceRect.left = Left;
    SourceRect.top = Top;
    SourceRect.right = Left + Width;
    SourceRect.bottom = Top + Height;
    This->pFuncsTable->pfnSetSourceRect(This, &SourceRect);

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_GetSourcePosition(IBasicVideo *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight)
{
    RECT SourceRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
    This->pFuncsTable->pfnGetSourceRect(This, &SourceRect);

    *pLeft = SourceRect.left;
    *pTop = SourceRect.top;
    *pWidth = SourceRect.right - SourceRect.left;
    *pHeight = SourceRect.bottom - SourceRect.top;

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_SetDefaultSourcePosition(IBasicVideo *iface)
{
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->()\n", This, iface);
    return This->pFuncsTable->pfnSetDefaultSourceRect(This);
}

HRESULT WINAPI BaseControlVideoImpl_SetDestinationPosition(IBasicVideo *iface, LONG Left, LONG Top, LONG Width, LONG Height)
{
    RECT DestRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height);

    DestRect.left = Left;
    DestRect.top = Top;
    DestRect.right = Left + Width;
    DestRect.bottom = Top + Height;
    This->pFuncsTable->pfnSetTargetRect(This, &DestRect);

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_GetDestinationPosition(IBasicVideo *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight)
{
    RECT DestRect;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
    This->pFuncsTable->pfnGetTargetRect(This, &DestRect);

    *pLeft = DestRect.left;
    *pTop = DestRect.top;
    *pWidth = DestRect.right - DestRect.left;
    *pHeight = DestRect.bottom - DestRect.top;

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_SetDefaultDestinationPosition(IBasicVideo *iface)
{
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->()\n", This, iface);
    return This->pFuncsTable->pfnSetDefaultTargetRect(This);
}

HRESULT WINAPI BaseControlVideoImpl_GetVideoSize(IBasicVideo *iface, LONG *pWidth, LONG *pHeight)
{
    VIDEOINFOHEADER *vih;
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);

    vih = This->pFuncsTable->pfnGetVideoFormat(This);
    *pHeight = vih->bmiHeader.biHeight;
    *pWidth = vih->bmiHeader.biWidth;

    return S_OK;
}

HRESULT WINAPI BaseControlVideoImpl_GetVideoPaletteEntries(IBasicVideo *iface, LONG StartIndex, LONG Entries, LONG *pRetrieved, LONG *pPalette)
{
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    TRACE("(%p/%p)->(%d, %d, %p, %p)\n", This, iface, StartIndex, Entries, pRetrieved, pPalette);

    if (pRetrieved)
        *pRetrieved = 0;
    return VFW_E_NO_PALETTE_AVAILABLE;
}

HRESULT WINAPI BaseControlVideoImpl_GetCurrentImage(IBasicVideo *iface, LONG *pBufferSize, LONG *pDIBImage)
{
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    return This->pFuncsTable->pfnGetStaticImage(This, pBufferSize, pDIBImage);
}

HRESULT WINAPI BaseControlVideoImpl_IsUsingDefaultSource(IBasicVideo *iface)
{
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    return This->pFuncsTable->pfnIsDefaultSourceRect(This);
}

HRESULT WINAPI BaseControlVideoImpl_IsUsingDefaultDestination(IBasicVideo *iface)
{
    BaseControlVideo *This = impl_from_IBasicVideo(iface);

    return This->pFuncsTable->pfnIsDefaultTargetRect(This);
}
