// SwiftShader Software Renderer
//
// Copyright(c) 2005-2011 TransGaming Inc.
//
// All rights reserved. No part of this software may be copied, distributed, transmitted,
// transcribed, stored in a retrieval system, translated into any human or computer
// language by any means, or disclosed to third parties without the explicit written
// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
// or implied, including but not limited to any patent rights, are granted to you.
//

#include "Direct3DSwapChain9.hpp"

#include "Direct3DDevice9.hpp"
#include "Renderer.hpp"
#include "Timer.hpp"
#include "Resource.hpp"
#include "Configurator.hpp"
#include "Debug.hpp"

#include "FrameBufferDD.hpp"
#include "FrameBufferGDI.hpp"

namespace D3D9
{
	Direct3DSwapChain9::Direct3DSwapChain9(Direct3DDevice9 *device, D3DPRESENT_PARAMETERS *presentParameters) : device(device), presentParameters(*presentParameters)
	{
		frameBuffer = 0;

		for(int i = 0; i < 3; i++)
		{
			backBuffer[i] = 0;
		}

		reset(presentParameters);
	}

	Direct3DSwapChain9::~Direct3DSwapChain9()
	{
		release();
	}

	long Direct3DSwapChain9::QueryInterface(const IID &iid, void **object)
	{
		CriticalSection cs(device);

		TRACE("");

		if(iid == IID_IDirect3DSwapChain9 ||
		   iid == IID_IUnknown)
		{
			AddRef();
			*object = this;

			return S_OK;
		}

		*object = 0;

		return NOINTERFACE(iid);
	}

	unsigned long Direct3DSwapChain9::AddRef()
	{
		TRACE("");

		return Unknown::AddRef();
	}

	unsigned long Direct3DSwapChain9::Release()
	{
		TRACE("");

		return Unknown::Release();
	}

	long Direct3DSwapChain9::Present(const RECT *sourceRect, const RECT *destRect, HWND destWindowOverride, const RGNDATA *dirtyRegion, unsigned long flags)
	{
		CriticalSection cs(device);

		TRACE("");

		#if PERF_PROFILE
			profiler.nextFrame();
		#endif

		#if PERF_HUD
			sw::Renderer *renderer = device->renderer;

			static int64_t frame = sw::Timer::ticks();

			int64_t frameTime = sw::Timer::ticks() - frame;
			frame = sw::Timer::ticks();

			if(frameTime > 0)
			{
				unsigned int *frameBuffer = (unsigned int*)lockBackBuffer(0);   // FIXME: Don't assume A8R8G8B8 mode
				unsigned int stride = backBuffer[0]->getInternalPitchP();

				int thread;
				for(thread = 0; thread < renderer->getThreadCount(); thread++)
				{
					int64_t drawTime = renderer->getVertexTime(thread) + renderer->getSetupTime(thread) + renderer->getPixelTime(thread);

					int vertexPercentage = sw::clamp((int)(100 * renderer->getVertexTime(thread) / frameTime), 0, 100);
					int setupPercentage = sw::clamp((int)(100 * renderer->getSetupTime(thread) / frameTime), 0, 100);
					int pixelPercentage = sw::clamp((int)(100 * renderer->getPixelTime(thread) / frameTime), 0, 100);

					for(int i = 0; i < 100; i++)
					{
						frameBuffer[thread * stride + i] = 0x00000000;
					}

					unsigned int *buffer = frameBuffer;

					for(int i = 0; i < vertexPercentage; i++)
					{
						buffer[thread * stride] = 0x000000FF;
						buffer++;
					}

					for(int i = 0; i < setupPercentage; i++)
					{
						buffer[thread * stride] = 0x0000FF00;
						buffer++;
					}

					for(int i = 0; i < pixelPercentage; i++)
					{
						buffer[thread * stride] = 0x00FF0000;
						buffer++;
					}

					frameBuffer[thread * stride + 100] = 0x00FFFFFF;
				}

				for(int i = 0; i <= 100; i++)
				{
					frameBuffer[thread * stride + i] = 0x00FFFFFF;
				}

				unlockBackBuffer(0);
			}

			renderer->resetTimers();
		#endif

		HWND window = destWindowOverride ? destWindowOverride : presentParameters.hDeviceWindow;
		void *source = backBuffer[0]->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);   // FIXME: External
		sw::Format format = backBuffer[0]->getInternalFormat();

		POINT point;
		GetCursorPos(&point);
		ScreenToClient(window, &point);

		frameBuffer->setCursorPosition(point.x, point.y);

		if(!sourceRect && !destRect)   // FIXME: More cases?
		{
			frameBuffer->flip(window, source, format);
		}
		else   // FIXME: Check for SWAPEFFECT_COPY
		{
			sw::Rect sRect(0, 0, 0, 0);
			sw::Rect dRect(0, 0, 0, 0);

			if(sourceRect)
			{
				sRect.x0 = sourceRect->left;
				sRect.y0 = sourceRect->top;
				sRect.x1 = sourceRect->right;
				sRect.y1 = sourceRect->bottom;
			}

			if(destRect)
			{
				dRect.x0 = destRect->left;
				dRect.y0 = destRect->top;
				dRect.x1 = destRect->right;
				dRect.y1 = destRect->bottom;
			}

			frameBuffer->blit(window, source, sourceRect ? &sRect : 0, destRect ? &dRect : 0, format);
		}

		backBuffer[0]->unlockInternal();   // FIXME: External

