/*
 * MVKFoundation.h
 *
 * Copyright (c) 2015-2020 The Brenwill Workshop Ltd. (http://www.brenwill.com)
 *
 * 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.
 */


#pragma once


#include "MVKCommonEnvironment.h"
#include "mvk_vulkan.h"
#include <algorithm>
#include <string>
#include <simd/simd.h>


#pragma mark Math

// Common scaling multipliers
#define KIBI		(1024)
#define MEBI		(KIBI * KIBI)
#define GIBI        (KIBI * MEBI)

/** Represents a non-existent index. */
static const int kMVKIndexNone = -1;

/** A type definition for 16-bit half-float values. */
typedef uint16_t MVKHalfFloat;

/** A representation of the value of 1.0 as a 16-bit half-float. */
#define kHalfFloat1	0x3C00


#pragma mark -
#pragma mark Vertex content structures

/** 2D vertex position and texcoord content. */
typedef struct {
	simd::float2 position;
	simd::float2 texCoord;
} MVKVertexPosTex;


#pragma mark -
#pragma mark Vulkan support

/** Tracks the Vulkan command currently being used. */
typedef enum : uint8_t {
    kMVKCommandUseNone,                     /**< No use defined. */
    kMVKCommandUseQueueSubmit,              /**< vkQueueSubmit. */
    kMVKCommandUseQueuePresent,             /**< vkQueuePresentKHR. */
    kMVKCommandUseQueueWaitIdle,            /**< vkQueueWaitIdle. */
    kMVKCommandUseDeviceWaitIdle,           /**< vkDeviceWaitIdle. */
    kMVKCommandUseBeginRenderPass,          /**< vkCmdBeginRenderPass. */
    kMVKCommandUseNextSubpass,              /**< vkCmdNextSubpass. */
    kMVKCommandUsePipelineBarrier,          /**< vkCmdPipelineBarrier. */
    kMVKCommandUseBlitImage,                /**< vkCmdBlitImage. */
    kMVKCommandUseCopyImage,                /**< vkCmdCopyImage. */
    kMVKCommandUseResolveImage,             /**< vkCmdResolveImage - resolve stage. */
    kMVKCommandUseResolveExpandImage,       /**< vkCmdResolveImage - expand stage. */
    kMVKCommandUseResolveCopyImage,         /**< vkCmdResolveImage - copy stage. */
    kMVKCommandUseCopyBuffer,               /**< vkCmdCopyBuffer. */
    kMVKCommandUseCopyBufferToImage,        /**< vkCmdCopyBufferToImage. */
    kMVKCommandUseCopyImageToBuffer,        /**< vkCmdCopyImageToBuffer. */
    kMVKCommandUseFillBuffer,               /**< vkCmdFillBuffer. */
    kMVKCommandUseUpdateBuffer,             /**< vkCmdUpdateBuffer. */
    kMVKCommandUseClearColorImage,          /**< vkCmdClearColorImage. */
    kMVKCommandUseClearDepthStencilImage,   /**< vkCmdClearDepthStencilImage. */
    kMVKCommandUseResetQueryPool,           /**< vkCmdResetQueryPool. */
    kMVKCommandUseDispatch,                 /**< vkCmdDispatch. */
    kMVKCommandUseTessellationControl,      /**< vkCmdDraw* - tessellation control stage. */
    kMVKCommandUseCopyQueryPoolResults      /**< vkCmdCopyQueryPoolResults. */
} MVKCommandUse;

/** Represents a given stage of a graphics pipeline. */
enum MVKGraphicsStage {
	kMVKGraphicsStageVertex = 0,	/**< The vertex shader stage. */
	kMVKGraphicsStageTessControl,	/**< The tessellation control shader stage. */
	kMVKGraphicsStageRasterization	/**< The rest of the pipeline. */
};

/** Returns the name of the result value. */
const char* mvkVkResultName(VkResult vkResult);

/** Returns the name of the component swizzle. */
const char* mvkVkComponentSwizzleName(VkComponentSwizzle swizzle);

/** Returns the Vulkan API version number as a string. */
static inline std::string mvkGetVulkanVersionString(uint32_t vkVersion) {
	std::string verStr;
	verStr += std::to_string(VK_VERSION_MAJOR(vkVersion));
	verStr += ".";
	verStr += std::to_string(VK_VERSION_MINOR(vkVersion));
	verStr += ".";
	verStr += std::to_string(VK_VERSION_PATCH(vkVersion));
	return verStr;
}

