/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 The Khronos Group Inc.
 *
 * 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.
 *
 *//*!
 * \file
 * \brief Negative viewport height (part of VK_KHR_maintenance1)
 *//*--------------------------------------------------------------------*/

#include "vktDrawNegativeViewportHeightTests.hpp"
#include "vktDrawCreateInfoUtil.hpp"
#include "vktDrawImageObjectUtil.hpp"
#include "vktDrawBufferObjectUtil.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTestCaseUtil.hpp"

#include "vkPrograms.hpp"
#include "vkTypeUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkCmdUtil.hpp"

#include "tcuVector.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuTestLog.hpp"

#include "deSharedPtr.hpp"

namespace vkt
{
namespace Draw
{
namespace
{
using namespace vk;
using tcu::Vec4;
using de::SharedPtr;
using de::MovePtr;

enum Constants
{
	WIDTH	= 256,
	HEIGHT	= WIDTH/2,
};

struct TestParams
{
	VkFrontFace			frontFace;
	VkCullModeFlagBits	cullMode;
	bool				zeroViewportHeight;
};

class NegativeViewportHeightTestInstance : public TestInstance
{
public:
									NegativeViewportHeightTestInstance	(Context& context, const TestParams& params);
	tcu::TestStatus					iterate								(void);
	tcu::ConstPixelBufferAccess		draw								(const VkViewport viewport);
	MovePtr<tcu::TextureLevel>		generateReferenceImage				(void) const;
	bool							isCulled							(const VkFrontFace triangleFace) const;

private:
	const TestParams				m_params;
	const VkFormat					m_colorAttachmentFormat;
	SharedPtr<Image>				m_colorTargetImage;
	Move<VkImageView>				m_colorTargetView;
	SharedPtr<Buffer>				m_vertexBuffer;
	Move<VkRenderPass>				m_renderPass;
	Move<VkFramebuffer>				m_framebuffer;
	Move<VkPipelineLayout>			m_pipelineLayout;
	Move<VkPipeline>				m_pipeline;
};

NegativeViewportHeightTestInstance::NegativeViewportHeightTestInstance (Context& context, const TestParams& params)
	: TestInstance				(context)
	, m_params					(params)
	, m_colorAttachmentFormat	(VK_FORMAT_R8G8B8A8_UNORM)
{
	const DeviceInterface&	vk		= m_context.getDeviceInterface();
	const VkDevice			device	= m_context.getDevice();

	// Vertex data
	{
		std::vector<Vec4> vertexData;

		// CCW triangle
		vertexData.push_back(Vec4(-0.8f, -0.6f, 0.0f, 1.0f));	//  0-----2
		vertexData.push_back(Vec4(-0.8f,  0.6f, 0.0f, 1.0f));	//   |  /
		vertexData.push_back(Vec4(-0.2f, -0.6f, 0.0f, 1.0f));	//  1|/

		// CW triangle
		vertexData.push_back(Vec4( 0.2f, -0.6f, 0.0f, 1.0f));	//  0-----1
		vertexData.push_back(Vec4( 0.8f, -0.6f, 0.0f, 1.0f));	//    \  |
		vertexData.push_back(Vec4( 0.8f,  0.6f, 0.0f, 1.0f));	//      \|2

		const VkDeviceSize dataSize = vertexData.size() * sizeof(Vec4);
		m_vertexBuffer = Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
												m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);

		deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), &vertexData[0], static_cast<std::size_t>(dataSize));
		flushMappedMemoryRange(vk, device, m_vertexBuffer->getBoundMemory().getMemory(), m_vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
	}

