// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "FrameBufferDD.hpp"

#include "Debug.hpp"

namespace sw
{
	extern bool forceWindowed;

	GUID secondaryDisplay = {0};

	int __stdcall enumDisplayCallback(GUID* guid, char *driverDescription, char *driverName, void *context, HMONITOR monitor)
	{
		if(strcmp(driverName, "\\\\.\\DISPLAY2") == 0)
		{
			secondaryDisplay = *guid;
		}

		return 1;
	}

	FrameBufferDD::FrameBufferDD(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin) : FrameBufferWin(windowHandle, width, height, fullscreen, topLeftOrigin)
	{
		directDraw = 0;
		frontBuffer = 0;
		backBuffer = 0;

		locked = 0;

		ddraw = LoadLibrary("ddraw.dll");
		DirectDrawCreate = (DIRECTDRAWCREATE)GetProcAddress(ddraw, "DirectDrawCreate");
		DirectDrawEnumerateExA = (DIRECTDRAWENUMERATEEXA)GetProcAddress(ddraw, "DirectDrawEnumerateExA");

		if(!windowed)
		{
			initFullscreen();
		}
		else
		{
			initWindowed();
		}
	}

	FrameBufferDD::~FrameBufferDD()
	{
		releaseAll();

		FreeLibrary(ddraw);
	}

	void FrameBufferDD::createSurfaces()
	{
		if(backBuffer)
		{
			backBuffer->Release();
			backBuffer = 0;
		}

		if(frontBuffer)
		{
			frontBuffer->Release();
			frontBuffer = 0;
		}

		if(!windowed)
		{
			DDSURFACEDESC surfaceDescription = {0};
			surfaceDescription.dwSize = sizeof(surfaceDescription);
			surfaceDescription.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
			surfaceDescription.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
			surfaceDescription.dwBackBufferCount = 1;
			long result = directDraw->CreateSurface(&surfaceDescription, &frontBuffer, 0);

			if(frontBuffer)
			{
				DDSCAPS surfaceCapabilties = {0};
				surfaceCapabilties.dwCaps = DDSCAPS_BACKBUFFER;
				frontBuffer->GetAttachedSurface(&surfaceCapabilties, &backBuffer);
				backBuffer->AddRef();
			}
		}
		else
		{
			IDirectDrawClipper *clipper;

			DDSURFACEDESC ddsd = {0};
			ddsd.dwSize = sizeof(ddsd);
			ddsd.dwFlags = DDSD_CAPS;
			ddsd.ddsCaps.dwCaps	= DDSCAPS_PRIMARYSURFACE;

			long result = directDraw->CreateSurface(&ddsd, &frontBuffer, 0);
			directDraw->GetDisplayMode(&ddsd);

			switch(ddsd.ddpfPixelFormat.dwRGBBitCount)
			{
			case 32: destFormat = FORMAT_X8R8G8B8; break;
			case 24: destFormat = FORMAT_R8G8B8;   break;
			case 16: destFormat = FORMAT_R5G6B5;   break;
			default: destFormat = FORMAT_NULL;     break;
			}

			if((result != DD_OK && result != DDERR_PRIMARYSURFACEALREADYEXISTS) || (destFormat == FORMAT_NULL))
			{
				assert(!"Failed to initialize graphics: Incompatible display mode.");
			}
			else
			{
				ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
				ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
				ddsd.dwWidth = width;
				ddsd.dwHeight = height;

				directDraw->CreateSurface(&ddsd, &backBuffer, 0);

				directDraw->CreateClipper(0, &clipper, 0);
				clipper->SetHWnd(0, windowHandle);
				frontBuffer->SetClipper(clipper);
				clipper->Release();
			}
		}
	}

	bool FrameBufferDD::readySurfaces()
	{
		if(!frontBuffer || !backBuffer)
		{
			createSurfaces();
		}

		if(frontBuffer && backBuffer)
		{
			if(frontBuffer->IsLost() || backBuffer->IsLost())
			{
				restoreSurfaces();
			}

			if(frontBuffer && backBuffer)
			{
				if(!frontBuffer->IsLost() && !backBuffer->IsLost())
				{
					return true;
				}
			}
		}

		return false;
	}

