/**********************************************************************************************
 * 
 * Raylib - A simple and easy-to-use library to learn videogames programming (www.raylib.com)
 * Original - https://github.com/raysan5/raylib/blob/master/src/raylib.h
 * 
**********************************************************************************************/

using System;
using System.Runtime.InteropServices;

namespace Raylib
{
    #region Raylib-cs Enums

    public enum LogType
    {
        LOG_INFO = 1,
        LOG_WARNING = 2,
        LOG_ERROR = 4,
        LOG_DEBUG = 8,
        LOG_OTHER = 16
    }

    public enum ShaderLocationIndex
    {
        LOC_VERTEX_POSITION = 0,
        LOC_VERTEX_TEXCOORD01 = 1,
        LOC_VERTEX_TEXCOORD02 = 2,
        LOC_VERTEX_NORMAL = 3,
        LOC_VERTEX_TANGENT = 4,
        LOC_VERTEX_COLOR = 5,
        LOC_MATRIX_MVP = 6,
        LOC_MATRIX_MODEL = 7,
        LOC_MATRIX_VIEW = 8,
        LOC_MATRIX_PROJECTION = 9,
        LOC_VECTOR_VIEW = 10,
        LOC_COLOR_DIFFUSE = 11,
        LOC_COLOR_SPECULAR = 12,
        LOC_COLOR_AMBIENT = 13,
        LOC_MAP_ALBEDO = 14,
        LOC_MAP_METALNESS = 15,
        LOC_MAP_NORMAL = 16,
        LOC_MAP_ROUGHNESS = 17,
        LOC_MAP_OCCLUSION = 18,
        LOC_MAP_EMISSION = 19,
        LOC_MAP_HEIGHT = 20,
        LOC_MAP_CUBEMAP = 21,
        LOC_MAP_IRRADIANCE = 22,
        LOC_MAP_PREFILTER = 23,
        LOC_MAP_BRDF = 24
    }

    public enum TexmapIndex
    {
        MAP_ALBEDO = 0,
        MAP_METALNESS = 1,
        MAP_NORMAL = 2,
        MAP_ROUGHNESS = 3,
        MAP_OCCLUSION = 4,
        MAP_EMISSION = 5,
        MAP_HEIGHT = 6,
        MAP_CUBEMAP = 7,
        MAP_IRRADIANCE = 8,
        MAP_PREFILTER = 9,
        MAP_BRDF = 10
    }

    public enum PixelFormat
    {
        UNCOMPRESSED_GRAYSCALE = 1,
        UNCOMPRESSED_GRAY_ALPHA = 2,
        UNCOMPRESSED_R5G6B5 = 3,
        UNCOMPRESSED_R8G8B8 = 4,
        UNCOMPRESSED_R5G5B5A1 = 5,
        UNCOMPRESSED_R4G4B4A4 = 6,
        UNCOMPRESSED_R8G8B8A8 = 7,
        UNCOMPRESSED_R32 = 8,
        UNCOMPRESSED_R32G32B32 = 9,
        UNCOMPRESSED_R32G32B32A32 = 10,
        COMPRESSED_DXT1RGB = 11,
        COMPRESSED_DXT1RGBA = 12,
        COMPRESSED_DXT3RGBA = 13,
        COMPRESSED_DXT5RGBA = 14,
        COMPRESSED_ETC1RGB = 15,
        COMPRESSED_ETC2RGB = 16,
        COMPRESSED_ETC2EAC_RGBA = 17,
        COMPRESSED_PVRT_RGB = 18,
        COMPRESSED_PVRT_RGBA = 19,
        COMPRESSED_ASTC_4x4RGBA = 20,
        COMPRESSED_ASTC_8x8RGBA = 21
    }

    public enum TextureFilterMode
    {
        FILTER_POINT = 0,
        FILTER_BILINEAR = 1,
        FILTER_TRILINEAR = 2,
        FILTER_ANISOTROPIC_4X = 3,
        FILTER_ANISOTROPIC_8X = 4,
        FILTER_ANISOTROPIC_16X = 5
    }

    public enum TextureWrapMode
    {
        WRAP_REPEAT = 0,
        WRAP_CLAMP = 1,
        WRAP_MIRROR = 2
    }

    public enum BlendMode
    {
        BLEND_ALPHA = 0,
        BLEND_ADDITIVE = 1,
        BLEND_MULTIPLIED = 2
    }

    [Flags]
    public enum Gestures
    {
        GESTURE_NONE = 0,
        GESTURE_TAP = 1,
        GESTURE_DOUBLETAP = 2,
        GESTURE_HOLD = 4,
        GESTURE_DRAG = 8,
        GESTURE_SWIPE_RIGHT = 16,
        GESTURE_SWIPE_LEFT = 32,
        GESTURE_SWIPE_UP = 64,
        GESTURE_SWIPE_DOWN = 128,
        GESTURE_PINCH_IN = 256,
        GESTURE_PINCH_OUT = 512
    }

    public enum CameraMode
    {
        CAMERA_CUSTOM = 0,
        CAMERA_FREE = 1,
        CAMERA_ORBITAL = 2,
        CAMERA_FIRST_PERSON = 3,
        CAMERA_THIRD_PERSON = 4
    }

    public enum CameraType
    {
        CAMERA_PERSPECTIVE = 0,
        CAMERA_ORTHOGRAPHIC = 1
    }

    public enum VrDeviceType
    {
        HMD_DEFAULT_DEVICE = 0,
        HMD_OCULUS_RIFT_DK2 = 1,
        HMD_OCULUS_RIFT_CV1 = 2,
        HMD_OCULUS_GO = 3,
        HMD_VALVE_HTC_VIVE = 4,
        HMD_SONY_PSVR = 5
    }

    [Flags]
    public enum Flag
    {
        SHOW_LOGO = 1,
        FULLSCREEN_MODE = 2,
        WINDOW_RESIZABLE = 4,
        WINDOW_UNDECORATED = 8,
        WINDOW_TRANSPARENT = 16,
        MSAA_4X_HINT = 32,
        VSYNC_HINT = 64
    }