	// Render pass
	{
		const VkExtent3D		targetImageExtent		= { WIDTH, HEIGHT, 1 };
		const VkImageUsageFlags	targetImageUsageFlags	= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;

		const ImageCreateInfo	targetImageCreateInfo(
			VK_IMAGE_TYPE_2D,						// imageType,
			m_colorAttachmentFormat,				// format,
			targetImageExtent,						// extent,
			1u,										// mipLevels,
			1u,										// arrayLayers,
			VK_SAMPLE_COUNT_1_BIT,					// samples,
			VK_IMAGE_TILING_OPTIMAL,				// tiling,
			targetImageUsageFlags);					// usage,

		m_colorTargetImage = Image::createAndAlloc(vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());

		RenderPassCreateInfo	renderPassCreateInfo;
		renderPassCreateInfo.addAttachment(AttachmentDescription(
			m_colorAttachmentFormat,				// format
			VK_SAMPLE_COUNT_1_BIT,					// samples
			VK_ATTACHMENT_LOAD_OP_LOAD,				// loadOp
			VK_ATTACHMENT_STORE_OP_STORE,			// storeOp
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,		// stencilLoadOp
			VK_ATTACHMENT_STORE_OP_DONT_CARE,		// stencilStoreOp
			VK_IMAGE_LAYOUT_GENERAL,				// initialLayout
			VK_IMAGE_LAYOUT_GENERAL));				// finalLayout

		const VkAttachmentReference colorAttachmentReference =
		{
			0u,
			VK_IMAGE_LAYOUT_GENERAL
		};

		renderPassCreateInfo.addSubpass(SubpassDescription(
			VK_PIPELINE_BIND_POINT_GRAPHICS,		// pipelineBindPoint
			(VkSubpassDescriptionFlags)0,			// flags
			0u,										// inputAttachmentCount
			DE_NULL,								// inputAttachments
			1u,										// colorAttachmentCount
			&colorAttachmentReference,				// colorAttachments
			DE_NULL,								// resolveAttachments
			AttachmentReference(),					// depthStencilAttachment
			0u,										// preserveAttachmentCount
			DE_NULL));								// preserveAttachments

		m_renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
	}

	// Framebuffer
	{
		const ImageViewCreateInfo colorTargetViewInfo (m_colorTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
		m_colorTargetView = createImageView(vk, device, &colorTargetViewInfo);

		std::vector<VkImageView> colorAttachments(1);
		colorAttachments[0] = *m_colorTargetView;

		const FramebufferCreateInfo	framebufferCreateInfo(*m_renderPass, colorAttachments, WIDTH, HEIGHT, 1);
		m_framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
	}

	// Vertex input

	const VkVertexInputBindingDescription		vertexInputBindingDescription =
	{
		0u,										// uint32_t             binding;
		sizeof(Vec4),							// uint32_t             stride;
		VK_VERTEX_INPUT_RATE_VERTEX,			// VkVertexInputRate    inputRate;
	};

	const VkVertexInputAttributeDescription		vertexInputAttributeDescription =
	{
		0u,										// uint32_t    location;
		0u,										// uint32_t    binding;
		VK_FORMAT_R32G32B32A32_SFLOAT,			// VkFormat    format;
		0u										// uint32_t    offset;
	};

	const PipelineCreateInfo::VertexInputState	vertexInputState = PipelineCreateInfo::VertexInputState(1, &vertexInputBindingDescription,
																										1, &vertexInputAttributeDescription);

	// Graphics pipeline

	const VkRect2D scissor = makeRect2D(WIDTH, HEIGHT);

	std::vector<VkDynamicState>		dynamicStates;
	dynamicStates.push_back(VK_DYNAMIC_STATE_VIEWPORT);

	const Unique<VkShaderModule>	vertexModule	(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
	const Unique<VkShaderModule>	fragmentModule	(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));

	const PipelineLayoutCreateInfo	pipelineLayoutCreateInfo;
	m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);

	const PipelineCreateInfo::ColorBlendState::Attachment colorBlendAttachmentState;

	PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vertexModule,   "main", VK_SHADER_STAGE_VERTEX_BIT));
	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fragmentModule, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
	pipelineCreateInfo.addState (PipelineCreateInfo::VertexInputState	(vertexInputState));
	pipelineCreateInfo.addState (PipelineCreateInfo::InputAssemblerState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
	pipelineCreateInfo.addState (PipelineCreateInfo::ColorBlendState	(1, &colorBlendAttachmentState));
	pipelineCreateInfo.addState (PipelineCreateInfo::ViewportState		(1, std::vector<VkViewport>(), std::vector<VkRect2D>(1, scissor)));
	pipelineCreateInfo.addState (PipelineCreateInfo::DepthStencilState	());
	pipelineCreateInfo.addState (PipelineCreateInfo::RasterizerState	(
		VK_FALSE,					// depthClampEnable
		VK_FALSE,					// rasterizerDiscardEnable
		VK_POLYGON_MODE_FILL,		// polygonMode
		m_params.cullMode,			// cullMode
		m_params.frontFace,			// frontFace
		VK_FALSE,					// depthBiasEnable
		0.0f,						// depthBiasConstantFactor
		0.0f,						// depthBiasClamp
		0.0f,						// depthBiasSlopeFactor
		1.0f));						// lineWidth
	pipelineCreateInfo.addState (PipelineCreateInfo::MultiSampleState	());
	pipelineCreateInfo.addState (PipelineCreateInfo::DynamicState		(dynamicStates));

	m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
}

tcu::ConstPixelBufferAccess NegativeViewportHeightTestInstance::draw (const VkViewport viewport)
{
	const DeviceInterface&	vk					= m_context.getDeviceInterface();
	const VkDevice			device				= m_context.getDevice();
	const VkQueue			queue				= m_context.getUniversalQueue();
	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();

	// Command buffer

	const CmdPoolCreateInfo			cmdPoolCreateInfo	(queueFamilyIndex);
	const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, &cmdPoolCreateInfo));
	const Unique<VkCommandBuffer>	cmdBuffer			(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	// Draw

	beginCommandBuffer(vk, *cmdBuffer);

	vk.cmdSetViewport(*cmdBuffer, 0u, 1u, &viewport);

	{
		const VkClearColorValue		clearColor			= makeClearValueColorF32(0.125f, 0.25f, 0.5f, 1.0f).color;
		const ImageSubresourceRange subresourceRange	(VK_IMAGE_ASPECT_COLOR_BIT);

		initialTransitionColor2DImage(vk, *cmdBuffer, m_colorTargetImage->object(), VK_IMAGE_LAYOUT_GENERAL,
									  VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
		vk.cmdClearColorImage(*cmdBuffer, m_colorTargetImage->object(), VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRange);
	}

	if (m_params.zeroViewportHeight)
	{
		// Set zero viewport height
		const VkViewport zeroViewportHeight =
		{
			viewport.x,			// float    x;
			viewport.y / 2.0f,	// float    y;
			viewport.width,		// float    width;
			0.0f,				// float    height;
			viewport.minDepth,	// float    minDepth;
			viewport.maxDepth	// float    maxDepth;
		};

		vk.cmdSetViewport(*cmdBuffer, 0u, 1u, &zeroViewportHeight);
	}

	{
		const VkMemoryBarrier memBarrier =
		{
			VK_STRUCTURE_TYPE_MEMORY_BARRIER,												// VkStructureType    sType;
			DE_NULL,																		// const void*        pNext;
			VK_ACCESS_TRANSFER_WRITE_BIT,													// VkAccessFlags      srcAccessMask;
			VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT		// VkAccessFlags      dstAccessMask;
		};

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
	}

	beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT));

	{
		const VkDeviceSize	offset	= 0;
		const VkBuffer		buffer	= m_vertexBuffer->object();

		vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &buffer, &offset);
	}

	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
	vk.cmdDraw(*cmdBuffer, 6, 1, 0, 0);
	endRenderPass(vk, *cmdBuffer);
	endCommandBuffer(vk, *cmdBuffer);

	// Submit
	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());

	// Get result
	{
		const VkOffset3D zeroOffset = { 0, 0, 0 };
		return m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, VK_IMAGE_ASPECT_COLOR_BIT);
	}
}

//! Determine if a triangle with triangleFace orientation will be culled or not
bool NegativeViewportHeightTestInstance::isCulled (const VkFrontFace triangleFace) const
{
	const bool isFrontFacing = (triangleFace == m_params.frontFace);

	if (m_params.cullMode == VK_CULL_MODE_FRONT_BIT && isFrontFacing)
		return true;
	if (m_params.cullMode == VK_CULL_MODE_BACK_BIT  && !isFrontFacing)
		return true;

	return m_params.cullMode == VK_CULL_MODE_FRONT_AND_BACK;
}

