/*
 *IDirect3DSwapChain9 implementation
 *
 *Copyright 2002-2003 Jason Edmeades
 *Copyright 2002-2003 Raphael Junqueira
 *Copyright 2005 Oliver Stieber
 *
 *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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "wined3d_private.h"


/* TODO: move to shared header (or context manager )*/
/* x11drv GDI escapes */
#define X11DRV_ESCAPE 6789
enum x11drv_escape_codes
{
    X11DRV_GET_DISPLAY,   /* get X11 display for a DC */
    X11DRV_GET_DRAWABLE,  /* get current drawable for a DC */
    X11DRV_GET_FONT,      /* get current X font for a DC */
};

/* retrieve the X display to use on a given DC */
inline static Display *get_display( HDC hdc )
{
    Display *display;
    enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;

    if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
                    sizeof(display), (LPSTR)&display )) display = NULL;
    return display;
}

/*TODO: some of the additional parameters may be required to
    set the gamma ramp (for some weird reason microsoft have left swap gammaramp in device
    but it operates on a swapchain, it may be a good idea to move it to IWineD3DSwapChain for IWineD3D)*/


WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(d3d_fps);


/* IDirect3DSwapChain IUnknown parts follow: */
ULONG WINAPI IWineD3DSwapChainImpl_AddRef(IWineD3DSwapChain *iface) {
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    DWORD refCount = InterlockedIncrement(&This->ref);
    TRACE("(%p) : AddRef increasing from %ld\n", This, refCount - 1);
    return refCount;
}

HRESULT WINAPI IWineD3DSwapChainImpl_QueryInterface(IWineD3DSwapChain *iface, REFIID riid, LPVOID *ppobj)
{
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppobj);
    if (IsEqualGUID(riid, &IID_IUnknown)
        || IsEqualGUID(riid, &IID_IWineD3DBase)
        || IsEqualGUID(riid, &IID_IWineD3DSwapChain)){
        IWineD3DSwapChainImpl_AddRef(iface);
        if(ppobj == NULL){
            ERR("Query interface called but now data allocated\n");
            return E_NOINTERFACE;
        }
        *ppobj = This;
        return D3D_OK;
    }
    return E_NOINTERFACE;
}


ULONG WINAPI IWineD3DSwapChainImpl_Release(IWineD3DSwapChain *iface) {
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    DWORD refCount;
    refCount = InterlockedDecrement(&This->ref);
    TRACE("(%p) : ReleaseRef to %ld\n", This, refCount);
    if (refCount == 0) {
        IUnknown* bufferParent;

        /* tell the device that we've been released */
        IWineD3DDevice_SwapChainReleased((IWineD3DDevice *)This->wineD3DDevice, iface);

        /* release the ref to the front and back buffer parents */
        IWineD3DSurface_SetContainer(This->frontBuffer, 0);
        IWineD3DSurface_GetParent(This->frontBuffer, &bufferParent);
        IUnknown_Release(bufferParent); /* once for the get parent */
        if(IUnknown_Release(bufferParent) > 0){
            FIXME("(%p) Something's still holding the front buffer\n",This);
        }

        IWineD3DSurface_SetContainer(This->backBuffer, 0);
        IWineD3DSurface_GetParent(This->backBuffer, &bufferParent);
        IUnknown_Release(bufferParent); /* once for the get parent */
        if(IUnknown_Release(bufferParent) > 0){
            FIXME("(%p) Something's still holding the back buffer\n",This);
        }
        /* Clean up the context */
        /* check that we are the current context first */
        if(glXGetCurrentContext() == This->glCtx){
            glXMakeCurrent(This->display, None, NULL);
        }
        glXDestroyContext(This->display, This->glCtx);
        /* IUnknown_Release(This->parent); This should only apply to the primary swapchain,
         all others are crated by the caller, so releasing the parent should cause
         the child to be released, not the other way around!
         */
        HeapFree(GetProcessHeap(), 0, This);
    }
    return refCount;
}

HRESULT WINAPI IWineD3DSwapChainImpl_GetParent(IWineD3DSwapChain *iface, IUnknown ** ppParent){
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    *ppParent = This->parent;
    IUnknown_AddRef(*ppParent);
    TRACE("(%p) returning %p\n", This , *ppParent);
    return D3D_OK;
}

