/*	DirectDrawSurface HAL driver
 *
 * Copyright 2001 TransGaming Technologies Inc.
 *
 * 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 <assert.h>
#include <stdlib.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "wine/debug.h"
#include "ddraw_private.h"
#include "ddraw/user.h"
#include "ddraw/hal.h"
#include "dsurface/main.h"
#include "dsurface/dib.h"
#include "dsurface/user.h"
#include "dsurface/hal.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddraw);

static ICOM_VTABLE(IDirectDrawSurface7) HAL_IDirectDrawSurface7_VTable;

static HRESULT HAL_DirectDrawSurface_create_surface(IDirectDrawSurfaceImpl* This,
						    IDirectDrawImpl* pDD)
{
    HAL_PRIV_VAR(priv, This);
    HAL_DDRAW_PRIV_VAR(ddpriv, pDD);
    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = pDD->local.lpGbl;
    LPDDRAWI_DDRAWSURFACE_LCL local = &This->local;
    DDHAL_CREATESURFACEDATA data;
    HRESULT hr;

    data.lpDD = dd_gbl;
    data.lpDDSurfaceDesc = (LPDDSURFACEDESC)&This->surface_desc;
    data.lplpSList = &local;
    data.dwSCnt = 1;
    data.ddRVal = 0;
    data.CreateSurface = dd_gbl->lpDDCBtmp->HALDD.CreateSurface;
    hr = data.CreateSurface(&data);

    if (hr == DDHAL_DRIVER_HANDLED) {
	if (This->global.fpVidMem < 4) {
	    /* grab framebuffer data from current_mode */
	    priv->hal.fb_pitch = dd_gbl->vmiData.lDisplayPitch;
	    priv->hal.fb_vofs  = ddpriv->hal.next_vofs;
	    priv->hal.fb_addr  = ((LPBYTE)dd_gbl->vmiData.fpPrimary) +
				 dd_gbl->vmiData.lDisplayPitch * priv->hal.fb_vofs;
	    TRACE("vofs=%ld, addr=%p\n", priv->hal.fb_vofs, priv->hal.fb_addr);
	    ddpriv->hal.next_vofs += This->surface_desc.dwHeight;

	    This->global.fpVidMem = (FLATPTR)priv->hal.fb_addr;
	    This->global.u4.lPitch = priv->hal.fb_pitch;
	}
	This->surface_desc.lpSurface = (LPVOID)This->global.fpVidMem;
	This->surface_desc.dwFlags |= DDSD_LPSURFACE;
	if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER) {
	    This->surface_desc.u1.dwLinearSize = This->global.u4.dwLinearSize;
	    This->surface_desc.dwFlags |= DDSD_LINEARSIZE;
	} else {
	    This->surface_desc.u1.lPitch = This->global.u4.lPitch;
	    This->surface_desc.dwFlags |= DDSD_PITCH;
	}
    }
    else priv->hal.need_late = TRUE;

    return data.ddRVal;
}

static inline BOOL HAL_IsUser(IDirectDrawSurfaceImpl* This)
{
    HAL_PRIV_VAR(priv, This);
    if (This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_TEXTURE | DDSCAPS_EXECUTEBUFFER))
	return FALSE;
    if (priv->hal.fb_addr)
	return FALSE;
    return TRUE;
}