/** Returns the MoltenVK API version number as a string. */
static inline std::string mvkGetMoltenVKVersionString(uint32_t mvkVersion) {
	std::string verStr;
	verStr += std::to_string(mvkVersion / 10000);
	verStr += ".";
	verStr += std::to_string((mvkVersion % 10000) / 100);
	verStr += ".";
	verStr += std::to_string(mvkVersion % 100);
	return verStr;
}


#pragma mark -
#pragma mark Alignment functions

/** Returns whether the specified positive value is a power-of-two. */
template<typename T>
static inline bool mvkIsPowerOfTwo(T value) {
	// Test POT:  (x != 0) && ((x & (x - 1)) == 0)
	return value && ((value & (value - 1)) == 0);
}

/**
 * Ensures the specified positive value is a power-of-two. Returns the specified value
 * if it is a power-of-two value. If it is not, returns the next power-of-two value
 * that is larger than the specified value is returned.
 */
template<typename T>
static inline T mvkEnsurePowerOfTwo(T value) {
	if (mvkIsPowerOfTwo(value)) { return value; }

	T pot = 1;
	while(pot <= value) { pot <<= 1; };
	return pot;
}

/**
 * Returns the power-of-two exponent of the next power-of-two 
 * number that is at least as big as the specified value.
 *
 * This implementation returns zero for both zero and one as inputs.
 */
template<typename T>
static inline T mvkPowerOfTwoExponent(T value) {
    T p2Value = mvkEnsurePowerOfTwo(value);

    // Count the trailing zeros
    p2Value = (p2Value ^ (p2Value - 1)) >> 1;  // Set trailing 0s to 1s and zero rest
    T potExp = 0;
    while (p2Value) {
        p2Value >>= 1;
        potExp++;
    }
    return potExp;
}

/**
 * Aligns the byte reference to the specified alignment, and returns the aligned value,
 * which will be greater than or equal to the reference if alignDown is false, or less
 * than or equal to the reference if alignDown is true.
 *
 * This is a low level utility method. Usually you will use the convenience functions
 * mvkAlignAddress() and mvkAlignByteCount() to align addresses and offsets respectively.
 */
static inline uintptr_t mvkAlignByteRef(uintptr_t byteRef, uintptr_t byteAlignment, bool alignDown = false) {
	if (byteAlignment == 0) { return byteRef; }

	assert(mvkIsPowerOfTwo(byteAlignment));

	uintptr_t mask = byteAlignment - 1;
	uintptr_t alignedRef = (byteRef + mask) & ~mask;

	if (alignDown && (alignedRef > byteRef)) {
		alignedRef -= byteAlignment;
	}

	return alignedRef;
}

/**
 * Aligns the memory address to the specified byte alignment, and returns the aligned address,
 * which will be greater than or equal to the original address if alignDown is false, or less
 * than or equal to the original address if alignDown is true.
 */
static inline void* mvkAlignAddress(void* address, uintptr_t byteAlignment, bool alignDown = false) {
	return (void*)mvkAlignByteRef((uintptr_t)address, byteAlignment, alignDown);
}

/**
 * Aligns the byte offset to the specified byte alignment, and returns the aligned offset,
 * which will be greater than or equal to the original offset if alignDown is false, or less
 * than or equal to the original offset if alignDown is true.
 */
static inline uintptr_t mvkAlignByteCount(uintptr_t byteCount, uintptr_t byteAlignment, bool alignDown = false) {
	return mvkAlignByteRef(byteCount, byteAlignment, alignDown);
}

/**
 * Reverses the order of the rows in the specified data block.
 * The transformation is performed in-place.
 *
 * This function may be used to reverse the order of the rows of any row-major memory
 * structure, but is particularly useful for vertically flipping the contents of a texture
 * or image, which is a common requirement when converting content data between a Vulkan
 * texture orientation and a Metal texture orientation.
 *
 * The specified data block is assumed to be in row-major order, containing the specified
 * number of rows, and with the specified number of bytes in each row. The total number of
 * bytes in the data block must be at least (bytesPerRow * rowCount).
 */
void mvkFlipVertically(void* rowMajorData, uint32_t rowCount, size_t bytesPerRow);

/**
 * The following constants are used to indicate values that have no defined limit.
 * They are ridiculously large numbers, but low enough to be safely used as both
 * uint and int values without risking overflowing between positive and negative values.
 */