	void FrameBufferDD::updateClipper(HWND windowOverride)
	{
		if(windowed)
		{
			if(frontBuffer)
			{
				HWND window = windowOverride ? windowOverride : windowHandle;

				IDirectDrawClipper *clipper;
				frontBuffer->GetClipper(&clipper);
				clipper->SetHWnd(0, window);
				clipper->Release();
			}
		}
	}

	void FrameBufferDD::restoreSurfaces()
	{
		long result1 = frontBuffer->Restore();
		long result2 = backBuffer->Restore();

		if(result1 != DD_OK || result2 != DD_OK)   // Surfaces could not be restored; recreate them
		{
			createSurfaces();
		}
	}

	void FrameBufferDD::initFullscreen()
	{
		releaseAll();

		if(true)   // Render to primary display
		{
			DirectDrawCreate(0, &directDraw, 0);
		}
		else   // Render to secondary display
		{
			DirectDrawEnumerateEx(&enumDisplayCallback, 0, DDENUM_ATTACHEDSECONDARYDEVICES);
			DirectDrawCreate(&secondaryDisplay, &directDraw, 0);
		}

		directDraw->SetCooperativeLevel(windowHandle, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);

		long result;

		do
		{
			destFormat = FORMAT_X8R8G8B8;
			result = directDraw->SetDisplayMode(width, height, 32);

			if(result == DDERR_INVALIDMODE)
			{
				destFormat = FORMAT_R8G8B8;
				result = directDraw->SetDisplayMode(width, height, 24);

				if(result == DDERR_INVALIDMODE)
				{
					destFormat = FORMAT_R5G6B5;
					result = directDraw->SetDisplayMode(width, height, 16);

					if(result == DDERR_INVALIDMODE)
					{
						assert(!"Failed to initialize graphics: Display mode not supported.");
					}
				}
			}

			if(result != DD_OK)
			{
				Sleep(1);
			}
		}
		while(result != DD_OK);

		createSurfaces();

		updateBounds(windowHandle);
	}

	void FrameBufferDD::initWindowed()
	{
		releaseAll();

		DirectDrawCreate(0, &directDraw, 0);
		directDraw->SetCooperativeLevel(windowHandle, DDSCL_NORMAL);

		createSurfaces();

		updateBounds(windowHandle);
	}

	void FrameBufferDD::flip(void *source, Format sourceFormat, size_t sourceStride)
	{
		copy(source, sourceFormat, sourceStride);

		if(!readySurfaces())
		{
			return;
		}

		while(true)
		{
			long result;

			if(windowed)
			{
				result = frontBuffer->Blt(&bounds, backBuffer, 0, DDBLT_WAIT, 0);
			}
			else
			{
				result = frontBuffer->Flip(0, DDFLIP_NOVSYNC);
			}

			if(result != DDERR_WASSTILLDRAWING)
			{
				break;
			}

			Sleep(0);
		}
	}