/*IWineD3DSwapChain parts follow: */
HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) {
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;

    ENTER_GL();

    if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect);
    /* TODO: If only source rect or dest rect are supplied then clip the window to match */
    TRACE("preseting display %p, drawable %ld\n", This->display, This->drawable);

    /* Don't call checkGLcall, as glGetError is not applicable here */
    if (hDestWindowOverride && This->win_handle != hDestWindowOverride) {
        /* Set this swapchain up to point to the new destination.. */
#ifdef USE_CONTEXT_MANAGER
            /* TODO: use a context mamager */
#endif

            /* FIXME: Never access */
            IWineD3DSwapChainImpl *swapChainImpl;
            IWineD3DDevice_GetSwapChain((IWineD3DDevice *)This->wineD3DDevice, 0 , (IWineD3DSwapChain **)&swapChainImpl);
            FIXME("Unable to render to a destination window %p\n", hDestWindowOverride );
            if(This == swapChainImpl){
                /* FIXME: this will be fixed by moving to a context management system */
                FIXME("Cannot change the target of the implicit swapchain\n");
            }else{
                HDC               hDc;
                XVisualInfo       template;
                int               num;
                Display          *oldDisplay = This->display;
                GLXContext        oldContext = This->glCtx;
                IUnknown*         tmp;
                GLXContext        currentContext;
                Drawable          currentDrawable;
                hDc                          = GetDC(hDestWindowOverride);
                This->win_handle             = hDestWindowOverride;
                This->win                    = (Window)GetPropA( hDestWindowOverride, "__wine_x11_whole_window" );

                TRACE("Creating a new context for the window %p\n", hDestWindowOverride);
                ENTER_GL();
                TRACE("Desctroying context %p %p\n", This->display, This->render_ctx);



                LEAVE_GL();
                ENTER_GL();

                This->display    = get_display(hDc);
                TRACE("Got display%p  for  %p %p\n",  This->display, hDc, hDestWindowOverride);
                ReleaseDC(hDestWindowOverride, hDc);
                template.visualid = (VisualID)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
                This->visInfo   = XGetVisualInfo(This->display, VisualIDMask, &template, &num);
                if (NULL == This->visInfo) {
                    ERR("cannot really get XVisual\n");
                    LEAVE_GL();
                    return D3DERR_NOTAVAILABLE;
                }
                /* Now we have problems? well not really we just need to know what the implicit context is */
                /* now destroy the old context and create a new one (we should really copy the buffers over, and do the whole make current thing! */
                /* destroy the active context?*/
                TRACE("Creating new context for %p %p %p\n",This->display, This->visInfo, swapChainImpl->glCtx);
                This->glCtx = glXCreateContext(This->display, This->visInfo, swapChainImpl->glCtx, GL_TRUE);

                if (NULL == This->glCtx) {
                    ERR("cannot create glxContext\n");
                }
                This->drawable     = This->win;
                This->render_ctx   = This->glCtx;
                /* Setup some default states TODO: apply the stateblock to the new context */
                /** save current context and drawable **/
                currentContext  =   glXGetCurrentContext();
                currentDrawable =   glXGetCurrentDrawable();

                if (glXMakeCurrent(This->display, This->win, This->glCtx) == False) {
                    ERR("Error in setting current context (display %p context %p drawable %ld)!\n", This->display, This->glCtx, This->win);
                }

                checkGLcall("glXMakeCurrent");

                /* Clear the screen */
                glClearColor(0.0, 0.0, 0.0, 0.0);
                checkGLcall("glClearColor");
                glClearIndex(0);
                glClearDepth(1);
                glClearStencil(0);

                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
                checkGLcall("glClear");

                glColor3f(1.0, 1.0, 1.0);
                checkGLcall("glColor3f");

                glEnable(GL_LIGHTING);
                checkGLcall("glEnable");

                glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
                checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");

                glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
                checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");

                glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
                checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");

                /* If this swapchain is currently the active context then make this swapchain active */
                if(IWineD3DSurface_GetContainer(This->wineD3DDevice->renderTarget, &IID_IWineD3DSwapChain, (void **)&tmp) == D3D_OK){
                    if(tmp != (IUnknown *)This){
                        glXMakeCurrent(This->display, currentDrawable, currentContext);
                        checkGLcall("glXMakeCurrent");
                    }
                    IUnknown_Release(tmp);
                }else{
                    /* reset the context */
                    glXMakeCurrent(This->display, currentDrawable, currentContext);
                    checkGLcall("glXMakeCurrent");
                }
                /* delete the old contxt*/
                glXDestroyContext(oldDisplay, oldContext); /* Should this happen on an active context? seems a bad idea */
                LEAVE_GL();
            }
            IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapChainImpl);

        }


        /* TODO: The slow way, save the data to memory, create a new context for the destination window, transfer the data cleanup, it may be a good idea to the move this swapchain over to the using the target winows context so that it runs faster in feature. */

    glXSwapBuffers(This->display, This->drawable); /* TODO: cycle through the swapchain buffers */

    TRACE("glXSwapBuffers called, Starting new frame\n");
    /* FPS support */
    if (TRACE_ON(d3d_fps))
    {
        static long prev_time, frames;

        DWORD time = GetTickCount();
        frames++;
        /* every 1.5 seconds */
        if (time - prev_time > 1500) {
            TRACE_(d3d_fps)("@ approx %.2ffps\n", 1000.0*frames/(time - prev_time));
            prev_time = time;
            frames = 0;
        }
    }