HRESULT
HAL_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This,
				IDirectDrawImpl* pDD,
				const DDSURFACEDESC2* pDDSD)
{
    HAL_PRIV_VAR(priv, This);
    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = pDD->local.lpGbl;
    HRESULT hr;

    TRACE("(%p,%p,%p)\n",This,pDD,pDDSD);

    /* copy surface_desc, we may want to modify it before DIB construction */
    This->surface_desc = *pDDSD;

    /* the driver may want to dereference these pointers */
    This->local.lpSurfMore = &This->more;
    This->local.lpGbl = &This->global;
    This->gmore = &This->global_more;

    if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) {
	hr = HAL_DirectDrawSurface_create_surface(This, pDD);
	if (FAILED(hr)) return hr;

	hr = DIB_DirectDrawSurface_Construct(This, pDD, &This->surface_desc);
	if (FAILED(hr)) return hr;
    }
    else if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER) {
	FIXME("create execute buffer\n");
	return DDERR_GENERIC;
    }
    else {
	if (!(dd_gbl->dwFlags & DDRAWI_MODECHANGED)) {
	    /* force a mode set (HALs like DGA may need it) */
	    hr = HAL_DirectDraw_SetDisplayMode(ICOM_INTERFACE(pDD, IDirectDraw7),
					       pDD->width, pDD->height,
					       pDD->pixelformat.u1.dwRGBBitCount,
					       0, 0);
	    if (FAILED(hr)) return hr;
	}

	if (dd_gbl->vmiData.fpPrimary) {
	    hr = HAL_DirectDrawSurface_create_surface(This, pDD);
	    if (FAILED(hr)) return hr;

	    if (priv->hal.need_late) {
		/* this doesn't make sense... driver error? */
		ERR("driver failed to create framebuffer surface\n");
		return DDERR_GENERIC;
	    }

	    hr = DIB_DirectDrawSurface_Construct(This, pDD, &This->surface_desc);
	    if (FAILED(hr)) return hr;
	} else {
	    /* no framebuffer, construct User-based primary */
	    hr = User_DirectDrawSurface_Construct(This, pDD, pDDSD);
	    if (FAILED(hr)) return hr;

	    /* must notify HAL *after* creating User-based primary */
	    /* (or use CreateSurfaceEx, which we don't yet) */
	    hr = HAL_DirectDrawSurface_create_surface(This, pDD);
	    if (FAILED(hr)) return hr;

	    priv->hal.need_late = FALSE;
	}
    }

    ICOM_INIT_INTERFACE(This, IDirectDrawSurface7,
			HAL_IDirectDrawSurface7_VTable);

    This->final_release = HAL_DirectDrawSurface_final_release;
    This->late_allocate = HAL_DirectDrawSurface_late_allocate;
    This->duplicate_surface = HAL_DirectDrawSurface_duplicate_surface;

    This->flip_data   = HAL_DirectDrawSurface_flip_data;
    This->flip_update = HAL_DirectDrawSurface_flip_update;

    This->set_palette    = HAL_DirectDrawSurface_set_palette;

    This->get_display_window = HAL_DirectDrawSurface_get_display_window;

    return DD_OK;
}

HRESULT
HAL_DirectDrawSurface_Create(IDirectDrawImpl *pDD,
			     const DDSURFACEDESC2 *pDDSD,
			     LPDIRECTDRAWSURFACE7 *ppSurf,
			     IUnknown *pUnkOuter)
{
    IDirectDrawSurfaceImpl* This;
    HRESULT hr;
    assert(pUnkOuter == NULL);

    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
		     sizeof(*This) + sizeof(HAL_DirectDrawSurfaceImpl));
    if (This == NULL) return E_OUTOFMEMORY;

    This->private = (HAL_DirectDrawSurfaceImpl*)(This+1);

    hr = HAL_DirectDrawSurface_Construct(This, pDD, pDDSD);
    if (FAILED(hr))
	HeapFree(GetProcessHeap(), 0, This);
    else
	*ppSurf = ICOM_INTERFACE(This, IDirectDrawSurface7);

    return hr;
}

void HAL_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This)
{
    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl;
    DDHAL_DESTROYSURFACEDATA data;

    /* destroy HAL surface */
    data.lpDD = dd_gbl;
    data.lpDDSurface = &This->local;
    data.ddRVal = 0;
    data.DestroySurface = dd_gbl->lpDDCBtmp->HALDDSurface.DestroySurface;
    data.DestroySurface(&data);

    if (HAL_IsUser(This)) {
	User_DirectDrawSurface_final_release(This);
    } else {
	DIB_DirectDrawSurface_final_release(This);
    }
}