    // Keyboard Function Keys
    public enum Key
    {
        SPACE = 32,
        ESCAPE = 256,
        ENTER = 257,
        TAB = 258,
        BACKSPACE = 259,
        INSERT = 260,
        DELETE = 261,
        RIGHT = 262,
        LEFT = 263,
        DOWN = 264,
        UP = 265,
        PAGE_UP = 266,
        PAGE_DOWN = 267,
        HOME = 268,
        END = 269,
        CAPS_LOCK = 280,
        SCROLL_LOCK = 281,
        NUM_LOCK = 282,
        PRINT_SCREEN = 283,
        PAUSE = 284,
        F1 = 290,
        F2 = 291,
        F3 = 292,
        F4 = 293,
        F5 = 294,
        F6 = 295,
        F7 = 296,
        F8 = 297,
        F9 = 298,
        F10 = 299,
        F11 = 300,
        F12 = 301,
        LEFT_SHIFT = 340,
        LEFT_CONTROL = 341,
        LEFT_ALT = 342,
        RIGHT_SHIFT = 344,
        RIGHT_CONTROL = 345,
        RIGHT_ALT = 346,
        GRAVE = 96,
        SLASH = 47,
        BACKSLASH = 92,

        // Keyboard Alpha Numeric Keys
        ZERO = 48,
        ONE = 49,
        TWO = 50,
        THREE = 51,
        FOUR = 52,
        FIVE = 53,
        SIX = 54,
        SEVEN = 55,
        EIGHT = 56,
        NINE = 57,
        A = 65,
        B = 66,
        C = 67,
        D = 68,
        E = 69,
        F = 70,
        G = 71,
        H = 72,
        I = 73,
        J = 74,
        K = 75,
        L = 76,
        M = 77,
        N = 78,
        O = 79,
        P = 80,
        Q = 81,
        R = 82,
        S = 83,
        T = 84,
        U = 85,
        V = 86,
        W = 87,
        X = 88,
        Y = 89,
        Z = 90,

        // Android Physical Buttons
        BACK = 4,
        MENU = 82,
        VOLUME_UP = 24,
        VOLUME_DOWN = 25
    }

    // Mouse Buttons
    public enum Mouse
    {
        LEFT_BUTTON = 0,
        RIGHT_BUTTON = 1,
        MIDDLE_BUTTON = 2
    }

    public enum Gamepad
    {
        PLAYER1 = 0,
        PLAYER2 = 1,
        PLAYER3 = 2,
        PLAYER4 = 3,
        PS3BUTTON_TRIANGLE = 0,
        PS3BUTTON_CIRCLE = 1,
        PS3BUTTON_CROSS = 2,
        PS3BUTTON_SQUARE = 3,
        PS3BUTTON_L1 = 6,
        PS3BUTTON_R1 = 7,
        PS3BUTTON_L2 = 4,
        PS3BUTTON_R2 = 5,
        PS3BUTTON_START = 8,
        PS3BUTTON_SELECT = 9,
        PS3BUTTON_UP = 24,
        PS3BUTTON_RIGHT = 25,
        PS3BUTTON_DOWN = 26,
        PS3BUTTON_LEFT = 27,
        PS3BUTTON_PS = 12,
        PS3AXIS_LEFT_X = 0,
        PS3AXIS_LEFT_Y = 1,
        PS3AXIS_RIGHT_X = 2,
        PS3AXIS_RIGHT_Y = 5,
        PS3AXIS_L2 = 3,
        PS3AXIS_R2 = 4,
        XBOX_BUTTON_A = 0,
        XBOX_BUTTON_B = 1,
        XBOX_BUTTON_X = 2,
        XBOX_BUTTON_Y = 3,
        XBOX_BUTTON_LB = 4,
        XBOX_BUTTON_RB = 5,
        XBOX_BUTTON_SELECT = 6,
        XBOX_BUTTON_START = 7,
        XBOX_BUTTON_UP = 10,
        XBOX_BUTTON_RIGHT = 11,
        XBOX_BUTTON_DOWN = 12,
        XBOX_BUTTON_LEFT = 13,
        XBOX_BUTTON_HOME = 8,
        ANDROID_DPAD_UP = 19,
        ANDROID_DPAD_DOWN = 20,
        ANDROID_DPAD_LEFT = 21,
        ANDROID_DPAD_RIGHT = 22,
        ANDROID_DPAD_CENTER = 23,
        ANDROID_BUTTON_A = 96,
        ANDROID_BUTTON_B = 97,
        ANDROID_BUTTON_C = 98,
        ANDROID_BUTTON_X = 99,
        ANDROID_BUTTON_Y = 100,
        ANDROID_BUTTON_Z = 101,
        ANDROID_BUTTON_L1 = 102,
        ANDROID_BUTTON_R1 = 103,
        ANDROID_BUTTON_L2 = 104,
        ANDROID_BUTTON_R2 = 105,
        XBOX_AXIS_LEFT_X = 0,
        XBOX_AXIS_LEFT_Y = 1,
        XBOX_AXIS_RIGHT_X = 2,
        XBOX_AXIS_RIGHT_Y = 3,
        XBOX_AXIS_LT = 4,
        XBOX_AXIS_RT = 5
    }

    #endregion

    #region Raylib-cs Types

    // Color type, RGBA (32bit)
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Color
    {
        public byte r;
        public byte g;
        public byte b;
        public byte a;

        public Color(byte r, byte g, byte b, byte a)
        {
            this.r = r;
            this.g = g;
            this.b = b;
            this.a = a;
        }
	    
	    // Access colours from struct extension
	    // By default accessed from Raylib class
	    // Custom raylib color palette for amazing visuals
        public static Color LIGHTGRAY = new Color(200, 200, 200, 255);
        public static Color GRAY = new Color(130, 130, 130, 255);
        public static Color DARKGRAY = new Color(80, 80, 80, 255);
        public static Color YELLOW = new Color(253, 249, 0, 255);
        public static Color GOLD = new Color(255, 203, 0, 255);
        public static Color ORANGE = new Color(255, 161, 0, 255);
        public static Color PINK = new Color(255, 109, 194, 255);
        public static Color RED = new Color(230, 41, 55, 255);
        public static Color MAROON = new Color(190, 33, 55, 255);
        public static Color GREEN = new Color(0, 228, 48, 255);
        public static Color LIME = new Color(0, 158, 47, 255);
        public static Color DARKGREEN = new Color(0, 117, 44, 255);
        public static Color SKYBLUE = new Color(102, 191, 255, 255);
        public static Color BLUE = new Color(0, 121, 241, 255);
        public static Color DARKBLUE = new Color(0, 82, 172, 255);
        public static Color PURPLE = new Color(200, 122, 255, 255);
        public static Color VIOLET = new Color(135, 60, 190, 255);
        public static Color DARKPURPLE = new Color(112, 31, 126, 255);
        public static Color BEIGE = new Color(211, 176, 131, 255);
        public static Color BROWN = new Color(127, 106, 79, 255);
        public static Color DARKBROWN = new Color(76, 63, 47, 255);
        public static Color WHITE = new Color(255, 255, 255, 255);
        public static Color BLACK = new Color(0, 0, 0, 255);
        public static Color BLANK = new Color(0, 0, 0, 0);
        public static Color MAGENTA = new Color(255, 0, 255, 255);
        public static Color RAYWHITE = new Color(245, 245, 245, 255);
    }

