// 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;
			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 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;
			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;
		}
	}
}