HRESULT HAL_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl* This)
{
    HAL_PRIV_VAR(priv, This);
    if (priv->hal.need_late) {
	priv->hal.need_late = FALSE;
	return HAL_DirectDrawSurface_create_surface(This, This->ddraw_owner);
    }
    return DD_OK;
}

void HAL_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
				       IDirectDrawPaletteImpl* pal)
{
    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl;
    DDHAL_SETPALETTEDATA data;

    DIB_DirectDrawSurface_set_palette(This, pal);
    data.lpDD = dd_gbl;
    data.lpDDSurface = &This->local;
    data.lpDDPalette = (pal != NULL ? &pal->global : NULL);
    data.ddRVal = 0;
    data.Attach = TRUE; /* what's this? */
    data.SetPalette = dd_gbl->lpDDCBtmp->HALDDSurface.SetPalette;
    if (data.SetPalette)
	data.SetPalette(&data);
}

HRESULT HAL_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This,
						LPDIRECTDRAWSURFACE7* ppDup)
{
    return HAL_DirectDrawSurface_Create(This->ddraw_owner,
					     &This->surface_desc, ppDup, NULL);
}

void HAL_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This,
				       LPCRECT pRect, DWORD dwFlags)
{
    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl;
    DDHAL_LOCKDATA	data;

    data.lpDD		= dd_gbl;
    data.lpDDSurface	= &This->local;
    data.ddRVal		= 0;
    data.lpSurfData	= This->surface_desc.lpSurface; /* FIXME: correct? */
    if (pRect) {
	data.rArea.top	= pRect->top;
	data.rArea.bottom	= pRect->bottom;
	data.rArea.left	= pRect->left;
	data.rArea.right	= pRect->right;
	data.bHasRect 	= TRUE;
    } else {
	data.bHasRect 	= FALSE;
    }
    data.dwFlags	= dwFlags;

    data.Lock		= dd_gbl->lpDDCBtmp->HALDDSurface.Lock;
    if (data.Lock && (data.Lock(&data) == DDHAL_DRIVER_HANDLED))
	return;

    if (HAL_IsUser(This)) {
	User_DirectDrawSurface_lock_update(This, pRect, dwFlags);
    } else {
	Main_DirectDrawSurface_lock_update(This, pRect, dwFlags);
    }
}

void HAL_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
					 LPCRECT pRect)
{
    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl;
    DDHAL_UNLOCKDATA	data;

    data.lpDD		= dd_gbl;
    data.lpDDSurface	= &This->local;
    data.ddRVal		= 0;
    data.Unlock		= dd_gbl->lpDDCBtmp->HALDDSurface.Unlock;
    if (data.Unlock && (data.Unlock(&data) == DDHAL_DRIVER_HANDLED))
	return;

    if (HAL_IsUser(This)) {
	User_DirectDrawSurface_unlock_update(This, pRect);
    } else {
	Main_DirectDrawSurface_unlock_update(This, pRect);
    }
}

BOOL HAL_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
				     IDirectDrawSurfaceImpl* back,
				     DWORD dwFlags)
{
    HAL_PRIV_VAR(front_priv, front);
    HAL_PRIV_VAR(back_priv, back);
    LPDDRAWI_DIRECTDRAW_GBL dd_gbl = front->more.lpDD_lcl->lpGbl;
    DDHAL_FLIPDATA data;
    BOOL ret;

    {
	DWORD tmp;
	tmp = front_priv->hal.fb_vofs;
	front_priv->hal.fb_vofs = back_priv->hal.fb_vofs;
	back_priv->hal.fb_vofs = tmp;
    }
    {
	LPVOID tmp;
	tmp = front_priv->hal.fb_addr;
	front_priv->hal.fb_addr = back_priv->hal.fb_addr;
	back_priv->hal.fb_addr = tmp;
    }

    if (HAL_IsUser(front)) {
	ret = User_DirectDrawSurface_flip_data(front, back, dwFlags);
    } else {
	ret = DIB_DirectDrawSurface_flip_data(front, back, dwFlags);
    }

    TRACE("(%p,%p)\n",front,back);
    data.lpDD = dd_gbl;
    data.lpSurfCurr = &front->local;
    data.lpSurfTarg = &back->local;
    data.lpSurfCurrLeft = NULL;
    data.lpSurfTargLeft = NULL;
    data.dwFlags = dwFlags;
    data.ddRVal = 0;
    data.Flip = dd_gbl->lpDDCBtmp->HALDDSurface.Flip;
    if (data.Flip)
	if (data.Flip(&data) == DDHAL_DRIVER_HANDLED) ret = FALSE;

    return ret;
}