MovePtr<tcu::TextureLevel> NegativeViewportHeightTestInstance::generateReferenceImage (void) const
{
	DE_ASSERT(HEIGHT == WIDTH/2);

	MovePtr<tcu::TextureLevel>		image	(new tcu::TextureLevel(mapVkFormat(m_colorAttachmentFormat), WIDTH, HEIGHT));
	const tcu::PixelBufferAccess	access	(image->getAccess());
	const Vec4						blue	(0.125f, 0.25f, 0.5f, 1.0f);
	const Vec4						white	(1.0f);
	const Vec4						gray	(0.5f, 0.5f, 0.5f, 1.0f);

	tcu::clear(access, blue);

	// Zero viewport height
	if (m_params.zeroViewportHeight)
	{
		return image;
	}
	// Negative viewport height
	else
	{
		const int p1 =      static_cast<int>(static_cast<float>(HEIGHT) * (1.0f - 0.6f) / 2.0f);
		const int p2 = p1 + static_cast<int>(static_cast<float>(HEIGHT) * (2.0f * 0.6f) / 2.0f);

		// left triangle (CCW -> CW after y-flip)
		if (!isCulled(VK_FRONT_FACE_CLOCKWISE))
		{
			const Vec4& color = (m_params.frontFace == VK_FRONT_FACE_CLOCKWISE ? white : gray);

			for (int y = p1; y <= p2; ++y)
			for (int x = p1; x <  y;  ++x)
				access.setPixel(color, x, y);
		}

		// right triangle (CW -> CCW after y-flip)
		if (!isCulled(VK_FRONT_FACE_COUNTER_CLOCKWISE))
		{
			const Vec4& color = (m_params.frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE ? white : gray);

			for (int y = p1;        y <= p2;          ++y)
			for (int x = WIDTH - y; x <  p2 + HEIGHT; ++x)
				access.setPixel(color, x, y);
		}

		return image;
	}
}

std::string getCullModeStr (const VkCullModeFlagBits cullMode)
{
	// Cull mode flags are a bit special, because there's a meaning to 0 and or'ed flags.
	// The function getCullModeFlagsStr() doesn't work too well in this case.

	switch (cullMode)
	{
		case VK_CULL_MODE_NONE:				return "VK_CULL_MODE_NONE";
		case VK_CULL_MODE_FRONT_BIT:		return "VK_CULL_MODE_FRONT_BIT";
		case VK_CULL_MODE_BACK_BIT:			return "VK_CULL_MODE_BACK_BIT";
		case VK_CULL_MODE_FRONT_AND_BACK:	return "VK_CULL_MODE_FRONT_AND_BACK";

		default:
			DE_ASSERT(0);
			return std::string();
	}
}

tcu::TestStatus NegativeViewportHeightTestInstance::iterate (void)
{
	// Set up the viewport and draw

	const VkViewport viewport =
	{
		0.0f,							// float    x;
		static_cast<float>(HEIGHT),		// float    y;
		static_cast<float>(WIDTH),		// float    width;
		-static_cast<float>(HEIGHT),	// float    height;
		0.0f,							// float    minDepth;
		1.0f,							// float    maxDepth;
	};

	const tcu::ConstPixelBufferAccess	resultImage	= draw(viewport);

	// Verify the results

	tcu::TestLog&				log				= m_context.getTestContext().getLog();
	MovePtr<tcu::TextureLevel>	referenceImage	= generateReferenceImage();

	// Zero viewport height
	if (m_params.zeroViewportHeight)
	{
		log << tcu::TestLog::Message
			<< "Drawing two triangles with zero viewport height."
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message
			<< "Result image should be empty."
			<< tcu::TestLog::EndMessage;
	}
	// Negative viewport height
	else
	{
		log << tcu::TestLog::Message
			<< "Drawing two triangles with negative viewport height, which will cause a y-flip. This changes the sign of the triangle's area."
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message
			<< "After the flip, the triangle on the left is CW and the triangle on the right is CCW. Right angles of the both triangles should be at the bottom of the image."
			<< " Front face is white, back face is gray."
			<< tcu::TestLog::EndMessage;
	}

	log << tcu::TestLog::Message
		<< "Front face: " << getFrontFaceName(m_params.frontFace) << "\n"
		<< "Cull mode: "  << getCullModeStr  (m_params.cullMode)  << "\n"
		<< tcu::TestLog::EndMessage;

	if (!tcu::fuzzyCompare(log, "Image compare", "Image compare", referenceImage->getAccess(), resultImage, 0.02f, tcu::COMPARE_LOG_RESULT))
		return tcu::TestStatus::fail("Rendered image is incorrect");
	else
		return tcu::TestStatus::pass("Pass");
}