		return D3D_OK;
	}

	long Direct3DSwapChain9::GetFrontBufferData(IDirect3DSurface9 *destSurface)
	{
		CriticalSection cs(device);

		TRACE("");

		if(!destSurface)
		{
			return INVALIDCALL();
		}
		
		sw::Surface *dest = static_cast<Direct3DSurface9*>(destSurface);
		void *buffer = dest->lockExternal(0, 0, 0, sw::LOCK_WRITEONLY, sw::PRIVATE);

		frameBuffer->screenshot(buffer);

		dest->unlockExternal();
		
		return D3D_OK;
	}

	long Direct3DSwapChain9::GetBackBuffer(unsigned int index, D3DBACKBUFFER_TYPE type, IDirect3DSurface9 **backBuffer)
	{
		CriticalSection cs(device);

		TRACE("");

		if(!backBuffer/* || type != D3DBACKBUFFER_TYPE_MONO*/)
		{
			return INVALIDCALL();
		}

		*backBuffer = 0;

		if(index >= 3 || this->backBuffer[index] == 0)
		{
			return INVALIDCALL();
		}

		*backBuffer = this->backBuffer[index];
		this->backBuffer[index]->AddRef();

		return D3D_OK;
	}

	long Direct3DSwapChain9::GetRasterStatus(D3DRASTER_STATUS *rasterStatus)
	{
		CriticalSection cs(device);

		TRACE("");

		if(!rasterStatus)
		{
			return INVALIDCALL();
		}

		bool inVerticalBlank;
		unsigned int scanline;
		bool supported = frameBuffer->getScanline(inVerticalBlank, scanline);

		if(supported)
		{
			rasterStatus->InVBlank = inVerticalBlank;
			rasterStatus->ScanLine = scanline;
		}
		else
		{
			return INVALIDCALL();
		}

		return D3D_OK;
	}

	long Direct3DSwapChain9::GetDisplayMode(D3DDISPLAYMODE *displayMode)
	{
		CriticalSection cs(device);

		TRACE("");

		if(!displayMode)
		{
			return INVALIDCALL();
		}

		device->getAdapterDisplayMode(D3DADAPTER_DEFAULT, displayMode);

		return D3D_OK;
	}

	long Direct3DSwapChain9::GetDevice(IDirect3DDevice9 **device)
	{
		CriticalSection cs(this->device);

		TRACE("");

		if(!device)
		{
			return INVALIDCALL();
		}

		this->device->AddRef();
		*device = this->device;

		return D3D_OK;
	}

	long Direct3DSwapChain9::GetPresentParameters(D3DPRESENT_PARAMETERS *presentParameters)
	{
		CriticalSection cs(device);

		TRACE("");

		if(!presentParameters)
		{
			return INVALIDCALL();
		}

		*presentParameters = this->presentParameters;

		return D3D_OK;
	}

	void Direct3DSwapChain9::reset(D3DPRESENT_PARAMETERS *presentParameters)
	{
		release();

		ASSERT(presentParameters->BackBufferCount <= 3);   // Maximum of three back buffers

		if(presentParameters->BackBufferCount == 0)
		{
			presentParameters->BackBufferCount = 1;
		}

		if(presentParameters->BackBufferFormat == D3DFMT_UNKNOWN)
		{
			D3DDISPLAYMODE displayMode;
			GetDisplayMode(&displayMode);

			presentParameters->BackBufferFormat = displayMode.Format;
		}

		D3DDEVICE_CREATION_PARAMETERS creationParameters;
		device->GetCreationParameters(&creationParameters);

		HWND windowHandle = presentParameters->hDeviceWindow ? presentParameters->hDeviceWindow : creationParameters.hFocusWindow;

		if(presentParameters->Windowed && (presentParameters->BackBufferHeight == 0 || presentParameters->BackBufferWidth == 0))
		{
			RECT rectangle;
			GetClientRect(windowHandle, &rectangle);

			presentParameters->BackBufferWidth = rectangle.right - rectangle.left;
			presentParameters->BackBufferHeight = rectangle.bottom - rectangle.top;
		}

		frameBuffer = createFrameBufferWin(windowHandle, presentParameters->BackBufferWidth, presentParameters->BackBufferHeight, presentParameters->Windowed == FALSE, true);

		lockable = presentParameters->Flags & D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;

		backBuffer[0] = 0;
		backBuffer[1] = 0;
		backBuffer[2] = 0;

		for(int i = 0; i < (int)presentParameters->BackBufferCount; i++)
		{
			backBuffer[i] = new Direct3DSurface9(device, this, presentParameters->BackBufferWidth, presentParameters->BackBufferHeight, presentParameters->BackBufferFormat, D3DPOOL_DEFAULT, presentParameters->MultiSampleType, presentParameters->MultiSampleQuality, lockable, D3DUSAGE_RENDERTARGET);
			backBuffer[i]->bind();
		}

		this->presentParameters = *presentParameters;
	}

	void Direct3DSwapChain9::release()
	{
		delete frameBuffer;
		frameBuffer = 0;

		for(int i = 0; i < 3; i++)
		{
			if(backBuffer[i])
			{
				backBuffer[i]->unbind();
				backBuffer[i] = 0;
			}
		}
	}

	void Direct3DSwapChain9::setGammaRamp(sw::GammaRamp *gammaRamp, bool calibrate)
	{
		frameBuffer->setGammaRamp(gammaRamp, calibrate);
	}

	void Direct3DSwapChain9::getGammaRamp(sw::GammaRamp *gammaRamp)
	{
		frameBuffer->getGammaRamp(gammaRamp);
	}

	void *Direct3DSwapChain9::lockBackBuffer(int index)
	{
		return backBuffer[index]->lockInternal(0, 0, 0, sw::LOCK_READWRITE, sw::PUBLIC);   // FIXME: External
	}
	
	void Direct3DSwapChain9::unlockBackBuffer(int index)
	{
		backBuffer[index]->unlockInternal();   // FIXME: External
	}
}