static  int32_t kMVKUndefinedLargePositiveInt32 =  mvkEnsurePowerOfTwo(std::numeric_limits<int32_t>::max() / 2);
static  int32_t kMVKUndefinedLargeNegativeInt32 = -kMVKUndefinedLargePositiveInt32;
static uint32_t kMVKUndefinedLargeUInt32        =  kMVKUndefinedLargePositiveInt32;
static  int64_t kMVKUndefinedLargePositiveInt64 =  mvkEnsurePowerOfTwo(std::numeric_limits<int64_t>::max() / 2);
static  int64_t kMVKUndefinedLargeNegativeInt64 = -kMVKUndefinedLargePositiveInt64;
static uint64_t kMVKUndefinedLargeUInt64        =  kMVKUndefinedLargePositiveInt64;


#pragma mark Vulkan structure support functions

/** Returns a VkExtent2D created from the width and height of a VkExtent3D. */
static inline VkExtent2D mvkVkExtent2DFromVkExtent3D(VkExtent3D e) { return {e.width, e.height }; }

/** Returns a VkExtent3D, created from a VkExtent2D, and with depth of 1. */
static inline VkExtent3D mvkVkExtent3DFromVkExtent2D(VkExtent2D e) { return {e.width, e.height, 1U }; }

/** Returns whether the two Vulkan extents are equal by comparing their respective components. */
static inline bool mvkVkExtent2DsAreEqual(VkExtent2D e1, VkExtent2D e2) {
	return (e1.width == e2.width) && (e1.height == e2.height);
}

/** Returns whether the two Vulkan extents are equal by comparing their respective components. */
static inline bool mvkVkExtent3DsAreEqual(VkExtent3D e1, VkExtent3D e2) {
	return (e1.width == e2.width) && (e1.height == e2.height) && (e1.depth == e2.depth);
}

/** Returns whether the two Vulkan offsets are equal by comparing their respective components. */
static inline bool mvkVkOffset2DsAreEqual(VkOffset2D os1, VkOffset2D os2) {
	return (os1.x == os2.x) && (os1.y == os2.y);
}

/** Returns whether the two Vulkan offsets are equal by comparing their respective components. */
static inline bool mvkVkOffset3DsAreEqual(VkOffset3D os1, VkOffset3D os2) {
	return (os1.x == os2.x) && (os1.y == os2.y) && (os1.z == os2.z);
}

/**
 * Returns the difference between two offsets, by subtracting the subtrahend from the minuend,
 * which is accomplished by subtracting each of the corresponding x,y,z components.
 */
static inline VkOffset3D mvkVkOffset3DDifference(VkOffset3D minuend, VkOffset3D subtrahend) {
	VkOffset3D rslt;
	rslt.x = minuend.x - subtrahend.x;
	rslt.y = minuend.y - subtrahend.y;
	rslt.z = minuend.z - subtrahend.z;
	return rslt;
}

/** Packs the four swizzle components into a single 32-bit word. */
static inline uint32_t mvkPackSwizzle(VkComponentMapping components) {
	return ((components.r & 0xFF) << 0) | ((components.g & 0xFF) << 8) |
	((components.b & 0xFF) << 16) | ((components.a & 0xFF) << 24);
}

/** Unpacks a single 32-bit word containing four swizzle components. */
static inline VkComponentMapping mvkUnpackSwizzle(uint32_t packed) {
	VkComponentMapping components;
	components.r = (VkComponentSwizzle)((packed >> 0) & 0xFF);
	components.g = (VkComponentSwizzle)((packed >> 8) & 0xFF);
	components.b = (VkComponentSwizzle)((packed >> 16) & 0xFF);
	components.a = (VkComponentSwizzle)((packed >> 24) & 0xFF);
	return components;
}

/**
 * Returns whether the two component swizzles, cs1 and cs2 match. Positional identity matches
 * and wildcard matches are allowed. The two values match under any of the following conditions:
 *   1) cs1 and cs2 are equal to each other.
 *   2) Either cs1 or cs2 is equal to VK_COMPONENT_SWIZZLE_IDENTITY and the other value
 *      is equal to the positional value csPos, which is one of VK_COMPONENT_SWIZZLE_R,
 *      VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, or VK_COMPONENT_SWIZZLE_A.
 *   3) Either cs1 or cs2 is VK_COMPONENT_SWIZZLE_MAX_ENUM, which is considered a wildcard,
 *      and matches any value.
 */
static inline bool mvkVKComponentSwizzlesMatch(VkComponentSwizzle cs1,
											   VkComponentSwizzle cs2,
											   VkComponentSwizzle csPos) {
	return ((cs1 == cs2) ||
			((cs1 == VK_COMPONENT_SWIZZLE_IDENTITY) && (cs2 == csPos)) ||
			((cs2 == VK_COMPONENT_SWIZZLE_IDENTITY) && (cs1 == csPos)) ||
			(cs1 == VK_COMPONENT_SWIZZLE_MAX_ENUM) || (cs2 == VK_COMPONENT_SWIZZLE_MAX_ENUM));
}