    // Rectangle type
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Rectangle
    {
        public float x;
        public float y;
        public float width;
        public float height;

        public Rectangle(float x, float y, float width, float height)
        {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }
    }

    // Image type, bpp always RGBA (32bit)
    // NOTE: Data stored in CPU memory (RAM)
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Image
    {
        public IntPtr data;
        public int width;
        public int height;
        public int mipmaps;
        public int format;
    }

    // Texture2D type
    // NOTE: Data stored in GPU memory
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Texture2D
    {
        public uint id;
        public int width;
        public int height;
        public int mipmaps;
        public int format;
    }

    // RenderTexture2D type, for texture rendering
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct RenderTexture2D
    {
        public uint id;
        public Texture2D texture;
        public Texture2D depth;
    }

    // RenderTexture type, same as RenderTexture2D
    // typedef RenderTexture2D RenderTexture;

    // Font character info
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct CharInfo
    {
        public int value;
        public Rectangle rec;
        public int offsetX;
        public int offsetY;
        public int advanceX;

        // [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = Raylib.PHYSAC_MAX_VERTICES)]
        // public unsafe void* data;
        public IntPtr data;
    }

    // Font type, includes texture and charSet array data
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Font
    {
        public Texture2D texture;
        public int baseSize;
        public int charsCount;

        // [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = Raylib.PHYSAC_MAX_VERTICES)]
        // public unsafe CharInfo* data;
        //public CharInfo[] chars;
        public IntPtr data;
    }

    // Camera type, defines a camera position/orientation in 3d space
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Camera3D
    {
        public Vector3 position;
        public Vector3 target;
        public Vector3 up;

        public float fovy;

        public CameraType type;

        public Camera3D(Vector3 position, Vector3 target, Vector3 up, float fovy = 90,
            CameraType type = CameraType.CAMERA_PERSPECTIVE)
        {
            this.position = position;
            this.target = target;
            this.up = up;
            this.fovy = fovy;
            this.type = type;
        }
    }

    // Camera2D type, defines a 2d camera
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Camera2D
    {
        public Vector2 offset;
        public Vector2 target;
        public float rotation;
        public float zoom;
    }

    // Bounding box type
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct BoundingBox
    {
        public Vector3 min;
        public Vector3 max;
    }