	void FrameBufferDD::blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride)
	{
		copy(source, sourceFormat, sourceStride);

		if(!readySurfaces())
		{
			return;
		}

		RECT dRect;

		if(destRect)
		{
			dRect.bottom = bounds.top + destRect->y1;
			dRect.left = bounds.left + destRect->x0;
			dRect.right = bounds.left + destRect->x1;
			dRect.top = bounds.top + destRect->y0;
		}
		else
		{
			dRect.bottom = bounds.top + height;
			dRect.left = bounds.left + 0;
			dRect.right = bounds.left + width;
			dRect.top = bounds.top + 0;
		}

		while(true)
		{
			long result = frontBuffer->Blt(&dRect, backBuffer, (LPRECT)sourceRect, DDBLT_WAIT, 0);

			if(result != DDERR_WASSTILLDRAWING)
			{
				break;
			}

			Sleep(0);
		}
	}

	void FrameBufferDD::flip(HWND windowOverride, void *source, Format sourceFormat, size_t sourceStride)
	{
		updateClipper(windowOverride);
		updateBounds(windowOverride);

		flip(source, sourceFormat, sourceStride);
	}

	void FrameBufferDD::blit(HWND windowOverride, void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride)
	{
		updateClipper(windowOverride);
		updateBounds(windowOverride);

		blit(source, sourceRect, destRect, sourceFormat, sourceStride);
	}

	void FrameBufferDD::screenshot(void *destBuffer)
	{
		if(!readySurfaces())
		{
			return;
		}

		DDSURFACEDESC DDSD;
		DDSD.dwSize = sizeof(DDSD);

		long result = frontBuffer->Lock(0, &DDSD, DDLOCK_WAIT, 0);

		if(result == DD_OK)
		{
			int width = DDSD.dwWidth;
			int height = DDSD.dwHeight;
			int bitDepth = DDSD.ddpfPixelFormat.dwRGBBitCount;
			int stride = DDSD.lPitch;

			void *sourceBuffer = DDSD.lpSurface;

			for(int y = 0; y < height; y++)
			{
				memcpy(destBuffer, sourceBuffer, width * 4);   // FIXME: Assumes 32-bit buffer

				(char*&)sourceBuffer += stride;
				(char*&)destBuffer += 4 * width;
			}

			frontBuffer->Unlock(0);
		}
	}

	void FrameBufferDD::setGammaRamp(GammaRamp *gammaRamp, bool calibrate)
	{
		IDirectDrawGammaControl *gammaControl = 0;

		if(frontBuffer)
		{
			frontBuffer->QueryInterface(IID_IDirectDrawGammaControl, (void**)&gammaControl);

			if(gammaControl)
			{
				gammaControl->SetGammaRamp(calibrate ? DDSGR_CALIBRATE : 0, (DDGAMMARAMP*)gammaRamp);

				gammaControl->Release();
			}
		}
	}

	void FrameBufferDD::getGammaRamp(GammaRamp *gammaRamp)
	{
		IDirectDrawGammaControl *gammaControl = 0;

		if(frontBuffer)
		{
			frontBuffer->QueryInterface(IID_IDirectDrawGammaControl, (void**)&gammaControl);

			if(gammaControl)
			{
				gammaControl->GetGammaRamp(0, (DDGAMMARAMP*)gammaRamp);

				gammaControl->Release();
			}
		}
	}

	void *FrameBufferDD::lock()
	{
		if(locked)
		{
			return locked;
		}

		if(!readySurfaces())
		{
			return 0;
		}

		DDSURFACEDESC DDSD;
		DDSD.dwSize = sizeof(DDSD);

		long result = backBuffer->Lock(0, &DDSD, DDLOCK_WAIT, 0);

		if(result == DD_OK)
		{
			width = DDSD.dwWidth;
			height = DDSD.dwHeight;
			int bitDepth = DDSD.ddpfPixelFormat.dwRGBBitCount;
			stride = DDSD.lPitch;

			locked = DDSD.lpSurface;

			return locked;
		}

		return 0;
	}

	void FrameBufferDD::unlock()
	{
		if(!locked || !backBuffer) return;

		backBuffer->Unlock(0);

		locked = 0;
	}

	void FrameBufferDD::drawText(int x, int y, const char *string, ...)
	{
		char buffer[256];
		va_list arglist;

		va_start(arglist, string);
		vsprintf(buffer, string, arglist);
		va_end(arglist);

		HDC hdc;

		backBuffer->GetDC(&hdc);

		SetBkColor(hdc, RGB(0, 0, 255));
		SetTextColor(hdc, RGB(255, 255, 255));

		TextOut(hdc, x, y, buffer, lstrlen(buffer));

		backBuffer->ReleaseDC(hdc);
	}

	bool FrameBufferDD::getScanline(bool &inVerticalBlank, unsigned int &scanline)
	{
		HRESULT result = directDraw->GetScanLine((unsigned long*)&scanline);

		if(result == DD_OK)
		{
			inVerticalBlank = false;
		}
		else if(result == DDERR_VERTICALBLANKINPROGRESS)
		{
			inVerticalBlank = true;
		}
		else if(result == DDERR_UNSUPPORTED)
		{
			return false;
		}
		else ASSERT(false);

		return true;
	}

	void FrameBufferDD::releaseAll()
	{
		unlock();

		if(backBuffer)
		{
			backBuffer->Release();
			backBuffer = 0;
		}

		if(frontBuffer)
		{
			frontBuffer->Release();
			frontBuffer = 0;
		}

		if(directDraw)
		{
			directDraw->SetCooperativeLevel(0, DDSCL_NORMAL);
			directDraw->Release();
			directDraw = 0;
		}
	}
}