class NegativeViewportHeightTest : public TestCase
{
public:
	NegativeViewportHeightTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
		: TestCase	(testCtx, name, description)
		, m_params	(params)
	{
	}

	void initPrograms (SourceCollections& programCollection) const
	{
		// Vertex shader
		{
			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "layout(location = 0) in vec4 in_position;\n"
				<< "\n"
				<< "out gl_PerVertex {\n"
				<< "    vec4  gl_Position;\n"
				<< "};\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "    gl_Position = in_position;\n"
				<< "}\n";

			programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
		}

		// Fragment shader
		{
			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "layout(location = 0) out vec4 out_color;\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "    if (gl_FrontFacing)\n"
				<< "        out_color = vec4(1.0);\n"
				<< "    else\n"
				<< "        out_color = vec4(vec3(0.5), 1.0);\n"
				<< "}\n";

			programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
		}
	}

	virtual void checkSupport (Context& context) const
	{
		context.requireDeviceFunctionality("VK_KHR_maintenance1");
	}

	virtual TestInstance* createInstance (Context& context) const
	{
		return new NegativeViewportHeightTestInstance(context, m_params);
	}

private:
	const TestParams	m_params;
};

void populateTestGroup (tcu::TestCaseGroup* testGroup, bool zeroViewportHeight)
{
	const struct
	{
		const char* const	name;
		VkFrontFace			frontFace;
	} frontFace[] =
	{
		{ "front_ccw",	VK_FRONT_FACE_COUNTER_CLOCKWISE	},
		{ "front_cw",	VK_FRONT_FACE_CLOCKWISE			},
	};

	const struct
	{
		const char* const	name;
		VkCullModeFlagBits	cullMode;
	} cullMode[] =
	{
		{ "cull_none",	VK_CULL_MODE_NONE			},
		{ "cull_front",	VK_CULL_MODE_FRONT_BIT		},
		{ "cull_back",	VK_CULL_MODE_BACK_BIT		},
		{ "cull_both",	VK_CULL_MODE_FRONT_AND_BACK	},
	};

	for (int ndxFrontFace = 0; ndxFrontFace < DE_LENGTH_OF_ARRAY(frontFace); ++ndxFrontFace)
	for (int ndxCullMode  = 0; ndxCullMode  < DE_LENGTH_OF_ARRAY(cullMode);  ++ndxCullMode)
	{
		const TestParams params =
		{
			frontFace[ndxFrontFace].frontFace,
			cullMode[ndxCullMode].cullMode,
			zeroViewportHeight
		};
		std::ostringstream	name;
		name << frontFace[ndxFrontFace].name << "_" << cullMode[ndxCullMode].name;

		testGroup->addChild(new NegativeViewportHeightTest(testGroup->getTestContext(), name.str(), "", params));
	}
}

}	// anonymous

tcu::TestCaseGroup*	createNegativeViewportHeightTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "negative_viewport_height", "Negative viewport height (VK_KHR_maintenance1)", populateTestGroup, false);
}

tcu::TestCaseGroup*	createZeroViewportHeightTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "zero_viewport_height", "Zero viewport height (VK_KHR_maintenance1)", populateTestGroup, true);
}

}	// Draw
}	// vkt