    // Vertex data definning a mesh
    // NOTE: Data stored in CPU memory (and GPU)
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Mesh
    {
        public int vertexCount;
        public int triangleCount;

        public float[] vertices;
        public float[] texcoords;
        public float[] texcoords2;
        public float[] normals;
        public float[] tangents;
        public byte[] colors;
        public ushort[] indices;

        public uint vaoId;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] // Raylib.PHYSAC_MAX_VERTICES)]
        public uint[] vboId;
    }

    // Shader type (generic)
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public unsafe struct Shader
    {
        public uint id;

        // public IntPtr locs;
        // [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = Raylib.MAX_SHADER_LOCATIONS)]
        // [MarshalAs(UnmanagedType.ByValArray, SizeConst = Raylib.MAX_SHADER_LOCATIONS)]
        //[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_I4)]
        // public int[] locs;
        public fixed int locs[Raylib.MAX_SHADER_LOCATIONS];
    }

    // Material texture map
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct MaterialMap
    {
        public Texture2D texture;
        public Color color;
        public float value;
    }

    // Material type (generic)
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Material
    {
        public Shader shader;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = Raylib.MAX_MATERIAL_MAPS)]
        public MaterialMap[] maps;

        public float[] param;
    }

    // Model type
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Model
    {
        public Mesh mesh;
        public Matrix transform;
        public Material material;
    }

    // Ray type (useful for raycast)
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Ray
    {
        public Vector3 position;
        public Vector3 direction;

        public Ray(Vector3 position, Vector3 direction)
        {
            this.position = position;
            this.direction = direction;
        }
    }

    // Raycast hit information
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct RayHitInfo
    {
        public bool hit;
        public float distance;
        public Vector3 position;
        public Vector3 normal;
    }

    // Wave type, defines audio wave data
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Wave
    {
        public uint sampleCount;
        public uint sampleRate;
        public uint sampleSize;
        public uint channels;
        public IntPtr data;
    }

    // Sound source type
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct Sound
    {
        public IntPtr audioBuffer;
        public uint source;
        public uint buffer;
        public int format;
    }

    // Audio stream type
    // NOTE: Useful to create custom audio streams not bound to a specific file
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public class AudioStream
    {
        public uint sampleRate;
        public uint sampleSize;
        public uint channels;
        public IntPtr audioBuffer;
        public int format;

        public uint source;
        public uint[] buffers = new uint[2];
    }

    // Head-Mounted-Display device parameters
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public class VrDeviceInfo
    {
        public int hResolution;
        public int vResolution;
        public float hScreenSize;
        public float vScreenSize;
        public float vScreenCenter;
        public float eyeToScreenDistance;
        public float lensSeparationDistance;

        public float interpupillaryDistance;
        public float[] lensDistortionValues = new float[4];
        public float[] chromaAbCorrection = new float[4];
    }

    #endregion

    public static partial class Raylib
    {
        #region Raylib-cs Variables

        // Used by DllImport to load the native library.
        public const string nativeLibName = "raylib.dll";
        public const int MAX_SHADER_LOCATIONS = 32;
        public const int MAX_MATERIAL_MAPS = 12;

        // colors

        // Custom raylib color palette for amazing visuals
        public static Color LIGHTGRAY = new Color(200, 200, 200, 255);
        public static Color GRAY = new Color(130, 130, 130, 255);
        public static Color DARKGRAY = new Color(80, 80, 80, 255);
        public static Color YELLOW = new Color(253, 249, 0, 255);
        public static Color GOLD = new Color(255, 203, 0, 255);
        public static Color ORANGE = new Color(255, 161, 0, 255);
        public static Color PINK = new Color(255, 109, 194, 255);
        public static Color RED = new Color(230, 41, 55, 255);
        public static Color MAROON = new Color(190, 33, 55, 255);
        public static Color GREEN = new Color(0, 228, 48, 255);
        public static Color LIME = new Color(0, 158, 47, 255);
        public static Color DARKGREEN = new Color(0, 117, 44, 255);
        public static Color SKYBLUE = new Color(102, 191, 255, 255);
        public static Color BLUE = new Color(0, 121, 241, 255);
        public static Color DARKBLUE = new Color(0, 82, 172, 255);
        public static Color PURPLE = new Color(200, 122, 255, 255);
        public static Color VIOLET = new Color(135, 60, 190, 255);
        public static Color DARKPURPLE = new Color(112, 31, 126, 255);
        public static Color BEIGE = new Color(211, 176, 131, 255);
        public static Color BROWN = new Color(127, 106, 79, 255);
        public static Color DARKBROWN = new Color(76, 63, 47, 255);
        public static Color WHITE = new Color(255, 255, 255, 255);
        public static Color BLACK = new Color(0, 0, 0, 255);
        public static Color BLANK = new Color(0, 0, 0, 0);
        public static Color MAGENTA = new Color(255, 0, 255, 255);
        public static Color RAYWHITE = new Color(245, 245, 245, 255);

        #endregion

        #region Raylib-cs Functions 

	    // Initialize window and OpenGL context
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr InitWindow(int width, int height, string title);

		 // Close window and unload OpenGL context
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void CloseWindow();

	    // Check if window has been initialized successfully
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsWindowReady();

	    // Check if KEY_ESCAPE pressed or Close icon pressed
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool WindowShouldClose();

	    // Check if window has been minimized (or lost focus)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsWindowMinimized();
	    
	    // Toggle fullscreen mode (only PLATFORM_DESKTOP)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ToggleFullscreen();

	    // Set icon for window (only PLATFORM_DESKTOP)
	    [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
	    public static extern void SetWindowIcon(Image image);

	    // Set title for window (only PLATFORM_DESKTOP)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetWindowTitle(string title);

	    // Set window position on screen (only PLATFORM_DESKTOP)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetWindowPosition(int x, int y);

	    // Set monitor for the current window (fullscreen mode)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetWindowMonitor(int monitor);

	    // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetWindowMinSize(int width, int height);

	    // Set window dimensions
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetWindowSize(int width, int height);

	    // Get current screen width
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetScreenWidth();

	    // Get current screen height
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetScreenHeight();

         // Get number of connected monitors
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
        public static extern int GetMonitorCount();

        // Get primary monitor width
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
        public static extern int GetMonitorWidth(int monitor);

        // Get primary monitor height
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
        public static extern int GetMonitorHeight(int monitor);

        // Get primary monitor physical width in millimetres
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
        public static extern int GetMonitorPhysicalWidth(int monitor);

        // Get primary monitor physical height in millimetres
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
        public static extern int GetMonitorPhysicalHeight(int monitor);

        // Get the human-readable, UTF-8 encoded name of the primary monitor
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
        public static extern string GetMonitorName(int monitor);

        // Get handle from window
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr GetWindowHandle();

        // Get current clipboard text
        //[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
        //public static extern string GetClipboard();

        // Set current clipboard text
        //[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
        //public static extern void SetClipboard(string text);

        // Shows cursor
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ShowCursor();

	    // Hides cursor
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void HideCursor();

	    // Check if cursor is not visible
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsCursorHidden();

	    // Enables cursor (unlock cursor)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void EnableCursor();

	    // Disables cursor (lock cursor)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DisableCursor();

	    // Set background color (framebuffer clear color)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ClearBackground(Color color);

	    // Setup canvas (framebuffer) to start drawing
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void BeginDrawing();

	    // End canvas drawing and swap buffers (double buffering)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void EndDrawing();

	    // Initialize 2D mode with custom camera (2D)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void BeginMode2D(Camera2D camera);

	    // Ends 2D mode with custom camera
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void EndMode2D();
	  
	    // Initializes 3D mode with custom camera (3D)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void BeginMode3D(Camera3D camera);
	    
	    // Ends 3D mode and returns to default 2D orthographic mode
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void EndMode3D();

	    // Initializes render texture for drawing
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void BeginTextureMode(RenderTexture2D target);

	    // Ends drawing to render texture
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void EndTextureMode();

	    // Returns a ray trace from mouse position
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Ray GetMouseRay(Vector2 mousePosition, Camera3D camera);

	    // Returns the screen space position for a 3d world space position
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Vector2 GetWorldToScreen(Vector3 position, Camera3D camera);

	    // Returns camera transform matrix (view matrix)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Matrix GetCameraMatrix(Camera3D camera);

	    // Set target FPS (maximum)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetTargetFPS(int fps);

	    // Returns current FPS
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetFPS();

	    // Returns time in seconds for last frame drawn
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern float GetFrameTime();

	    // Returns elapsed time in seconds since InitWindow()
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern double GetTime();

	    // Returns hexadecimal value for a Color
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int ColorToInt(Color color);

	    // Returns color normalized as float [0..1]
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Vector4 ColorNormalize(Color color);

	    // Returns HSV values for a Color
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Vector3 ColorToHSV(Color color);

	    // Returns a Color struct from hexadecimal value
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Color GetColor(int hexValue);

	    // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Color Fade(Color color, float alpha);

	    // Activate raylib logo at startup (can be done with flags)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ShowLogo();

	    // Setup window configuration flags (view FLAGS)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetConfigFlags(byte flags);

	    // Enable trace log message types (bit flags based)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetTraceLog(byte types);

	    // Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void TraceLog(int logType, string text, params object[] args);
	    
	    // Takes a screenshot of current screen (saved a .png)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void TakeScreenshot(string fileName);

	    // Returns a random value between min and max (both included)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetRandomValue(int min, int max);

	    // Check file extension
	    [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
	    public static extern bool IsFileExtension(string fileName, string ext);

	    // Get pointer to extension for a filename string
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern string GetExtension(string fileName);

	    // Get pointer to filename for a path string
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern string GetFileName(string filePath);

	    // Get full path for a given fileName (uses static string)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern string GetDirectoryPath(string fileName);

	    // Get current working directory (uses static string)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern string GetWorkingDirectory();

	    // Change working directory, returns true if success
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool ChangeDirectory(string dir);

	    // Check if a file has been dropped into window
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsFileDropped();

	    // Get dropped files names
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern char[] GetDroppedFiles(int[] count);
	  
	    // Clear dropped files paths buffer
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ClearDroppedFiles();

	    // Save integer value to storage file (to defined position)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void StorageSaveValue(int position, int value);

	    // Load integer value from storage file (from defined position)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int StorageLoadValue(int position);
	    
	    // Detect if a key has been pressed once
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsKeyPressed(int key);

	    // Detect if a key is being pressed
	    [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsKeyDown(int key);

	    // Detect if a key has been released once
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsKeyReleased(int key);
	    
	    // Detect if a key is NOT being pressed
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsKeyUp(int key);

	    // Get latest key pressed
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetKeyPressed();

	    // Set a custom key to exit program (default is ESC)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetExitKey(int key);

	    // Detect if a gamepad is available
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsGamepadAvailable(int gamepad);

	    // Check gamepad name (if available)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsGamepadName(int gamepad, string name);
	    
	    // Return gamepad internal name id
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern string GetGamepadName(int gamepad);

	    // Detect if a gamepad button has been pressed once
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsGamepadButtonPressed(int gamepad, int button);

	    // Detect if a gamepad button is being pressed
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsGamepadButtonDown(int gamepad, int button);

	    // Detect if a gamepad button has been released once
	    [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
	    public static extern bool IsGamepadButtonReleased(int gamepad, int button);

	    // Detect if a gamepad button is NOT being pressed
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsGamepadButtonUp(int gamepad, int button);

	    // Get the last gamepad button pressed
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetGamepadButtonPressed();

	    // Return gamepad axis count for a gamepad
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetGamepadAxisCount(int gamepad);

	    // Return axis movement value for a gamepad axis
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern float GetGamepadAxisMovement(int gamepad, int axis);
	    
		// Detect if a mouse button has been pressed once
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsMouseButtonPressed(int button);

	    // Detect if a mouse button is being pressed
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsMouseButtonDown(int button);

	    // Detect if a mouse button has been released once
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsMouseButtonReleased(int button);

	    // Detect if a mouse button is NOT being pressed
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsMouseButtonUp(int button);

	    // Returns mouse position X
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetMouseX();

	    // Returns mouse position Y
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetMouseY();

	    // Returns mouse position XY
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Vector2 GetMousePosition();

	    // Set mouse position XY
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetMousePosition(Vector2 position);

	    // Set mouse scaling
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetMouseScale(float scale);
	    
	    // Returns mouse wheel movement Y
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetMouseWheelMove();
	    
	    // Returns touch position X for touch point 0 (relative to screen size)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetTouchX();

	    // Returns touch position Y for touch point 0 (relative to screen size)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetTouchY();

	    // Returns touch position XY for a touch point index (relative to screen size)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Vector2 GetTouchPosition(int index);

	    // Enable a set of gestures using flags
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetGesturesEnabled(uint gestureFlags);
	    
	    // Check if a gesture have been detected
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsGestureDetected(int gesture);

	    // Get latest detected gesture
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetGestureDetected();

	    // Get touch points count
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetTouchPointsCount();
	    
	    // Get gesture hold time in milliseconds	    
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern float GetGestureHoldDuration();
	    
	    // Get gesture drag vector
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Vector2 GetGestureDragVector();

	    // Get gesture drag angle
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern float GetGestureDragAngle();

	    // Get gesture pinch delta
	    [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
	    public static extern Vector2 GetGesturePinchVector();
	    
	    // Get gesture pinch angle
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern float GetGesturePinchAngle();

	    // Set camera mode (multiple camera modes available)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetCameraMode(Camera3D camera, int mode);

	    // Update camera position for selected mode
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UpdateCamera(Camera3D camera);

	    // Set camera pan key to combine with mouse movement (free camera)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetCameraPanControl(int panKey);

	    // Set camera alt key to combine with mouse movement (free camera)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetCameraAltControl(int altKey);

	    // Set camera smooth zoom key to combine with mouse (free camera)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetCameraSmoothZoomControl(int szKey);

	    // Set camera move controls (1st person and 3rd person cameras)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetCameraMoveControls(int frontKey, int backKey, int rightKey, int leftKey, int upKey, int downKey);

	    // Draw a pixel
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawPixel(int posX, int posY, Color color);

	    // Draw a pixel (Vector version)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawPixelV(Vector2 position, Color color);

	    // Draw a line
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color);

	    // Draw a line (Vector version)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawLineV(Vector2 startPos, Vector2 endPos, Color color);

	    // Draw a line defining thickness
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color);

	    // Draw a line using cubic-bezier curves in-out
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color);

	    // Draw a color-filled circle
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawCircle(int centerX, int centerY, float radius, Color color);

	    // Draw a gradient-filled circle
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2);

	    // Draw a color-filled circle (Vector version)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawCircleV(Vector2 center, float radius, Color color);

	    // Draw circle outline
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawCircleLines(int centerX, int centerY, float radius, Color color);

	    // Draw a color-filled rectangle
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawRectangle(int posX, int posY, int width, int height, Color color);

	    // Draw a color-filled rectangle (Vector version)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawRectangleV(Vector2 position, Vector2 size, Color color);

	    // Draw a color-filled rectangle
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawRectangleRec(Rectangle rec, Color color);

	    // Draw a color-filled rectangle with pro parameters
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color);

	    // Draw a vertical-gradient-filled rectangle
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2);

	    // Draw a horizontal-gradient-filled rectangle
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawRectangleGradientH(int posX, int posY, int width, int height, Color color1, Color color2);

	    // Draw a gradient-filled rectangle with custom vertex colors
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4);

	    // Draw rectangle outline
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawRectangleLines(int posX, int posY, int width, int height, Color color);

	    // Draw rectangle outline with extended parameters
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawRectangleLinesEx(Rectangle rec, int lineThick, Color color);
	    
	    // Draw a color-filled triangle
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color);

	    // Draw triangle outline
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color);

	    // Draw a regular polygon (Vector version)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color);

	    // Draw a closed polygon defined by points
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawPolyEx(Vector2[] points, int numPoints, Color color);

	    // Draw polygon lines
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawPolyExLines(Vector2[] points, int numPoints, Color color);

	    // Check collision between two rectangles
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2);

	    // Check collision between two circles
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2);

	    // Check collision between circle and rectangle
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec);
		
	    // Get collision rectangle for two rectangles collision
	    [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2);

        // Check if point is inside rectangle
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool CheckCollisionPointRec(Vector2 point, Rectangle rec);

        // Check if point is inside circle
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius);

        // Check if point is inside a triangle
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3);

        // Load image from file into CPU memory (RAM)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image LoadImage(string fileName);

        // Load image from Color array data (RGBA - 32bit)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image LoadImageEx(Color pixels, int width, int height);

        // Load image from raw data with parameters
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image LoadImagePro(IntPtr data, int width, int height, int format);

        // Load image from RAW file data
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image LoadImageRaw(string fileName, int width, int height, int format, int headerSize);

        // Export image as a PNG file
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ExportImage(string fileName, Image image);

        // Load texture from file into GPU memory (VRAM)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Texture2D LoadTexture(string fileName);

        // Load texture from image data
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Texture2D LoadTextureFromImage(Image image);

        // Load texture for rendering (framebuffer)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern RenderTexture2D LoadRenderTexture(int width, int height);

        // Unload image from CPU memory (RAM)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UnloadImage(Image image);

        // Unload texture from GPU memory (VRAM)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UnloadTexture(Texture2D texture);

        // Unload render texture from GPU memory (VRAM)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UnloadRenderTexture(RenderTexture2D target);

        // Get pixel data from image as a Color struct array
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Color[] GetImageData(Image image);

        // Get pixel data from image as Vector4 array (float normalized)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Vector4[] GetImageDataNormalized(Image image);

        // Get pixel data size in bytes (image or texture)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetPixelDataSize(int width, int height, int format);

        // Get pixel data from GPU texture and return an Image
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image GetTextureData(Texture2D texture);

        // Update GPU texture with new data
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UpdateTexture(Texture2D texture, byte[] pixels);

        // Create an image duplicate (useful for transformations)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image ImageCopy(Image image);

        // Convert image to POT (power-of-two)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageToPOT(Image image, Color fillColor);

        // Convert image data to desired format
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageFormat(Image image, int newFormat);

        // Apply alpha mask to image
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageAlphaMask(Image image, Image alphaMask);

        // Clear alpha channel to desired color
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageAlphaClear(Image image, Color color, float threshold);

        // Crop image depending on alpha value
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageAlphaCrop(Image image, float threshold);

        // Premultiply alpha channel
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageAlphaPremultiply(Image image);

        // Crop an image to a defined rectangle
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageCrop(Image image, Rectangle crop);

        // Resize image (bilinear filtering)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageResize(Image image, int newWidth, int newHeight);

        // Resize image (Nearest-Neighbor scaling algorithm)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageResizeNN(Image image, int newWidth,int newHeight);

        // Resize canvas and fill with color
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageResizeCanvas(Image image, int newWidth, int newHeight, int offsetX, int offsetY, Color color);

        // Generate all mipmap levels for a provided image
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageMipmaps(Image image);

        // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageDither(Image image, int rBpp, int gBpp, int bBpp, int aBpp);

        // Create an image from text (default font)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image ImageText(string text, int fontSize, Color color);

        // Create an image from text (custom sprite font)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image ImageTextEx(Font font, string text, float fontSize, float spacing, Color tint);

        // Draw a source image within a destination image
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageDraw(Image dst, Image src, Rectangle srcRec, Rectangle dstRec);

        // Draw rectangle within an image
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageDrawRectangle(Image dst, Vector2 position, Rectangle rec, Color color);

        // Draw text (default font) within an image (destination)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageDrawText(Image dst, Vector2 position, string text, int fontSize, Color color);

        // Draw text (custom sprite font) within an image (destination)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageDrawTextEx(Image dst, Vector2 position, Font font, string text, float fontSize, float spacing, Color color);

        // Flip image vertically
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageFlipVertical(Image image);

        // Flip image horizontally
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageFlipHorizontal(Image image);

        // Rotate image clockwise 90deg
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageRotateCW(Image image);

        // Rotate image counter-clockwise 90deg
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageRotateCCW(Image image);

        // Modify image color: tint
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageColorTint(Image image, Color color);

        // Modify image color: invert
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageColorInvert(Image image);

        // Modify image color: grayscale
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageColorGrayscale(Image image);

        // Modify image color: contrast (-100 to 100)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageColorContrast(Image image, float contrast);

        // Modify image color: brightness (-255 to 255)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageColorBrightness(Image image, int brightness);

        // Modify image color: replace color
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ImageColorReplace(Image image, Color color, Color replace);

        // Generate image: plain color
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image GenImageColor(int width, int height, Color color);

        // Generate image: vertical gradient
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image GenImageGradientV(int width, int height, Color top, Color bottom);

        // Generate image: horizontal gradient
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image GenImageGradientH(int width, int height, Color left, Color right);

        // Generate image: radial gradient
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer);

        // Generate image: checked
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2);

        // Generate image: white noise
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image GenImageWhiteNoise(int width, int height, float factor);

        // Generate image: perlin noise
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float scale);

        // Generate image: cellular algorithm. Bigger tileSize means bigger cells
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image GenImageCellular(int width, int height, int tileSize);

        // Generate GPU mipmaps for a texture
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void GenTextureMipmaps(Texture2D texture);

        // Set texture scaling filter mode
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetTextureFilter(Texture2D texture, int filterMode);

        // Set texture wrapping mode
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetTextureWrap(Texture2D texture, int wrapMode);

        // Draw a Texture2D
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawTexture(Texture2D texture, int posX, int posY, Color tint);

        // Draw a Texture2D with position defined as Vector2
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawTextureV(Texture2D texture, Vector2 position, Color tint);

        // Draw a Texture2D with extended parameters
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint);

        // Draw a part of a texture defined by a rectangle
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint);

        // Draw a part of a texture defined by a rectangle with 'pro' parameters
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint);

        // Get the default Font
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Font GetFontDefault();

        // Load font from file into GPU memory (VRAM)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Font LoadFont(string fileName);

        // Load font from file with extended parameters
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Font LoadFontEx(string fileName, int fontSize, int charsCount, int[] fontChars);

        // Load font data for further use
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern CharInfo[] LoadFontData(string fileName, int fontSize, int[] fontChars, int charsCount, bool sdf);

        // Generate image font atlas using chars info
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Image GenImageFontAtlas(CharInfo[] chars, int fontSize, int charsCount, int padding, int packMethod);

	    // Unload Font from GPU memory (VRAM)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UnloadFont(Font font);

	    // Shows current FPS
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawFPS(int posX, int posY);

        // Draw text (using default font)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawText(string text, int posX, int posY, int fontSize, Color color);

        // Draw text using font and additional parameters
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawTextEx(Font font, string text, Vector2 position, float fontSize, float spacing, Color tint);

        // Measure string width for default font
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int MeasureText(string text, int fontSize);

        // Measure string size for Font
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Vector2 MeasureTextEx(Font font, string text, float fontSize, float spacing);

        // Formatting of text with variables to 'embed'
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern string FormatText(string text, params object[] args);

        // Get a piece of a text string
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern string SubText(string text, int position, int length);

        // Get index position for a unicode character on font
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetGlyphIndex(Font font, int character);

        // Draw a line in 3D world space
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color);

        // Draw a circle in 3D world space
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color);

        // Draw cube
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawCube(Vector3 position, float width, float height, float length, Color color);

        // Draw cube (Vector version)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawCubeV(Vector3 position, Vector3 size, Color color);

        // Draw cube wires
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawCubeWires(Vector3 position, float width, float height, float length, Color color);

        // Draw cube textured
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color);

        // Draw sphere
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawSphere(Vector3 centerPos, float radius, Color color);

        // Draw sphere with extended parameters
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color);

        // Draw sphere wires
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color);

        // Draw a cylinder/cone
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color);

        // Draw a cylinder/cone wires
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color);

        // Draw a plane XZ
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawPlane(Vector3 centerPos, Vector2 size, Color color);

        // Draw a ray line
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawRay(Ray ray, Color color);

        // Draw a grid (centered at (0, 0, 0))
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawGrid(int slices, float spacing);

        // Draw simple gizmo
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawGizmo(Vector3 position);

        // Load model from files (mesh and material)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Model LoadModel(string fileName);

        // Load model from generated mesh
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Model LoadModelFromMesh(Mesh mesh);

        // Unload model from memory (RAM and/or VRAM)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UnloadModel(Model model);

        // Load mesh from file
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Mesh LoadMesh(string fileName);

        // Unload mesh from memory (RAM and/or VRAM)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UnloadMesh(Mesh mesh);

        // Export mesh as an OBJ file
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ExportMesh(string fileName, Mesh mesh);

        // Compute mesh bounding box limits
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern BoundingBox MeshBoundingBox(Mesh mesh);

        // Compute mesh tangents
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void MeshTangents(Mesh mesh);

        // Compute mesh binormals
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void MeshBinormals(Mesh mesh);

        // Generate plane mesh (with subdivisions)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Mesh GenMeshPlane(float width, float length, int resX, int resZ);

        // Generate cuboid mesh
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Mesh GenMeshCube(float width, float height, float length);

        // Generate sphere mesh (standard sphere)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Mesh GenMeshSphere(float radius, int rings, int slices);

        // Generate half-sphere mesh (no bottom cap)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Mesh GenMeshHemiSphere(float radius, int rings, int slices);

        // Generate cylinder mesh
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Mesh GenMeshCylinder(float radius, float height, int slices);

        // Generate torus mesh
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Mesh GenMeshTorus(float radius, float size, int radSeg, int sides);

        // Generate trefoil knot mesh
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Mesh GenMeshKnot(float radius, float size, int radSeg, int sides);

        // Generate heightmap mesh from image data
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Mesh GenMeshHeightmap(Image heightmap, Vector3 size);

        // Generate cubes-based map mesh from image data
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);

        // Load material from file
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Material LoadMaterial(string fileName);

        // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Material LoadMaterialDefault();

        // Unload material from GPU memory (VRAM)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UnloadMaterial(Material material);

        // Draw a model (with texture if set)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawModel(Model model, Vector3 position, float scale, Color tint);

        // Draw a model with extended parameters
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint);

        // Draw a model wires (with texture if set)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawModelWires(Model model, Vector3 position, float scale, Color tint);

        // Draw a model wires (with texture if set) with extended parameters
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint);

        // Draw bounding box (wires)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawBoundingBox(BoundingBox box, Color color);

        // Draw a billboard texture
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void DrawBillboard(Camera3D camera, Texture2D texture, Vector3 center, float size, Color tint);

        // Draw a billboard texture defined by sourceRec
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
        public static extern void DrawBillboardRec(Camera3D camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint);

        // Detect collision between two spheres
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB);

        // Detect collision between two bounding boxes
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2);

        // Detect collision between box and sphere
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere);

        // Detect collision between ray and sphere
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius);

        // Detect collision between ray and sphere, returns collision point
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 collisionPoint);

        // Detect collision between ray and box
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool CheckCollisionRayBox(Ray ray, BoundingBox box);

        // Get collision info between ray and model
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern RayHitInfo GetCollisionRayModel(Ray ray, Model model);

        // Get collision info between ray and triangle
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3);

        // Get collision info between ray and ground plane (Y-normal plane)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight);

        // Load chars array from text file
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern string LoadText(string fileName);

        // Load shader from files and bind default locations
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Shader LoadShader(string vsFileName, string fsFileName);

        // Load shader from code strings and bind default locations
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Shader LoadShaderCode(string vsCode, string fsCode);

        // Unload shader from GPU memory (VRAM)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UnloadShader(Shader shader);

        // Get default shader
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Shader GetShaderDefault();

        // Get default texture
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Texture2D GetTextureDefault();

        // Get shader uniform location
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern int GetShaderLocation(Shader shader, string uniformName);

        // Set shader uniform value (float)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetShaderValue(Shader shader, int uniformLoc, float[] value, int size);

        // Set shader uniform value (int)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetShaderValuei(Shader shader, int uniformLoc, int[] value, int size);

        // Set shader uniform value (matrix 4x4)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat);

        // Set a custom projection matrix (replaces internal projection matrix)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetMatrixProjection(Matrix proj);

        // Set a custom modelview matrix (replaces internal modelview matrix)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetMatrixModelview(Matrix view);

        // Get internal modelview matrix
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Matrix GetMatrixModelview();

        // Generate cubemap texture from HDR texture
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Texture2D GenTextureCubemap(Shader shader, Texture2D skyHDR, int size);

        // Generate irradiance texture using cubemap data
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Texture2D GenTextureIrradiance(Shader shader, Texture2D cubemap, int size);

        // Generate prefilter texture using cubemap data
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Texture2D GenTexturePrefilter(Shader shader, Texture2D cubemap, int size);

        // Generate BRDF texture using cubemap data
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Texture2D GenTextureBRDF(Shader shader, Texture2D cubemap, int size);

        // Begin custom shader drawing
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void BeginShaderMode(Shader shader);

        // End custom shader drawing (use default shader)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void EndShaderMode();

        // Begin blending mode (alpha, additive, multiplied)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void BeginBlendMode(int mode);

        // End blending mode (reset to default: alpha blending)
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void EndBlendMode();

        // Get VR device information for some standard devices
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern VrDeviceInfo GetVrDeviceInfo(int vrDeviceType);

        // Init VR simulator for selected device parameters
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void InitVrSimulator(VrDeviceInfo info);

        // Close VR simulator for current device
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void CloseVrSimulator();

        // Detect if VR simulator is ready
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsVrSimulatorReady();

        // Set VR distortion shader for stereoscopic rendering
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetVrDistortionShader(Shader shader);

        // Update VR tracking (position and orientation) and camera
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UpdateVrTracking(Camera3D camera);

        // Enable/Disable VR experience
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ToggleVrMode();

        // Begin VR simulator stereo rendering
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void BeginVrDrawing();

        // End VR simulator stereo rendering
        [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void EndVrDrawing();

	    // Initialize audio device and context
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void InitAudioDevice();
	    
	    // Close the audio device and context
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void CloseAudioDevice();
	    
	    // Check if audio device has been initialized successfully
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsAudioDeviceReady();

	    // Set master volume (listener)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetMasterVolume(float volume);

	    // Load wave data from file
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Wave LoadWave(string fileName);

	    // Load wave data from raw array data
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Wave LoadWaveEx(IntPtr data, int sampleCount, int sampleRate, int sampleSize, int channels);

	    // Load sound from file
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Sound LoadSound(string fileName);

	    // Load sound from wave data
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Sound LoadSoundFromWave(Wave wave);

	    // Update sound buffer with new data
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UpdateSound(Sound sound, byte[] data, int samplesCount);

	    // Unload wave data
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UnloadWave(Wave wave);

	    // Unload sound
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UnloadSound(Sound sound);

	    // Play a sound
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void PlaySound(Sound sound);

	    // Pause a sound
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void PauseSound(Sound sound);
	    
	    // Resume a paused sound
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ResumeSound(Sound sound);

	    // Stop playing a sound
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void StopSound(Sound sound);

	    // Check if a sound is currently playing
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsSoundPlaying(Sound sound);

	    // Set volume for a sound (1.0 is max level)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetSoundVolume(Sound sound, float volume);

	    // Set pitch for a sound (1.0 is base level)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetSoundPitch(Sound sound, float pitch);

		// Convert wave data to desired format
	    [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
	    public static extern void WaveFormat(out Wave wave, int sampleRate, int sampleSize, int channels);

	    // Copy a wave to a new wave
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern Wave WaveCopy(Wave wave);

	    // Crop a wave to defined samples range
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void WaveCrop(out Wave wave, int initSample, int finalSample);

	    // Get samples data from wave as a floats array
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern float[] GetWaveData(Wave wave);

	    // Load IntPtr stream from file
	    [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
	    public static extern IntPtr LoadMusicStream(string fileName);

	    // Unload IntPtr stream
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UnloadMusicStream(IntPtr music);

	    // Start IntPtr playing
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void PlayMusicStream(IntPtr music);

	    // Updates buffers for IntPtr streaming
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UpdateMusicStream(IntPtr music);

	    // Stop IntPtr playing
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void StopMusicStream(IntPtr music);

	    // Pause IntPtr playing
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void PauseMusicStream(IntPtr music);

	    // Resume playing paused music
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ResumeMusicStream(IntPtr music);

	    // Check if IntPtr is playing
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsMusicPlaying(IntPtr music);

	    // Set volume for IntPtr (1.0 is max level)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetMusicVolume(IntPtr music, float volume);

	    // Set pitch for a IntPtr (1.0 is base level)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetMusicPitch(IntPtr music, float pitch);

		// Set IntPtr loop count (loop repeats)
	    [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
	    public static extern void SetMusicLoopCount(IntPtr music, int count);

	    // Get IntPtr time length (in seconds)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern float GetMusicTimeLength(IntPtr music);

	    // Get current IntPtr time played (in seconds)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern float GetMusicTimePlayed(IntPtr music);

	    // Init audio stream (to stream raw audio pcm data)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern AudioStream InitAudioStream(uint sampleRate, uint sampleSize, uint channels);

	    // Update audio stream buffers with data
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void UpdateAudioStream(AudioStream stream, byte[] data, int samplesCount);

	    // Close audio stream and free memory
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void CloseAudioStream(AudioStream stream);

	    // Check if any audio stream buffers requires refill
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsAudioBufferProcessed(AudioStream stream);

	    // Play audio stream
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void PlayAudioStream(AudioStream stream);

	    // Pause audio stream
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void PauseAudioStream(AudioStream stream);

	    // Resume audio stream
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void ResumeAudioStream(AudioStream stream);

	    // Check if audio stream is playing
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern bool IsAudioStreamPlaying(AudioStream stream);

	    // Stop audio stream
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void StopAudioStream(AudioStream stream);

	    // Set volume for audio stream (1.0 is max level)
	    [DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
	    public static extern void SetAudioStreamVolume(AudioStream stream, float volume);

	    // Set pitch for audio stream (1.0 is base level)
		[DllImport(nativeLibName,CallingConvention = CallingConvention.Cdecl)]
		public static extern void SetAudioStreamPitch(AudioStream stream, float pitch);
	    
		#endregion
    }
}