#if defined(FRAME_DEBUGGING)
{
    if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES) {
        if (!isOn) {
            isOn = TRUE;
            FIXME("Enabling D3D Trace\n");
            __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 1);
#if defined(SHOW_FRAME_MAKEUP)
            FIXME("Singe Frame snapshots Starting\n");
            isDumpingFrames = TRUE;
            glClear(GL_COLOR_BUFFER_BIT);
#endif

#if defined(SINGLE_FRAME_DEBUGGING)
        } else {
#if defined(SHOW_FRAME_MAKEUP)
            FIXME("Singe Frame snapshots Finishing\n");
            isDumpingFrames = FALSE;
#endif
            FIXME("Singe Frame trace complete\n");
            DeleteFileA("C:\\D3DTRACE");
            __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
#endif
        }
    } else {
        if (isOn) {
            isOn = FALSE;
#if defined(SHOW_FRAME_MAKEUP)
            FIXME("Single Frame snapshots Finishing\n");
            isDumpingFrames = FALSE;
#endif
            FIXME("Disabling D3D Trace\n");
            __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
        }
    }
}
#endif

    LEAVE_GL();
    /* Although this is not strictly required, a simple demo showed this does occur
       on (at least non-debug) d3d                                                  */
    if (This->presentParms.SwapEffect & WINED3DSWAPEFFECT_DISCARD) {

        TRACE("Clearing\n");

        IWineD3DDevice_Clear((IWineD3DDevice*)This->wineD3DDevice, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0);

    } else {
        TRACE("Clearing z/stencil buffer\n");

        IWineD3DDevice_Clear((IWineD3DDevice*)This->wineD3DDevice, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER, 0x00, 1.0, 0);
    }

    TRACE("returning\n");
    return D3D_OK;
}

HRESULT WINAPI IWineD3DSwapChainImpl_GetFrontBufferData(IWineD3DSwapChain *iface, IWineD3DSurface *pDestSurface) {
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    WINED3DFORMAT d3dformat;
    UINT width;
    UINT height;
    WINED3DSURFACE_DESC desc;
    glDescriptor *glDescription;

    TRACE("(%p) : iface(%p) pDestSurface(%p)\n", This, iface, pDestSurface);
    ENTER_GL();
    memset(&desc, 0, sizeof(desc));
    desc.Width =  &width;
    desc.Height = &height;
    desc.Format = &d3dformat;
#if 0 /* TODO: make sure that this swapchains context is active */
    IWineD3DDevice_ActivateSwapChainContext(This->wineD3DDevice, iface);
#endif
    IWineD3DSurface_GetDesc(pDestSurface, &desc);
    /* make sure that the front buffer is the active read buffer */
    glReadBuffer(GL_FRONT);
    /* Read the pixels from the buffer into the surfaces memory */
    IWineD3DSurface_GetGlDesc(pDestSurface, &glDescription);
    glReadPixels(glDescription->target,
                glDescription->level,
                width,
                height,
                glDescription->glFormat,
                glDescription->glType,
                (void *)IWineD3DSurface_GetData(pDestSurface));
    LEAVE_GL();
    return D3D_OK;
}

HRESULT WINAPI IWineD3DSwapChainImpl_GetBackBuffer(IWineD3DSwapChain *iface, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IWineD3DSurface **ppBackBuffer) {

    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;

    *ppBackBuffer = This->backBuffer;
    TRACE("(%p) : BackBuf %d Type %d  returning %p\n", This, iBackBuffer, Type, *ppBackBuffer);

    if (iBackBuffer > This->presentParms.BackBufferCount - 1) {
        FIXME("Only one backBuffer currently supported\n");
        return D3DERR_INVALIDCALL;
    }

    /* Note inc ref on returned surface */
    IWineD3DSurface_AddRef(*ppBackBuffer);
    return D3D_OK;

}

HRESULT WINAPI IWineD3DSwapChainImpl_GetRasterStatus(IWineD3DSwapChain *iface, D3DRASTER_STATUS*pRasterStatus) {
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    static BOOL showFixmes = TRUE;
    pRasterStatus->InVBlank = TRUE;
    pRasterStatus->ScanLine = 0;
    /* No openGL equivalent */
    if(showFixmes) {
        FIXME("(%p) : stub (once)\n", This);
        showFixmes = FALSE;
    }
    return D3D_OK;
}