/**
 * Returns whether the two swizzle component mappings match each other, by comparing the
 * corresponding elements of the two mappings. A component value of VK_COMPONENT_SWIZZLE_IDENTITY
 * on either mapping matches the VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B,
 * or VK_COMPONENT_SWIZZLE_A value in the other mapping if it is the correct position.
 * A component value of VK_COMPONENT_SWIZZLE_MAX_ENUM is considered a wildcard and matches
 * any value in the corresponding component in the other mapping.
 */
static inline bool mvkVkComponentMappingsMatch(VkComponentMapping cm1, VkComponentMapping cm2) {
	return (mvkVKComponentSwizzlesMatch(cm1.r, cm2.r, VK_COMPONENT_SWIZZLE_R) &&
			mvkVKComponentSwizzlesMatch(cm1.g, cm2.g, VK_COMPONENT_SWIZZLE_G) &&
			mvkVKComponentSwizzlesMatch(cm1.b, cm2.b, VK_COMPONENT_SWIZZLE_B) &&
			mvkVKComponentSwizzlesMatch(cm1.a, cm2.a, VK_COMPONENT_SWIZZLE_A));
}

/** Print the size of the type. */
#define mvkPrintSizeOf(type)    printf("Size of " #type " is %lu.\n", sizeof(type))


#pragma mark -
#pragma mark Template functions

#pragma mark Math

/** Returns whether the value will fit inside the numeric type. */
template<typename T, typename Tval>
const bool mvkFits(const Tval& val) {
	return val <= std::numeric_limits<T>::max();
}

/** Clamps the value between the lower and upper bounds, inclusive. */
template<typename T>
const T& mvkClamp(const T& val, const T& lower, const T& upper) {
    return std::min(std::max(val, lower), upper);
}

/** Returns the result of a division, rounded up. */
template<typename T>
T mvkCeilingDivide(T numerator, T denominator) {
	// Short circuit very common usecase of dividing by one.
	return (denominator == 1) ? numerator : (numerator + denominator - 1) / denominator;
}


#pragma mark Hashing

/**
 * Returns a hash value calculated from the specified array of numeric elements,
 * using the DJB2a algorithm:  hash = (hash * 33) ^ value.
 *
 * For a hash on a single array, leave the seed value unspecified, to use the default
 * seed value. To accumulate a single hash value over several arrays, use the hash
 * value returned by previous calls as the seed in subsequent calls.
 */
template<class N>
std::size_t mvkHash(const N* pVals, std::size_t count = 1, std::size_t seed = 5381) {
    std::size_t hash = seed;
    for (std::size_t i = 0; i < count; i++) { hash = ((hash << 5) + hash) ^ pVals[i]; }
    return hash;
}


#pragma mark Containers

/**
 * Structure to reference an array of typed elements in contiguous memory.
 * Allocation and management of the memory is handled externally.
 */
template<typename Type>
struct MVKArrayRef {
	Type* data;
	const size_t size;

	const Type* begin() const { return data; }
	const Type* end() const { return &data[size]; }
	const Type& operator[]( const size_t i ) const { return data[i]; }
	Type& operator[]( const size_t i ) { return data[i]; }
	MVKArrayRef() : MVKArrayRef(nullptr, 0) {}
	MVKArrayRef(Type* d, size_t s) : data(d), size(s) {}
};

/** Ensures the size of the specified container is at least the specified size. */
template<typename C, typename S>
void mvkEnsureSize(C& container, S size) {
    if (size > container.size()) { container.resize(size); }
}

/**
 * Iterates through the contents of the specified object pointer container and destroys
 * each object, including freeing the object memory, and clearing the container.
 */
template<typename C>
void mvkDestroyContainerContents(C& container) {
    for (auto elem : container) { elem->destroy(); }
    container.clear();
}

/**
 * Iterates through the contents of the specified Objective-C object pointer 
 * container and releases each object, and clears the container.
 */
#ifdef __OBJC__
template<typename C>
void mvkReleaseContainerContents(C& container) {
    for (auto elem : container) { [elem release]; }
    container.clear();
}
#endif

/** Returns whether the container contains an item equal to the value. */
template<class C, class T>
bool contains(const C& container, const T& val) {
	for (const T& cVal : container) { if (cVal == val) { return true; } }
	return false;
}