void HAL_DirectDrawSurface_flip_update(IDirectDrawSurfaceImpl* This, DWORD dwFlags)
{
    if (HAL_IsUser(This)) {
	User_DirectDrawSurface_flip_update(This, dwFlags);
    }
}

HWND HAL_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This)
{
    return 0;
}

static ICOM_VTABLE(IDirectDrawSurface7) HAL_IDirectDrawSurface7_VTable =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    Main_DirectDrawSurface_QueryInterface,
    Main_DirectDrawSurface_AddRef,
    Main_DirectDrawSurface_Release,
    Main_DirectDrawSurface_AddAttachedSurface,
    Main_DirectDrawSurface_AddOverlayDirtyRect,
    DIB_DirectDrawSurface_Blt,
    Main_DirectDrawSurface_BltBatch,
    DIB_DirectDrawSurface_BltFast,
    Main_DirectDrawSurface_DeleteAttachedSurface,
    Main_DirectDrawSurface_EnumAttachedSurfaces,
    Main_DirectDrawSurface_EnumOverlayZOrders,
    Main_DirectDrawSurface_Flip,
    Main_DirectDrawSurface_GetAttachedSurface,
    Main_DirectDrawSurface_GetBltStatus,
    Main_DirectDrawSurface_GetCaps,
    Main_DirectDrawSurface_GetClipper,
    Main_DirectDrawSurface_GetColorKey,
    Main_DirectDrawSurface_GetDC,
    Main_DirectDrawSurface_GetFlipStatus,
    Main_DirectDrawSurface_GetOverlayPosition,
    Main_DirectDrawSurface_GetPalette,
    Main_DirectDrawSurface_GetPixelFormat,
    Main_DirectDrawSurface_GetSurfaceDesc,
    Main_DirectDrawSurface_Initialize,
    Main_DirectDrawSurface_IsLost,
    Main_DirectDrawSurface_Lock,
    Main_DirectDrawSurface_ReleaseDC,
    DIB_DirectDrawSurface_Restore,
    Main_DirectDrawSurface_SetClipper,
    Main_DirectDrawSurface_SetColorKey,
    Main_DirectDrawSurface_SetOverlayPosition,
    Main_DirectDrawSurface_SetPalette,
    Main_DirectDrawSurface_Unlock,
    Main_DirectDrawSurface_UpdateOverlay,
    Main_DirectDrawSurface_UpdateOverlayDisplay,
    Main_DirectDrawSurface_UpdateOverlayZOrder,
    Main_DirectDrawSurface_GetDDInterface,
    Main_DirectDrawSurface_PageLock,
    Main_DirectDrawSurface_PageUnlock,
    DIB_DirectDrawSurface_SetSurfaceDesc,
    Main_DirectDrawSurface_SetPrivateData,
    Main_DirectDrawSurface_GetPrivateData,
    Main_DirectDrawSurface_FreePrivateData,
    Main_DirectDrawSurface_GetUniquenessValue,
    Main_DirectDrawSurface_ChangeUniquenessValue,
    Main_DirectDrawSurface_SetPriority,
    Main_DirectDrawSurface_GetPriority,
    Main_DirectDrawSurface_SetLOD,
    Main_DirectDrawSurface_GetLOD
};