HRESULT WINAPI IWineD3DSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface, D3DDISPLAYMODE*pMode) {
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    HDC                 hdc;
    int                 bpp = 0;

    pMode->Width        = GetSystemMetrics(SM_CXSCREEN);
    pMode->Height       = GetSystemMetrics(SM_CYSCREEN);
    pMode->RefreshRate  = 85; /* FIXME: How to identify? */

    hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
    bpp = GetDeviceCaps(hdc, BITSPIXEL);
    DeleteDC(hdc);

    switch (bpp) {
    case  8: pMode->Format       = D3DFMT_R8G8B8; break;
    case 16: pMode->Format       = D3DFMT_R5G6B5; break;
    case 24: /*pMode->Format       = D3DFMT_R8G8B8; break; */ /* 32bpp and 24bpp can be aliased for X */
    case 32: pMode->Format       = D3DFMT_A8R8G8B8; break;
    default:
       FIXME("Unrecognized display mode format\n");
       pMode->Format       = D3DFMT_UNKNOWN;
    }

    TRACE("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate,
    pMode->Format, debug_d3dformat(pMode->Format));
    return D3D_OK;
}

HRESULT WINAPI IWineD3DSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice**ppDevice) {
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;

    *ppDevice = (IWineD3DDevice *) This->wineD3DDevice;

    /* Note  Calling this method will increase the internal reference count
       on the IDirect3DDevice9 interface. */
    IWineD3DDevice_AddRef(*ppDevice);
    TRACE("(%p) : returning %p\n", This, *ppDevice);
    return D3D_OK;
}

HRESULT WINAPI IWineD3DSwapChainImpl_GetPresentParameters(IWineD3DSwapChain *iface, WINED3DPRESENT_PARAMETERS *pPresentationParameters) {
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    TRACE("(%p)\n", This);
    *pPresentationParameters->BackBufferWidth = This->presentParms.BackBufferWidth;
    *pPresentationParameters->BackBufferHeight = This->presentParms.BackBufferHeight;
    *pPresentationParameters->BackBufferFormat = This->presentParms.BackBufferFormat;
    *pPresentationParameters->BackBufferCount = This->presentParms.BackBufferCount;
    *pPresentationParameters->MultiSampleType = This->presentParms.MultiSampleType;
    *pPresentationParameters->MultiSampleQuality = This->presentParms.MultiSampleQuality;
    *pPresentationParameters->SwapEffect = This->presentParms.SwapEffect;
    *pPresentationParameters->hDeviceWindow = This->presentParms.hDeviceWindow;
    *pPresentationParameters->Windowed = This->presentParms.Windowed;
    *pPresentationParameters->EnableAutoDepthStencil = This->presentParms.EnableAutoDepthStencil;
    *pPresentationParameters->Flags = This->presentParms.Flags;
    *pPresentationParameters->FullScreen_RefreshRateInHz = This->presentParms.FullScreen_RefreshRateInHz;
    *pPresentationParameters->PresentationInterval = This->presentParms.PresentationInterval;
    return D3D_OK;
}

HRESULT WINAPI IWineD3DSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface, DWORD Flags, CONST D3DGAMMARAMP *pRamp){

    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    HDC hDC;
    TRACE("(%p) : pRamp@%p flags(%ld)\n", This, pRamp, Flags);
    hDC = GetDC(This->win_handle);
    SetDeviceGammaRamp(hDC, (LPVOID)pRamp);
    ReleaseDC(This->win_handle, hDC);
    return D3D_OK;

}

HRESULT WINAPI IWineD3DSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface, D3DGAMMARAMP *pRamp){

    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    HDC hDC;
    TRACE("(%p) : pRamp@%p\n", This, pRamp);
    hDC = GetDC(This->win_handle);
    GetDeviceGammaRamp(hDC, pRamp);
    ReleaseDC(This->win_handle, hDC);
    return D3D_OK;

}


IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
{
    /* IUnknown */
    IWineD3DSwapChainImpl_QueryInterface,
    IWineD3DSwapChainImpl_AddRef,
    IWineD3DSwapChainImpl_Release,
    /* IWineD3DSwapChain */
    IWineD3DSwapChainImpl_GetParent,
    IWineD3DSwapChainImpl_GetDevice,
    IWineD3DSwapChainImpl_Present,
    IWineD3DSwapChainImpl_GetFrontBufferData,
    IWineD3DSwapChainImpl_GetBackBuffer,
    IWineD3DSwapChainImpl_GetRasterStatus,
    IWineD3DSwapChainImpl_GetDisplayMode,
    IWineD3DSwapChainImpl_GetPresentParameters,
    IWineD3DSwapChainImpl_SetGammaRamp,
    IWineD3DSwapChainImpl_GetGammaRamp
};