/** Removes the first occurance of the specified value from the specified container. */
template<class C, class T>
void mvkRemoveFirstOccurance(C& container, T val) {
    for (auto iter = container.begin(), end = container.end(); iter != end; iter++) {
        if( *iter == val ) {
            container.erase(iter);
            return;
        }
    }
}

/** Removes all occurances of the specified value from the specified container. */
template<class C, class T>
void mvkRemoveAllOccurances(C& container, T val) {
    container.erase(remove(container.begin(), container.end(), val), container.end());
}


#pragma mark Values and structs

/** Selects and returns one of the values, based on the platform OS. */
template<typename T>
const T& mvkSelectPlatformValue(const T& macOSVal, const T& iOSVal) {
#if MVK_IOS
	return iOSVal;
#endif
#if MVK_MACOS
	return macOSVal;
#endif
}

/**
 * If pVal is not null, clears the memory occupied by *pVal by writing zeros to all bytes.
 * The optional count allows clearing multiple elements in an array.
 */
template<typename T>
void mvkClear(T* pVal, size_t count = 1) { if (pVal) { memset(pVal, 0, sizeof(T) * count); } }

/**
 * If pVal is not null, overrides the const declaration, and clears the memory occupied by *pVal
 * by writing zeros to all bytes. The optional count allows clearing multiple elements in an array.
*/
template<typename T>
void mvkClear(const T* pVal, size_t count = 1) { mvkClear((T*)pVal, count); }

/**
 * If pSrc and pDst are both not null, copies the contents of the source value to the
 * destination value. The optional count allows copying of multiple elements in an array.
 */
template<typename T>
void mvkCopy(T* pDst, const T* pSrc, size_t count = 1) {
	if (pSrc && pDst) { memcpy(pDst, pSrc, sizeof(T) * count); }
}

/**
 * If pV1 and pV2 are both not null, returns whether the contents of the two values are equal,
 * otherwise returns false. The optional count allows comparing multiple elements in an array.
 */
template<typename T>
bool mvkAreEqual(const T* pV1, const T* pV2, size_t count = 1) {
	return (pV1 && pV2) ? (memcmp(pV1, pV2, sizeof(T) * count) == 0) : false;
}

/**
 * Sets the value referenced by the destination pointer with the value referenced by
 * the source pointer, and returns whether the value was set.
 *
 * If both specified pointers are non-NULL, populates the value referenced by the
 * destination pointer with the value referenced by the source pointer, and returns true.
 *
 * If the source pointer is NULL, the value referenced by the destination pointer
 * is overwritten with zeros to clear it, and returns false.
 *
 * If the destination pointer is NULL, does nothing, and returns false.
 */
template<typename T>
bool mvkSetOrClear(T* pDest, const T* pSrc) {
    if (pDest && pSrc) {
        *pDest = *pSrc;
        return true;
    }
    if (pDest) { mvkClear(pDest); }
    return false;
}


#pragma mark Boolean flags

/** Enables the flags (sets bits to 1) within the value parameter specified by the bitMask parameter. */
template<typename Tv, typename Tm>
void mvkEnableFlags(Tv& value, const Tm bitMask) { value = (Tv)(value | bitMask); }

/** Disables the flags (sets bits to 0) within the value parameter specified by the bitMask parameter. */
template<typename Tv, typename Tm>
void mvkDisableFlags(Tv& value, const Tm bitMask) { value = (Tv)(value & ~(Tv)bitMask); }

/** Returns whether the specified value has ANY of the flags specified in bitMask enabled (set to 1). */
template<typename Tv, typename Tm>
bool mvkIsAnyFlagEnabled(Tv value, const Tm bitMask) { return !!(value & bitMask); }

/** Returns whether the specified value has ALL of the flags specified in bitMask enabled (set to 1). */
template<typename Tv, typename Tm>
bool mvkAreAllFlagsEnabled(Tv value, const Tm bitMask) { return ((value & bitMask) == bitMask); }

/** Returns whether the specified value has ONLY one or more of the flags specified in bitMask enabled (set to 1), and none others. */
template<typename Tv, typename Tm>
bool mvkIsOnlyAnyFlagEnabled(Tv value, const Tm bitMask) { return (mvkIsAnyFlagEnabled(value, bitMask) && ((value | bitMask) == bitMask)); }

/** Returns whether the specified value has ONLY ALL of the flags specified in bitMask enabled (set to 1), and none others. */
template<typename Tv, typename Tm>
bool mvkAreOnlyAllFlagsEnabled(Tv value, const Tm bitMask) { return (value == bitMask); }

