/*
 *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_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_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_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 & D3DSWAPEFFECT_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, D3DPRESENT_PARAMETERS *pPresentationParameters) {
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    FIXME("(%p) : copy\n", This);
    memcpy(pPresentationParameters, &This->presentParms, sizeof(D3DPRESENT_PARAMETERS));
    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
};
