// ImGui library
// See ImGui::ShowTestWindow() for sample code.
// Read 'Programmer guide' below for notes on how to setup ImGui in your codebase.
// Get latest version at https://github.com/ocornut/imgui

/*
 
 MISSION STATEMENT

 - easy to use to create code-driven and data-driven tools
 - easy to use to create adhoc short-lived tools and long-lived, more elaborate tools
 - easy to hack and improve
 - minimize screen real-estate usage
 - minimize setup and maintainance
 - minimize state storage on user side
 - portable, minimize dependencies, run on target (consoles, etc.)
 - efficient runtime (nb- we do allocate when "growing" content - creating a window / opening a tree node for the first time, etc. - but a typical frame won't allocate anything)
 - read about immediate-mode GUI principles @ http://mollyrocket.com/861, http://mollyrocket.com/forums/index.html

 Designed for developers and content-creators, not the typical end-user! Some of the weaknesses includes:
 - doesn't look fancy, doesn't animate
 - limited layout features, intricate layouts are typically crafted in code
 - assume ASCII text, using strlen() and [] operators, etc
 - occasionally use statically sized buffers for string manipulations - won't crash, but some long text may be clipped
 
 USER GUIDE

 - double-click title bar to collapse window
 - click upper right corner to close a window, available when 'bool* open' is passed to ImGui::Begin()
 - click and drag on lower right corner to resize window
 - click and drag on any empty space to move window
 - double-click/double-tap on lower right corner grip to auto-fit to content
 - TAB/SHIFT+TAB to cycle through keyboard editable fields
 - use mouse wheel to scroll
 - use CTRL+mouse wheel to zoom window contents (if IO.FontAllowScaling is true)
 - CTRL+Click on a slider to input value as text
 - text editor:
   - Hold SHIFT or use mouse to select text.
   - CTRL+Left/Right to word jump
   - CTRL+Shift+Left/Right to select words
   - CTRL+A our Double-Click to select all
   - CTRL+X,CTRL+C,CTRL+V to use OS clipboard
   - CTRL+Z,CTRL+Y to undo/redo
   - ESCAPE to revert text to its original value
   - You can apply arithmetic operators +,*,/ on numerical values. Use +- to subtract (because - would set a negative value!)

 PROGRAMMER GUIDE

 - your code creates the UI, if your code doesn't run the UI is gone! == dynamic UI, no construction step, less data retention on your side, no state duplication, less sync, less errors.
 - see ImGui::ShowTestWindow() for user-side sample code
 - getting started:
   - initialisation: call ImGui::GetIO() and fill the 'Settings' data.
   - every frame: 
      1/ in your mainloop or right after you got your keyboard/mouse info, call ImGui::GetIO() and fill the 'Input' data, then call ImGui::NewFrame().
      2/ use any ImGui function you want between NewFrame() and Render()
      3/ ImGui::Render() to render all the accumulated command-lists. it will cack your RenderDrawListFn handler set in the IO structure.
   - all rendering information are stored into command-lists until ImGui::Render() is called.
   - effectively it means you can create widgets at any time in your code, regardless of "update" vs "render" considerations.
   - a typical application skeleton may be:

		// Application init
		// TODO: Fill all 'Settings' fields of the io structure
		ImGuiIO& io = ImGui::GetIO();
		io.DisplaySize.x = 1920.0f;
		io.DisplaySize.y = 1280.0f;
		io.DeltaTime = 1.0f/60.0f;
		io.IniFilename = "imgui.ini";

		// Application mainloop
		while (true)
		{
			// 1/ get low-level input
			// e.g. on Win32, GetKeyboardState(), or poll your events, etc.
			
			// 2/ TODO: Fill all 'Input' fields of io structure and call NewFrame
			ImGuiIO& io = ImGui::GetIO();
			io.MousePos = ...
			io.KeysDown[i] = ...
			ImGui::NewFrame();

			// 3/ most of your application code here - you can use any of ImGui::* functions between NewFrame() and Render() calls
			GameUpdate();
			GameRender();

			// 4/ render & swap video buffers
			ImGui::Render();
			// swap video buffer, etc.
		}

 - some widgets carry state and requires an unique ID to do so.
   - unique ID are typically derived from a string label, an indice or a pointer.
   - use PushID/PopID to easily create scopes and avoid ID conflicts. A Window is also an implicit scope.
   - when creating trees, ID are particularly important because you want to preserve the opened/closed state of tree nodes.
     depending on your use cases you may want to use strings, indices or pointers as ID. experiment and see what makes more sense!
      e.g. When displaying a single object, using a static string as ID will preserve your node open/closed state when the targetted object change
      e.g. When displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state per object
   - when passing a label you can optionally specify extra unique ID information within the same string using "##". This helps solving the simpler collision cases.
      e.g. "Label" display "Label" and uses "Label" as ID
      e.g. "Label##Foobar" display "Label" and uses "Label##Foobar" as ID
      e.g. "##Foobar" display an empty label and uses "##Foobar" as ID

 - if you want to use a different font than the default
   - create bitmap font data using BMFont. allocate ImGui::GetIO().Font and use ->LoadFromFile()/LoadFromMemory(), set ImGui::GetIO().FontHeight
   - load your texture yourself. texture *MUST* have white pixel at UV coordinate 'IMGUI_FONT_TEX_UV_FOR_WHITE' (you can #define it in imconfig.h), this is used by solid objects.

 - tip: the construct 'if (IMGUI_ONCE_UPON_A_FRAME)' will evaluate to true only once a frame, you can use it to add custom UI in the middle of a deep nested inner loop in your code.
 - tip: you can call Render() multiple times (e.g for VR renders), up to you to communicate the extra state to your RenderDrawListFn function.
 - tip: you can create widgets without a Begin/End block, they will go in an implicit window called "Debug"

 ISSUES AND TODO-LIST

 - misc: merge ImVec4 / ImGuiAabb, they are essentially duplicate containers
 - window: autofit is losing its purpose when user relies on any dynamic layout (window width multiplier, column). maybe just discard autofit?
 - window: support horizontal scroll
 - window: fix resize grip scaling along with Rounding style setting
 - widgets: switching from "widget-label" to "label-widget" would make it more convenient to integrate widgets in trees
 - widgets: clip text? hover clipped text shows it in a tooltip or in-place overlay
 - main: make IsHovered() more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes
 - main: make IsHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode?
 - scrollbar: use relative mouse movement when first-clicking inside of scroll grab box.
 - scrollbar: make the grab visible and a minimum size for long scroll regions
 - input number: optional range min/max
 - input number: holding [-]/[+] buttons should increase the step non-linearly
 - input number: use mouse wheel to step up/down
 - layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 horrible layout code. item width should include frame padding, then we can have a generic horizontal layout helper.
 - columns: declare column set (each column: fixed size, %, fill, distribute default size among fills)
 - columns: columns header to act as button (~sort op) and allow resize/reorder
 - columns: user specify columns size
 - combo: turn child handling code into popup helper
 - list selection, concept of a selectable "block" (that can be multiple widgets)
 - menubar, menus
 - plot: make it easier for user to draw into the graph (e.g: draw basis, highlight certain pointsm, 2d plots, multiple plots)
 - plot: "smooth" automatic scale, user give an input 0.0(full user scale) 1.0(full derived from value)
 - plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID)
 - file selection widget -> build the tool in our codebase to improve model-dialog idioms (may or not lead to ImGui changes)
 - slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt()
 - slider: initial absolute click is unprecise. change to relative movement slider? hide mouse cursor, allow more precise input using less screen-space.
 - text edit: centered text for slider or input text to it matches typical positionning.
 - text edit: flag to disable live update of the user buffer. 
 - text edit: field resize behaviour - field could stretch when being edited? hover tooltip shows more text?
 - text edit: pasting text into a number box should filter the characters the same way direct input does
 - text edit: allow code to catch user pressing Return (perhaps through disable live edit? so only Return apply the final value, also allow catching Return if value didn't changed)
 - settings: write more decent code to allow saving/loading new fields
 - log: be able to right-click and log a window or tree-node into tty/file/clipboard?
 - filters: set a current filter that tree node can automatically query to hide themselves
 - filters: handle wildcards (with implicit leading/trailing *), regexps
 - shortcuts: add a shortcut api, e.g. parse "&Save" and/or "Save (CTRL+S)", pass in to widgets or provide simple ways to use (button=activate, input=focus)
 - input: keyboard: full keyboard navigation and focus.
 - input: support trackpad style scrolling & slider edit.
 - misc: not thread-safe
 - misc: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon?
 - optimisation/render: use indexed rendering
 - optimisation/render: move clip-rect to vertex data? would allow merging all commands
 - optimisation/render: merge command-list of all windows into one command-list?
 - optimisation/render: font exported by bmfont is not tight fit on vertical axis, incur unneeded pixel-shading cost.
 - optimisation: turn some the various stack vectors into statically-sized arrays
 - optimisation: better clipping for multi-component widgets
 - optimisation: specialize for height based clipping first (assume widgets never go up + height tests before width tests?)
*/

#include "imgui.h"
#include <ctype.h>		// toupper
#include <math.h>		// sqrt
#include <stdint.h>		// intptr_t
#include <stdio.h>		// vsnprintf
#include <string.h>		// memset

#ifdef _MSC_VER
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#endif

//-------------------------------------------------------------------------
// Forward Declarations
//-------------------------------------------------------------------------

namespace ImGui
{

static bool			ButtonBehaviour(const ImGuiAabb& bb, const ImGuiID& id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, bool repeat = false);
static void			RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f);
static void			RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, const bool hide_text_after_hash = true);
static ImVec2		CalcTextSize(const char* text, const char* text_end = NULL, const bool hide_text_after_hash = true);
static void			LogText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL);

static void			ItemSize(ImVec2 size, ImVec2* adjust_start_offset = NULL);
static void			ItemSize(const ImGuiAabb& aabb, ImVec2* adjust_start_offset = NULL);
static void			PushColumnClipRect(int column_index = -1);
static bool			IsClipped(const ImGuiAabb& aabb);
static bool			ClipAdvance(const ImGuiAabb& aabb);

static bool			IsMouseHoveringBox(const ImGuiAabb& box);
static bool			IsKeyPressedMap(ImGuiKey key, bool repeat = true);

static bool			CloseWindowButton(bool* open = NULL);
static void			FocusWindow(ImGuiWindow* window);
static ImGuiWindow* FindWindow(const char* name);
static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs);

}; // namespace ImGui

//-----------------------------------------------------------------------------
// Platform dependant default implementations
//-----------------------------------------------------------------------------

static const char*	GetClipboardTextFn_DefaultImpl();
static void			SetClipboardTextFn_DefaultImpl(const char* text, const char* text_end);

//-----------------------------------------------------------------------------
// User facing structures
//-----------------------------------------------------------------------------

ImGuiStyle::ImGuiStyle()
{
	Alpha					= 1.0f;				// Global alpha applies to everything in ImGui
	WindowPadding			= ImVec2(8,8);		// Padding within a window
	WindowMinSize			= ImVec2(48,48);	// Minimum window size
	FramePadding			= ImVec2(5,4);		// Padding within a framed rectangle (used by most widgets)
	ItemSpacing				= ImVec2(10,5);		// Horizontal and vertical spacing between widgets/lines
	ItemInnerSpacing		= ImVec2(5,5);		// Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label)
	TouchExtraPadding		= ImVec2(0,0);		// Expand bounding box for touch-based system where touch position is not accurate enough (unnecessary for mouse inputs). Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget running. So dont grow this too much!
	AutoFitPadding			= ImVec2(8,8);		// Extra space after auto-fit (double-clicking on resize grip)
	WindowFillAlphaDefault	= 0.70f;			// Default alpha of window background, if not specified in ImGui::Begin()
	WindowRounding			= 10.0f;			// Radius of window corners rounding. Set to 0.0f to have rectangular windows
	TreeNodeSpacing			= 22.0f;			// Horizontal spacing when entering a tree node
	ColumnsMinSpacing		= 6.0f;				// Minimum horizontal spacing between two columns
	ScrollBarWidth			= 16.0f;			// Width of the vertical scroll bar

	Colors[ImGuiCol_Text]					= ImVec4(0.90f, 0.90f, 0.90f, 1.00f);
	Colors[ImGuiCol_WindowBg]				= ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
	Colors[ImGuiCol_Border]					= ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
	Colors[ImGuiCol_BorderShadow]			= ImVec4(0.00f, 0.00f, 0.00f, 0.60f);
	Colors[ImGuiCol_FrameBg]				= ImVec4(0.80f, 0.80f, 0.80f, 0.30f);	// Background of checkbox, radio button, plot, slider, text input
	Colors[ImGuiCol_TitleBg]				= ImVec4(0.50f, 0.50f, 1.00f, 0.45f);
	Colors[ImGuiCol_TitleBgCollapsed]		= ImVec4(0.40f, 0.40f, 0.80f, 0.20f);
	Colors[ImGuiCol_ScrollbarBg]			= ImVec4(0.40f, 0.40f, 0.80f, 0.15f);
	Colors[ImGuiCol_ScrollbarGrab]			= ImVec4(0.40f, 0.40f, 0.80f, 0.30f);
	Colors[ImGuiCol_ScrollbarGrabHovered]	= ImVec4(0.40f, 0.40f, 0.80f, 0.40f);
	Colors[ImGuiCol_ScrollbarGrabActive]	= ImVec4(0.80f, 0.50f, 0.50f, 0.40f);
	Colors[ImGuiCol_ComboBg]				= ImVec4(0.20f, 0.20f, 0.20f, 0.99f);
	Colors[ImGuiCol_CheckHovered]			= ImVec4(0.60f, 0.40f, 0.40f, 0.45f);
	Colors[ImGuiCol_CheckActive]			= ImVec4(0.90f, 0.90f, 0.90f, 0.50f);
	Colors[ImGuiCol_SliderGrab]				= ImVec4(1.00f, 1.00f, 1.00f, 0.30f);
	Colors[ImGuiCol_SliderGrabActive]		= ImVec4(0.80f, 0.50f, 0.50f, 1.00f);
	Colors[ImGuiCol_Button]					= ImVec4(0.67f, 0.40f, 0.40f, 0.60f);
	Colors[ImGuiCol_ButtonHovered]			= ImVec4(0.67f, 0.40f, 0.40f, 1.00f);
	Colors[ImGuiCol_ButtonActive]			= ImVec4(0.80f, 0.50f, 0.50f, 1.00f);
	Colors[ImGuiCol_Header]					= ImVec4(0.40f, 0.40f, 0.90f, 0.45f);
	Colors[ImGuiCol_HeaderHovered]			= ImVec4(0.45f, 0.45f, 0.90f, 0.80f);
	Colors[ImGuiCol_HeaderActive]			= ImVec4(0.60f, 0.60f, 0.80f, 1.00f);
	Colors[ImGuiCol_Column]					= ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
	Colors[ImGuiCol_ColumnHovered]			= ImVec4(0.60f, 0.40f, 0.40f, 1.00f);
	Colors[ImGuiCol_ColumnActive]			= ImVec4(0.80f, 0.50f, 0.50f, 1.00f);
	Colors[ImGuiCol_ResizeGrip]				= ImVec4(1.00f, 1.00f, 1.00f, 0.30f);
	Colors[ImGuiCol_ResizeGripHovered]		= ImVec4(1.00f, 1.00f, 1.00f, 0.60f);
	Colors[ImGuiCol_ResizeGripActive]		= ImVec4(1.00f, 1.00f, 1.00f, 0.90f);
	Colors[ImGuiCol_CloseButton]			= ImVec4(0.50f, 0.50f, 0.90f, 0.50f);
	Colors[ImGuiCol_CloseButtonHovered]		= ImVec4(0.70f, 0.70f, 0.90f, 0.60f);
	Colors[ImGuiCol_CloseButtonActive]		= ImVec4(0.70f, 0.70f, 0.70f, 1.00f);
	Colors[ImGuiCol_PlotLines]				= ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
	Colors[ImGuiCol_PlotLinesHovered]		= ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
	Colors[ImGuiCol_PlotHistogram]			= ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
	Colors[ImGuiCol_PlotHistogramHovered]	= ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
	Colors[ImGuiCol_TextSelectedBg]			= ImVec4(0.00f, 0.00f, 1.00f, 0.35f);
	Colors[ImGuiCol_TooltipBg]				= ImVec4(0.05f, 0.05f, 0.10f, 0.90f);
}

ImGuiIO::ImGuiIO()
{
	memset(this, 0, sizeof(*this));
	DeltaTime = 1.0f/60.0f;
	IniSavingRate = 5.0f;
	IniFilename = "imgui.ini";
	LogFilename = "imgui_log.txt";
	Font = NULL;
	FontAllowScaling = false;
	PixelCenterOffset = 0.5f;
	MousePos = ImVec2(-1,-1);
	MousePosPrev = ImVec2(-1,-1);
	MouseDoubleClickTime = 0.30f;
	MouseDoubleClickMaxDist = 6.0f;

	// Platform dependant default implementations
	GetClipboardTextFn = GetClipboardTextFn_DefaultImpl;
	SetClipboardTextFn = SetClipboardTextFn_DefaultImpl;
}

// Pass in translated ASCII characters for text input.
// - with glfw you can get those from the callback set in glfwSetCharCallback()
// - on Windows you can get those using ToAscii+keyboard state, or via the VM_CHAR message
void ImGuiIO::AddInputCharacter(char c)
{
	const size_t n = strlen(InputCharacters);
	if (n < sizeof(InputCharacters) / sizeof(InputCharacters[0]))
	{
		InputCharacters[n] = c;
		InputCharacters[n+1] = 0;
	}
}

//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------

#define IM_ARRAYSIZE(_ARR)			((int)(sizeof(_ARR)/sizeof(*_ARR)))

#undef PI
const float PI = 3.14159265358979323846f;

#ifdef INT_MAX
#define IM_INT_MAX INT_MAX
#else
#define IM_INT_MAX 2147483647
#endif

// Math bits
// We are keeping those static in the .cpp file so as not to leak them outside, in the case the user has implicit cast operators between ImVec2 and its own types.
static inline ImVec2 operator*(const ImVec2& lhs, const float rhs)				{ return ImVec2(lhs.x*rhs, lhs.y*rhs); }
static inline ImVec2 operator/(const ImVec2& lhs, const float rhs)				{ return ImVec2(lhs.x/rhs, lhs.y/rhs); }
static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs)			{ return ImVec2(lhs.x+rhs.x, lhs.y+rhs.y); }
static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs)			{ return ImVec2(lhs.x-rhs.x, lhs.y-rhs.y); }
static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2 rhs)				{ return ImVec2(lhs.x*rhs.x, lhs.y*rhs.y); }
static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2 rhs)				{ return ImVec2(lhs.x/rhs.x, lhs.y/rhs.y); }
static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs)				{ lhs.x += rhs.x; lhs.y += rhs.y; return lhs; }
static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs)				{ lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; }
static inline ImVec2& operator*=(ImVec2& lhs, const float rhs)					{ lhs.x *= rhs; lhs.y *= rhs; return lhs; }
static inline ImVec2& operator/=(ImVec2& lhs, const float rhs)					{ lhs.x /= rhs; lhs.y /= rhs; return lhs; }

static inline int    ImMin(int lhs, int rhs)									{ return lhs < rhs ? lhs : rhs; }
static inline int    ImMax(int lhs, int rhs)									{ return lhs >= rhs ? lhs : rhs; }
static inline float  ImMin(float lhs, float rhs)								{ return lhs < rhs ? lhs : rhs; }
static inline float  ImMax(float lhs, float rhs)								{ return lhs >= rhs ? lhs : rhs; }
static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs)				{ return ImVec2(ImMin(lhs.x,rhs.x), ImMin(lhs.y,rhs.y)); }
static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs)				{ return ImVec2(ImMax(lhs.x,rhs.x), ImMax(lhs.y,rhs.y)); }
static inline float  ImClamp(float f, float mn, float mx)						{ return (f < mn) ? mn : (f > mx) ? mx : f; }
static inline ImVec2 ImClamp(const ImVec2& f, const ImVec2& mn, ImVec2 mx)		{ return ImVec2(ImClamp(f.x,mn.x,mx.x), ImClamp(f.y,mn.y,mx.y)); }
static inline float  ImSaturate(float f)										{ return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; }
static inline float  ImLerp(float a, float b, float t)							{ return a + (b - a) * t; }
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t)			{ return a + (b - a) * t; }
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t)	{ return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); }
static inline float  ImLength(const ImVec2& lhs)								{ return sqrt(lhs.x*lhs.x + lhs.y*lhs.y); }

static int ImStricmp(const char* str1, const char* str2)
{
	int d;
	while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; }
	return d;
}

static const char* ImStristr(const char* haystack, const char* needle, const char* needle_end)
{
	if (!needle_end)
		needle_end = needle + strlen(needle);

	const char un0 = (char)toupper(*needle);
	while (*haystack)
	{
		if (toupper(*haystack) == un0)
		{
			const char* b = needle + 1;
			for (const char* a = haystack + 1; b < needle_end; a++, b++)
				if (toupper(*a) != toupper(*b))
					break;
			if (b == needle_end)
				return haystack;
		}
		haystack++;
	}
	return NULL;
}

static ImU32 crc32(const void* data, size_t data_size, ImU32 seed = 0) 
{ 
	static ImU32 crc32_lut[256] = { 0 };
	if (!crc32_lut[1])
	{
		const ImU32 polynomial = 0xEDB88320;
		for (ImU32 i = 0; i < 256; i++) 
		{ 
			ImU32 crc = i; 
			for (ImU32 j = 0; j < 8; j++) 
				crc = (crc >> 1) ^ (-int(crc & 1) & polynomial); 
			crc32_lut[i] = crc; 
		}
	}
	ImU32 crc = ~seed; 
	const unsigned char* current = (const unsigned char*)data; 
	while (data_size--) 
		crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ *current++]; 
	return ~crc; 
} 

static size_t ImFormatString(char* buf, size_t buf_size, const char* fmt, ...)
{
	va_list args;
	va_start(args, fmt);
	int w = vsnprintf(buf, buf_size, fmt, args);
	va_end(args);
	buf[buf_size-1] = 0;
	if (w == -1) w = (int)buf_size;
	return w;
}

static size_t ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args)
{
	int w = vsnprintf(buf, buf_size, fmt, args);
	buf[buf_size-1] = 0;
	if (w == -1) w = (int)buf_size;
	return w;
}

static ImU32 ImConvertColorFloat4ToU32(const ImVec4& in)
{
	ImU32 out  = ((ImU32)(ImSaturate(in.x)*255.f));
	out |= ((ImU32)(ImSaturate(in.y)*255.f) << 8);
	out |= ((ImU32)(ImSaturate(in.z)*255.f) << 16);
	out |= ((ImU32)(ImSaturate(in.w)*255.f) << 24);
	return out;
}

// Convert rgb floats ([0-1],[0-1],[0-1]) to hsv floats ([0-1],[0-1],[0-1]), from Foley & van Dam p592
// Optimized http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv
static void ImConvertColorRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v)
{
	float K = 0.f;
	if (g < b)
	{
		const float tmp = g; g = b; b = tmp;
		K = -1.f;
	}
	if (r < g)
	{
		const float tmp = r; r = g; g = tmp;
		K = -2.f / 6.f - K;
	}

	const float chroma = r - (g < b ? g : b);
	out_h = fabsf(K + (g - b) / (6.f * chroma + 1e-20f));
	out_s = chroma / (r + 1e-20f);
	out_v = r;
}

// Convert hsv floats ([0-1],[0-1],[0-1]) to rgb floats ([0-1],[0-1],[0-1]), from Foley & van Dam p593
// also http://en.wikipedia.org/wiki/HSL_and_HSV
static void ImConvertColorHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b)
{   
	if (s == 0.0f)
	{
		// gray
		out_r = out_g = out_b = v;
		return;
	}

	h = fmodf(h, 1.0f) / (60.0f/360.0f);
	int   i = (int)h;
	float f = h - (float)i;
	float p = v * (1.0f - s);
	float q = v * (1.0f - s * f);
	float t = v * (1.0f - s * (1.0f - f));

	switch (i)
	{
	case 0: out_r = v; out_g = t; out_b = p; break;
	case 1: out_r = q; out_g = v; out_b = p; break;
	case 2: out_r = p; out_g = v; out_b = t; break;
	case 3: out_r = p; out_g = q; out_b = v; break;
	case 4: out_r = t; out_g = p; out_b = v; break;
	case 5: default: out_r = v; out_g = p; out_b = q; break;
	}
}

//-----------------------------------------------------------------------------

struct ImGuiColMod	// Color/style modifier, backup of modified data so we can restore it
{
	ImGuiCol	Col;
	ImVec4		PreviousValue;
};

struct ImGuiAabb	// 2D axis aligned bounding-box
{
	ImVec2		Min;
	ImVec2		Max;

	ImGuiAabb()											{ Min = ImVec2(FLT_MAX,FLT_MAX); Max = ImVec2(-FLT_MAX,-FLT_MAX); }
	ImGuiAabb(const ImVec2& min, const ImVec2& max)		{ Min = min; Max = max; }
	ImGuiAabb(const ImVec4& v)							{ Min.x = v.x; Min.y = v.y; Max.x = v.z; Max.y = v.w; }
	ImGuiAabb(float x1, float y1, float x2, float y2)	{ Min.x = x1; Min.y = y1; Max.x = x2; Max.y = y2; }

	ImVec2		GetCenter() const						{ return Min + (Max-Min)*0.5f; }
	ImVec2		GetSize() const							{ return Max-Min; }
	float		GetWidth() const						{ return (Max-Min).x; }
	float		GetHeight() const						{ return (Max-Min).y; }
	ImVec2		GetTL() const							{ return Min; }
	ImVec2		GetTR() const							{ return ImVec2(Max.x,Min.y); }
	ImVec2		GetBL() const							{ return ImVec2(Min.x,Max.y); }
	ImVec2		GetBR() const							{ return Max; }
	bool		Contains(ImVec2 p) const 				{ return p.x >= Min.x && p.y >= Min.y && p.x <= Max.x && p.y <= Max.y; }
	bool		Contains(const ImGuiAabb& r) const		{ return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x <= Max.x && r.Max.y <= Max.y; }
	bool		Overlaps(const ImGuiAabb& r) const		{ return r.Min.y <= Max.y && r.Max.y >= Min.y && r.Min.x <= Max.x && r.Max.x >= Min.x; }
	void		Expand(ImVec2 sz)						{ Min -= sz; Max += sz; }
	void		Clip(const ImGuiAabb& clip)				{ Min.x = ImMax(Min.x, clip.Min.x); Min.y = ImMax(Min.y, clip.Min.y); Max.x = ImMin(Max.x, clip.Max.x); Max.y = ImMin(Max.y, clip.Max.y); }
};

// Temporary per-window data, reset at the beginning of the frame
struct ImGuiDrawContext
{
	ImVec2					CursorPos;
	ImVec2					CursorPosPrevLine;
	ImVec2					CursorStartPos;
	float					CurrentLineHeight;
	float					PrevLineHeight;
	float					LogLineHeight;
	int						TreeDepth;
	ImGuiAabb				LastItemAabb;
	bool					LastItemHovered;
	ImVector<ImGuiWindow*>	ChildWindows;
	ImVector<bool>			AllowKeyboardFocus;
	ImVector<float>			ItemWidth;
	ImVector<ImGuiColMod>	ColorModifiers;
	ImGuiColorEditMode		ColorEditMode;
	ImGuiStorage*			StateStorage;
	int						OpenNextNode;

	float					ColumnStartX;
	int						ColumnCurrent;
	int						ColumnsCount;
	bool					ColumnsShowBorders;
	ImVec2					ColumnsStartCursorPos;
	ImGuiID					ColumnsSetID;

	ImGuiDrawContext()
	{
		CursorPos = CursorPosPrevLine = CursorStartPos = ImVec2(0.0f, 0.0f);
		CurrentLineHeight = PrevLineHeight = 0.0f;
		LogLineHeight = -1.0f;
		TreeDepth = 0;
		LastItemAabb = ImGuiAabb(0.0f,0.0f,0.0f,0.0f);
		LastItemHovered = false;
		StateStorage = NULL;
		OpenNextNode = -1;

		ColumnStartX = 0.0f;
		ColumnCurrent = 0;
		ColumnsCount = 1;
		ColumnsShowBorders = true;
		ColumnsStartCursorPos = ImVec2(0,0);
	}
};

struct ImGuiTextEditState;
#define STB_TEXTEDIT_STRING	ImGuiTextEditState
#define STB_TEXTEDIT_CHARTYPE char
#include "stb_textedit.h"

// State of the currently focused/edited text input box
struct ImGuiTextEditState
{
	char				Text[1024];						// edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so own buffer.
	char				InitialText[1024];				// backup of end-user buffer at focusing time, to ESC key can do a revert. Also used for arithmetic operations (but could use a pre-parsed float there).
	size_t				BufSize;						// end-user buffer size, <= 1024 (or increase above)
	float				Width;							// widget width
	float				ScrollX;
	STB_TexteditState	StbState;
	float				CursorAnim;
	bool				SelectedAllMouseLock;
	ImFont				Font;
	float				FontSize;

	ImGuiTextEditState()								{ memset(this, 0, sizeof(*this)); }

	void				CursorAnimReset()				{ CursorAnim = -0.30f; }												// After a user-input the cursor stays on for a while without blinking
	bool				CursorIsVisible() const			{ return CursorAnim <= 0.0f || fmodf(CursorAnim, 1.20f) <= 0.80f; }		// Blinking
	bool				HasSelection() const			{ return StbState.select_start != StbState.select_end; }
	void				SelectAll()						{ StbState.select_start = 0; StbState.select_end = (int)strlen(Text); StbState.cursor = StbState.select_end; StbState.has_preferred_x = false; }

	void				OnKeyboardPressed(int key);
	void 				UpdateScrollOffset();
	ImVec2				CalcDisplayOffsetFromCharIdx(int i) const;

	// Static functions because they are used to render non-focused instances of a text input box
	static const char*	GetTextPointerClipped(ImFont font, float font_size, const char* text, float width, ImVec2* out_text_size = NULL);
	static void			RenderTextScrolledClipped(ImFont font, float font_size, const char* text, ImVec2 pos_base, float width, float scroll_x);
};

struct ImGuiIniData
{
	char*	Name;
	ImVec2	Pos;
	ImVec2	Size;
	bool	Collapsed;

	ImGuiIniData() { memset(this, 0, sizeof(*this)); }
	~ImGuiIniData() { if (Name) { free(Name); Name = NULL; } }
};

struct ImGuiState
{
	bool					Initialized;
	ImGuiIO					IO;
	ImGuiStyle				Style;
	float					Time;
	int						FrameCount;
	int						FrameCountRendered;
	ImVector<ImGuiWindow*>	Windows;
	ImGuiWindow*			CurrentWindow;						// Being drawn into
	ImVector<ImGuiWindow*>	CurrentWindowStack;
	ImGuiWindow*			FocusedWindow;						// Will catch keyboard inputs
	ImGuiWindow*			HoveredWindow;						// Will catch mouse inputs
	ImGuiWindow*			HoveredWindowExcludingChilds;		// Will catch mouse inputs (for focus/move only)
	ImGuiID					HoveredId;
	ImGuiID					ActiveId;
	ImGuiID					ActiveIdPreviousFrame;
	bool					ActiveIdIsAlive;
	float					SettingsDirtyTimer;
	ImVector<ImGuiIniData*>	Settings;
	ImVec2					NewWindowDefaultPos;

	// Render
	ImVector<ImDrawList*>	RenderDrawLists;

	// Widget state
	ImGuiTextEditState		InputTextState;
	ImGuiID					SliderAsInputTextId;
	ImGuiStorage			ColorEditModeStorage;				// for user selection
	ImGuiID					ActiveComboID;
	char					Tooltip[1024];
	char*					PrivateClipboard;					// if no custom clipboard handler is defined

	// Logging
	bool					LogEnabled;
	FILE*					LogFile;
	ImGuiTextBuffer			LogClipboard;
	int						LogAutoExpandMaxDepth;

	ImGuiState()
	{
		Initialized = false;
		Time = 0.0f;
		FrameCount = 0;
		FrameCountRendered = -1;
		CurrentWindow = NULL;
		FocusedWindow = NULL;
		HoveredWindow = NULL;
		HoveredWindowExcludingChilds = NULL;
		ActiveIdIsAlive = false;
		SettingsDirtyTimer = 0.0f;
		NewWindowDefaultPos = ImVec2(60, 60);
		SliderAsInputTextId = 0;
		ActiveComboID = 0;
		memset(Tooltip, 0, sizeof(Tooltip));
		PrivateClipboard = NULL;
		LogEnabled = false;
		LogFile = NULL;
		LogAutoExpandMaxDepth = 2;
	}
};

static ImGuiState	GImGui;

struct ImGuiWindow
{
	char*					Name;
	ImGuiID					ID;
	ImGuiWindowFlags		Flags;
	ImVec2					PosFloat;
	ImVec2					Pos;								// Position rounded-up to nearest pixel
	ImVec2					Size;								// Current size (==SizeFull or collapsed title bar size)
	ImVec2					SizeFull;							// Size when non collapsed
	ImVec2					SizeContentsFit;					// Size of contents (extents reach by the drawing cursor) - may not fit within Size.
	float					ScrollY;
	float					NextScrollY;
	bool					ScrollbarY;
	bool					Visible;							// Set to true on Begin()
	bool					Accessed;							// Set to true when any widget access the current window
	bool					Collapsed;							// Set when collapsing window to become only title-bar
	bool					SkipItems;							// == Visible && !Collapsed
	int						AutoFitFrames;

	ImGuiDrawContext		DC;
	ImVector<ImGuiID>		IDStack;
	ImVector<ImVec4>		ClipRectStack;
	int						LastFrameDrawn;
	float					ItemWidthDefault;
	ImGuiStorage			StateStorage;
	float					FontScale;

	int						FocusIdxCounter;					// Start at -1 and increase as assigned via FocusItemRegister()
	int						FocusIdxRequestCurrent;				// Item being requested for focus, rely on layout to be stable between the frame pressing TAB and the next frame
	int						FocusIdxRequestNext;				// Item being requested for focus, for next update

	ImDrawList*				DrawList;

public:
	ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_size);
	~ImGuiWindow();

	ImGuiID		GetID(const char* str);
	ImGuiID		GetID(const void* ptr);

	void		AddToRenderList();
	bool		FocusItemRegister(bool is_active, int* out_idx = NULL);	// Return TRUE if focus is requested
	void		FocusItemUnregister();

	ImGuiAabb	Aabb() const							{ return ImGuiAabb(Pos, Pos+Size); }
	ImFont		Font() const							{ return GImGui.IO.Font; }
	float		FontSize() const						{ return GImGui.IO.FontHeight * FontScale; }
	ImVec2		CursorPos() const						{ return DC.CursorPos; }
	float		TitleBarHeight() const					{ return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0 : FontSize() + GImGui.Style.FramePadding.y * 2.0f; }
	ImGuiAabb	TitleBarAabb() const					{ return ImGuiAabb(Pos, Pos + ImVec2(SizeFull.x, TitleBarHeight())); }
	ImVec2		WindowPadding() const					{ return ((Flags & ImGuiWindowFlags_ChildWindow) && !(Flags & ImGuiWindowFlags_ShowBorders)) ? ImVec2(1,1) : GImGui.Style.WindowPadding; }
	ImU32		Color(ImGuiCol idx, float a=1.f) const	{ ImVec4 c = GImGui.Style.Colors[idx]; c.w *= GImGui.Style.Alpha * a; return ImConvertColorFloat4ToU32(c); }
	ImU32		Color(const ImVec4& col) const			{ ImVec4 c = col; c.w *= GImGui.Style.Alpha; return ImConvertColorFloat4ToU32(c); }
};

static ImGuiWindow*	GetCurrentWindow()
{
	IM_ASSERT(GImGui.CurrentWindow != NULL);	// ImGui::NewFrame() hasn't been called yet?
	GImGui.CurrentWindow->Accessed = true;
	return GImGui.CurrentWindow;
}

static void RegisterAliveId(const ImGuiID& id)
{
	if (GImGui.ActiveId == id)
		GImGui.ActiveIdIsAlive = true;
}

//-----------------------------------------------------------------------------

void ImGuiStorage::Clear()
{
	Data.clear();
}

// std::lower_bound but without the bullshit
static ImVector<ImGuiStorage::Pair>::iterator LowerBound(ImVector<ImGuiStorage::Pair>& data, ImU32 key)
{
	ImVector<ImGuiStorage::Pair>::iterator first = data.begin();
	ImVector<ImGuiStorage::Pair>::iterator last = data.end();
	int count = (int)(last - first);
	while (count > 0)
	{
		int count2 = count / 2;
		ImVector<ImGuiStorage::Pair>::iterator mid = first + count2;
		if (mid->key < key)
		{
			first = ++mid;
			count -= count2 + 1;
		}
		else
		{
			count = count2;
		}
	}
	return first;
}

int* ImGuiStorage::Find(ImU32 key)
{
	ImVector<Pair>::iterator it = LowerBound(Data, key);
	if (it == Data.end())
		return NULL;
	if (it->key != key)
		return NULL;
	return &it->val;
}

int ImGuiStorage::GetInt(ImU32 key, int default_val)
{
	int* pval = Find(key);
	if (!pval)
		return default_val;
	return *pval;
}

// FIXME-OPT: We are wasting time because all SetInt() are preceeded by GetInt() calls so we should have the result from lower_bound already in place.
// However we only use SetInt() on explicit user action (so that's maximum once a frame) so the optimisation isn't much needed.
void ImGuiStorage::SetInt(ImU32 key, int val)
{
	ImVector<Pair>::iterator it = LowerBound(Data, key);
	if (it != Data.end() && it->key == key)
	{
		it->val = val;
	}
	else
	{
		Pair pair_key;
		pair_key.key = key;
		pair_key.val = val;
		Data.insert(it, pair_key);
	}
}

void ImGuiStorage::SetAllInt(int v)
{
	for (size_t i = 0; i < Data.size(); i++)
		Data[i].val = v;
}

//-----------------------------------------------------------------------------

ImGuiTextFilter::ImGuiTextFilter()
{
	InputBuf[0] = 0;
	CountGrep = 0;
}

void ImGuiTextFilter::Draw(const char* label, float width)
{
	ImGuiWindow* window = GetCurrentWindow();
	if (width < 0.0f)
	{
		ImVec2 label_size = ImGui::CalcTextSize(label, NULL);
		width = ImMax(window->Pos.x + ImGui::GetWindowContentRegionMax().x - window->DC.CursorPos.x - (label_size.x + GImGui.Style.ItemSpacing.x*4), 10.0f);
	}
	ImGui::PushItemWidth(width);
	ImGui::InputText(label, InputBuf, IM_ARRAYSIZE(InputBuf));
	ImGui::PopItemWidth();
	Build();
}

void ImGuiTextFilter::TextRange::split(char separator, ImVector<TextRange>& out)
{
	out.resize(0);
	const char* wb = b;
	const char* we = wb;
	while (we < e)
	{
		if (*we == separator)
		{
			out.push_back(TextRange(wb, we));
			wb = we + 1;
		}
		we++;
	}
	if (wb != we)
		out.push_back(TextRange(wb, we));
}

void ImGuiTextFilter::Build()
{
	Filters.resize(0);
	TextRange input_range(InputBuf, InputBuf+strlen(InputBuf));
	input_range.split(',', Filters);

	CountGrep = 0;
	for (size_t i = 0; i != Filters.size(); i++)
	{
		Filters[i].trim_blanks();
		if (Filters[i].empty())
			continue;
		if (Filters[i].front() != '-')
			CountGrep += 1;
	}
}

bool ImGuiTextFilter::PassFilter(const char* val) const
{
	if (Filters.empty())
		return true;

	if (val == NULL)
		val = "";

	for (size_t i = 0; i != Filters.size(); i++)
	{
		const TextRange& f = Filters[i];
		if (f.empty())
			continue;
		if (f.front() == '-')
		{
			// Subtract
			if (ImStristr(val, f.begin()+1, f.end()) != NULL)
				return false;
		}
		else
		{
			// Grep
			if (ImStristr(val, f.begin(), f.end()) != NULL)
				return true;
		}
	}

	// Implicit * grep
	if (CountGrep == 0)
		return true;

	return false;
}

//-----------------------------------------------------------------------------

void ImGuiTextBuffer::append(const char* fmt, ...)
{
	va_list args;
	va_start(args, fmt);
	int len = vsnprintf(NULL, 0, fmt, args);
	va_end(args);
	if (len <= 0)
		return;

	const size_t write_off = Buf.size();
	if (write_off + len >= Buf.capacity())
		Buf.reserve(Buf.capacity() * 2);

	Buf.resize(write_off + (size_t)len);

	va_start(args, fmt);
	ImFormatStringV(&Buf[write_off] - 1, len+1, fmt, args);
	va_end(args);
}

//-----------------------------------------------------------------------------

ImGuiWindow::ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_size)
{
	Name = strdup(name);
	ID = GetID(name); 
	IDStack.push_back(ID);

	PosFloat = default_pos;
	Pos = ImVec2((float)(int)PosFloat.x, (float)(int)PosFloat.y);
	Size = SizeFull = default_size;
	SizeContentsFit = ImVec2(0.0f, 0.0f);
	ScrollY = 0.0f;
	NextScrollY = 0.0f;
	ScrollbarY = false;
	Visible = false;
	Accessed = false;
	Collapsed = false;
	SkipItems = false;
	AutoFitFrames = -1;
	LastFrameDrawn = -1;
	ItemWidthDefault = 0.0f;
	FontScale = 1.0f;

	if (ImLength(Size) < 0.001f)
		AutoFitFrames = 3;

	FocusIdxCounter = -1;
	FocusIdxRequestCurrent = IM_INT_MAX;
	FocusIdxRequestNext = IM_INT_MAX;

	DrawList = new ImDrawList();
}

ImGuiWindow::~ImGuiWindow()
{
	delete DrawList;
	DrawList = NULL;
	free(Name);
	Name = NULL;
}

ImGuiID ImGuiWindow::GetID(const char* str)
{
	const ImGuiID seed = IDStack.empty() ? 0 : IDStack.back();
	const ImGuiID id = crc32(str, strlen(str), seed);
	RegisterAliveId(id);
	return id;
}

ImGuiID ImGuiWindow::GetID(const void* ptr)
{
	const ImGuiID seed = IDStack.empty() ? 0 : IDStack.back();
	const ImGuiID id = crc32(&ptr, sizeof(void*), seed);
	RegisterAliveId(id);
	return id;
}

bool ImGuiWindow::FocusItemRegister(bool is_active, int* out_idx)
{
	FocusIdxCounter++;
	if (out_idx)
		*out_idx = FocusIdxCounter;

	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (!window->DC.AllowKeyboardFocus.back())
		return false;

	// Process input at this point: TAB, Shift-TAB switch focus
	if (FocusIdxRequestNext == IM_INT_MAX && is_active && ImGui::IsKeyPressedMap(ImGuiKey_Tab))
	{
		// Modulo on index will be applied at the end of frame once we've got the total counter of items.
		FocusIdxRequestNext = FocusIdxCounter + (g.IO.KeyShift ? -1 : +1);
	}

	const bool focus_requested = (FocusIdxCounter == FocusIdxRequestCurrent);
	return focus_requested;
}

void ImGuiWindow::FocusItemUnregister()
{
	FocusIdxCounter--;
}

void ImGuiWindow::AddToRenderList()
{
	ImGuiState& g = GImGui;

	if (!DrawList->commands.empty() && !DrawList->vtx_buffer.empty())
	{
		if (DrawList->commands.back().vtx_count == 0)
			DrawList->commands.pop_back();
		g.RenderDrawLists.push_back(DrawList);
	}
	for (size_t i = 0; i < DC.ChildWindows.size(); i++)
	{
		ImGuiWindow* child = DC.ChildWindows[i];
		if (child->Visible)					// clipped childs may have been marked not Visible
			child->AddToRenderList();
	}
}

//-----------------------------------------------------------------------------

namespace ImGui
{

static ImGuiIniData* FindWindowSettings(const char* name)
{
	ImGuiState& g = GImGui;

	for (size_t i = 0; i != g.Settings.size(); i++)
	{
		ImGuiIniData* ini = g.Settings[i];
		if (ImStricmp(ini->Name, name) == 0)
			return ini;
	}
	ImGuiIniData* ini = new ImGuiIniData();
	ini->Name = strdup(name);
	ini->Collapsed = false;
	ini->Pos = ImVec2(FLT_MAX,FLT_MAX);
	ini->Size = ImVec2(0,0);
	g.Settings.push_back(ini);
	return ini;
}

// Zero-tolerance, poor-man .ini parsing
// FIXME: Write something less rubbish
static void LoadSettings()
{
	ImGuiState& g = GImGui;
	const char* filename = g.IO.IniFilename;
	if (!filename)
		return;

	// Load file
	FILE* f;
	if ((f = fopen(filename, "rt")) == NULL)
		return;
	if (fseek(f, 0, SEEK_END)) 
		return;
	long f_size = ftell(f);	
	if (f_size == -1) 
		return;
	if (fseek(f, 0, SEEK_SET)) 
		return;
	char* f_data = new char[f_size+1];
	f_size = (long)fread(f_data, 1, f_size, f);	// Text conversion alter read size so let's not be fussy about return value
	fclose(f);
	if (f_size == 0)
	{
		delete[] f_data;
		return;
	}
	f_data[f_size] = 0;

	ImGuiIniData* settings = NULL;
	const char* buf_end = f_data + f_size;
	for (const char* line_start = f_data; line_start < buf_end; )
	{
		const char* line_end = line_start;
		while (line_end < buf_end && *line_end != '\n' && *line_end != '\r')
			line_end++;
		
		if (line_start[0] == '[' && line_end > line_start && line_end[-1] == ']')
		{
			char name[64];
			ImFormatString(name, IM_ARRAYSIZE(name), "%.*s", line_end-line_start-2, line_start+1);
			settings = FindWindowSettings(name);
		}
		else if (settings)
		{
			float x, y;
			int i;
			if (sscanf(line_start, "Pos=%f,%f", &x, &y) == 2)
				settings->Pos = ImVec2(x, y);
			else if (sscanf(line_start, "Size=%f,%f", &x, &y) == 2)
				settings->Size = ImMax(ImVec2(x, y), g.Style.WindowMinSize);
			else if (sscanf(line_start, "Collapsed=%d", &i) == 1)
				settings->Collapsed = (i != 0);
		}

		line_start = line_end+1;
	}

	delete[] f_data;
}

static void SaveSettings()
{
	ImGuiState& g = GImGui;
	const char* filename = g.IO.IniFilename;
	if (!filename)
		return;

	// Gather data from windows that were active during this session
	for (size_t i = 0; i != g.Windows.size(); i++)
	{
		ImGuiWindow* window = g.Windows[i];
		if (window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip))
			continue;
		ImGuiIniData* settings = FindWindowSettings(window->Name);
		settings->Pos = window->Pos;
		settings->Size = window->SizeFull;
		settings->Collapsed = window->Collapsed;
	}

	// Write .ini file
	// If a window wasn't opened in this session we preserve its settings
	FILE* f = fopen(filename, "wt");
	if (!f)
		return;
	for (size_t i = 0; i != g.Settings.size(); i++)
	{
		const ImGuiIniData* settings = g.Settings[i];
		if (settings->Pos.x == FLT_MAX)
			continue;
		fprintf(f, "[%s]\n", settings->Name);
		fprintf(f, "Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y);
		fprintf(f, "Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y);
		fprintf(f, "Collapsed=%d\n", settings->Collapsed);
		fprintf(f, "\n");
	}

	fclose(f);
}

static void MarkSettingsDirty()
{
	ImGuiState& g = GImGui;

	if (g.SettingsDirtyTimer <= 0.0f)
		g.SettingsDirtyTimer = g.IO.IniSavingRate;
}

ImGuiIO& GetIO()
{
	return GImGui.IO;
}

ImGuiStyle& GetStyle()
{
	return GImGui.Style;
}

void NewFrame()
{
	ImGuiState& g = GImGui;

	// Check user inputs
	IM_ASSERT(g.IO.DeltaTime > 0.0f);
	IM_ASSERT(g.IO.DisplaySize.x > 0.0f && g.IO.DisplaySize.y > 0.0f);
	IM_ASSERT(g.IO.RenderDrawListsFn != NULL);	// Must be implemented

	if (!g.Initialized)
	{
		// Initialize on first frame
		IM_ASSERT(g.Settings.empty());
		LoadSettings();
		if (!g.IO.Font)
		{
			// Default font
			const void* fnt_data;
			unsigned int fnt_size;
			ImGui::GetDefaultFontData(&fnt_data, &fnt_size, NULL, NULL);
			g.IO.Font = new ImBitmapFont();
			g.IO.Font->LoadFromMemory(fnt_data, fnt_size);
			g.IO.FontHeight = g.IO.Font->GetFontSize();
		}
		g.Initialized = true;
	}

	g.Time += g.IO.DeltaTime;
	g.FrameCount += 1;
	g.Tooltip[0] = '\0';

	// Update inputs state
	if (g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0)
		g.IO.MousePos = ImVec2(-9999.0f, -9999.0f);
	if ((g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) || (g.IO.MousePosPrev.x < 0 && g.IO.MousePosPrev.y < 0))	// if mouse just appeared or disappeared (negative coordinate) we cancel out movement in MouseDelta
		g.IO.MouseDelta = ImVec2(0.0f, 0.0f);
	else
		g.IO.MouseDelta = g.IO.MousePos - g.IO.MousePosPrev;
	g.IO.MousePosPrev = g.IO.MousePos;
	for (size_t i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++)
	{
		g.IO.MouseDownTime[i] = g.IO.MouseDown[i] ? (g.IO.MouseDownTime[i] < 0.0f ? 0.0f : g.IO.MouseDownTime[i] + g.IO.DeltaTime) : -1.0f;
		g.IO.MouseClicked[i] = (g.IO.MouseDownTime[i] == 0.0f);
		g.IO.MouseDoubleClicked[i] = false;
		if (g.IO.MouseClicked[i])
		{
			if (g.Time - g.IO.MouseClickedTime[i] < g.IO.MouseDoubleClickTime)
			{
				if (ImLength(g.IO.MousePos - g.IO.MouseClickedPos[i]) < g.IO.MouseDoubleClickMaxDist)
					g.IO.MouseDoubleClicked[i] = true;
				g.IO.MouseClickedTime[i] = -FLT_MAX;	// so the third click isn't turned into a double-click
			}
			else
			{
				g.IO.MouseClickedTime[i] = g.Time;
				g.IO.MouseClickedPos[i] = g.IO.MousePos;
			}
		}
	}
	for (size_t i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++)
		g.IO.KeysDownTime[i] = g.IO.KeysDown[i] ? (g.IO.KeysDownTime[i] < 0.0f ? 0.0f : g.IO.KeysDownTime[i] + g.IO.DeltaTime) : -1.0f;

	// Clear reference to active widget if the widget isn't alive anymore
	g.HoveredId = 0;
	if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
		g.ActiveId = 0;
	g.ActiveIdPreviousFrame = g.ActiveId;
	g.ActiveIdIsAlive = false;

	// Delay saving settings so we don't spam disk too much
	if (g.SettingsDirtyTimer > 0.0f)
	{
		g.SettingsDirtyTimer -= g.IO.DeltaTime;
		if (g.SettingsDirtyTimer <= 0.0f)
			SaveSettings();
	}

	g.HoveredWindow = ImGui::FindHoveredWindow(g.IO.MousePos, false);
	g.HoveredWindowExcludingChilds = ImGui::FindHoveredWindow(g.IO.MousePos, true);

	// Are we snooping input?
	g.IO.WantCaptureMouse = (g.HoveredWindow != NULL) || (g.ActiveId != 0);
	g.IO.WantCaptureKeyboard = (g.ActiveId != 0);

	// Scale & Scrolling
	if (g.HoveredWindow && g.IO.MouseWheel != 0)
	{
		ImGuiWindow* window = g.HoveredWindow;
		if (g.IO.KeyCtrl)
		{
			if (g.IO.FontAllowScaling)
			{
				// Zoom / Scale window
				float new_font_scale = ImClamp(window->FontScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f);
				float scale = new_font_scale / window->FontScale;
				window->FontScale = new_font_scale;

				const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size;
				window->Pos += offset;
				window->PosFloat += offset;
				window->Size *= scale;
				window->SizeFull *= scale;
			}
		}
		else
		{
			// Scroll
			const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5;
			window->NextScrollY -= g.IO.MouseWheel * window->FontSize() * scroll_lines;
		}
	}

	// Pressing TAB activate widget focus
	// NB: Don't discard FocusedWindow if it isn't active, so that a window that go on/off programatically won't lose its keyboard focus.
	if (g.ActiveId == 0 && g.FocusedWindow != NULL && g.FocusedWindow->Visible && IsKeyPressedMap(ImGuiKey_Tab, false))
	{
		g.FocusedWindow->FocusIdxRequestNext = 0;			
	}

	// Mark all windows as not visible
	for (size_t i = 0; i != g.Windows.size(); i++)
	{
		ImGuiWindow* window = g.Windows[i];
		window->Visible = false;
		window->Accessed = false;
	}

	// No window should be open at the beginning of the frame.
	// But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear.
	g.CurrentWindowStack.clear();

	// Create implicit window - we will only render it if the user has added something to it.
	ImGui::Begin("Debug", NULL, ImVec2(400,400));
}

// NB: behaviour of ImGui after Shutdown() is not tested/guaranteed at the moment. This function is merely here to free heap allocations.
void Shutdown()
{
	ImGuiState& g = GImGui;
	if (!g.Initialized)
		return;

	SaveSettings();

	for (size_t i = 0; i < g.Windows.size(); i++)
		delete g.Windows[i];
	g.Windows.clear();
	g.CurrentWindowStack.clear();
	g.FocusedWindow = NULL;
	g.HoveredWindow = NULL;
	g.HoveredWindowExcludingChilds = NULL;
	for (size_t i = 0; i < g.Settings.size(); i++)
		delete g.Settings[i];
	g.Settings.clear();
	g.ColorEditModeStorage.Clear();
	if (g.LogFile && g.LogFile != stdout)
	{
		fclose(g.LogFile);
		g.LogFile = NULL;
	}
	if (g.IO.Font)
	{
		delete g.IO.Font;
		g.IO.Font = NULL;
	}

	if (g.PrivateClipboard)
	{
		free(g.PrivateClipboard);
		g.PrivateClipboard = NULL;
	}

	g.Initialized = false;
}

static void AddWindowToSortedBuffer(ImGuiWindow* window, ImVector<ImGuiWindow*>& sorted_windows)
{
	sorted_windows.push_back(window);
	if (window->Visible)
	{
		for (size_t i = 0; i < window->DC.ChildWindows.size(); i++)
		{
			ImGuiWindow* child = window->DC.ChildWindows[i];
			if (child->Visible)
				AddWindowToSortedBuffer(child, sorted_windows);
		}
	}
}

static void PushClipRect(const ImVec4& clip_rect, bool clipped = true)
{
	ImGuiWindow* window = GetCurrentWindow();

	ImVec4 cr = clip_rect;
	if (clipped && !window->ClipRectStack.empty())
	{
		// Clip to new clip rect
		const ImVec4 cur_cr = window->ClipRectStack.back();
		cr = ImVec4(ImMax(cr.x, cur_cr.x), ImMax(cr.y, cur_cr.y), ImMin(cr.z, cur_cr.z), ImMin(cr.w, cur_cr.w));
	}

	window->ClipRectStack.push_back(cr);
	window->DrawList->PushClipRect(cr);
}

static void PopClipRect()
{
	ImGuiWindow* window = GetCurrentWindow();
	window->ClipRectStack.pop_back();
	window->DrawList->PopClipRect();
}

void Render()
{
	ImGuiState& g = GImGui;
	IM_ASSERT(g.Initialized);						// Forgot to call ImGui::NewFrame()

	const bool first_render_of_the_frame = (g.FrameCountRendered != g.FrameCount);
	g.FrameCountRendered = g.FrameCount;
	
	if (first_render_of_the_frame)
	{
		// Hide implicit window if it hasn't been used
		IM_ASSERT(g.CurrentWindowStack.size() == 1);	// Mismatched Begin/End 
		if (g.CurrentWindow && !g.CurrentWindow->Accessed)
			g.CurrentWindow->Visible = false;
		ImGui::End();

		// Sort the window list so that all child windows are after their parent
		// We cannot do that on FocusWindow() because childs may not exist yet
		ImVector<ImGuiWindow*> sorted_windows;
		sorted_windows.reserve(g.Windows.size());
		for (size_t i = 0; i != g.Windows.size(); i++)
		{
			ImGuiWindow* window = g.Windows[i];
			if (window->Flags & ImGuiWindowFlags_ChildWindow)			// if a child is visible its parent will add it
				if (window->Visible)
					continue;
			AddWindowToSortedBuffer(window, sorted_windows);
		}
		IM_ASSERT(g.Windows.size() == sorted_windows.size());			// We done something wrong
		g.Windows.swap(sorted_windows);

		// Clear data for next frame
		g.IO.MouseWheel = 0;
		memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
	}

	// Skip render altogether if alpha is 0.0
	// Note that vertex buffers have been created, so it is best practice that you don't call Begin/End in the first place.
	if (g.Style.Alpha > 0.0f)
	{
		// Render tooltip
		if (g.Tooltip[0])
		{
			// Use a dummy window to render the tooltip
			ImGui::BeginTooltip();
			ImGui::TextUnformatted(g.Tooltip);
			ImGui::EndTooltip();
		}

		// Gather windows to render
		g.RenderDrawLists.resize(0);
		for (size_t i = 0; i != g.Windows.size(); i++)
		{
			ImGuiWindow* window = g.Windows[i];
			if (window->Visible && (window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) == 0)
				window->AddToRenderList();
		}
		for (size_t i = 0; i != g.Windows.size(); i++)
		{
			ImGuiWindow* window = g.Windows[i];
			if (window->Visible && (window->Flags & ImGuiWindowFlags_Tooltip))
				window->AddToRenderList();
		}

		// Render
		if (!g.RenderDrawLists.empty())
			g.IO.RenderDrawListsFn(&g.RenderDrawLists[0], (int)g.RenderDrawLists.size());
		g.RenderDrawLists.resize(0);
	}
}

// Find the optional ## from which we stop displaying text.
static const char*	FindTextDisplayEnd(const char* text, const char* text_end = NULL)
{
	const char* text_display_end = text;
	while ((!text_end || text_display_end < text_end) && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#'))
		text_display_end++;
	return text_display_end;
}

static void LogText(const ImVec2& ref_pos, const char* text, const char* text_end)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();

	if (!text_end)
		text_end = FindTextDisplayEnd(text, text_end);

	const bool log_new_line = ref_pos.y > window->DC.LogLineHeight+1;
	window->DC.LogLineHeight = ref_pos.y;

	const char* text_remaining = text;
	const int tree_depth = window->DC.TreeDepth;
	while (true)
	{
		const char* line_end = text_remaining;
		while (line_end < text_end)
			if (*line_end == '\n')
				break;
			else
				line_end++;
		if (line_end >= text_end)
			line_end = NULL;

		bool is_first_line = (text == text_remaining);
		bool is_last_line = false;
		if (line_end == NULL)
		{
			is_last_line = true;
			line_end = text_end;
		}
		if (line_end != NULL && !(is_last_line && (line_end - text_remaining)==0))
		{
			const int char_count = (int)(line_end - text_remaining);
			if (g.LogFile)
			{
				if (log_new_line || !is_first_line)
					fprintf(g.LogFile, "\n%*s%.*s", tree_depth*4, "", char_count, text_remaining);
				else
					fprintf(g.LogFile, " %.*s", char_count, text_remaining);
			}
			else
			{
				if (log_new_line || !is_first_line)
					g.LogClipboard.append("\n%*s%.*s", tree_depth*4, "", char_count, text_remaining);
				else
					g.LogClipboard.append(" %.*s", char_count, text_remaining);
			}
		}

		if (is_last_line)
			break;
		text_remaining = line_end + 1;
	}
}

static void RenderText(ImVec2 pos, const char* text, const char* text_end, const bool hide_text_after_hash)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();

	// Hide anything after a '##' string
	const char* text_display_end;
	if (hide_text_after_hash)
	{
		text_display_end = FindTextDisplayEnd(text, text_end);
	}
	else
	{
		if (!text_end)
			text_end = text + strlen(text);
		text_display_end = text_end;
	}

	const int text_len = (int)(text_display_end - text);
	//IM_ASSERT(text_len >= 0 && text_len < 10000);	// Suspicious text length
	if (text_len > 0)
	{
		// Render
		window->DrawList->AddText(window->Font(), window->FontSize(), pos, window->Color(ImGuiCol_Text), text, text + text_len);

		// Log as text. We split text into individual lines to add the tree level padding
		if (g.LogEnabled)
			LogText(pos, text, text_display_end);
	}
}

static void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, float rounding)
{
	ImGuiWindow* window = GetCurrentWindow();

	window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding);
	if (border && (window->Flags & ImGuiWindowFlags_ShowBorders))
	{
		window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), window->Color(ImGuiCol_BorderShadow), rounding);
		window->DrawList->AddRect(p_min, p_max, window->Color(ImGuiCol_Border), rounding);
	}
}

static void RenderCollapseTriangle(ImVec2 p_min, bool open, float scale = 1.0f, bool shadow = false)
{
	ImGuiWindow* window = GetCurrentWindow();

	const float h = window->FontSize() * 1.00f;
	const float r = h * 0.40f * scale;
	ImVec2 center = p_min + ImVec2(h*0.50f, h*0.50f*scale);

	ImVec2 a, b, c;
	if (open)
	{
		center.y -= r*0.25f;
		a = center + ImVec2(0,1)*r;
		b = center + ImVec2(-0.866f,-0.5f)*r;
		c = center + ImVec2(0.866f,-0.5f)*r;
	}
	else
	{
		a = center + ImVec2(1,0)*r;
		b = center + ImVec2(-0.500f,0.866f)*r;
		c = center + ImVec2(-0.500f,-0.866f)*r;
	}
	
	if (shadow)
		window->DrawList->AddTriangleFilled(a+ImVec2(2,2), b+ImVec2(2,2), c+ImVec2(2,2), window->Color(ImGuiCol_BorderShadow));
	window->DrawList->AddTriangleFilled(a, b, c, window->Color(ImGuiCol_Border));
}

static ImVec2 CalcTextSize(const char* text, const char* text_end, const bool hide_text_after_hash)
{
	ImGuiWindow* window = GetCurrentWindow();

	const char* text_display_end;
	if (hide_text_after_hash)
		text_display_end = FindTextDisplayEnd(text, text_end);		// Hide anything after a '##' string
	else
		text_display_end = text_end;

	const ImVec2 size = window->Font()->CalcTextSize(window->FontSize(), 0, text, text_display_end, NULL);
	return size;
}

static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs)
{
	ImGuiState& g = GImGui;
	for (int i = (int)g.Windows.size()-1; i >= 0; i--)
	{
		ImGuiWindow* window = g.Windows[(size_t)i];
		if (!window->Visible)
			continue;
		if (excluding_childs && (window->Flags & ImGuiWindowFlags_ChildWindow) != 0)
			continue;
		ImGuiAabb bb(window->Pos - g.Style.TouchExtraPadding, window->Pos+window->Size + g.Style.TouchExtraPadding);
		if (bb.Contains(pos))
			return window;
	}
	return NULL;
}

// - Box is clipped by our current clip setting
// - Expand to be generous on unprecise inputs systems (touch)
static bool IsMouseHoveringBox(const ImGuiAabb& box)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();

	// Clip
	ImGuiAabb box_clipped = box;
	if (!window->ClipRectStack.empty())
	{
		const ImVec4 clip_rect = window->ClipRectStack.back();
		box_clipped.Clip(ImGuiAabb(ImVec2(clip_rect.x, clip_rect.y), ImVec2(clip_rect.z, clip_rect.w)));
	}

	// Expand for touch input
	ImGuiAabb box_for_touch(box_clipped.Min - g.Style.TouchExtraPadding, box_clipped.Max + g.Style.TouchExtraPadding);
	return box_for_touch.Contains(g.IO.MousePos);
}

bool IsMouseHoveringBox(const ImVec2& box_min, const ImVec2& box_max)
{
	return IsMouseHoveringBox(ImGuiAabb(box_min, box_max));
}

static bool IsKeyPressedMap(ImGuiKey key, bool repeat)
{
	ImGuiState& g = GImGui;
	const int key_index = g.IO.KeyMap[key];
	return IsKeyPressed(key_index, repeat);
}

bool IsKeyPressed(int key_index, bool repeat)
{
	ImGuiState& g = GImGui;
	IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown));
	const float t = g.IO.KeysDownTime[key_index];
	if (t == 0.0f)
		return true;

	// FIXME: Repeat rate should be provided elsewhere?
	const float KEY_REPEAT_DELAY = 0.250f;
	const float KEY_REPEAT_RATE = 0.020f;
	if (repeat && t > KEY_REPEAT_DELAY)
		if ((fmodf(t - KEY_REPEAT_DELAY, KEY_REPEAT_RATE) > KEY_REPEAT_RATE*0.5f) != (fmodf(t - KEY_REPEAT_DELAY - g.IO.DeltaTime, KEY_REPEAT_RATE) > KEY_REPEAT_RATE*0.5f))
			return true;

	return false;
}

bool IsMouseClicked(int button, bool repeat)
{
	ImGuiState& g = GImGui;
	IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
	const float t = g.IO.MouseDownTime[button];
	if (t == 0.0f)
		return true;

	// FIXME: Repeat rate should be provided elsewhere?
	const float MOUSE_REPEAT_DELAY = 0.250f;
	const float MOUSE_REPEAT_RATE = 0.020f;
	if (repeat && t > MOUSE_REPEAT_DELAY)
		if ((fmodf(t - MOUSE_REPEAT_DELAY, MOUSE_REPEAT_RATE) > MOUSE_REPEAT_RATE*0.5f) != (fmodf(t - MOUSE_REPEAT_DELAY - g.IO.DeltaTime, MOUSE_REPEAT_RATE) > MOUSE_REPEAT_RATE*0.5f))
			return true;

	return false;
}

bool IsMouseDoubleClicked(int button)
{
	ImGuiState& g = GImGui;
	IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
	return g.IO.MouseDoubleClicked[button];
}

ImVec2 GetMousePos()
{
	return GImGui.IO.MousePos;
}

bool IsHovered()
{
	ImGuiWindow* window = GetCurrentWindow();
	return window->DC.LastItemHovered;
}

ImVec2 GetItemBoxMin()
{
	ImGuiWindow* window = GetCurrentWindow();
	return window->DC.LastItemAabb.Min;
}

ImVec2 GetItemBoxMax()
{
	ImGuiWindow* window = GetCurrentWindow();
	return window->DC.LastItemAabb.Max;
}

void SetTooltip(const char* fmt, ...)
{
	ImGuiState& g = GImGui;
	va_list args;
	va_start(args, fmt);
	ImFormatStringV(g.Tooltip, IM_ARRAYSIZE(g.Tooltip), fmt, args);
	va_end(args);
}

void SetNewWindowDefaultPos(const ImVec2& pos)
{
	ImGuiState& g = GImGui;
	g.NewWindowDefaultPos = pos;
}

float GetTime()
{
	return GImGui.Time;
}

int GetFrameCount()
{
	return GImGui.FrameCount;
}

static ImGuiWindow* FindWindow(const char* name)
{
	ImGuiState& g = GImGui;
	for (size_t i = 0; i != g.Windows.size(); i++)
		if (strcmp(g.Windows[i]->Name, name) == 0)
			return g.Windows[i];
	return NULL;
}

void BeginTooltip()
{
	ImGui::Begin("##Tooltip", NULL, ImVec2(0,0), 0.9f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_Tooltip);
}

void EndTooltip()
{
	IM_ASSERT(GetCurrentWindow()->Flags & ImGuiWindowFlags_Tooltip);
	ImGui::End();
}

void BeginChild(const char* str_id, ImVec2 size, bool border, ImGuiWindowFlags extra_flags)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();

	ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_ChildWindow;

	const ImVec2 content_max = window->Pos + ImGui::GetWindowContentRegionMax();
	const ImVec2 cursor_pos = window->Pos + ImGui::GetCursorPos();
	if (size.x <= 0.0f)
	{
		size.x = ImMax(content_max.x - cursor_pos.x, g.Style.WindowMinSize.x);
		flags |= ImGuiWindowFlags_ChildWindowAutoFitX;
	}
	if (size.y <= 0.0f)
	{
		size.y = ImMax(content_max.y - cursor_pos.y, g.Style.WindowMinSize.y);
		flags |= ImGuiWindowFlags_ChildWindowAutoFitY;
	}
	if (border)
		flags |= ImGuiWindowFlags_ShowBorders;
	flags |= extra_flags;

	char title[256];
	ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s", window->Name, str_id);

	const float alpha = (flags & ImGuiWindowFlags_ComboBox) ? 1.0f : 0.0f;
	ImGui::Begin(title, NULL, size, alpha, flags);

	if (!(window->Flags & ImGuiWindowFlags_ShowBorders))
		g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders;
}

void EndChild()
{
	ImGuiWindow* window = GetCurrentWindow();

	if (window->Flags & ImGuiWindowFlags_ComboBox)
	{
		ImGui::End();
	}
	else
	{
		// When using filling child window, we don't provide the width/height to ItemSize so that it doesn't feed back into automatic fitting
		ImVec2 sz = ImGui::GetWindowSize();
		if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitX)
			sz.x = 0;
		if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitY)
			sz.y = 0;
		
		ImGui::End();
		ImGui::ItemSize(sz);
	}
}

bool Begin(const char* name, bool* open, ImVec2 size, float fill_alpha, ImGuiWindowFlags flags)
{
	ImGuiState& g = GImGui;
	const ImGuiStyle& style = g.Style;

	ImGuiWindow* window = FindWindow(name);
	if (!window)
	{
		// Create window the first time, and load settings
		if (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip))
		{
			window = new ImGuiWindow(name, ImVec2(0,0), size);
		}
		else
		{
			ImGuiIniData* settings = FindWindowSettings(name);
			if (settings && ImLength(settings->Size) > 0.0f && !(flags & ImGuiWindowFlags_NoResize))// && ImLengthsize) == 0.0f)
				size = settings->Size;

			window = new ImGuiWindow(name, g.NewWindowDefaultPos, size);

			if (settings->Pos.x != FLT_MAX)
			{
				window->PosFloat = settings->Pos;
				window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y);
				window->Collapsed = settings->Collapsed;
			}
		}
		g.Windows.push_back(window);
	}
	window->Flags = (ImGuiWindowFlags)flags;

	g.CurrentWindowStack.push_back(window);
	g.CurrentWindow = window;

	// Default alpha
	if (fill_alpha < 0.0f)
		fill_alpha = style.WindowFillAlphaDefault;

	// When reusing window again multiple times a frame, just append content (don't need to setup again)
	const int current_frame = ImGui::GetFrameCount();
	const bool first_begin_of_the_frame = (window->LastFrameDrawn != current_frame);
	if (first_begin_of_the_frame)
	{
		window->DrawList->Clear();
		window->Visible = true;

		// New windows appears in front
		if (window->LastFrameDrawn < current_frame - 1)
		{
			ImGui::FocusWindow(window);
			if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0)
			{
				// Hide for 1 frame while resizing
				window->AutoFitFrames = 2;
				window->Visible = false;
			}
		}

		window->LastFrameDrawn = current_frame;
		window->ClipRectStack.resize(0);

		if (flags & ImGuiWindowFlags_ChildWindow)
		{
			ImGuiWindow* parent_window = g.CurrentWindowStack[g.CurrentWindowStack.size()-2];
			parent_window->DC.ChildWindows.push_back(window);
			window->Pos = window->PosFloat = parent_window->DC.CursorPos;
			window->SizeFull = size;
		}

		// Outer clipping rectangle
		if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_ComboBox))
			ImGui::PushClipRect(g.CurrentWindowStack[g.CurrentWindowStack.size()-2]->ClipRectStack.back());
		else
			ImGui::PushClipRect(ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y));

		// ID stack
		window->IDStack.resize(0);
		ImGui::PushID(window);

		// Move window (at the beginning of the frame)
		const ImGuiID move_id = window->GetID("#MOVE");
		RegisterAliveId(move_id);
		if (g.ActiveId == move_id)
		{
			if (g.IO.MouseDown[0])
			{
				if (!(window->Flags & ImGuiWindowFlags_NoMove))
				{
					window->PosFloat += g.IO.MouseDelta;
					MarkSettingsDirty();
				}
				ImGui::FocusWindow(window);
			}
			else
			{
				g.ActiveId = 0;
			}
		}

		// Tooltips always follow mouse
		if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0)
		{
			window->PosFloat = g.IO.MousePos + ImVec2(32,16) - g.Style.FramePadding*2;
		}

		// Clamp into view
		if (!(window->Flags & ImGuiWindowFlags_ChildWindow))
		{
			const ImVec2 pad = ImVec2(window->FontSize()*2.0f, window->FontSize()*2.0f);
			window->PosFloat = ImMax(window->PosFloat + window->Size, pad) - window->Size;
			window->PosFloat = ImMin(window->PosFloat, ImVec2(g.IO.DisplaySize.x, g.IO.DisplaySize.y) - pad);
			window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y);
			window->SizeFull = ImMax(window->SizeFull, pad);
		}
		else
		{
			window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y);
		}

		// Default item width
		if (window->Size.x > 0.0f && !(window->Flags & ImGuiWindowFlags_Tooltip))
			window->ItemWidthDefault = (float)(int)(window->Size.x * 0.65f);
		else
			window->ItemWidthDefault = 200.0f;

		// Prepare for focus requests
		if (window->FocusIdxRequestNext == IM_INT_MAX || window->FocusIdxCounter == -1)
		{
			window->FocusIdxRequestCurrent = IM_INT_MAX;
		}
		else
		{
			const int mod = window->FocusIdxCounter+1;
			window->FocusIdxRequestCurrent = (window->FocusIdxRequestNext + mod) % mod;
		}
		window->FocusIdxCounter = -1;
		window->FocusIdxRequestNext = IM_INT_MAX;

		ImGuiAabb title_bar_aabb = window->TitleBarAabb();

		// Apply and ImClamp scrolling
		window->ScrollY = window->NextScrollY;
		window->ScrollY = ImMax(window->ScrollY, 0.0f);
		if (!window->Collapsed && !window->SkipItems)
			window->ScrollY = ImMin(window->ScrollY, ImMax(0.0f, (float)window->SizeContentsFit.y - window->SizeFull.y));
		window->NextScrollY = window->ScrollY;

		// NB- at this point we don't have a clipping rectangle setup yet!
		// Collapse window by double-clicking on title bar
		if (!(window->Flags & ImGuiWindowFlags_NoTitleBar))
		{
			if (g.HoveredWindow == window && IsMouseHoveringBox(title_bar_aabb) && g.IO.MouseDoubleClicked[0])
			{
				window->Collapsed = !window->Collapsed;
				MarkSettingsDirty();
				ImGui::FocusWindow(window);
			}
		}
		else
		{
			window->Collapsed = false;
		}

		if (window->Collapsed)
		{
			// Title bar only
			window->Size = title_bar_aabb.GetSize();
			window->DrawList->AddRectFilled(title_bar_aabb.GetTL(), title_bar_aabb.GetBR(), window->Color(ImGuiCol_TitleBgCollapsed), g.Style.WindowRounding);
			if (window->Flags & ImGuiWindowFlags_ShowBorders)
			{
				window->DrawList->AddRect(title_bar_aabb.GetTL()+ImVec2(1,1), title_bar_aabb.GetBR()+ImVec2(1,1), window->Color(ImGuiCol_BorderShadow), g.Style.WindowRounding);
				window->DrawList->AddRect(title_bar_aabb.GetTL(), title_bar_aabb.GetBR(), window->Color(ImGuiCol_Border), g.Style.WindowRounding);
			}
		}
		else
		{
			window->Size = window->SizeFull;

			// Draw resize grip and resize
			ImU32 resize_col = 0;
			if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0)
			{
				if (window->AutoFitFrames > 0)
				{
					// Tooltip always resize
					window->SizeFull = window->SizeContentsFit + g.Style.WindowPadding - ImVec2(0.0f, g.Style.ItemSpacing.y);
				}
			}
			else if (!(window->Flags & ImGuiWindowFlags_NoResize))
			{
				const ImGuiAabb resize_aabb(window->Aabb().GetBR()-ImVec2(18,18), window->Aabb().GetBR());
				const ImGuiID resize_id = window->GetID("#RESIZE");
				bool hovered, held;
				ButtonBehaviour(resize_aabb, resize_id, &hovered, &held, true);
				resize_col = window->Color(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip);

				ImVec2 size_auto_fit = ImClamp(window->SizeContentsFit + style.AutoFitPadding, style.WindowMinSize, g.IO.DisplaySize - style.AutoFitPadding);
				if (window->AutoFitFrames > 0)
				{
					// Auto-fit only grows during the first few frames
					window->SizeFull = ImMax(window->SizeFull, size_auto_fit);
					MarkSettingsDirty();
				}
				else if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0])
				{
					// Manual auto-fit
					window->SizeFull = size_auto_fit;
					window->Size = window->SizeFull;
					MarkSettingsDirty();
				}
				else if (held)
				{
					// Resize
					window->SizeFull = ImMax(window->SizeFull + g.IO.MouseDelta, style.WindowMinSize);
					window->Size = window->SizeFull;
					MarkSettingsDirty();
				}

				// Update aabb immediately so that the rendering below isn't one frame late
				title_bar_aabb = window->TitleBarAabb();
			}

			// Title bar + Window box
			if (fill_alpha > 0.0f)
			{
				if ((window->Flags & ImGuiWindowFlags_ComboBox) != 0)
					window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_ComboBg, fill_alpha), 0);
				else
					window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_WindowBg, fill_alpha), g.Style.WindowRounding);
			}

			if (!(window->Flags & ImGuiWindowFlags_NoTitleBar))
				window->DrawList->AddRectFilled(title_bar_aabb.GetTL(), title_bar_aabb.GetBR(), window->Color(ImGuiCol_TitleBg), g.Style.WindowRounding, 1|2);

			if (window->Flags & ImGuiWindowFlags_ShowBorders)
			{
				const float rounding = (window->Flags & ImGuiWindowFlags_ComboBox) ? 0.0f : g.Style.WindowRounding;
				window->DrawList->AddRect(window->Pos+ImVec2(1,1), window->Pos+window->Size+ImVec2(1,1), window->Color(ImGuiCol_BorderShadow), rounding);
				window->DrawList->AddRect(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_Border), rounding);
				if (!(window->Flags & ImGuiWindowFlags_NoTitleBar))
					window->DrawList->AddLine(title_bar_aabb.GetBL(), title_bar_aabb.GetBR(), window->Color(ImGuiCol_Border));
			}

			// Scrollbar
			window->ScrollbarY = (window->SizeContentsFit.y > window->Size.y) && !(window->Flags & ImGuiWindowFlags_NoScrollbar);
			if (window->ScrollbarY)
			{
				ImGuiAabb scrollbar_bb(window->Aabb().Max.x - style.ScrollBarWidth, title_bar_aabb.Max.y+1, window->Aabb().Max.x, window->Aabb().Max.y-1);
				//window->DrawList->AddLine(scrollbar_bb.GetTL(), scrollbar_bb.GetBL(), g.Colors[ImGuiCol_Border]);
				window->DrawList->AddRectFilled(scrollbar_bb.Min, scrollbar_bb.Max, window->Color(ImGuiCol_ScrollbarBg));
				scrollbar_bb.Max.x -= 3;
				scrollbar_bb.Expand(ImVec2(0,-3));

				const float grab_size_y_norm = ImSaturate(window->Size.y / ImMax(window->SizeContentsFit.y, window->Size.y));
				const float grab_size_y = scrollbar_bb.GetHeight() * grab_size_y_norm;

				// Handle input right away (none of the code above is relying on scrolling)
				bool held = false;
				bool hovered = false;
				if (grab_size_y_norm < 1.0f)
				{
					const ImGuiID scrollbar_id = window->GetID("#SCROLLY");
					ButtonBehaviour(scrollbar_bb, scrollbar_id, &hovered, &held, true);
					if (held)
					{
						g.HoveredId = scrollbar_id;
						const float pos_y_norm = ImSaturate((g.IO.MousePos.y - (scrollbar_bb.Min.y + grab_size_y*0.5f)) / (scrollbar_bb.GetHeight() - grab_size_y)) * (1.0f - grab_size_y_norm);
						window->ScrollY = pos_y_norm * window->SizeContentsFit.y;
						window->NextScrollY = window->ScrollY;
					}
				}

				// Normalized height of the grab
				const float pos_y_norm = ImSaturate(window->ScrollY / ImMax(0.0f, window->SizeContentsFit.y));
				const ImU32 grab_col = window->Color(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab);
				window->DrawList->AddRectFilled(
					ImVec2(scrollbar_bb.Min.x, ImLerp(scrollbar_bb.Min.y, scrollbar_bb.Max.y, pos_y_norm)), 
					ImVec2(scrollbar_bb.Max.x, ImLerp(scrollbar_bb.Min.y, scrollbar_bb.Max.y, pos_y_norm + grab_size_y_norm)), grab_col);
			}

			// Render resize grip
			// (after the input handling so we don't have a frame of latency)
			if (!(window->Flags & ImGuiWindowFlags_NoResize))
			{
				const float r = style.WindowRounding;
				const ImVec2 br = window->Aabb().GetBR();
				if (r == 0.0f)
				{
					window->DrawList->AddTriangleFilled(br, br-ImVec2(0,14), br-ImVec2(14,0), resize_col);
				}
				else
				{
					// FIXME: We should draw 4 triangles and decide on a size that's not dependant on the rounding size (previously used 18)
					window->DrawList->AddArc(br - ImVec2(r,r), r, resize_col, 6, 9, true);
					window->DrawList->AddTriangleFilled(br+ImVec2(0,-2*r),br+ImVec2(0,-r),br+ImVec2(-r,-r), resize_col);
					window->DrawList->AddTriangleFilled(br+ImVec2(-r,-r), br+ImVec2(-r,0),br+ImVec2(-2*r,0), resize_col);
				}
			}
		}

		// Setup drawing context
		window->DC.ColumnStartX = window->WindowPadding().x;
		window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.ColumnStartX, window->TitleBarHeight() + window->WindowPadding().y) - ImVec2(0.0f, window->ScrollY);
		window->DC.CursorPos = window->DC.CursorStartPos;
		window->DC.CursorPosPrevLine = window->DC.CursorPos;
		window->DC.CurrentLineHeight = window->DC.PrevLineHeight = 0.0f;
		window->DC.LogLineHeight = window->DC.CursorPos.y - 9999.0f;
		window->DC.ChildWindows.resize(0);
		window->DC.ItemWidth.resize(0); 
		window->DC.ItemWidth.push_back(window->ItemWidthDefault);
		window->DC.AllowKeyboardFocus.resize(0);
		window->DC.AllowKeyboardFocus.push_back(true);
		window->DC.ColorModifiers.resize(0);
		window->DC.ColorEditMode = ImGuiColorEditMode_UserSelect;
		window->DC.ColumnCurrent = 0;
		window->DC.ColumnsCount = 1;
		window->DC.TreeDepth = 0;
		window->DC.StateStorage = &window->StateStorage;
		window->DC.OpenNextNode = -1;

		// Reset contents size for auto-fitting
		window->SizeContentsFit = ImVec2(0.0f, 0.0f);
		if (window->AutoFitFrames > 0)
			window->AutoFitFrames--;

		// Title bar
		if (!(window->Flags & ImGuiWindowFlags_NoTitleBar))
		{
			RenderCollapseTriangle(window->Pos + style.FramePadding, !window->Collapsed, 1.0f, true);
			if (open)
				ImGui::CloseWindowButton(open);

			const ImVec2 text_size = CalcTextSize(name);
			const ImVec2 text_min = window->Pos + style.FramePadding + ImVec2(window->FontSize() + style.ItemInnerSpacing.x, 0.0f);
			const ImVec2 text_max = window->Pos + ImVec2(window->Size.x - (open ? (title_bar_aabb.GetHeight()-3) : style.FramePadding.x), style.FramePadding.y + text_size.y);
			const bool clip_title = text_size.x > (text_max.x - text_min.x);	// only push a clip rectangle if we need to, because it may turn into a separate draw call
			if (clip_title)
				ImGui::PushClipRect(ImVec4(text_min.x, text_min.y, text_max.x, text_max.y));
			RenderText(text_min, name);
			if (clip_title)
				ImGui::PopClipRect();
		}
	}
	else
	{
		// Outer clipping rectangle
		if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_ComboBox))
		{
			ImGuiWindow* parent_window = g.CurrentWindowStack[g.CurrentWindowStack.size()-2];
			ImGui::PushClipRect(parent_window->ClipRectStack.back());
		}
		else
		{
			ImGui::PushClipRect(ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y));
		}
	}

	// Inner clipping rectangle
	// We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame
	const ImGuiAabb title_bar_aabb = window->TitleBarAabb();
	ImVec4 clip_rect(title_bar_aabb.Min.x+0.5f+window->WindowPadding().x*0.5f, title_bar_aabb.Max.y+0.5f, window->Aabb().Max.x+0.5f-window->WindowPadding().x*0.5f, window->Aabb().Max.y-1.5f);
	if (window->ScrollbarY)
		clip_rect.z -= g.Style.ScrollBarWidth;
	ImGui::PushClipRect(clip_rect);

	if (first_begin_of_the_frame)
	{
		// Clear 'accessed' flag last thing
		window->Accessed = false;
	}

	// Child window can be out of sight and have "negative" clip windows.
	// Mark them as collapsed so commands are skipped earlier (we can't manually collapse because they have no title bar).
	if (flags & ImGuiWindowFlags_ChildWindow)
	{
		IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0);
		const ImVec4 clip_rect = window->ClipRectStack.back();
		window->Collapsed = (clip_rect.x >= clip_rect.z || clip_rect.y >= clip_rect.w);

		// We also hide the window from rendering because we've already added its border to the command list.
		// (we could perform the check earlier in the function but it is simplier at this point)
		if (window->Collapsed)
			window->Visible = false;
	}
	if (g.Style.Alpha <= 0.0f)
		window->Visible = false;

	// Return false if we don't intend to display anything to allow user to perform an early out optimisation
	window->SkipItems = window->Collapsed || (!window->Visible && window->AutoFitFrames == 0);
	return !window->SkipItems;
}

void End()
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = g.CurrentWindow;

	ImGui::Columns(1, "#CloseColumns");
	ImGui::PopClipRect();	// inner window clip rectangle
	ImGui::PopClipRect();	// outer window clip rectangle

	// Select window for move/focus when we're done with all our widgets
	ImGuiAabb bb(window->Pos, window->Pos+window->Size);
	if (g.ActiveId == 0 && g.HoveredId == 0 && g.HoveredWindowExcludingChilds == window && IsMouseHoveringBox(bb) && g.IO.MouseClicked[0])
		g.ActiveId = window->GetID("#MOVE");

	// Stop logging
	if (!(window->Flags & ImGuiWindowFlags_ChildWindow))	// FIXME: more options for scope of logging
	{
		g.LogEnabled = false;
		if (g.LogFile != NULL)
		{
			fprintf(g.LogFile, "\n");
			if (g.LogFile == stdout)
				fflush(g.LogFile);
			else
				fclose(g.LogFile);
			g.LogFile = NULL;
		}
		if (g.LogClipboard.size() > 1)
		{
			g.LogClipboard.append("\n");
			if (g.IO.SetClipboardTextFn)
				g.IO.SetClipboardTextFn(g.LogClipboard.begin(), g.LogClipboard.end());
			g.LogClipboard.clear();
		}
	}

	// Pop
	g.CurrentWindowStack.pop_back();
	g.CurrentWindow = g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back();
}

static void FocusWindow(ImGuiWindow* window)
{
	ImGuiState& g = GImGui;
	g.FocusedWindow = window;

	// Move to front
	for (size_t i = 0; i < g.Windows.size(); i++)
		if (g.Windows[i] == window)
		{
			g.Windows.erase(g.Windows.begin() + i);
			break;
		}
	g.Windows.push_back(window);
}

void PushItemWidth(float item_width)
{
	ImGuiWindow* window = GetCurrentWindow();
	item_width = (float)(int)item_width;
	window->DC.ItemWidth.push_back(item_width > 0.0f ? item_width : window->ItemWidthDefault);
}

void PopItemWidth()
{
	ImGuiWindow* window = GetCurrentWindow();
	window->DC.ItemWidth.pop_back();
}

float GetItemWidth()
{
	ImGuiWindow* window = GetCurrentWindow();
	return window->DC.ItemWidth.back();
}

void PushAllowKeyboardFocus(bool allow_keyboard_focus)
{
	ImGuiWindow* window = GetCurrentWindow();
	window->DC.AllowKeyboardFocus.push_back(allow_keyboard_focus);
}

void PopAllowKeyboardFocus()
{
	ImGuiWindow* window = GetCurrentWindow();
	window->DC.AllowKeyboardFocus.pop_back();
}

void PushStyleColor(ImGuiCol idx, const ImVec4& col)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();

	ImGuiColMod backup;
	backup.Col = idx;
	backup.PreviousValue = g.Style.Colors[idx];
	window->DC.ColorModifiers.push_back(backup);
	g.Style.Colors[idx] = col;
}

void PopStyleColor()
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();

	ImGuiColMod& backup = window->DC.ColorModifiers.back();
	g.Style.Colors[backup.Col] = backup.PreviousValue;
	window->DC.ColorModifiers.pop_back();
}

const char* GetStyleColorName(ImGuiCol idx)
{
	// Create with regexp: ImGuiCol_{.*}, --> case ImGuiCol_\1: return "\1";
	switch (idx)
	{
	case ImGuiCol_Text: return "Text";
	case ImGuiCol_WindowBg: return "WindowBg";
	case ImGuiCol_Border: return "Border";
	case ImGuiCol_BorderShadow: return "BorderShadow";
	case ImGuiCol_FrameBg: return "FrameBg";
	case ImGuiCol_TitleBg: return "TitleBg";
	case ImGuiCol_TitleBgCollapsed: return "TitleBgCollapsed";
	case ImGuiCol_ScrollbarBg: return "ScrollbarBg";
	case ImGuiCol_ScrollbarGrab: return "ScrollbarGrab";
	case ImGuiCol_ScrollbarGrabHovered: return "ScrollbarGrabHovered";
	case ImGuiCol_ScrollbarGrabActive: return "ScrollbarGrabActive";
	case ImGuiCol_ComboBg: return "ComboBg";
	case ImGuiCol_CheckHovered: return "CheckHovered";
	case ImGuiCol_CheckActive: return "CheckActive";
	case ImGuiCol_SliderGrab: return "SliderGrab";
	case ImGuiCol_SliderGrabActive: return "SliderGrabActive";
	case ImGuiCol_Button: return "Button";
	case ImGuiCol_ButtonHovered: return "ButtonHovered";
	case ImGuiCol_ButtonActive: return "ButtonActive";
	case ImGuiCol_Header: return "Header";
	case ImGuiCol_HeaderHovered: return "HeaderHovered";
	case ImGuiCol_HeaderActive: return "HeaderActive";
	case ImGuiCol_Column: return "Column";
	case ImGuiCol_ColumnHovered: return "ColumnHovered";
	case ImGuiCol_ColumnActive: return "ColumnActive";
	case ImGuiCol_ResizeGrip: return "ResizeGrip";
	case ImGuiCol_ResizeGripHovered: return "ResizeGripHovered";
	case ImGuiCol_ResizeGripActive: return "ResizeGripActive";
	case ImGuiCol_CloseButton: return "CloseButton";
	case ImGuiCol_CloseButtonHovered: return "CloseButtonHovered";
	case ImGuiCol_CloseButtonActive: return "CloseButtonActive";
	case ImGuiCol_PlotLines: return "PlotLines";
	case ImGuiCol_PlotLinesHovered: return "PlotLinesHovered";
	case ImGuiCol_PlotHistogram: return "PlotHistogram";
	case ImGuiCol_PlotHistogramHovered: return "ImGuiCol_PlotHistogramHovered";
	case ImGuiCol_TextSelectedBg: return "TextSelectedBg";
	case ImGuiCol_TooltipBg: return "TooltipBg";
	}
	IM_ASSERT(0);
	return "Unknown";
}

bool GetWindowIsFocused()
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	return g.FocusedWindow == window;
}

float GetWindowWidth()
{
	ImGuiWindow* window = GetCurrentWindow();
	return window->Size.x;
}

ImVec2 GetWindowPos()
{
	ImGuiWindow* window = GetCurrentWindow();
	return window->Pos;
}

void SetWindowPos(const ImVec2& pos)
{
	ImGuiWindow* window = GetCurrentWindow();
	const ImVec2 old_pos = window->Pos;
	window->PosFloat = pos;
	window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y);

	// If we happen to move the window while it is showing (which is a bad idea) let's at least offset the cursor
	window->DC.CursorPos += (window->Pos - old_pos);
}

ImVec2 GetWindowSize()
{
	ImGuiWindow* window = GetCurrentWindow();
	return window->Size;
}

ImVec2 GetWindowContentRegionMin()
{
	ImGuiWindow* window = GetCurrentWindow();
	return ImVec2(0, window->TitleBarHeight()) + window->WindowPadding();
}

ImVec2 GetWindowContentRegionMax()
{
	ImGuiWindow* window = GetCurrentWindow();
	ImVec2 m = window->Size - window->WindowPadding();
	if (window->ScrollbarY)
		m.x -= GImGui.Style.ScrollBarWidth;
	return m;
}

float GetTextLineHeight()
{
	ImGuiWindow* window = GetCurrentWindow();
	return window->FontSize();
}

float GetTextLineSpacing()
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	return window->FontSize() + g.Style.ItemSpacing.y;
}

ImDrawList*	GetWindowDrawList()
{
	ImGuiWindow* window = GetCurrentWindow();
	return window->DrawList;
}

void SetFontScale(float scale)
{
	ImGuiWindow* window = GetCurrentWindow();
	window->FontScale = scale;
}

ImVec2 GetCursorPos()
{
	ImGuiWindow* window = GetCurrentWindow();
	return window->DC.CursorPos - window->Pos;
}

void SetCursorPos(const ImVec2& pos)
{
	ImGuiWindow* window = GetCurrentWindow();
	window->DC.CursorPos = window->Pos + pos;
}

void SetScrollPosHere()
{
	ImGuiWindow* window = GetCurrentWindow();
	window->NextScrollY = (window->DC.CursorPos.y + window->ScrollY) - (window->Pos.y + window->SizeFull.y * 0.5f) - (window->TitleBarHeight() + window->WindowPadding().y);
}

void SetTreeStateStorage(ImGuiStorage* tree)
{
	ImGuiWindow* window = GetCurrentWindow();
	window->DC.StateStorage = tree ? tree : &window->StateStorage;
}

ImGuiStorage* GetTreeStateStorage()
{
	ImGuiWindow* window = GetCurrentWindow();
	return window->DC.StateStorage;
}

void TextV(const char* fmt, va_list args)
{
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return;

	static char buf[1024];
	const char* text_end = buf + ImFormatStringV(buf, IM_ARRAYSIZE(buf), fmt, args);
	TextUnformatted(buf, text_end);
}

void Text(const char* fmt, ...)
{
	va_list args;
	va_start(args, fmt);
	TextV(fmt, args);
	va_end(args);
}

void TextColored(const ImVec4& col, const char* fmt, ...)
{
	ImGui::PushStyleColor(ImGuiCol_Text, col);
	va_list args;
	va_start(args, fmt);
	TextV(fmt, args);
	va_end(args);
	ImGui::PopStyleColor();
}

void TextUnformatted(const char* text, const char* text_end)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return;

	const char* text_begin = text;
	if (text_end == NULL)
		text_end = text + strlen(text);

	if (text_end - text > 2000)
	{
		// Long text!
		// Perform manual coarse clipping to optimize for long multi-line text
		// From this point we will only compute the width of lines that are visible.
		const char* line = text;
		const float line_height = ImGui::GetTextLineHeight();
		const ImVec2 start_pos = window->DC.CursorPos;
		const ImVec4 clip_rect = window->ClipRectStack.back();
		ImVec2 text_size(0,0);

		if (start_pos.y <= clip_rect.w)
		{
			ImVec2 pos = start_pos;

			// lines to skip (can't skip when logging text)
			if (!g.LogEnabled)
			{
				int lines_skippable = (int)((clip_rect.y - start_pos.y) / line_height) - 1;
				if (lines_skippable > 0)
				{
					int lines_skipped = 0;
					while (line < text_end && lines_skipped <= lines_skippable)
					{
						const char* line_end = strchr(line, '\n');
						line = line_end + 1;
						lines_skipped++;
					}
					pos.y += lines_skipped * line_height;
				}
			}

			// lines to render?
			if (line < text_end)
			{
				ImGuiAabb line_box(pos, pos + ImVec2(ImGui::GetWindowWidth(), line_height));
				while (line < text_end)
				{
					const char* line_end = strchr(line, '\n');
					if (ImGui::IsClipped(line_box))
						break;

					const ImVec2 line_size = CalcTextSize(line, line_end, false);
					text_size.x = ImMax(text_size.x, line_size.x);
					RenderText(pos, line, line_end, false);
					if (!line_end)
						line_end = text_end;
					line = line_end + 1;
					line_box.Min.y += line_height;
					line_box.Max.y += line_height;
					pos.y += line_height;
				}

				// count remaining lines
				int lines_skipped = 0;
				while (line < text_end)
				{
					const char* line_end = strchr(line, '\n');
					if (!line_end)
						line_end = text_end;
					line = line_end + 1;
					lines_skipped++;
				}
				pos.y += lines_skipped * line_height;
			}

			text_size.y += (pos - start_pos).y;
		}
		const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + text_size);
		ItemSize(bb);
		ClipAdvance(bb);
	}
	else
	{
		const ImVec2 text_size = CalcTextSize(text_begin, text_end, false);
		ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + text_size);
		ItemSize(bb.GetSize(), &bb.Min);

		if (ClipAdvance(bb))
			return;

		// Render
		// We don't hide text after # in this end-user function.
		RenderText(bb.Min, text_begin, text_end, false);
	}
}

void AlignFirstTextHeightToWidgets()
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return;

	// Declare a dummy item size to that upcoming items that are smaller will center-align on the newly expanded line height.
	ImGui::ItemSize(ImVec2(0, window->FontSize() + g.Style.FramePadding.y*2));
	ImGui::SameLine(0, 0);
}

void LabelText(const char* label, const char* fmt, ...)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return;
	const ImGuiStyle& style = g.Style;
	const float w = window->DC.ItemWidth.back();

	static char buf[1024];
	va_list args;
	va_start(args, fmt);
	const char* text_begin = &buf[0];
	const char* text_end = text_begin + ImFormatStringV(buf, IM_ARRAYSIZE(buf), fmt, args);
	va_end(args);

	const ImVec2 text_size = CalcTextSize(label);
	const ImGuiAabb value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2, text_size.y));
	const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + style.FramePadding.x*2 + style.ItemInnerSpacing.x, 0.0f) + text_size);
	ItemSize(bb);

	if (ClipAdvance(value_bb))
		return;

	// Render
	RenderText(value_bb.Min, text_begin, text_end);
	RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y), label);
}

static bool ButtonBehaviour(const ImGuiAabb& bb, const ImGuiID& id, bool* out_hovered, bool* out_held, bool allow_key_modifiers, bool repeat)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();

	const bool hovered = (g.HoveredWindow == window) && (g.HoveredId == 0) && IsMouseHoveringBox(bb);
	bool pressed = false;
	if (hovered)
	{
		g.HoveredId = id;
		if (allow_key_modifiers || (!g.IO.KeyCtrl && !g.IO.KeyShift))
		{
			if (g.IO.MouseClicked[0])
			{
				g.ActiveId = id;
			}
			else if (repeat && g.ActiveId && ImGui::IsMouseClicked(0, true))
			{
				pressed = true;
			}
		}
	}

	bool held = false;
	if (g.ActiveId == id)
	{
		if (g.IO.MouseDown[0])
		{
			held = true;
		}
		else
		{
			if (hovered)
				pressed = true;
			g.ActiveId = 0;
		}
	}

	if (out_hovered) *out_hovered = hovered;
	if (out_held) *out_held = held;

	return pressed;
}

bool Button(const char* label, ImVec2 size, bool repeat_when_held)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return false;

	const ImGuiStyle& style = g.Style;
	const ImGuiID id = window->GetID(label);

	const ImVec2 text_size = CalcTextSize(label);
	if (size.x == 0.0f)
		size.x = text_size.x;
	if (size.y == 0.0f)
		size.y = text_size.y;

	const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos+size + style.FramePadding*2.0f);
	ItemSize(bb);

	if (ClipAdvance(bb))
		return false;

	bool hovered, held;
	bool pressed = ButtonBehaviour(bb, id, &hovered, &held, true, repeat_when_held);

	// Render
	const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
	RenderFrame(bb.Min, bb.Max, col);

	if (size.x < text_size.x || size.y < text_size.y)
		PushClipRect(ImVec4(bb.Min.x+style.FramePadding.x, bb.Min.y+style.FramePadding.y, bb.Max.x, bb.Max.y-style.FramePadding.y));		// Allow extra to draw over the horizontal padding to make it visible that text doesn't fit
	const ImVec2 off = ImVec2(ImMax(0.0f, size.x - text_size.x) * 0.5f, ImMax(0.0f, size.y - text_size.y) * 0.5f);
	RenderText(bb.Min + style.FramePadding + off, label);
	if (size.x < text_size.x || size.y < text_size.y)
		PopClipRect();

	return pressed;
}

// Fits within text without additional spacing.
bool SmallButton(const char* label)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return false;

	const ImGuiStyle& style = g.Style;
	const ImGuiID id = window->GetID(label);

	const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos+CalcTextSize(label) + ImVec2(style.FramePadding.x*2,0));
	ItemSize(bb);

	if (ClipAdvance(bb))
		return false;

	bool hovered, held;
	bool pressed = ButtonBehaviour(bb, id, &hovered, &held, true);

	// Render
	const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
	RenderFrame(bb.Min, bb.Max, col);
	RenderText(bb.Min + ImVec2(style.FramePadding.x,0), label);

	return pressed;
}

static bool CloseWindowButton(bool* open)
{
	ImGuiWindow* window = GetCurrentWindow();

	const ImGuiID id = window->GetID("##CLOSE");
	const float title_bar_height = window->TitleBarHeight();
	const ImGuiAabb bb(window->Aabb().GetTR() + ImVec2(-title_bar_height+3.0f,2.0f), window->Aabb().GetTR() + ImVec2(-2.0f,+title_bar_height-2.0f));

	bool hovered, held;
	bool pressed = ButtonBehaviour(bb, id, &hovered, &held, true);

	// Render
	const ImU32 col = window->Color((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_CloseButtonHovered : ImGuiCol_CloseButton);
	window->DrawList->AddCircleFilled(bb.GetCenter(), ImMax(2.0f,title_bar_height*0.5f-4), col, 16);

	const float cross_padding = 4;
	if (hovered && bb.GetWidth() >= (cross_padding+1)*2 && bb.GetHeight() >= (cross_padding+1)*2)
	{
		window->DrawList->AddLine(bb.GetTL()+ImVec2(+cross_padding,+cross_padding), bb.GetBR()+ImVec2(-cross_padding,-cross_padding), window->Color(ImGuiCol_Text));
		window->DrawList->AddLine(bb.GetBL()+ImVec2(+cross_padding,-cross_padding), bb.GetTR()+ImVec2(-cross_padding,+cross_padding), window->Color(ImGuiCol_Text));
	}

	if (open != NULL && pressed)
		*open = !*open;

	return pressed;
}

void LogToTTY(int max_depth)
{
	ImGuiState& g = GImGui;
	if (g.LogEnabled)
		return;
	g.LogEnabled = true;
	g.LogFile = stdout;
	if (max_depth >= 0)
		g.LogAutoExpandMaxDepth = max_depth;
}

void LogToFile(int max_depth, const char* filename)
{
	ImGuiState& g = GImGui;
	if (g.LogEnabled)
		return;
	if (!filename)
		filename = g.IO.LogFilename;
	g.LogEnabled = true;
	g.LogFile = fopen(filename, "at");
	if (max_depth >= 0)
		g.LogAutoExpandMaxDepth = max_depth;
}

void LogToClipboard(int max_depth)
{
	ImGuiState& g = GImGui;
	if (g.LogEnabled)
		return;
	g.LogEnabled = true;
	g.LogFile = NULL;
	if (max_depth >= 0)
		g.LogAutoExpandMaxDepth = max_depth;
}

void LogButtons()
{
	ImGuiState& g = GImGui;

	ImGui::PushID("LogButtons");
	const bool log_to_tty = ImGui::Button("Log To TTY");
	ImGui::SameLine();		
	const bool log_to_file = ImGui::Button("Log To File");
	ImGui::SameLine();
	const bool log_to_clipboard = ImGui::Button("Log To Clipboard");
	ImGui::SameLine();

	ImGui::PushItemWidth(80.0f);
	ImGui::PushAllowKeyboardFocus(false);
	ImGui::SliderInt("Depth", &g.LogAutoExpandMaxDepth, 0, 9, NULL);
	ImGui::PopAllowKeyboardFocus();
	ImGui::PopItemWidth();
	ImGui::PopID();

	// Start logging at the end of the function so that the buttons don't appear in the log
	if (log_to_tty)
		LogToTTY(g.LogAutoExpandMaxDepth);
	if (log_to_file)
		LogToFile(g.LogAutoExpandMaxDepth, g.IO.LogFilename);
	if (log_to_clipboard)
		LogToClipboard(g.LogAutoExpandMaxDepth);
}

bool CollapsingHeader(const char* label, const char* str_id, const bool display_frame, const bool default_open)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return false;

	const ImGuiStyle& style = g.Style;

	IM_ASSERT(str_id != NULL || label != NULL);
	if (str_id == NULL)
		str_id = label;
	if (label == NULL)
		label = str_id;
	const ImGuiID id = window->GetID(str_id);

	ImGuiStorage* tree = window->DC.StateStorage;
	bool opened;
	if (window->DC.OpenNextNode != -1)
	{
		opened = window->DC.OpenNextNode > 0;
		tree->SetInt(id, opened);
		window->DC.OpenNextNode = -1;
	}
	else
	{
		opened = tree->GetInt(id, default_open) != 0;
	}

	const ImVec2 window_padding = window->WindowPadding();
	const ImVec2 text_size = CalcTextSize(label);
	const ImVec2 pos_min = window->DC.CursorPos;
	const ImVec2 pos_max = window->Pos + GetWindowContentRegionMax();
	ImGuiAabb bb = ImGuiAabb(pos_min, ImVec2(pos_max.x, pos_min.y + text_size.y));
	if (display_frame)
	{
		bb.Min.x -= window_padding.x*0.5f;
		bb.Max.x += window_padding.x*0.5f;
		bb.Max.y += style.FramePadding.y * 2;
	}

	const ImGuiAabb text_bb(bb.Min, bb.Min + ImVec2(window->FontSize() + style.FramePadding.x*2*2,0) + text_size);
	ItemSize(ImVec2(text_bb.GetSize().x, bb.GetSize().y));	// NB: we don't provide our width so that it doesn't get feed back into AutoFit

	// Logging auto expand tree nodes (but not collapsing headers.. seems like sensible behaviour)
	// NB- If we are above max depth we still allow manually opened nodes to be logged
	if (!display_frame)	
		if (g.LogEnabled && window->DC.TreeDepth < g.LogAutoExpandMaxDepth)
			opened = true;

	if (ClipAdvance(bb))
		return opened;

	bool hovered, held;
	bool pressed = ButtonBehaviour(display_frame ? bb : text_bb, id, &hovered, &held, false);
	if (pressed)
	{
		opened = !opened;
		tree->SetInt(id, opened);
	}

	// Render
	const ImU32 col = window->Color((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
	if (display_frame)
	{
		RenderFrame(bb.Min, bb.Max, col, true);
		RenderCollapseTriangle(bb.Min + style.FramePadding, opened, 1.0f, true);
		RenderText(bb.Min + style.FramePadding + ImVec2(window->FontSize() + style.FramePadding.x*2,0), label);
	}
	else
	{
		if ((held && hovered) || hovered)
			RenderFrame(bb.Min, bb.Max, col, false);
		RenderCollapseTriangle(bb.Min + ImVec2(style.FramePadding.x, window->FontSize()*0.15f), opened, 0.70f);
		RenderText(bb.Min + ImVec2(window->FontSize() + style.FramePadding.x*2,0), label);
	}

	return opened;
}

void BulletText(const char* fmt, ...)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return;

	static char buf[1024];
	va_list args;
	va_start(args, fmt);
	const char* text_begin = buf;
	const char* text_end = text_begin + ImFormatStringV(buf, IM_ARRAYSIZE(buf), fmt, args);
	va_end(args);

	const float line_height = window->FontSize();
	const ImVec2 text_size = CalcTextSize(text_begin, text_end);
	const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(line_height + (text_size.x > 0.0f ? (g.Style.FramePadding.x*2) : 0.0f),0) + text_size);	// Empty text doesn't add padding
	ItemSize(bb);

	if (ClipAdvance(bb))
		return;

	// Render
	const float bullet_size = line_height*0.15f;
	window->DrawList->AddCircleFilled(bb.Min + ImVec2(g.Style.FramePadding.x + line_height*0.5f, line_height*0.5f), bullet_size, window->Color(ImGuiCol_Text));
	RenderText(bb.Min+ImVec2(window->FontSize()+g.Style.FramePadding.x*2,0), text_begin, text_end);
}

bool TreeNode(const char* str_id, const char* fmt, ...)
{
	static char buf[1024];
	va_list args;
	va_start(args, fmt);
	ImFormatStringV(buf, IM_ARRAYSIZE(buf), fmt, args);
	va_end(args);

	if (!str_id || !str_id[0])
		str_id = fmt;

	ImGui::PushID(str_id);
	const bool opened = ImGui::CollapsingHeader(buf, "", false);		// do not add to the ID so that TreeNodeSetOpen can access
	ImGui::PopID();

	if (opened)
		ImGui::TreePush(str_id);

	return opened;
}

bool TreeNode(const void* ptr_id, const char* fmt, ...)
{
	static char buf[1024];
	va_list args;
	va_start(args, fmt);
	ImFormatStringV(buf, IM_ARRAYSIZE(buf), fmt, args);
	va_end(args);

	if (!ptr_id)
		ptr_id = fmt;

	ImGui::PushID(ptr_id);
	const bool opened = ImGui::CollapsingHeader(buf, "", false);
	ImGui::PopID();

	if (opened)
		ImGui::TreePush(ptr_id);

	return opened;
}

bool TreeNode(const char* str_label_id)
{
	return TreeNode(str_label_id, "%s", str_label_id);
}

void OpenNextNode(bool open)
{
	ImGuiWindow* window = GetCurrentWindow();
	window->DC.OpenNextNode = open ? 1 : 0;
}

void PushID(const char* str_id)
{
	ImGuiWindow* window = GetCurrentWindow();
	window->IDStack.push_back(window->GetID(str_id));
}

void PushID(const void* ptr_id)
{
	ImGuiWindow* window = GetCurrentWindow();
	window->IDStack.push_back(window->GetID(ptr_id));
}

void PushID(int int_id)
{
	const void* ptr_id = (void*)(intptr_t)int_id;
	ImGuiWindow* window = GetCurrentWindow();
	window->IDStack.push_back(window->GetID(ptr_id));
}

void PopID()
{
	ImGuiWindow* window = GetCurrentWindow();
	window->IDStack.pop_back();
}

// NB: only call right after InputText because we are using its InitialValue storage
static void ApplyNumericalTextInput(const char* buf, float *v)
{
	while (*buf == ' ' || *buf == '\t')
		buf++;

	// We don't support '-' op because it would conflict with inputing negative value.
	// Instead you can use +-100 to subtract from an existing value
	char op = buf[0];
	if (op == '+' || op == '*' || op == '/')
	{
		buf++;
		while (*buf == ' ' || *buf == '\t')
			buf++;
	}
	else
	{
		op = 0;
	}
	if (!buf[0])
		return;

	float ref_v = *v;
	if (op)
		if (sscanf(GImGui.InputTextState.InitialText, "%f", &ref_v) < 1)
			return;

	float op_v = 0.0f;
	if (sscanf(buf, "%f", &op_v) < 1)
		return;

	if (op == '+')
		*v = ref_v + op_v;
	else if (op == '*')
		*v = ref_v * op_v;
	else if (op == '/')
	{
		if (op_v == 0.0f)
			return;
		*v = ref_v / op_v;
	}
	else
		*v = op_v;
}

// use power!=1.0 for logarithmic sliders
bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format, float power)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return false;

	const ImGuiStyle& style = g.Style;
	const ImGuiID id = window->GetID(label);
	const float w = window->DC.ItemWidth.back();

	if (!display_format)
		display_format = "%.3f";

	// Dodgily parse display precision back from the display format
	int decimal_precision = 3;
	if (const char* p = strchr(display_format, '%'))
	{
		p++;
		while (*p >= '0' && *p <= '9')
			p++;
		if (*p == '.')
		{
			decimal_precision = atoi(p+1);
			if (decimal_precision < 0 || decimal_precision > 10)
				decimal_precision = 3;
		}
	}

	const bool tab_focus_requested = window->FocusItemRegister(g.ActiveId == id);

	const ImVec2 text_size = CalcTextSize(label);
	const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, text_size.y) + style.FramePadding*2.0f);
	const ImGuiAabb slider_bb(frame_bb.Min+g.Style.FramePadding, frame_bb.Max-g.Style.FramePadding);
	const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(style.ItemInnerSpacing.x + text_size.x, 0.0f));

	if (IsClipped(slider_bb))
	{
		// NB- we don't use ClipAdvance() because we don't want to submit ItemSize() because we may change into a text edit later which may submit an ItemSize itself
		ItemSize(bb);
		return false;
	}

	const bool is_unbound = v_min == -FLT_MAX || v_min == FLT_MAX || v_max == -FLT_MAX || v_max == FLT_MAX;

	const float grab_size_in_units = 1.0f;															// In 'v' units. Probably needs to be parametrized, based on a 'v_step' value? decimal precision?
	float grab_size_in_pixels;
	if (decimal_precision > 0 || is_unbound)
		grab_size_in_pixels = 10.0f;
	else
		grab_size_in_pixels = ImMax(grab_size_in_units * (w / (v_max-v_min+1.0f)), 8.0f);				// Integer sliders
	const float slider_effective_w = slider_bb.GetWidth() - grab_size_in_pixels;
	const float slider_effective_x1 = slider_bb.Min.x + grab_size_in_pixels*0.5f;
	const float slider_effective_x2 = slider_bb.Max.x - grab_size_in_pixels*0.5f;

	// For logarithmic sliders that cross over sign boundary we want the exponential increase to be symetric around 0.0
	float linear_zero_pos = 0.0f;	// 0.0->1.0f
	if (!is_unbound)
	{
		if (v_min * v_max < 0.0f)
		{
			// Different sign
			const float linear_dist_min_to_0 = powf(fabsf(0.0f - v_min), 1.0f/power);
			const float linear_dist_max_to_0 = powf(fabsf(v_max - 0.0f), 1.0f/power);
			linear_zero_pos = linear_dist_min_to_0 / (linear_dist_min_to_0+linear_dist_max_to_0);
		}
		else
		{
			// Same sign
			linear_zero_pos = v_min < 0.0f ? 1.0f : 0.0f;
		}
	}

	const bool hovered = (g.HoveredWindow == window) && (g.HoveredId == 0) && IsMouseHoveringBox(slider_bb);
	if (hovered)
		g.HoveredId = id;

	bool start_text_input = false;
	if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]))
	{
		g.ActiveId = id;

		const bool is_ctrl_down = g.IO.KeyCtrl;
		if (tab_focus_requested || is_ctrl_down || is_unbound)
		{
			start_text_input = true;
			g.SliderAsInputTextId = 0;
		}
	}

	// Tabbing thru or CTRL-clicking through slider turns into an input box
	bool value_changed = false;
	if (start_text_input || (g.ActiveId == id && id == g.SliderAsInputTextId))
	{
		char text_buf[64];
		ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%.*f", decimal_precision, *v);

		g.ActiveId = g.SliderAsInputTextId;
		g.HoveredId = 0;
		window->FocusItemUnregister();	// Our replacement slider will override the focus ID (that we needed to declare previously to allow for a TAB focus to happen before we got selected)
		value_changed = ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_AlignCenter);
		if (g.SliderAsInputTextId == 0)
		{
			// First frame
			IM_ASSERT(g.ActiveId == id);	// InputText ID should match the Slider ID (else we'd need to store them both)
			g.SliderAsInputTextId = g.ActiveId;
			g.ActiveId = id;
			g.HoveredId = id;
		}
		else
		{
			if (g.ActiveId == g.SliderAsInputTextId)
				g.ActiveId = id;
			else
				g.ActiveId = g.SliderAsInputTextId = 0;
		}
		if (value_changed)
		{
			ApplyNumericalTextInput(text_buf, v);
		}
		return value_changed;
	}

	ItemSize(bb);
	RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg));

	if (g.ActiveId == id)
	{
		if (g.IO.MouseDown[0])
		{
			if (!is_unbound)
			{
				const float normalized_pos = ImClamp((g.IO.MousePos.x - slider_effective_x1) / slider_effective_w, 0.0f, 1.0f);
				
				// Linear slider
				//float new_value = ImLerp(v_min, v_max, normalized_pos);

				// Account for logarithmic scale on both sides of the zero
				float new_value;
				if (normalized_pos < linear_zero_pos)
				{
					// Negative: rescale to the negative range before powering
					float a = 1.0f - (normalized_pos / linear_zero_pos);
					a = powf(a, power);
					new_value = ImLerp(ImMin(v_max,0.f), v_min, a);
				}
				else
				{
					// Positive: rescale to the positive range before powering
					float a;
					if (fabsf(linear_zero_pos - 1.0f) > 1.e-6)
						a = (normalized_pos - linear_zero_pos) / (1.0f - linear_zero_pos);
					else
						a = normalized_pos;
					a = powf(a, power);
					new_value = ImLerp(ImMax(v_min,0.0f), v_max, a);
				}

				// Round past decimal precision
				//  0: 1
				//  1: 0.1
				//  2: 0.01
				//  etc..
				// So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0
				const float min_step = 1.0f / powf(10.0f, (float)decimal_precision);
				const float remainder = fmodf(new_value, min_step);
				if (remainder <= min_step*0.5f)
					new_value -= remainder;
				else
					new_value += (min_step - remainder);

				if (*v != new_value)
				{
					*v = new_value;
					value_changed = true;
				}
			}
		}
		else
		{
			g.ActiveId = 0;
		}
	}

	if (!is_unbound)
	{
		// Linear slider
		// const float grab_t = (ImClamp(*v, v_min, v_max) - v_min) / (v_max - v_min);

		// Calculate slider grab positioning
		float grab_t;
		float v_clamped = ImClamp(*v, v_min, v_max);
		if (v_clamped < 0.0f)
		{
			float f = 1.0f - (v_clamped - v_min) / (ImMin(0.0f,v_max) - v_min);
			grab_t = (1.0f - powf(f, 1.0f/power)) * linear_zero_pos;
		}
		else
		{
			float f = (v_clamped - ImMax(0.0f,v_min)) / (v_max - ImMax(0.0f,v_min));
			grab_t = linear_zero_pos + powf(f, 1.0f/power) * (1.0f - linear_zero_pos);
		}

		// Draw
		const float grab_x = ImLerp(slider_effective_x1, slider_effective_x2, grab_t);
		const ImGuiAabb grab_bb(ImVec2(grab_x-grab_size_in_pixels*0.5f,frame_bb.Min.y+2.0f), ImVec2(grab_x+grab_size_in_pixels*0.5f,frame_bb.Max.y-1.0f));
		window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, window->Color(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab));
	}

	char value_buf[64];
	ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v);
	RenderText(ImVec2(slider_bb.GetCenter().x-CalcTextSize(value_buf).x*0.5f, frame_bb.Min.y + style.FramePadding.y), value_buf);

	RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, slider_bb.Min.y), label);

	return value_changed;
}

bool SliderAngle(const char* label, float* v, float v_degrees_min, float v_degrees_max)
{
	float v_deg = *v * 360.0f / (2*PI);
	bool changed = ImGui::SliderFloat(label, &v_deg, v_degrees_min, v_degrees_max, "%.0f deg", 1.0f);
	*v = v_deg * (2*PI) / 360.0f;
	return changed;
}

bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format)
{
	if (!display_format)
		display_format = "%.0f";
	float v_f = (float)*v;
	bool changed = ImGui::SliderFloat(label, &v_f, (float)v_min, (float)v_max, display_format, 1.0f);
	*v = (int)v_f;
	return changed;
}

static bool SliderFloatN(const char* label, float v[3], int components, float v_min, float v_max, const char* display_format, float power)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return false;

	const ImGuiStyle& style = g.Style;
	const float w_full = window->DC.ItemWidth.back();
	const float w_item_one  = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f+style.ItemInnerSpacing.x)*(components-1)) / (float)components));
	const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one+style.FramePadding.x*2.0f+style.ItemInnerSpacing.x)*(components-1)));

	bool value_changed = false;
	ImGui::PushID(label);
	ImGui::PushItemWidth(w_item_one);
	for (int i = 0; i < components; i++)
	{
		ImGui::PushID(i);
		if (i + 1 == components)
		{
			ImGui::PopItemWidth();
			ImGui::PushItemWidth(w_item_last);
		}
		value_changed |= ImGui::SliderFloat("##v", &v[i], v_min, v_max, display_format, power);
		ImGui::SameLine(0, 0);
		ImGui::PopID();
	}
	ImGui::PopItemWidth();
	ImGui::PopID();

	ImGui::TextUnformatted(label, FindTextDisplayEnd(label));

	return value_changed;
}

bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format, float power)
{
	return SliderFloatN(label, v, 2, v_min, v_max, display_format, power);
}

bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format, float power)
{
	return SliderFloatN(label, v, 3, v_min, v_max, display_format, power);
}

bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format, float power)
{
	return SliderFloatN(label, v, 4, v_min, v_max, display_format, power);
}

// Enum for ImGui::Plot()
enum ImGuiPlotType
{
	ImGuiPlotType_Lines,
	ImGuiPlotType_Histogram,
};

static float PlotGetValue(const float* values, size_t stride, int idx)
{
	float v = *(float*)((unsigned char*)values + idx * stride);
	return v;
}

static void Plot(ImGuiPlotType plot_type, const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, size_t stride)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return;

	const ImGuiStyle& style = g.Style;

	const ImVec2 text_size = CalcTextSize(label);
	if (graph_size.x == 0)
		graph_size.x = window->DC.ItemWidth.back();
	if (graph_size.y == 0)
		graph_size.y = text_size.y;

	const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(graph_size.x, graph_size.y) + style.FramePadding*2.0f);
	const ImGuiAabb graph_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding);
	const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(style.ItemInnerSpacing.x + text_size.x,0));
	ItemSize(bb);

	if (ClipAdvance(bb))
		return;

	// Determine scale if not specified
	if (scale_min == FLT_MAX || scale_max == FLT_MAX)
	{
		float v_min = FLT_MAX;
		float v_max = -FLT_MAX;
		for (int i = 0; i < values_count; i++)
		{
			const float v = PlotGetValue(values, stride, i);
			v_min = ImMin(v_min, v);
			v_max = ImMax(v_max, v);
		}
		if (scale_min == FLT_MAX)
			scale_min = v_min;
		if (scale_max == FLT_MAX)
			scale_max = v_max;
	}

	RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg));

	int res_w = ImMin((int)graph_size.x, values_count);
	if (plot_type == ImGuiPlotType_Lines)
		res_w -= 1;

	// Tooltip on hover
	int v_hovered = -1;
	if (IsMouseHoveringBox(graph_bb))
	{
		const float t = ImClamp((g.IO.MousePos.x - graph_bb.Min.x) / (graph_bb.Max.x - graph_bb.Min.x), 0.0f, 0.9999f);
		const int v_idx = (int)(t * (values_count + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0)));
		IM_ASSERT(v_idx >= 0 && v_idx < values_count);
		
		const float v0 = PlotGetValue(values, stride, (v_idx + values_offset) % values_count);
		const float v1 = PlotGetValue(values, stride, (v_idx + 1 + values_offset) % values_count);
		if (plot_type == ImGuiPlotType_Lines)
			ImGui::SetTooltip("%d: %8.4g\n%d: %8.4g", v_idx, v0, v_idx+1, v1);
		else if (plot_type == ImGuiPlotType_Histogram)
			ImGui::SetTooltip("%d: %8.4g", v_idx, v0);
		v_hovered = v_idx;
	}

	const float t_step = 1.0f / (float)res_w;

	float v0 = PlotGetValue(values, stride, (0 + values_offset) % values_count);
	float t0 = 0.0f;
	ImVec2 p0 = ImVec2( t0, 1.0f - ImSaturate((v0 - scale_min) / (scale_max - scale_min)) );

	const ImU32 col_base = window->Color((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLines : ImGuiCol_PlotHistogram);
	const ImU32 col_hovered = window->Color((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLinesHovered : ImGuiCol_PlotHistogramHovered);

	for (int n = 0; n < res_w; n++)
	{
		const float t1 = t0 + t_step;
		const int v_idx = (int)(t0 * values_count);
		IM_ASSERT(v_idx >= 0 && v_idx < values_count);
		const float v1 = PlotGetValue(values, stride, (v_idx + values_offset + 1) % values_count);
		const ImVec2 p1 = ImVec2( t1, 1.0f - ImSaturate((v1 - scale_min) / (scale_max - scale_min)) );

		// NB: draw calls are merged into ones
		if (plot_type == ImGuiPlotType_Lines)
			window->DrawList->AddLine(ImLerp(graph_bb.Min, graph_bb.Max, p0), ImLerp(graph_bb.Min, graph_bb.Max, p1), v_hovered == v_idx ? col_hovered : col_base);
		else if (plot_type == ImGuiPlotType_Histogram)
			window->DrawList->AddRectFilled(ImLerp(graph_bb.Min, graph_bb.Max, p0), ImLerp(graph_bb.Min, graph_bb.Max, ImVec2(p1.x, 1.0f))+ImVec2(-1,0), v_hovered == v_idx ? col_hovered : col_base);

		v0 = v1;
		t0 = t1;
		p0 = p1;
	}

	// Overlay last value
	if (overlay_text)
		RenderText(ImVec2(graph_bb.GetCenter().x-CalcTextSize(overlay_text).x*0.5f, frame_bb.Min.y + style.FramePadding.y), overlay_text);

	RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, graph_bb.Min.y), label);
}

void PlotLines(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, size_t stride)
{
	ImGui::Plot(ImGuiPlotType_Lines, label, values, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size, stride);
}

void PlotHistogram(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, size_t stride)
{
	ImGui::Plot(ImGuiPlotType_Histogram, label, values, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size, stride);
}

void Checkbox(const char* label, bool* v)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return;

	const ImGuiStyle& style = g.Style;
	const ImGuiID id = window->GetID(label);

	const ImVec2 text_size = CalcTextSize(label);

	const ImGuiAabb check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(text_size.y + style.FramePadding.y*2, text_size.y + style.FramePadding.y*2));
	ItemSize(check_bb);
	SameLine(0, (int)g.Style.ItemInnerSpacing.x);

	const ImGuiAabb text_bb(window->DC.CursorPos + ImVec2(0,style.FramePadding.y), window->DC.CursorPos + ImVec2(0,style.FramePadding.y) + text_size);
	ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()));
	const ImGuiAabb total_bb(ImMin(check_bb.Min, text_bb.Min), ImMax(check_bb.Max, text_bb.Max));

	if (ClipAdvance(total_bb))
		return;

	const bool hovered = (g.HoveredWindow == window) && (g.HoveredId == 0) && IsMouseHoveringBox(total_bb);
	const bool pressed = hovered && g.IO.MouseClicked[0];
	if (hovered)
		g.HoveredId = id;
	if (pressed)
	{
		*v = !(*v);
		g.ActiveId = 0;	// Clear focus
	}

	RenderFrame(check_bb.Min, check_bb.Max, window->Color(hovered ? ImGuiCol_CheckHovered : ImGuiCol_FrameBg));
	if (*v)
	{
		window->DrawList->AddRectFilled(check_bb.Min+ImVec2(4,4), check_bb.Max-ImVec2(4,4), window->Color(ImGuiCol_CheckActive));
	}

	if (g.LogEnabled)
		LogText(text_bb.GetTL(), *v ? "[x]" : "[ ]");
	RenderText(text_bb.GetTL(), label);
}

void CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value)
{
	bool v = (*flags & flags_value) ? true : false;
	ImGui::Checkbox(label, &v);
	if (v)
		*flags |= flags_value;
	else
		*flags &= ~flags_value;
}

bool RadioButton(const char* label, bool active)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return false;

	const ImGuiStyle& style = g.Style;
	const ImGuiID id = window->GetID(label);

	const ImVec2 text_size = CalcTextSize(label);

	const ImGuiAabb check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(text_size.y + style.FramePadding.y*2-1, text_size.y + style.FramePadding.y*2-1));
	ItemSize(check_bb);
	SameLine(0, (int)style.ItemInnerSpacing.x);

	const ImGuiAabb text_bb(window->DC.CursorPos + ImVec2(0, style.FramePadding.y), window->DC.CursorPos + ImVec2(0, style.FramePadding.y) + text_size);
	ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()));
	const ImGuiAabb total_bb(ImMin(check_bb.Min, text_bb.Min), ImMax(check_bb.Max, text_bb.Max));

	if (ClipAdvance(total_bb))
		return false;

	ImVec2 center = check_bb.GetCenter();
	center.x = (float)(int)center.x + 0.5f;
	center.y = (float)(int)center.y + 0.5f;
	const float radius = check_bb.GetHeight() * 0.5f;

	const bool hovered = (g.HoveredWindow == window) && (g.HoveredId == 0) && IsMouseHoveringBox(total_bb);
	const bool pressed = hovered && g.IO.MouseClicked[0];
	if (hovered)
		g.HoveredId = id;

	window->DrawList->AddCircleFilled(center, radius, window->Color(hovered ? ImGuiCol_CheckHovered : ImGuiCol_FrameBg), 16);
	if (active)
		window->DrawList->AddCircleFilled(center, radius-2, window->Color(ImGuiCol_CheckActive), 16);

	if (window->Flags & ImGuiWindowFlags_ShowBorders)
	{
		window->DrawList->AddCircle(center+ImVec2(1,1), radius, window->Color(ImGuiCol_BorderShadow), 16);
		window->DrawList->AddCircle(center, radius, window->Color(ImGuiCol_Border), 16);
	}

	RenderText(text_bb.GetTL(), label);

	return pressed;
}

bool RadioButton(const char* label, int* v, int v_button)
{
	const bool pressed = ImGui::RadioButton(label, *v == v_button);
	if (pressed)
	{
		*v = v_button;
	}
	return pressed;
}

}; // namespace ImGui

// Wrapper for stb_textedit.h to edit text (our wrapper is for: statically sized buffer, single-line, ASCII, fixed-width font)
int		STB_TEXTEDIT_STRINGLEN(const STB_TEXTEDIT_STRING* obj)									{ return (int)strlen(obj->Text); }
char	STB_TEXTEDIT_GETCHAR(const STB_TEXTEDIT_STRING* obj, int idx)							{ return (char)obj->Text[idx]; }
float	STB_TEXTEDIT_GETWIDTH(STB_TEXTEDIT_STRING* obj, int line_start_idx, int char_idx)		{ (void)line_start_idx; return obj->Font->CalcTextSize(obj->FontSize, 0, &obj->Text[char_idx], &obj->Text[char_idx]+1, NULL).x; }
char	STB_TEXTEDIT_KEYTOTEXT(int key)															{ return key >= 0x10000 ? 0 : (char)key; }
char	STB_TEXTEDIT_NEWLINE = '\n';
void	STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* obj, int line_start_idx)
{
	const char* text_remaining = NULL;
	const ImVec2 size = obj->Font->CalcTextSize(obj->FontSize, FLT_MAX, obj->Text + line_start_idx, NULL, &text_remaining);
	r->x0 = 0.0f;
	r->x1 = size.x;
	r->baseline_y_delta = size.y;
	r->ymin = 0.0f;
	r->ymax = size.y;
	r->num_chars = (int)(text_remaining - (obj->Text + line_start_idx));
}

static bool is_white(char c)		{ return c==0 || c==' ' || c=='\t' || c=='\r' || c=='\n'; }
static bool is_separator(char c)	{ return c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; }

#define	STB_TEXTEDIT_IS_SPACE(c)																(is_white(c) || is_separator(c))
void	STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int idx, int n)						{ char* dst = obj->Text+idx; const char* src = obj->Text+idx+n; while (char c = *src++) *dst++ = c; *dst = '\0'; }

bool	STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int idx, const char* new_text, int new_text_len)
{
	char* buf_end = obj->Text + obj->BufSize;
	const int text_len = (int)strlen(obj->Text);

	if (new_text_len > buf_end - (obj->Text + text_len + 1))
		return false;

	memmove(obj->Text + idx + new_text_len, obj->Text + idx, text_len - idx);
	memcpy(obj->Text + idx, new_text, new_text_len);
	obj->Text[text_len + new_text_len] = 0;

	return true;
}

enum
{
	STB_TEXTEDIT_K_LEFT = 1 << 16,	// keyboard input to move cursor left
	STB_TEXTEDIT_K_RIGHT,			// keyboard input to move cursor right
	STB_TEXTEDIT_K_UP,				// keyboard input to move cursor up
	STB_TEXTEDIT_K_DOWN,			// keyboard input to move cursor down
	STB_TEXTEDIT_K_LINESTART,		// keyboard input to move cursor to start of line
	STB_TEXTEDIT_K_LINEEND,			// keyboard input to move cursor to end of line
	STB_TEXTEDIT_K_TEXTSTART,		// keyboard input to move cursor to start of text
	STB_TEXTEDIT_K_TEXTEND,			// keyboard input to move cursor to end of text
	STB_TEXTEDIT_K_DELETE,			// keyboard input to delete selection or character under cursor
	STB_TEXTEDIT_K_BACKSPACE,		// keyboard input to delete selection or character left of cursor
	STB_TEXTEDIT_K_UNDO,			// keyboard input to perform undo
	STB_TEXTEDIT_K_REDO,			// keyboard input to perform redo
	STB_TEXTEDIT_K_WORDLEFT,		// keyboard input to move cursor left one word
	STB_TEXTEDIT_K_WORDRIGHT,		// keyboard input to move cursor right one word
	STB_TEXTEDIT_K_SHIFT = 1 << 17,
};

#define STB_TEXTEDIT_IMPLEMENTATION
#include "stb_textedit.h"

void ImGuiTextEditState::OnKeyboardPressed(int key)
{ 
	stb_textedit_key(this, &StbState, key); 
	CursorAnimReset(); 
}

void ImGuiTextEditState::UpdateScrollOffset()
{
	// Scroll in chunks of quarter width
	const float scroll_x_increment = Width * 0.25f;
	const float cursor_offset_x = Font->CalcTextSize(FontSize, 0, Text, Text+StbState.cursor, NULL).x;
	if (ScrollX > cursor_offset_x)
		ScrollX = ImMax(0.0f, cursor_offset_x - scroll_x_increment);	
	else if (ScrollX < cursor_offset_x - Width)
		ScrollX = cursor_offset_x - Width + scroll_x_increment;
}

ImVec2 ImGuiTextEditState::CalcDisplayOffsetFromCharIdx(int i) const
{
	const char* text_start = GetTextPointerClipped(Font, FontSize, Text, ScrollX, NULL);
	const char* text_end = (Text+i >= text_start) ? Text+i : text_start;					// Clip if requested character is outside of display
	IM_ASSERT(text_end >= text_start);

	const ImVec2 offset = Font->CalcTextSize(FontSize, Width, text_start, text_end, NULL);
	return offset;
}

// [Static]
const char*	ImGuiTextEditState::GetTextPointerClipped(ImFont font, float font_size, const char* text, float width, ImVec2* out_text_size)
{
	if (width <= 0.0f)
		return text;

	const char* text_clipped_end = NULL;
	const ImVec2 text_size = font->CalcTextSize(font_size, width, text, NULL, &text_clipped_end);
	if (out_text_size)
		*out_text_size = text_size;
	return text_clipped_end;
}

// [Static]
void ImGuiTextEditState::RenderTextScrolledClipped(ImFont font, float font_size, const char* buf, ImVec2 pos, float width, float scroll_x)
{
	// NB- We start drawing at character boundary
	ImVec2 text_size;
	const char* text_start = GetTextPointerClipped(font, font_size, buf, scroll_x, NULL);
	const char* text_end = GetTextPointerClipped(font, font_size, text_start, width, &text_size);

	// Draw a little clip symbol if we've got text on either left or right of the box
	const char symbol_c = '~';
	const float symbol_w = font_size*0.40f;		// FIXME: compute correct width
	const float clip_begin = (text_start > buf && text_start < text_end) ? symbol_w : 0.0f;
	const float clip_end = (text_end[0] != '\0' && text_end > text_start) ? symbol_w : 0.0f;

	// Draw text
	ImGui::RenderText(pos+ImVec2(clip_begin,0), text_start+(clip_begin>0.0f?1:0), text_end-(clip_end>0.0f?1:0), false);//, &text_params_with_clipping);

	// Draw the clip symbol
	const char s[2] = {symbol_c,'\0'};
	if (clip_begin > 0.0f)
		ImGui::RenderText(pos, s);
	if (clip_end > 0.0f)
		ImGui::RenderText(pos+ImVec2(width-clip_end,0.0f), s);
}

namespace ImGui
{

bool InputFloat(const char* label, float *v, float step, float step_fast, int decimal_precision)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return false;

	const ImGuiStyle& style = g.Style;
	const float w = window->DC.ItemWidth.back();
	const ImVec2 text_size = CalcTextSize(label);
	const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, text_size.y) + style.FramePadding*2.0f);

	ImGui::PushID(label);
	const float button_sz = window->FontSize();
	if (step > 0.0f)
		ImGui::PushItemWidth(ImMax(1.0f, window->DC.ItemWidth.back() - (button_sz+g.Style.FramePadding.x*2.0f+g.Style.ItemInnerSpacing.x)*2));

	char buf[64];
	if (decimal_precision < 0)
		ImFormatString(buf, IM_ARRAYSIZE(buf), "%f", *v);		// Ideally we'd have a minimum decimal precision of 1 to visually denote that it is a float, while hiding non-significant digits?
	else
		ImFormatString(buf, IM_ARRAYSIZE(buf), "%.*f", decimal_precision, *v);
	bool value_changed = false;
	if (ImGui::InputText("", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsDecimal|ImGuiInputTextFlags_AlignCenter|ImGuiInputTextFlags_AutoSelectAll))
	{
		ApplyNumericalTextInput(buf, v);
		value_changed = true;
	}

	if (step > 0.0f)
	{
		ImGui::PopItemWidth();
		ImGui::SameLine(0, 0);
		if (ImGui::Button("-", ImVec2(button_sz,button_sz), true))
		{
			*v -= g.IO.KeyCtrl && step_fast > 0.0f ? step_fast : step;
			value_changed = true;
		}
		ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x);
		if (ImGui::Button("+", ImVec2(button_sz,button_sz), true))
		{
			*v += g.IO.KeyCtrl && step_fast > 0.0f ? step_fast : step;
			value_changed = true;
		}
	}

	ImGui::PopID();

	RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + g.Style.FramePadding.y), label);

	//ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x);
	//ImGui::TextUnformatted(label, FindTextDisplayEnd(label));

	return value_changed;
}

bool InputInt(const char* label, int *v, int step, int step_fast)
{
	float f = (float)*v;
	const bool value_changed = ImGui::InputFloat(label, &f, (float)step, (float)step_fast, 0);
	*v = (int)f;
	return value_changed;
}

bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return false;

	const ImGuiIO& io = g.IO;
	const ImGuiStyle& style = g.Style;

	const ImGuiID id = window->GetID(label);
	const float w = window->DC.ItemWidth.back();

	const ImVec2 text_size = CalcTextSize(label);
	const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, text_size.y) + style.FramePadding*2.0f);
	const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(style.ItemInnerSpacing.x + text_size.x, 0.0f));
	ItemSize(bb);

	if (ClipAdvance(frame_bb))
		return false;

	// NB: we can only read/write if we are the active widget!
	ImGuiTextEditState& edit_state = g.InputTextState;

	const bool is_ctrl_down = io.KeyCtrl;
	const bool is_shift_down = io.KeyShift;
	const bool tab_focus_requested = window->FocusItemRegister(g.ActiveId == id);
	//const bool align_center = (bool)(flags & ImGuiInputTextFlags_AlignCenter);	// FIXME: Unsupported

	const bool hovered = (g.HoveredWindow == window) && (g.HoveredId == 0) && IsMouseHoveringBox(frame_bb);
	if (hovered)
		g.HoveredId = id;

	bool select_all = (g.ActiveId != id) && (flags & ImGuiInputTextFlags_AutoSelectAll) != 0;
	if (tab_focus_requested || (hovered && io.MouseClicked[0]))
	{
		if (g.ActiveId != id)
		{
			// Start edition
			strcpy(edit_state.Text, buf);
			strcpy(edit_state.InitialText, buf);
			edit_state.ScrollX = 0.0f;
			edit_state.Width = w;
			stb_textedit_initialize_state(&edit_state.StbState, true); 
			edit_state.CursorAnimReset();

			if (tab_focus_requested || is_ctrl_down)
				select_all = true;
		}
		g.ActiveId = id;
	}
	else if (io.MouseClicked[0])
	{
		// Release focus when we click outside
		if (g.ActiveId == id)
		{
			g.ActiveId = 0;
		}
	}

	bool value_changed = false;
	bool cancel_edit = false;
	if (g.ActiveId == id)
	{
		edit_state.BufSize = buf_size < IM_ARRAYSIZE(edit_state.Text) ? buf_size : IM_ARRAYSIZE(edit_state.Text);
		edit_state.Font = window->Font();
		edit_state.FontSize = window->FontSize();
	
		const float mx = g.IO.MousePos.x - frame_bb.Min.x - style.FramePadding.x;
		const float my = window->FontSize()*0.5f;	// Better for single line

		edit_state.UpdateScrollOffset();
		if (select_all || (hovered && io.MouseDoubleClicked[0]))
		{
			edit_state.SelectAll();
			edit_state.SelectedAllMouseLock = true;
		}
		else if (io.MouseClicked[0] && !edit_state.SelectedAllMouseLock)
		{
			stb_textedit_click(&edit_state, &edit_state.StbState, mx + edit_state.ScrollX, my);
			edit_state.CursorAnimReset();

		}
		else if (io.MouseDown[0] && !edit_state.SelectedAllMouseLock)
		{
			stb_textedit_drag(&edit_state, &edit_state.StbState, mx + edit_state.ScrollX, my);
			edit_state.CursorAnimReset();
		}
		if (edit_state.SelectedAllMouseLock && !io.MouseDown[0])
			 edit_state.SelectedAllMouseLock = false;

		const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0);
			 if (IsKeyPressedMap(ImGuiKey_LeftArrow))			edit_state.OnKeyboardPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask);
		else if (IsKeyPressedMap(ImGuiKey_RightArrow))			edit_state.OnKeyboardPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask  : STB_TEXTEDIT_K_RIGHT | k_mask);
		else if (IsKeyPressedMap(ImGuiKey_UpArrow))				edit_state.OnKeyboardPressed(STB_TEXTEDIT_K_UP | k_mask);
		else if (IsKeyPressedMap(ImGuiKey_DownArrow))			edit_state.OnKeyboardPressed(STB_TEXTEDIT_K_DOWN | k_mask);
		else if (IsKeyPressedMap(ImGuiKey_Home))				edit_state.OnKeyboardPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask);
		else if (IsKeyPressedMap(ImGuiKey_End))					edit_state.OnKeyboardPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask);
		else if (IsKeyPressedMap(ImGuiKey_Delete))				edit_state.OnKeyboardPressed(STB_TEXTEDIT_K_DELETE | k_mask);
		else if (IsKeyPressedMap(ImGuiKey_Backspace))			edit_state.OnKeyboardPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask);
		else if (IsKeyPressedMap(ImGuiKey_Enter))				{ g.ActiveId = 0; }
		else if (IsKeyPressedMap(ImGuiKey_Escape))				{ g.ActiveId = 0; cancel_edit = true; }
		else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Z))	edit_state.OnKeyboardPressed(STB_TEXTEDIT_K_UNDO);		// I don't want to use shortcuts but we should probably have an Input-catch stack
		else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_Y))	edit_state.OnKeyboardPressed(STB_TEXTEDIT_K_REDO);
		else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_A))	edit_state.SelectAll();
		else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_X))
		{
			if (!edit_state.HasSelection())
				edit_state.SelectAll();

			const int ib = ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end);
			const int ie = ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end);
			if (g.IO.SetClipboardTextFn)
				g.IO.SetClipboardTextFn(edit_state.Text+ib, edit_state.Text+ie);
			stb_textedit_cut(&edit_state, &edit_state.StbState);
		}
		else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_C))	
		{
			const int ib = edit_state.HasSelection() ? ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end) : 0;
			const int ie = edit_state.HasSelection() ? ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end) : (int)strlen(edit_state.Text);
			if (g.IO.SetClipboardTextFn)
				g.IO.SetClipboardTextFn(edit_state.Text+ib, edit_state.Text+ie);
		}
		else if (is_ctrl_down && IsKeyPressedMap(ImGuiKey_V))
		{
			if (g.IO.GetClipboardTextFn)
				if (const char* clipboard = g.IO.GetClipboardTextFn())
				{
					// Remove new-line from pasted buffer
					size_t clipboard_len = strlen(clipboard);
					char* clipboard_filtered = (char*)malloc(clipboard_len+1);
					int clipboard_filtered_len = 0;
					for (int i = 0; clipboard[i]; i++)
					{
						const char c = clipboard[i];
						if (c == '\n' || c == '\r')
							continue;
						clipboard_filtered[clipboard_filtered_len++] = clipboard[i];
					}
					clipboard_filtered[clipboard_filtered_len] = 0;
					stb_textedit_paste(&edit_state, &edit_state.StbState, clipboard_filtered, clipboard_filtered_len);
					free(clipboard_filtered);
				}
		}
		else if (g.IO.InputCharacters[0])
		{
			// Text input
			for (int n = 0; n < IM_ARRAYSIZE(g.IO.InputCharacters) && g.IO.InputCharacters[n]; n++)
			{
				const char c = g.IO.InputCharacters[n];
				if (c)
				{
					// Filter
					if (!isprint(c) && c != ' ')
						continue;
					if (flags & ImGuiInputTextFlags_CharsDecimal)
						if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/'))
							continue;
					if (flags & ImGuiInputTextFlags_CharsHexadecimal)
						if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F'))
							continue;

					// Insert character!
					edit_state.OnKeyboardPressed(c);
				}
			}
		}

		edit_state.CursorAnim += g.IO.DeltaTime;
		edit_state.UpdateScrollOffset();

		if (cancel_edit)
		{
			// Restore initial value
			ImFormatString(buf, buf_size, "%s", edit_state.InitialText);
			value_changed = true;
		}
		else
		{
			// Apply new value immediately - copy modified buffer back
			if (strcmp(edit_state.Text, buf) != 0)
			{
				ImFormatString(buf, buf_size, "%s", edit_state.Text);
				value_changed = true;
			}
		}
	}
	
	RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true);//, style.Rounding);

	const ImVec2 font_off_up = ImVec2(0.0f,window->FontSize()+1.0f);	// FIXME: this should be part of the font API
	const ImVec2 font_off_dn = ImVec2(0.0f,2.0f);

	if (g.ActiveId == id)
	{
		// Draw selection
		const int select_begin_idx = edit_state.StbState.select_start;
		const int select_end_idx = edit_state.StbState.select_end;
		if (select_begin_idx != select_end_idx)
		{
			const ImVec2 select_begin_pos = frame_bb.Min + style.FramePadding + edit_state.CalcDisplayOffsetFromCharIdx(ImMin(select_begin_idx,select_end_idx));
			const ImVec2 select_end_pos = frame_bb.Min + style.FramePadding + edit_state.CalcDisplayOffsetFromCharIdx(ImMax(select_begin_idx,select_end_idx));
			window->DrawList->AddRectFilled(select_begin_pos - font_off_up, select_end_pos + font_off_dn, window->Color(ImGuiCol_TextSelectedBg));
		}
	}

	// FIXME: 'align_center' unsupported
	ImGuiTextEditState::RenderTextScrolledClipped(window->Font(), window->FontSize(), buf, frame_bb.Min + style.FramePadding, w, (g.ActiveId == id) ? edit_state.ScrollX : 0.0f);

	if (g.ActiveId == id)
	{
		// Draw blinking cursor
		if (g.InputTextState.CursorIsVisible())
		{
			const ImVec2 cursor_pos = frame_bb.Min + style.FramePadding + edit_state.CalcDisplayOffsetFromCharIdx(edit_state.StbState.cursor);
			window->DrawList->AddRect(cursor_pos - font_off_up + ImVec2(0,2), cursor_pos + font_off_dn - ImVec2(0,3), window->Color(ImGuiCol_Text));
		}
	}

	RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);

	return value_changed;
}

static bool InputFloatN(const char* label, float* v, int components, int decimal_precision)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return false;

	const ImGuiStyle& style = g.Style;
	const float w_full = window->DC.ItemWidth.back();
	const float w_item_one  = ImMax(1.0f, (float)(int)((w_full - (style.FramePadding.x*2.0f+style.ItemInnerSpacing.x) * (components-1)) / (float)components));
	const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one+style.FramePadding.x*2.0f+style.ItemInnerSpacing.x) * (components-1)));

	bool value_changed = false;
	ImGui::PushID(label);
	ImGui::PushItemWidth(w_item_one);
	for (int i = 0; i < components; i++)
	{
		ImGui::PushID(i);
		if (i + 1 == components)
		{
			ImGui::PopItemWidth();
			ImGui::PushItemWidth(w_item_last);
		}
		value_changed |= ImGui::InputFloat("##v", &v[i], 0, 0, decimal_precision);
		ImGui::SameLine(0, 0);
		ImGui::PopID();
	}
	ImGui::PopItemWidth();
	ImGui::PopID();

	ImGui::TextUnformatted(label, FindTextDisplayEnd(label));

	return value_changed;
}

bool InputFloat2(const char* label, float v[2], int decimal_precision)
{
	return InputFloatN(label, v, 2, decimal_precision);
}

bool InputFloat3(const char* label, float v[3], int decimal_precision)
{
	return InputFloatN(label, v, 3, decimal_precision);
}

bool InputFloat4(const char* label, float v[4], int decimal_precision)
{
	return InputFloatN(label, v, 4, decimal_precision);
}

static bool Combo_ArrayGetter(void* data, int idx, const char** out_text)
{
	const char** items = (const char**)data;
	if (out_text)
		*out_text = items[idx];
	return true;
}

bool Combo(const char* label, int* current_item, const char** items, int items_count, int popup_height_items)
{
	bool value_changed = Combo(label, current_item, Combo_ArrayGetter, (void*)items, items_count, popup_height_items);
	return value_changed;
}

static bool Combo_StringListGetter(void* data, int idx, const char** out_text)
{
	// FIXME-OPT: we could precompute the indices but let's not bother now.
	const char* items_separated_by_zeros = (const char*)data;
	int items_count = 0;
	const char* p = items_separated_by_zeros;
	while (*p)
	{
		if (idx == items_count)
			break;
		p += strlen(p) + 1;
		items_count++;
	}
	if (!*p)
		return false;
	if (out_text)
		*out_text = p;
	return true;
}

bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_height_items)
{
	int items_count = 0;
	const char* p = items_separated_by_zeros;
	while (*p)
	{
		p += strlen(p) + 1;
		items_count++;
	}
	bool value_changed = Combo(label, current_item, Combo_StringListGetter, (void*)items_separated_by_zeros, items_count, popup_height_items);
	return value_changed;
}

bool Combo(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int popup_height_items)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return false;

	const ImGuiStyle& style = g.Style;
	const ImGuiID id = window->GetID(label);

	const ImVec2 text_size = CalcTextSize(label);
	const float arrow_size = (window->FontSize() + style.FramePadding.x * 2.0f);
	const ImGuiAabb frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(window->DC.ItemWidth.back(), text_size.y) + style.FramePadding*2.0f);
	const ImGuiAabb bb(frame_bb.Min, frame_bb.Max + ImVec2(style.ItemInnerSpacing.x + text_size.x,0));

	if (ClipAdvance(frame_bb))
		return false;

	const bool hovered = (g.HoveredWindow == window) && (g.HoveredId == 0) && IsMouseHoveringBox(bb);

	bool value_changed = false;
	ItemSize(frame_bb);
	RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg));
	RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, window->Color(hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button));
	RenderCollapseTriangle(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y) + style.FramePadding, true);

	if (*current_item >= 0 && *current_item < items_count)
	{
		const char* item_text;
		if (items_getter(data, *current_item, &item_text))
			RenderText(frame_bb.Min + style.FramePadding, item_text, NULL, false);
	}

	ImGui::SameLine(0, (int)g.Style.ItemInnerSpacing.x);
	ImGui::TextUnformatted(label, FindTextDisplayEnd(label));

	ImGui::PushID(id);
	bool menu_toggled = false;
	if (hovered)
	{
		g.HoveredId = id;
		if (g.IO.MouseClicked[0])
		{
			menu_toggled = true;
			g.ActiveComboID = (g.ActiveComboID == id) ? 0 : id;
		}
	}
	
	if (g.ActiveComboID == id)
	{
		const ImVec2 backup_pos = ImGui::GetCursorPos();
		const float popup_off_x = 0.0f;//g.Style.ItemInnerSpacing.x;
		const float popup_height = (text_size.y + g.Style.ItemSpacing.y) * ImMin(items_count, popup_height_items) + g.Style.WindowPadding.y;
		const ImGuiAabb popup_aabb(ImVec2(frame_bb.Min.x+popup_off_x, frame_bb.Max.y), ImVec2(frame_bb.Max.x+popup_off_x, frame_bb.Max.y + popup_height));
		ImGui::SetCursorPos(popup_aabb.Min - window->Pos);

		ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0);
		ImGui::BeginChild("#ComboBox", popup_aabb.GetSize(), false, flags);
		ImGuiWindow* child_window = GetCurrentWindow();
		ImGui::Spacing();

		bool combo_item_active = false;
		combo_item_active |= (g.ActiveId == child_window->GetID("#SCROLLY"));

		for (int item_idx = 0; item_idx < items_count; item_idx++)
		{
			const float item_h = child_window->FontSize();
			const float spacing_up = (float)(int)(g.Style.ItemSpacing.y/2);
			const float spacing_dn = g.Style.ItemSpacing.y - spacing_up;
			const ImGuiAabb item_aabb(ImVec2(popup_aabb.Min.x, child_window->DC.CursorPos.y - spacing_up), ImVec2(popup_aabb.Max.x, child_window->DC.CursorPos.y + item_h + spacing_dn));
			const ImGuiID item_id = child_window->GetID((void*)(intptr_t)item_idx);

			bool item_hovered, item_held;
			bool item_pressed = ButtonBehaviour(item_aabb, item_id, &item_hovered, &item_held, true);
			bool item_selected = item_idx == *current_item;

			if (item_hovered || item_selected)
			{
				const ImU32 col = window->Color((item_held && item_hovered) ? ImGuiCol_HeaderActive : item_hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
				RenderFrame(item_aabb.Min, item_aabb.Max, col, false);
			}

			const char* item_text;
			if (!items_getter(data, item_idx, &item_text))
				item_text = "*Unknown item*";
			ImGui::Text("%s", item_text);
			
			if (item_selected)
			{
				if (menu_toggled)
					ImGui::SetScrollPosHere();
			}
			if (item_pressed)
			{
				g.ActiveId = 0;
				g.ActiveComboID = 0;
				value_changed = true;
				*current_item = item_idx;
			}

			combo_item_active |= (g.ActiveId == item_id);
		}
		ImGui::EndChild();
		ImGui::SetCursorPos(backup_pos);
		
		if (!combo_item_active && g.ActiveId != 0)
			g.ActiveComboID = 0;
	}

	ImGui::PopID();

	return value_changed;
}

// A little colored square. Return true when clicked.
bool ColorButton(const ImVec4& col, bool small_height, bool outline_border)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return false;

	const ImGuiStyle& style = g.Style;
	const float square_size = window->FontSize();
	const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(square_size + style.FramePadding.x*2, square_size + (small_height ? 0 : style.FramePadding.y*2)));
	ItemSize(bb);

	if (ClipAdvance(bb))
		return false;

	const bool hovered = (g.HoveredWindow == window) && (g.HoveredId == 0) && IsMouseHoveringBox(bb);
	const bool pressed = hovered && g.IO.MouseClicked[0];
	RenderFrame(bb.Min, bb.Max, window->Color(col), outline_border);

	if (hovered)
	{
		int ix = (int)(col.x * 255.0f + 0.5f);
		int iy = (int)(col.y * 255.0f + 0.5f);
		int iz = (int)(col.z * 255.0f + 0.5f);
		int iw = (int)(col.w * 255.0f + 0.5f);
		ImGui::SetTooltip("Color:\n(%.2f,%.2f,%.2f,%.2f)\n#%02X%02X%02X%02X", col.x, col.y, col.z, col.w, ix, iy, iz, iw);
	}

	return pressed;
}

bool ColorEdit3(const char* label, float col[3])
{
	float col4[4];
	col4[0] = col[0];
	col4[1] = col[1];
	col4[2] = col[2];
	col4[3] = 1.0f;
	bool value_changed = ImGui::ColorEdit4(label, col4, false);
	col[0] = col4[0];
	col[1] = col4[1];
	col[2] = col4[2];
	return value_changed;
}

// Edit colours components color in 0..1 range
// Use CTRL-Click to input value and TAB to go to next item.
bool ColorEdit4(const char* label, float col[4], bool alpha)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return false;

	const ImGuiStyle& style = g.Style;
	const ImGuiID id = window->GetID(label);
	const float w_full = window->DC.ItemWidth.back();
	const float square_sz = (window->FontSize() + style.FramePadding.x * 2.0f);

	ImGuiColorEditMode edit_mode = window->DC.ColorEditMode;
	if (edit_mode == ImGuiColorEditMode_UserSelect)
		edit_mode = g.ColorEditModeStorage.GetInt(id, 0) % 3;

	float fx = col[0];
	float fy = col[1];
	float fz = col[2];
	float fw = col[3];
	const ImVec4 col_display(fx, fy, fz, 1.0f);

	if (edit_mode == ImGuiColorEditMode_HSV)
		ImConvertColorRGBtoHSV(fx, fy, fz, fx, fy, fz);

	int ix = (int)(fx * 255.0f + 0.5f);
	int iy = (int)(fy * 255.0f + 0.5f);
	int iz = (int)(fz * 255.0f + 0.5f);
	int iw = (int)(fw * 255.0f + 0.5f);

	int components = alpha ? 4 : 3;
	bool value_changed = false;

	ImGui::PushID(label);

	bool hsv = (edit_mode == 1);
	switch (edit_mode)
	{
	case ImGuiColorEditMode_RGB:
	case ImGuiColorEditMode_HSV:
		{
			// 0: RGB 0..255
			// 1: HSV 0.255 Sliders
			const float w_items_all = w_full - (square_sz + style.ItemInnerSpacing.x);
			const float w_item_one  = ImMax(1.0f, (float)(int)((w_items_all - (style.FramePadding.x*2.0f+style.ItemInnerSpacing.x) * (components-1)) / (float)components));
			const float w_item_last = ImMax(1.0f, (float)(int)(w_items_all - (w_item_one+style.FramePadding.x*2.0f+style.ItemInnerSpacing.x) * (components-1)));

			ImGui::PushItemWidth(w_item_one);
			value_changed |= ImGui::SliderInt("##X", &ix, 0, 255, hsv ? "H:%3.0f" : "R:%3.0f");
			ImGui::SameLine(0, 0);
			value_changed |= ImGui::SliderInt("##Y", &iy, 0, 255, hsv ? "S:%3.0f" : "G:%3.0f");
			ImGui::SameLine(0, 0);
			if (alpha)
			{
				value_changed |= ImGui::SliderInt("##Z", &iz, 0, 255, hsv ? "V:%3.0f" : "B:%3.0f");
				ImGui::SameLine(0, 0);
				ImGui::PushItemWidth(w_item_last);
				value_changed |= ImGui::SliderInt("##W", &iw, 0, 255, "A:%3.0f");
			}
			else
			{
				ImGui::PushItemWidth(w_item_last);
				value_changed |= ImGui::SliderInt("##Z", &iz, 0, 255, hsv ? "V:%3.0f" : "B:%3.0f");
			}
			ImGui::PopItemWidth();
			ImGui::PopItemWidth();
		}
		break;
	case ImGuiColorEditMode_HEX:
		{
			// 2: RGB Hexadecimal
			const float w_slider_all = w_full - square_sz;
			char buf[64];
			if (alpha)
				sprintf(buf, "#%02X%02X%02X%02X", ix, iy, iz, iw);
			else
				sprintf(buf, "#%02X%02X%02X", ix, iy, iz);
			ImGui::PushItemWidth(w_slider_all - g.Style.ItemInnerSpacing.x);
			value_changed |= ImGui::InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal);
			ImGui::PopItemWidth();
			char* p = buf;
			while (*p == '#' || *p == ' ' || *p == '\t') 
				p++;
			ix = iy = iz = iw = 0;
			if (alpha)
				sscanf(p, "%02X%02X%02X%02X", &ix, &iy, &iz, &iw);
			else
				sscanf(p, "%02X%02X%02X", &ix, &iy, &iz);
		}
		break;
	}

	ImGui::SameLine(0, 0);
	ImGui::ColorButton(col_display);

	if (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelect)
	{
		ImGui::SameLine(0, (int)style.ItemInnerSpacing.x);
		const char* button_titles[3] = { "RGB", "HSV", "HEX" };
		if (ImGui::Button(button_titles[edit_mode]))
		{
			// Don't set 'edit_mode' right away!
			g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3);
		}
	}

	ImGui::SameLine();
	ImGui::TextUnformatted(label, FindTextDisplayEnd(label));

	// Convert back
	fx = ix / 255.0f;
	fy = iy / 255.0f;
	fz = iz / 255.0f;
	fw = iw / 255.0f;
	if (edit_mode == 1)
		ImConvertColorHSVtoRGB(fx, fy, fz, fx, fy, fz);

	if (value_changed)
	{
		col[0] = fx;
		col[1] = fy;
		col[2] = fz;
		if (alpha)
			col[3] = fw;
	}

	ImGui::PopID();

	return value_changed;
}

void ColorEditMode(ImGuiColorEditMode mode)
{
	ImGuiWindow* window = GetCurrentWindow();
	window->DC.ColorEditMode = mode;
}

void Separator()
{
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return;

	if (window->DC.ColumnsCount > 1)
		ImGui::PopClipRect();

	const ImGuiAabb bb(ImVec2(window->Pos.x, window->DC.CursorPos.y), ImVec2(window->Pos.x + window->Size.x, window->DC.CursorPos.y));
	ItemSize(ImVec2(0.0f, bb.GetSize().y));	// NB: we don't provide our width so that it doesn't get feed back into AutoFit

	if (ClipAdvance(bb))
	{
		if (window->DC.ColumnsCount > 1)
			ImGui::PushColumnClipRect();
		return;
	}

	window->DrawList->AddLine(bb.Min, bb.Max, window->Color(ImGuiCol_Border));

	if (window->DC.ColumnsCount > 1)
		ImGui::PushColumnClipRect();
}

void Spacing()
{
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return;

	ItemSize(ImVec2(0,0));
}

static void ItemSize(ImVec2 size, ImVec2* adjust_start_offset)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return;

	const float line_height = ImMax(window->DC.CurrentLineHeight, size.y);
	if (adjust_start_offset)
		adjust_start_offset->y = adjust_start_offset->y + (line_height - size.y) * 0.5f;

	// Always align ourselves on pixel boundaries
	window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y);
	window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.ColumnStartX), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y));

	window->SizeContentsFit = ImMax(window->SizeContentsFit, ImVec2(window->DC.CursorPosPrevLine.x, window->DC.CursorPos.y) - window->Pos + ImVec2(0.0f, window->ScrollY));

	window->DC.PrevLineHeight = line_height;
	window->DC.CurrentLineHeight = 0.0f;
}

static void ItemSize(const ImGuiAabb& aabb, ImVec2* adjust_start_offset) 
{ 
	ItemSize(aabb.GetSize(), adjust_start_offset); 
}

void NextColumn()
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return;

	if (window->DC.ColumnsCount > 1)
	{
		ImGui::PopItemWidth();
		ImGui::PopClipRect();
		if (++window->DC.ColumnCurrent < window->DC.ColumnsCount)
			SameLine((int)(ImGui::GetColumnOffset(window->DC.ColumnCurrent) + g.Style.ItemSpacing.x));
		else
			window->DC.ColumnCurrent = 0;
		ImGui::PushColumnClipRect();
		ImGui::PushItemWidth(ImGui::GetColumnWidth() * 0.65f);
	}
}

bool IsClipped(const ImGuiAabb& bb)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();

	if (!bb.Overlaps(ImGuiAabb(window->ClipRectStack.back())) && !g.LogEnabled)
		return true;
	return false;
}

bool IsClipped(const ImVec2& item_size)
{
	ImGuiWindow* window = GetCurrentWindow();
	return IsClipped(ImGuiAabb(window->DC.CursorPos, window->DC.CursorPos + item_size));
}

static bool ClipAdvance(const ImGuiAabb& bb)
{
	ImGuiWindow* window = GetCurrentWindow();
	window->DC.LastItemAabb = bb;
	if (ImGui::IsClipped(bb))
	{
		window->DC.LastItemHovered = false;
		return true;
	}
	window->DC.LastItemHovered = ImGui::IsMouseHoveringBox(bb);		// this is a sensible default but widgets are free to override it after calling ClipAdvance
	return false;
}

// Gets back to previous line and continue with horizontal layout
//		column_x == 0	: follow on previous item
//		columm_x != 0	: align to specified column
//		spacing_w < 0	: use default spacing if column_x==0, no spacing if column_x!=0
//		spacing_w >= 0	: enforce spacing
void SameLine(int column_x, int spacing_w)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return;
	
	float x, y;
	if (column_x != 0)
	{
		if (spacing_w < 0) spacing_w = 0;
		x = window->Pos.x + (float)column_x + (float)spacing_w;
		y = window->DC.CursorPosPrevLine.y;
	}
	else
	{
		if (spacing_w < 0) spacing_w = (int)g.Style.ItemSpacing.x;
		x = window->DC.CursorPosPrevLine.x + (float)spacing_w;
		y = window->DC.CursorPosPrevLine.y;
	}
	window->DC.CurrentLineHeight = window->DC.PrevLineHeight;
	window->DC.CursorPos = ImVec2(x, y);
}

float GetColumnOffset(int column_index)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (column_index < 0)
		column_index = window->DC.ColumnCurrent;

	const ImGuiID column_id = ImGuiID(window->DC.ColumnsSetID + column_index);
	RegisterAliveId(column_id);
	const float default_t = column_index / (float)window->DC.ColumnsCount;
	const float t = (float)window->StateStorage.GetInt(column_id, (int)(default_t * 8096)) / 8096;		// Cheaply store our floating point value inside the integer (could store an union into the map?)

	const float offset = window->DC.ColumnStartX + t * (window->Size.x - g.Style.ScrollBarWidth - window->DC.ColumnStartX);
	return offset;
}

void SetColumnOffset(int column_index, float offset)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (column_index < 0)
		column_index = window->DC.ColumnCurrent;

	const ImGuiID column_id = ImGuiID(window->DC.ColumnsSetID + column_index);
	const float t = (offset - window->DC.ColumnStartX) / (window->Size.x - g.Style.ScrollBarWidth - window->DC.ColumnStartX);
	window->StateStorage.SetInt(column_id, (int)(t*8096));
}

float GetColumnWidth(int column_index)
{
	ImGuiWindow* window = GetCurrentWindow();
	if (column_index < 0)
		column_index = window->DC.ColumnCurrent;

	const float w = GetColumnOffset(column_index+1) - GetColumnOffset(column_index);
	return w;
}

static void PushColumnClipRect(int column_index)
{
	ImGuiWindow* window = GetCurrentWindow();
	if (column_index < 0)
		column_index = window->DC.ColumnCurrent;

	const float x1 = window->Pos.x + ImGui::GetColumnOffset(column_index) - 1;
	const float x2 = window->Pos.x + ImGui::GetColumnOffset(column_index+1) - 1;
	ImGui::PushClipRect(ImVec4(x1,-FLT_MAX,x2,+FLT_MAX));
}

void Columns(int columns_count, const char* id, bool border)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->SkipItems)
		return;

	if (window->DC.ColumnsCount != 1)
	{
		if (window->DC.ColumnCurrent != 0)
			ImGui::ItemSize(ImVec2(0,0));	// Advance to column 0
		ImGui::PopItemWidth();
		ImGui::PopClipRect();
	}

	if (window->DC.ColumnsCount != columns_count && window->DC.ColumnsCount != 1 && window->DC.ColumnsShowBorders)
	{
		// Draw columns and handle resize
		const float y1 = window->DC.ColumnsStartCursorPos.y;
		const float y2 = window->DC.CursorPos.y;
		for (int i = 1; i < window->DC.ColumnsCount; i++)
		{
			float x = window->Pos.x + GetColumnOffset(i);
			
			const ImGuiID column_id = ImGuiID(window->DC.ColumnsSetID + i);
			const ImGuiAabb column_aabb(ImVec2(x-4,y1),ImVec2(x+4,y2));

			if (IsClipped(column_aabb))
				continue;

			bool hovered, held;
			ButtonBehaviour(column_aabb, column_id, &hovered, &held, true);

			// Draw before resize so our items positioning are in sync with the line
			const ImU32 col = window->Color(held ? ImGuiCol_ColumnActive : hovered ? ImGuiCol_ColumnHovered : ImGuiCol_Column);
			const float xi = (float)(int)x;
			window->DrawList->AddLine(ImVec2(xi, y1), ImVec2(xi, y2), col);

			if (held)
			{
				x -= window->Pos.x;
				x = ImClamp(x + g.IO.MouseDelta.x, ImGui::GetColumnOffset(i-1)+g.Style.ColumnsMinSpacing, ImGui::GetColumnOffset(i+1)-g.Style.ColumnsMinSpacing);
				SetColumnOffset(i, x);
				x += window->Pos.x;
			}
		}
	}

	window->DC.ColumnsSetID = window->GetID(id ? id : "");
	window->DC.ColumnCurrent = 0;
	window->DC.ColumnsCount = columns_count;
	window->DC.ColumnsShowBorders = border;
	window->DC.ColumnsStartCursorPos = window->DC.CursorPos;

	if (window->DC.ColumnsCount != 1)
	{
		ImGui::PushColumnClipRect();
		ImGui::PushItemWidth(ImGui::GetColumnWidth() * 0.65f);
	}
}

void TreePush(const char* str_id)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	window->DC.ColumnStartX += g.Style.TreeNodeSpacing;
	window->DC.CursorPos.x = window->Pos.x + window->DC.ColumnStartX;
	window->DC.TreeDepth++;
	PushID(str_id ? str_id : "#TreePush");
}

void TreePush(const void* ptr_id)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	window->DC.ColumnStartX += g.Style.TreeNodeSpacing;
	window->DC.CursorPos.x = window->Pos.x + window->DC.ColumnStartX;
	window->DC.TreeDepth++;
	PushID(ptr_id ? ptr_id : (const void*)"#TreePush");
}

void TreePop()
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	window->DC.ColumnStartX -= g.Style.TreeNodeSpacing;
	window->DC.CursorPos.x = window->Pos.x + window->DC.ColumnStartX;
	window->DC.TreeDepth--;
	PopID();
}

void Value(const char* prefix, bool b)
{
	ImGui::Text("%s: %s", prefix, (b ? "true" : "false"));
}

void Value(const char* prefix, int v)
{
	ImGui::Text("%s: %d", prefix, v);
}

void Value(const char* prefix, unsigned int v)
{
	ImGui::Text("%s: %d", prefix, v);
}

void Value(const char* prefix, float v, const char* float_format)
{
	if (float_format)
	{
		char fmt[64];
		sprintf(fmt, "%%s: %s", float_format);
		ImGui::Text(fmt, prefix, v);
	}
	else
	{
		ImGui::Text("%s: %.3f", prefix, v);
	}
}

void Color(const char* prefix, const ImVec4& v)
{
	ImGui::Text("%s: (%.2f,%.2f,%.2f,%.2f)", prefix, v.x, v.y, v.z, v.w);
	ImGui::SameLine();
	ImGui::ColorButton(v, true);
}

void Color(const char* prefix, unsigned int v)
{
	ImGui::Text("%s: %08X", prefix, v);
	ImGui::SameLine();

	ImVec4 col;
	col.x = (float)((v >> 0) & 0xFF) / 255.0f;
	col.y = (float)((v >> 8) & 0xFF) / 255.0f;
	col.z = (float)((v >> 16) & 0xFF) / 255.0f;
	col.w = (float)((v >> 24) & 0xFF) / 255.0f;
	ImGui::ColorButton(col, true);
}

}; // namespace ImGui

//-----------------------------------------------------------------------------
// ImDrawList
//-----------------------------------------------------------------------------

void ImDrawList::Clear()
{
	commands.resize(0);
	vtx_buffer.resize(0);
	vtx_write = NULL;
	clip_rect_stack.resize(0);
}

void ImDrawList::PushClipRect(const ImVec4& clip_rect)
{
	if (!commands.empty() && commands.back().vtx_count == 0)
	{
		// Reuse empty command because high-level clipping may have discarded the other vertices already
		commands.back().clip_rect = clip_rect;
	}
	else
	{
		ImDrawCmd draw_cmd;
		draw_cmd.vtx_count = 0;
		draw_cmd.clip_rect = clip_rect;
		commands.push_back(draw_cmd);
	}
	clip_rect_stack.push_back(clip_rect);
}

void ImDrawList::PopClipRect()
{
	clip_rect_stack.pop_back();
	const ImVec4 clip_rect = clip_rect_stack.empty() ? ImVec4(-9999.0f,-9999.0f, +9999.0f, +9999.0f) : clip_rect_stack.back();
	if (!commands.empty() && commands.back().vtx_count == 0)
	{
		// Reuse empty command because high-level clipping may have discarded the other vertices already
		commands.back().clip_rect = clip_rect;
	}
	else
	{
		ImDrawCmd draw_cmd;
		draw_cmd.vtx_count = 0;
		draw_cmd.clip_rect = clip_rect;
		commands.push_back(draw_cmd);
	}
}

void ImDrawList::ReserveVertices(unsigned int vtx_count)
{
	if (vtx_count > 0)
	{
		ImDrawCmd& draw_cmd = commands.back();
		draw_cmd.vtx_count += vtx_count;
		vtx_buffer.resize(vtx_buffer.size() + vtx_count);
		vtx_write = &vtx_buffer[vtx_buffer.size() - vtx_count];
	}
}

void ImDrawList::AddVtx(const ImVec2& pos, ImU32 col)
{
	vtx_write->pos = pos;
	vtx_write->col = col;
	vtx_write->uv = IMGUI_FONT_TEX_UV_FOR_WHITE;
	vtx_write++;
}

void ImDrawList::AddVtxLine(const ImVec2& a, const ImVec2& b, ImU32 col)
{
	const ImVec2 n = (b - a) / ImLength(b - a);
	const ImVec2 hn = ImVec2(n.y, -n.x) * 0.5f;

	AddVtx(a - hn, col);
	AddVtx(b - hn, col);
	AddVtx(a + hn, col);

	AddVtx(b - hn, col);
	AddVtx(b + hn, col);
	AddVtx(a + hn, col);
}

void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col)
{
	if ((col >> 24) == 0)
		return;

	ReserveVertices(6);
	AddVtxLine(a, b, col);
}

void ImDrawList::AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, int a_max, bool tris, const ImVec2& third_point_offset)
{
	if ((col >> 24) == 0)
		return;

	static ImVec2 circle_vtx[12];
	static bool circle_vtx_builds = false;
	if (!circle_vtx_builds)
	{
		for (int i = 0; i < IM_ARRAYSIZE(circle_vtx); i++)
		{
			const float a = ((float)i / (float)IM_ARRAYSIZE(circle_vtx)) * 2*PI;
			circle_vtx[i].x = cos(a + PI);
			circle_vtx[i].y = sin(a + PI);
		}
		circle_vtx_builds = true;
	}
	
	if (tris)
	{
		ReserveVertices((a_max-a_min) * 3);
		for (int a = a_min; a < a_max; a++)
		{
			AddVtx(center + circle_vtx[a % IM_ARRAYSIZE(circle_vtx)] * rad, col);
			AddVtx(center + circle_vtx[(a+1) % IM_ARRAYSIZE(circle_vtx)] * rad, col);
			AddVtx(center + third_point_offset, col);
		}
	}
	else
	{
		ReserveVertices((a_max-a_min) * 6);
		for (int a = a_min; a < a_max; a++)
			AddVtxLine(center + circle_vtx[a % IM_ARRAYSIZE(circle_vtx)] * rad, center + circle_vtx[(a+1) % IM_ARRAYSIZE(circle_vtx)] * rad, col);
	}
}

void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners)
{
	if ((col >> 24) == 0)
		return;

	//const float r = ImMin(rounding, ImMin(fabsf(b.x-a.x), fabsf(b.y-a.y))*0.5f);
	float r = rounding;
	r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners&(1|2))==(1|2)) || ((rounding_corners&(4|8))==(4|8)) ? 0.5f : 1.0f ));
	r = ImMin(r, fabsf(b.y-a.y) * ( ((rounding_corners&(1|8))==(1|8)) || ((rounding_corners&(2|4))==(2|4)) ? 0.5f : 1.0f ));

	if (r == 0.0f || rounding_corners == 0)
	{
		ReserveVertices(4*6);
		AddVtxLine(ImVec2(a.x,a.y), ImVec2(b.x,a.y), col);
		AddVtxLine(ImVec2(b.x,a.y), ImVec2(b.x,b.y), col);
		AddVtxLine(ImVec2(b.x,b.y), ImVec2(a.x,b.y), col);
		AddVtxLine(ImVec2(a.x,b.y), ImVec2(a.x,a.y), col);
	}
	else
	{
		ReserveVertices(4*6);
		AddVtxLine(ImVec2(a.x + ((rounding_corners & 1)?r:0), a.y), ImVec2(b.x - ((rounding_corners & 2)?r:0), a.y), col);
		AddVtxLine(ImVec2(b.x, a.y + ((rounding_corners & 2)?r:0)), ImVec2(b.x, b.y - ((rounding_corners & 4)?r:0)), col);
		AddVtxLine(ImVec2(b.x - ((rounding_corners & 4)?r:0), b.y), ImVec2(a.x + ((rounding_corners & 8)?r:0), b.y), col);
		AddVtxLine(ImVec2(a.x, b.y - ((rounding_corners & 8)?r:0)), ImVec2(a.x, a.y + ((rounding_corners & 1)?r:0)), col);

		if (rounding_corners & 1) AddArc(ImVec2(a.x+r,a.y+r), r, col, 0, 3);
		if (rounding_corners & 2) AddArc(ImVec2(b.x-r,a.y+r), r, col, 3, 6);
		if (rounding_corners & 4) AddArc(ImVec2(b.x-r,b.y-r), r, col, 6, 9);
		if (rounding_corners & 8) AddArc(ImVec2(a.x+r,b.y-r), r, col, 9, 12);
	}
}

void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners)
{
	if ((col >> 24) == 0)
		return;

	//const float r = ImMin(rounding, ImMin(fabsf(b.x-a.x), fabsf(b.y-a.y))*0.5f);
	float r = rounding;
	r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners&(1|2))==(1|2)) || ((rounding_corners&(4|8))==(4|8)) ? 0.5f : 1.0f ));
	r = ImMin(r, fabsf(b.y-a.y) * ( ((rounding_corners&(1|8))==(1|8)) || ((rounding_corners&(2|4))==(2|4)) ? 0.5f : 1.0f ));

	if (r == 0.0f || rounding_corners == 0)
	{
		// Use triangle so we can merge more draw calls together (at the cost of extra vertices)
		ReserveVertices(6);
		AddVtx(ImVec2(a.x,a.y), col);
		AddVtx(ImVec2(b.x,a.y), col);
		AddVtx(ImVec2(b.x,b.y), col);
		AddVtx(ImVec2(a.x,a.y), col);
		AddVtx(ImVec2(b.x,b.y), col);
		AddVtx(ImVec2(a.x,b.y), col);
	}
	else
	{
		ReserveVertices(6+6*2);
		AddVtx(ImVec2(a.x+r,a.y), col);
		AddVtx(ImVec2(b.x-r,a.y), col);
		AddVtx(ImVec2(b.x-r,b.y), col);
		AddVtx(ImVec2(a.x+r,a.y), col);
		AddVtx(ImVec2(b.x-r,b.y), col);
		AddVtx(ImVec2(a.x+r,b.y), col);
		
		float top_y = (rounding_corners & 1) ? a.y+r : a.y;
		float bot_y = (rounding_corners & 8) ? b.y-r : b.y;
		AddVtx(ImVec2(a.x,top_y), col);
		AddVtx(ImVec2(a.x+r,top_y), col);
		AddVtx(ImVec2(a.x+r,bot_y), col);
		AddVtx(ImVec2(a.x,top_y), col);
		AddVtx(ImVec2(a.x+r,bot_y), col);
		AddVtx(ImVec2(a.x,bot_y), col);

		top_y = (rounding_corners & 2) ? a.y+r : a.y;
		bot_y = (rounding_corners & 4) ? b.y-r : b.y;
		AddVtx(ImVec2(b.x-r,top_y), col);
		AddVtx(ImVec2(b.x,top_y), col);
		AddVtx(ImVec2(b.x,bot_y), col);
		AddVtx(ImVec2(b.x-r,top_y), col);
		AddVtx(ImVec2(b.x,bot_y), col);
		AddVtx(ImVec2(b.x-r,bot_y), col);

		if (rounding_corners & 1) AddArc(ImVec2(a.x+r,a.y+r), r, col, 0, 3, true);
		if (rounding_corners & 2) AddArc(ImVec2(b.x-r,a.y+r), r, col, 3, 6, true);
		if (rounding_corners & 4) AddArc(ImVec2(b.x-r,b.y-r), r, col, 6, 9, true);
		if (rounding_corners & 8) AddArc(ImVec2(a.x+r,b.y-r), r, col, 9, 12,true);
	}
}

void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col)
{
	if ((col >> 24) == 0)
		return;

	ReserveVertices(3);
	AddVtx(a, col);
	AddVtx(b, col);
	AddVtx(c, col);
}

void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments)
{
	if ((col >> 24) == 0)
		return;

	ReserveVertices(num_segments*6);
	const float a_step = 2*PI/(float)num_segments;
	float a0 = 0.0f;
	for (int i = 0; i < num_segments; i++)
	{
		const float a1 = (i + 1) == num_segments ? 0.0f : a0 + a_step;
		AddVtxLine(centre + ImVec2(cos(a0),sin(a0))*radius, centre + ImVec2(cos(a1),sin(a1))*radius, col);
		a0 = a1;
	}
}

void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments)
{
	if ((col >> 24) == 0)
		return;

	ReserveVertices(num_segments*3);
	const float a_step = 2*PI/(float)num_segments;
	float a0 = 0.0f;
	for (int i = 0; i < num_segments; i++)
	{
		const float a1 = (i + 1) == num_segments ? 0.0f : a0 + a_step;
		AddVtx(centre + ImVec2(cos(a0),sin(a0))*radius, col);
		AddVtx(centre + ImVec2(cos(a1),sin(a1))*radius, col);
		AddVtx(centre, col);
		a0 = a1;
	}
}

void ImDrawList::AddText(ImFont font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end)
{
	if ((col >> 24) == 0)
		return;

	if (text_end == NULL)
		text_end = text_begin + strlen(text_begin);

	// reserve vertices for worse case
	const int char_count = (int)(text_end - text_begin);
	const int vtx_count_max = char_count * 6;
	const size_t vtx_begin = vtx_buffer.size();
	ReserveVertices(vtx_count_max);

	font->RenderText(font_size, pos, col, clip_rect_stack.back(), text_begin, text_end, vtx_write);

	// give unused vertices
	vtx_buffer.resize(vtx_write - &vtx_buffer.front());
	const int vtx_count = (int)(vtx_buffer.size() - vtx_begin);
	commands.back().vtx_count -= (vtx_count_max - vtx_count);
	vtx_write -= (vtx_count_max - vtx_count);
}

//-----------------------------------------------------------------------------
// ImBitmapFont
//-----------------------------------------------------------------------------

ImBitmapFont::ImBitmapFont()
{
	Data = NULL;
	DataOwned = false;
	Info = NULL;
	Common = NULL;
	Glyphs = NULL;
	GlyphsCount = 0;
	TabCount = 4;
}

void	ImBitmapFont::Clear()
{
	if (Data && DataOwned)
		free(Data);
	Data = NULL;
	DataOwned = false;
	Info = NULL;
	Common = NULL;
	Glyphs = NULL;
	GlyphsCount = 0;
	Filenames.clear();
	IndexLookup.clear();
}

bool	ImBitmapFont::LoadFromFile(const char* filename)
{
	// Load file
	FILE* f;
	if ((f = fopen(filename, "rb")) == NULL)
		return false;
	if (fseek(f, 0, SEEK_END)) 
		return false;
	if ((DataSize = (int)ftell(f)) == -1)
		return false;
	if (fseek(f, 0, SEEK_SET)) 
		return false;
	if ((Data = (unsigned char*)malloc(DataSize)) == NULL)
	{
		fclose(f);
		return false;
	}
	if ((int)fread(Data, 1, DataSize, f) != DataSize)
	{
		fclose(f);
		free(Data);
		return false;
	}
	fclose(f);
	DataOwned = true;
	return LoadFromMemory(Data, DataSize);
}

bool	ImBitmapFont::LoadFromMemory(const void* data, int data_size)
{
	Data = (unsigned char*)data;
	DataSize = data_size;

	// Parse data
	if (DataSize < 4 || Data[0] != 'B' || Data[1] != 'M' || Data[2] != 'F' || Data[3] != 0x03)
		return false;
	for (const unsigned char* p = Data+4; p < Data + DataSize; )
	{
		const unsigned char block_type = *(unsigned char*)p;
		p += sizeof(unsigned char);
		const ImU32 block_size = *(ImU32*)p;
		p += sizeof(ImU32);

		switch (block_type)
		{
		case 1:
			IM_ASSERT(Info == NULL);
			Info = (FntInfo*)p;
			break;
		case 2:
			IM_ASSERT(Common == NULL);
			Common = (FntCommon*)p;
			break;
		case 3:
			for (const unsigned char* s = p; s < p+block_size && s < Data+DataSize; s = s + strlen((const char*)s) + 1)
				Filenames.push_back((const char*)s);
			break;
		case 4:
			IM_ASSERT(Glyphs == NULL && GlyphsCount == 0);
			Glyphs = (FntGlyph*)p;
			GlyphsCount = block_size / sizeof(FntGlyph);
			break;
		default:
			IM_ASSERT(Kerning == NULL && KerningCount == 0);
			Kerning = (FntKerning*)p;
			KerningCount = block_size / sizeof(FntKerning);
			break;
		}
		p += block_size;
	}

	BuildLookupTable();
	return true;
}

void ImBitmapFont::BuildLookupTable()
{
	ImU32 max_c = 0;
	for (size_t i = 0; i != GlyphsCount; i++)
		if (max_c < Glyphs[i].Id)
			max_c = Glyphs[i].Id;

	IndexLookup.clear();
	IndexLookup.resize(max_c + 1);
	for (size_t i = 0; i < IndexLookup.size(); i++)
		IndexLookup[i] = -1;
	for (size_t i = 0; i < GlyphsCount; i++)
		IndexLookup[Glyphs[i].Id] = (int)i;
}

const ImBitmapFont::FntGlyph* ImBitmapFont::FindGlyph(unsigned short c) const
{
	if (c < (int)IndexLookup.size())
	{
		const int i = IndexLookup[c];
		if (i >= 0 && i < (int)GlyphsCount)
			return &Glyphs[i];
	}
	return NULL;
}

ImVec2 ImBitmapFont::CalcTextSize(float size, float max_width, const char* text_begin, const char* text_end, const char** remaining) const
{
	if (max_width == 0.0f)
		max_width = FLT_MAX;
	if (!text_end)
		text_end = text_begin + strlen(text_begin);

	const float scale = size / (float)Info->FontSize;
	const float line_height = (float)Info->FontSize * scale;

	ImVec2 text_size = ImVec2(0,0);
	float line_width = 0.0f;

	const char* s = text_begin;
	while (s < text_end)
	{
		const char c = *s;
		if (c == '\n')
		{
			if (text_size.x < line_width)
				text_size.x = line_width;
			text_size.y += line_height;
			line_width = 0;
		}
		else if (const FntGlyph* glyph = FindGlyph((unsigned short)c))
		{
			const float char_width = (glyph->XAdvance + Info->SpacingHoriz) * scale;
			//const float char_extend = (glyph->XOffset + glyph->Width * scale);

			if (line_width + char_width >= max_width)
				break;
			line_width += char_width;
		}
		else if (c == '\t')
		{
			if (const FntGlyph* glyph = FindGlyph((unsigned short)' '))
				line_width += (glyph->XAdvance + Info->SpacingHoriz) * 4 * scale;
		}

		s += 1;
	}

	if (line_width > 0 || text_size.y == 0.0f)
	{
		if (text_size.x < line_width)
			text_size.x = line_width;
		text_size.y += line_height;
	}

	if (remaining)
		*remaining = s;

	return text_size;
}

void ImBitmapFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect_ref, const char* text_begin, const char* text_end, ImDrawVert*& out_vertices) const
{
	if (!text_end)
		text_end = text_begin + strlen(text_begin);

	const float line_height = (float)Info->FontSize;
	const float scale = size / (float)Info->FontSize;
	const float tex_scale_x = 1.0f / (float)Common->ScaleW;
	const float tex_scale_y = 1.0f / (float)(Common->ScaleH);
	const float outline = (float)Info->Outline;

	// Align to be pixel perfect
	pos.x = (float)(int)pos.x + 0.5f;
	pos.y = (float)(int)pos.y + 0.5f;

	const ImVec4 clip_rect = clip_rect_ref;

	const float uv_offset = GImGui.IO.PixelCenterOffset;

	float x = pos.x;
	float y = pos.y;
	for (const char* s = text_begin; s < text_end; s++)
	{
		const char c = *s;
		if (c == '\n')
		{
			x = pos.x;
			y += line_height * scale;
			continue;
		}

		if (const FntGlyph* glyph = FindGlyph((unsigned short)c))
		{
			const float char_width = (glyph->XAdvance + Info->SpacingHoriz) * scale;
			//const float char_extend = (glyph->XOffset + glyph->Width * scale);

			if (c != ' ' && c != '\n')
			{
				// Clipping due to Y limits is more likely
				const float y1 = (float)(y + (glyph->YOffset + outline*2) * scale);
				const float y2 = (float)(y1 + glyph->Height * scale);
				if (y1 > clip_rect.w || y2 < clip_rect.y)
				{
					x += char_width;
					continue;
				}

				const float x1 = (float)(x + (glyph->XOffset + outline) * scale);
				const float x2 = (float)(x1 + glyph->Width * scale);
				if (x1 > clip_rect.z || x2 < clip_rect.x)
				{
					x += char_width;
					continue;
				}

				const float s1 = (uv_offset + glyph->X) * tex_scale_x;
				const float t1 = (uv_offset + glyph->Y) * tex_scale_y;
				const float s2 = (uv_offset + glyph->X + glyph->Width) * tex_scale_x;
				const float t2 = (uv_offset + glyph->Y + glyph->Height) * tex_scale_y;

				out_vertices[0].pos = ImVec2(x1, y1);
				out_vertices[0].uv  = ImVec2(s1, t1);
				out_vertices[0].col = col;

				out_vertices[1].pos = ImVec2(x2, y1);
				out_vertices[1].uv  = ImVec2(s2, t1);
				out_vertices[1].col = col;

				out_vertices[2].pos = ImVec2(x2, y2);
				out_vertices[2].uv  = ImVec2(s2, t2);
				out_vertices[2].col = col;

				out_vertices[3] = out_vertices[0];
				out_vertices[4] = out_vertices[2];

				out_vertices[5].pos = ImVec2(x1, y2);
				out_vertices[5].uv  = ImVec2(s1, t2);
				out_vertices[5].col = col;

				out_vertices += 6;
			}

			x += char_width;
		}
		else if (c == '\t')
		{
			if (const FntGlyph* glyph = FindGlyph((unsigned short)' '))
				x += (glyph->XAdvance + Info->SpacingHoriz) * 4 * scale;
		}
	}
}

//-----------------------------------------------------------------------------
// PLATFORM DEPENDANT HELPERS
//-----------------------------------------------------------------------------

#if defined(_MSC_VER) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS)

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

// Win32 API clipboard implementation
static const char*	GetClipboardTextFn_DefaultImpl()
{
	static char* buf_local = NULL;
	if (buf_local)
	{
		free(buf_local);
		buf_local = NULL;
	}
	if (!OpenClipboard(NULL)) 
		return NULL;
	HANDLE buf_handle = GetClipboardData(CF_TEXT); 
	if (buf_handle == NULL)
		return NULL;
	if (char* buf_global = (char*)GlobalLock(buf_handle))
		buf_local = strdup(buf_global);
	GlobalUnlock(buf_handle); 
	CloseClipboard(); 
	return buf_local;
}

// Win32 API clipboard implementation
static void SetClipboardTextFn_DefaultImpl(const char* text, const char* text_end)
{
	if (!OpenClipboard(NULL))
		return;
	if (!text_end)
		text_end = text + strlen(text);
	const int buf_length = (int)(text_end - text) + 1;
	HGLOBAL buf_handle = GlobalAlloc(GMEM_MOVEABLE, buf_length * sizeof(char)); 
	if (buf_handle == NULL)
		return;
	char* buf_global = (char *)GlobalLock(buf_handle); 
	memcpy(buf_global, text, text_end - text);
	buf_global[text_end - text] = 0;
	GlobalUnlock(buf_handle); 
	EmptyClipboard();
	SetClipboardData(CF_TEXT, buf_handle);
	CloseClipboard();
}

#else

// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
static const char*	GetClipboardTextFn_DefaultImpl()
{
	return GImGui.PrivateClipboard;
}

// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
static void SetClipboardTextFn_DefaultImpl(const char* text, const char* text_end)
{
	if (GImGui.PrivateClipboard)
	{
		free(GImGui.PrivateClipboard);
		GImGui.PrivateClipboard = NULL;
	}
	if (!text_end)
		text_end = text + strlen(text);
	GImGui.PrivateClipboard = (char*)malloc(text_end - text + 1);
	memcpy(GImGui.PrivateClipboard, text, text_end - text);
	GImGui.PrivateClipboard[text_end - text] = 0;
}

#endif

//-----------------------------------------------------------------------------
// HELP
//-----------------------------------------------------------------------------

namespace ImGui
{

void ShowUserGuide()
{
	ImGuiState& g = GImGui;

	ImGui::BulletText("Double-click on title bar to collapse window.");
	ImGui::BulletText("Click and drag on lower right corner to resize window.");
	ImGui::BulletText("Click and drag on any empty space to move window.");
	ImGui::BulletText("Mouse Wheel to scroll.");
	if (g.IO.FontAllowScaling)
		ImGui::BulletText("CTRL+Mouse Wheel to zoom window contents.");
	ImGui::BulletText("TAB/SHIFT+TAB to cycle thru keyboard editable fields.");
	ImGui::BulletText("CTRL+Click on a slider to input text.");
	ImGui::BulletText(
		"While editing text:\n"
		"- Hold SHIFT or use mouse to select text\n"
		"- CTRL+Left/Right to word jump\n"
		"- CTRL+A select all\n"
		"- CTRL+X,CTRL+C,CTRL+V clipboard\n"
		"- CTRL+Z,CTRL+Y undo/redo\n"
		"- ESCAPE to revert\n"
		"- You can apply arithmetic operators +,*,/ on numerical values.\n"
		"  Use +- to subtract.\n");
}

void ShowStyleEditor(ImGuiStyle* ref)
{
	ImGuiState& g = GImGui;
	ImGuiStyle& style = g.Style;

	const ImGuiStyle def;

	if (ImGui::Button("Revert Style"))
		g.Style = ref ? *ref : def;
	if (ref)
	{
		ImGui::SameLine();
		if (ImGui::Button("Save Style"))
			*ref = g.Style;
	}

	ImGui::SliderFloat("Alpha", &style.Alpha, 0.20f, 1.0f, "%.2f");					// Not exposing zero here so user doesn't "lose" the UI. But application code could have a toggle to switch between zero and non-zero.
	ImGui::SliderFloat("Rounding", &style.WindowRounding, 0.0f, 16.0f, "%.0f");

	static ImGuiColorEditMode edit_mode = ImGuiColorEditMode_RGB;
	ImGui::RadioButton("RGB", &edit_mode, ImGuiColorEditMode_RGB);
	ImGui::SameLine();
	ImGui::RadioButton("HSV", &edit_mode, ImGuiColorEditMode_HSV);
	ImGui::SameLine();
	ImGui::RadioButton("HEX", &edit_mode, ImGuiColorEditMode_HEX);

	static ImGuiTextFilter filter;
	filter.Draw("Filter colors", 200);

	ImGui::ColorEditMode(edit_mode);
	for (int i = 0; i < ImGuiCol_COUNT; i++)
	{
		const char* name = GetStyleColorName(i);
		if (!filter.PassFilter(name))
			continue;
		ImGui::PushID(i);
		ImGui::ColorEdit4(name, (float*)&style.Colors[i], true);
		if (memcmp(&style.Colors[i], (ref ? &ref->Colors[i] : &def.Colors[i]), sizeof(ImVec4)) != 0)
		{
			ImGui::SameLine(); if (ImGui::Button("Revert")) style.Colors[i] = ref ? ref->Colors[i] : def.Colors[i];
			if (ref) { ImGui::SameLine(); if (ImGui::Button("Save")) ref->Colors[i] = style.Colors[i]; }
		}
		ImGui::PopID();
	}
}

//-----------------------------------------------------------------------------
// SAMPLE CODE
//-----------------------------------------------------------------------------

// Demonstrate ImGui features (unfortunately this makes this function a little bloated!)
void ShowTestWindow(bool* open)
{
	static bool no_titlebar = false;
	static bool no_border = true;
	static bool no_resize = false;
	static bool no_move = false;
	static bool no_scrollbar = false;
	static float fill_alpha = 0.65f;

	const ImU32 layout_flags = (no_titlebar ? ImGuiWindowFlags_NoTitleBar : 0) | (no_border ? 0 : ImGuiWindowFlags_ShowBorders) | (no_resize ? ImGuiWindowFlags_NoResize : 0) | (no_move ? ImGuiWindowFlags_NoMove : 0) | (no_scrollbar ? ImGuiWindowFlags_NoScrollbar : 0);
	ImGui::Begin("ImGui Test", open, ImVec2(550,680), fill_alpha, layout_flags);
	ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);

	ImGui::Text("ImGui says hello.");
	//ImGui::Text("MousePos (%g, %g)", g.IO.MousePos.x, g.IO.MousePos.y);
	//ImGui::Text("MouseWheel %d", g.IO.MouseWheel);

	ImGui::Spacing();
	if (ImGui::CollapsingHeader("Help"))
	{
		ImGui::ShowUserGuide();
	}

	if (ImGui::CollapsingHeader("Window options"))
	{
		ImGui::Checkbox("no titlebar", &no_titlebar); ImGui::SameLine(200);
		ImGui::Checkbox("no border", &no_border); ImGui::SameLine(400);
		ImGui::Checkbox("no resize", &no_resize); 
		ImGui::Checkbox("no move", &no_move); ImGui::SameLine(200);
		ImGui::Checkbox("no scrollbar", &no_scrollbar);
		ImGui::SliderFloat("fill alpha", &fill_alpha, 0.0f, 1.0f);
		if (ImGui::TreeNode("Style Editor"))
		{
			ImGui::ShowStyleEditor();
			ImGui::TreePop();
		}

		if (ImGui::TreeNode("Logging"))
		{
			ImGui::LogButtons();
			ImGui::TreePop();
		}
	}

	if (ImGui::CollapsingHeader("Widgets"))
	{
		//ImGui::PushItemWidth(ImGui::GetWindowWidth() - 220);

		static bool a=false;
		if (ImGui::Button("Button")) { printf("Clicked\n"); a ^= 1; }
		if (a)
		{
			ImGui::SameLine(); 
			ImGui::Text("Thanks for clicking me!");
		}

		static bool check = true;
		ImGui::Checkbox("checkbox", &check);

		if (ImGui::TreeNode("Tree"))
		{
			for (size_t i = 0; i < 5; i++)
			{
				if (ImGui::TreeNode((void*)i, "Child %d", i))
				{
					ImGui::Text("blah blah");
					ImGui::SameLine();
					if (ImGui::SmallButton("print"))
						printf("Child %d pressed", (int)i);
					ImGui::TreePop();
				}
			}
			ImGui::TreePop();
		}

		if (ImGui::TreeNode("Bullets"))
		{
			ImGui::BulletText("Bullet point 1");
			ImGui::BulletText("Bullet point 2\nOn multiple lines");
			ImGui::BulletText("Bullet point 3");
			ImGui::TreePop();
		}

		if (ImGui::TreeNode("Colored Text"))
		{
			// This is a merely a shortcut, you can use PushStyleColor()/PopStyleColor() for more flexibility.
			ImGui::TextColored(ImVec4(1.0f,0.0f,1.0f,1.0f), "Pink");
			ImGui::TextColored(ImVec4(1.0f,1.0f,0.0f,1.0f), "Yellow");
			ImGui::TreePop();
		}

		static int e = 0;
		ImGui::RadioButton("radio a", &e, 0); ImGui::SameLine();
		ImGui::RadioButton("radio b", &e, 1); ImGui::SameLine();
		ImGui::RadioButton("radio c", &e, 2);

		ImGui::Text("Hover me");
		if (ImGui::IsHovered())
			ImGui::SetTooltip("I am a tooltip");

		ImGui::SameLine();
		ImGui::Text("- or me");
		if (ImGui::IsHovered())
		{
			ImGui::BeginTooltip();
			ImGui::Text("I am a fancy tooltip");
			static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
			ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr));
			ImGui::EndTooltip();
		}

		static int item = 1;
		ImGui::Combo("combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0");

		const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK" };
		static int item2 = -1;
		ImGui::Combo("combo scroll", &item2, items, IM_ARRAYSIZE(items));

		static char str0[128] = "Hello, world!";
		static int i0=123;
		static float f0=0.001f;
		ImGui::InputText("string", str0, IM_ARRAYSIZE(str0));
		ImGui::InputInt("input int", &i0);
		ImGui::InputFloat("input float", &f0, 0.01f, 1.0f);

		//static float vec2a[3] = { 0.10f, 0.20f };
		//ImGui::InputFloat2("input float2", vec2a);

		static float vec3a[3] = { 0.10f, 0.20f, 0.30f };
		ImGui::InputFloat3("input float3", vec3a);

		//static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f };
		//ImGui::InputFloat4("input float4", vec4a);

		static int i1=0;
		static int i2=42;
		ImGui::SliderInt("int 0..3", &i1, 0, 3);
		ImGui::SliderInt("int -100..100", &i2, -100, 100);

		static float f1=1.123f;
		static float f2=0;
		static float f3=0;
		static float f4=123456789.0f;
		ImGui::SliderFloat("float", &f1, 0.0f, 2.0f);
		ImGui::SliderFloat("log float", &f2, 0.0f, 10.0f, "%.4f", 2.0f);
		ImGui::SliderFloat("signed log float", &f3, -10.0f, 10.0f, "%.4f", 3.0f);
		ImGui::SliderFloat("unbound float", &f4, -FLT_MAX, FLT_MAX, "%.4f");
		static float angle = 0.0f;
		ImGui::SliderAngle("angle", &angle);

		//static float vec2b[3] = { 0.10f, 0.20f };
		//ImGui::SliderFloat2("slider float2", vec2b, 0.0f, 1.0f);

		static float vec3b[3] = { 0.10f, 0.20f, 0.30f };
		ImGui::SliderFloat3("slider float3", vec3b, 0.0f, 1.0f);

		//static float vec4b[4] = { 0.10f, 0.20f, 0.30f, 0.40f };
		//ImGui::SliderFloat4("slider float4", vec4b, 0.0f, 1.0f);

		static float col1[3] = { 1.0f,0.0f,0.2f };
		static float col2[4] = { 0.4f,0.7f,0.0f,0.5f };
		ImGui::ColorEdit3("color 1", col1);
		ImGui::ColorEdit4("color 2", col2);

		//ImGui::PopItemWidth();
	}

	if (ImGui::CollapsingHeader("Graphs widgets"))
	{
		static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
		ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr));

		static bool pause;
		static ImVector<float> values; if (values.empty()) { values.resize(100); memset(&values.front(), 0, values.size()*sizeof(float)); } 
		static int values_offset = 0; 
		if (!pause) 
		{ 
			// create dummy data at 60 hz
			static float refresh_time = -1.0f;
			if (ImGui::GetTime() > refresh_time + 1.0f/60.0f)
			{
				refresh_time = ImGui::GetTime();
				static float phase = 0.0f;
				values[values_offset] = cos(phase); 
				values_offset = (values_offset+1)%values.size(); 
				phase += 0.10f*values_offset; 
			}
		}
		ImGui::PlotLines("Frame Times", &values.front(), (int)values.size(), values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,70));

		ImGui::SameLine(); ImGui::Checkbox("pause", &pause);
		ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,70));
	}

	if (ImGui::CollapsingHeader("Widgets on same line"))
	{
		// Text
		ImGui::Text("Hello");
		ImGui::SameLine();
		ImGui::Text("World");

		// Button
		if (ImGui::Button("Banana")) printf("Pressed!\n");
		ImGui::SameLine();
		ImGui::Button("Apple");
		ImGui::SameLine();
		ImGui::Button("Corniflower");

		// Button
		ImGui::SmallButton("Banana");
		ImGui::SameLine();
		ImGui::SmallButton("Apple");
		ImGui::SameLine();
		ImGui::SmallButton("Corniflower");
		ImGui::SameLine();
		ImGui::Text("Small buttons fit in a text block");

		// Checkbox
		static bool c1=false,c2=false,c3=false,c4=false;
		ImGui::Checkbox("My", &c1);
		ImGui::SameLine();
		ImGui::Checkbox("Tailor", &c2);
		ImGui::SameLine();
		ImGui::Checkbox("Is", &c3);
		ImGui::SameLine();
		ImGui::Checkbox("Rich", &c4);

		// SliderFloat
		static float f0=1.0f, f1=2.0f, f2=3.0f;
		ImGui::PushItemWidth(80);
		ImGui::SliderFloat("f0", &f0, 0.0f,5.0f);
		ImGui::SameLine();
		ImGui::SliderFloat("f1", &f1, 0.0f,5.0f);
		ImGui::SameLine();
		ImGui::SliderFloat("f2", &f2, 0.0f,5.0f);

		// InputText
		static char s0[128] = "one", s1[128] = "two", s2[128] = "three";
		ImGui::InputText("s0", s0, 128);
		ImGui::SameLine();
		ImGui::InputText("s1", s1, 128);
		ImGui::SameLine();
		ImGui::InputText("s2", s2, 128);

		// LabelText
		ImGui::LabelText("l0", "one");
		ImGui::SameLine();
		ImGui::LabelText("l0", "two");
		ImGui::SameLine();
		ImGui::LabelText("l0", "three");
		ImGui::PopItemWidth();
	}

	if (ImGui::CollapsingHeader("Child regions"))
	{
		ImGui::Text("Without border");
		static int line = 50;
		bool goto_line = ImGui::Button("Goto");
		ImGui::SameLine(); 
		ImGui::PushItemWidth(100);
		ImGui::InputInt("##Line", &line, 0); 
		ImGui::PopItemWidth();
		ImGui::BeginChild("Sub1", ImVec2(ImGui::GetWindowWidth()*0.5f,300));
		for (int i = 0; i < 100; i++)
		{
			ImGui::Text("%04d: scrollable region", i);
			if (goto_line && line == i)
				ImGui::SetScrollPosHere();
		}
		if (goto_line && line >= 100)
			ImGui::SetScrollPosHere();
		ImGui::EndChild();

		ImGui::SameLine();

		ImGui::BeginChild("Sub2", ImVec2(0,300), true);
		ImGui::Text("With border");
		ImGui::Columns(2);
		for (int i = 0; i < 100; i++)
		{
			char buf[32];
			ImFormatString(buf, IM_ARRAYSIZE(buf), "%08x", i*5731);
			ImGui::Button(buf);
			ImGui::NextColumn();
		}
		ImGui::EndChild();
	}

	if (ImGui::CollapsingHeader("Columns"))
	{
		ImGui::Columns(4, "data", true);
		ImGui::Text("ID"); ImGui::NextColumn();
		ImGui::Text("Name"); ImGui::NextColumn();
		ImGui::Text("Path"); ImGui::NextColumn();
		ImGui::Text("Flags"); ImGui::NextColumn();
		ImGui::Separator();

		ImGui::Text("0000"); ImGui::NextColumn();
		ImGui::Text("Robert"); ImGui::NextColumn();
		ImGui::Text("/path/robert"); ImGui::NextColumn();
		ImGui::Text("...."); ImGui::NextColumn();

		ImGui::Text("0001"); ImGui::NextColumn();
		ImGui::Text("Stephanie"); ImGui::NextColumn();
		ImGui::Text("/path/stephanie"); ImGui::NextColumn();
		ImGui::Text("...."); ImGui::NextColumn();

		ImGui::Text("0002"); ImGui::NextColumn();
		ImGui::Text("C64"); ImGui::NextColumn();
		ImGui::Text("/path/computer"); ImGui::NextColumn();
		ImGui::Text("...."); ImGui::NextColumn();
		ImGui::Columns(1);

		ImGui::Separator();

		ImGui::Columns(3, "mixed");
		ImGui::Text("Hello"); ImGui::NextColumn();
		ImGui::Text("World"); ImGui::NextColumn();
		ImGui::Text("Hmm..."); ImGui::NextColumn();

		ImGui::Button("Banana"); ImGui::NextColumn();
		ImGui::Button("Apple"); ImGui::NextColumn();
		ImGui::Button("Corniflower"); ImGui::NextColumn();

		static int e = 0;
		ImGui::RadioButton("radio a", &e, 0); ImGui::NextColumn();
		ImGui::RadioButton("radio b", &e, 1); ImGui::NextColumn();
		ImGui::RadioButton("radio c", &e, 2); ImGui::NextColumn();
		ImGui::Columns(1);

		ImGui::Separator();

		ImGui::Columns(2, "multiple components");
		static float foo = 1.0f;
		ImGui::InputFloat("red", &foo, 0.05f, 0, 3); ImGui::NextColumn();
		static float bar = 1.0f;
		ImGui::InputFloat("blue", &bar, 0.05f, 0, 3); ImGui::NextColumn();
		ImGui::Columns(1);

		ImGui::Separator();

		if (ImGui::TreeNode("Inside a tree.."))
		{
			if (ImGui::TreeNode("node 1 (with borders)"))
			{
				ImGui::Columns(4);
				ImGui::Text("aaa"); ImGui::NextColumn();
				ImGui::Text("bbb"); ImGui::NextColumn();
				ImGui::Text("ccc"); ImGui::NextColumn();
				ImGui::Text("ddd"); ImGui::NextColumn();
				ImGui::Text("eee"); ImGui::NextColumn();
				ImGui::Text("fff"); ImGui::NextColumn();
				ImGui::Text("ggg"); ImGui::NextColumn();
				ImGui::Text("hhh"); ImGui::NextColumn();
				ImGui::Columns(1);
				ImGui::TreePop();
			}
			if (ImGui::TreeNode("node 2 (without borders)"))
			{
				ImGui::Columns(4, NULL, false);
				ImGui::Text("aaa"); ImGui::NextColumn();
				ImGui::Text("bbb"); ImGui::NextColumn();
				ImGui::Text("ccc"); ImGui::NextColumn();
				ImGui::Text("ddd"); ImGui::NextColumn();
				ImGui::Text("eee"); ImGui::NextColumn();
				ImGui::Text("fff"); ImGui::NextColumn();
				ImGui::Text("ggg"); ImGui::NextColumn();
				ImGui::Text("hhh"); ImGui::NextColumn();
				ImGui::Columns(1);
				ImGui::TreePop();
			}
			ImGui::TreePop();
		}
	}

	if (ImGui::CollapsingHeader("Filtering"))
	{
		static ImGuiTextFilter filter;
		filter.Draw();
		const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" };
		for (size_t i = 0; i < IM_ARRAYSIZE(lines); i++)
			if (filter.PassFilter(lines[i]))
				ImGui::BulletText("%s", lines[i]);
	}

	if (ImGui::CollapsingHeader("Long text"))
	{
		static ImGuiTextBuffer log;
		static int lines = 0;
		ImGui::Text("Printing unusually long amount of text.");
		ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size());
		if (ImGui::Button("Clear")) { log.clear(); lines = 0; }
		ImGui::SameLine();
		if (ImGui::Button("Add 1000 lines"))
		{
			for (size_t i = 0; i < 1000; i++)
				log.append("%i The quick brown fox jumps over the lazy dog\n", lines+i);
			lines += 1000;
		}
		ImGui::BeginChild("Log");
		ImGui::TextUnformatted(log.begin(), log.end());
		ImGui::EndChild();
	}

	ImGui::End();
}
// End of Sample code

}; // namespace ImGui

//-----------------------------------------------------------------------------
// Font data
// Bitmap exported from proggy_clean.fon (c) by Tristan Grimmer http://www.proggyfonts.net
//-----------------------------------------------------------------------------
/*
// Copyright (c) 2004, 2005 Tristan Grimmer

// Permission is hereby granted, free of charge, to any person obtaining a copy 
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
// copies of the Software, and to permit persons to whom the Software is 
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all 
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
// SOFTWARE.
*/
//-----------------------------------------------------------------------------
// Exported with bmfont (www.angelcode.com/products/bmfont), size 13, no anti-aliasing
// We are using bmfont format and you can load your own font from a file by setting up ImGui::GetIO().Font
// PNG reduced in size with pngout.exe
// Manually converted to C++ array using the following program:
/*
static void binary_to_c(const char* name_in, const char* symbol)
{
	FILE* fi = fopen(name_in, "rb"); fseek(fi, 0, SEEK_END); long sz = ftell(fi); fseek(fi, 0, SEEK_SET);
	fprintf(stdout, "static const unsigned int %s_size = %d;\n", symbol, sz);
	fprintf(stdout, "static const unsigned int %s_data[%d/4] =\n{", symbol, ((sz+3)/4)*4);
	int column = 0;
	for (unsigned int data = 0; fread(&data, 1, 4, fi); data = 0)
		if ((column++ % 12) == 0)
			fprintf(stdout, "\n    0x%08x, ", data);
		else
			fprintf(stdout, "0x%08x, ", data);
	fprintf(stdout, "\n};\n\n");
	fclose(fi);
}

int main(int argc, char** argv)
{
	binary_to_c("proggy_clean_13.fnt", "proggy_clean_13_fnt");
	binary_to_c("proggy_clean_13.png", "proggy_clean_13_png");
	return 1;
}
*/
//-----------------------------------------------------------------------------

static const unsigned int proggy_clean_13_png_size = 1557;
static const unsigned int proggy_clean_13_png_data[1560/4] =
{
    0x474e5089, 0x0a1a0a0d, 0x0d000000, 0x52444849, 0x00010000, 0x80000000, 0x00000308, 0x476bd300, 0x00000038, 0x544c5006, 0x00000045, 0xa5ffffff, 
    0x00dd9fd9, 0x74010000, 0x00534e52, 0x66d8e640, 0xbd050000, 0x54414449, 0x9bed5e78, 0x30e36e51, 0xeef5440c, 0x31fde97f, 0x584ec0f0, 0x681ace39, 
    0xca120e6b, 0x1c5a28a6, 0xc5d98a89, 0x1a3d602e, 0x323c0043, 0xf6bc9e68, 0xbe3ad62c, 0x3d60260f, 0x82d60096, 0xe0bfc707, 0xfb9bf1d1, 0xbf0267ac, 
    0x1600260f, 0x061229c0, 0x0000c183, 0x37162c58, 0xdfa088fc, 0xde7d5704, 0x77fcbb80, 0x48e5c3f1, 0x73d8b8f8, 0xc4af7802, 0x1ca111ad, 0x0001ed7a, 
    0x76eda3ef, 0xb78d3e00, 0x801c7203, 0x0215c0b1, 0x0410b044, 0xa85100d4, 0x07627ec7, 0x0cf83fa8, 0x94001a22, 0xf87347f1, 0xdcb5cfc1, 0x1c3880cc, 
    0xd4e034ca, 0xfa928d9d, 0xb0167e31, 0x325cc570, 0x4bbd584b, 0xbd4e6574, 0x70bae084, 0xf0c0008a, 0x3f601ddb, 0x0bba506a, 0xa58a0082, 0x5b46946e, 
    0x720a4ccd, 0xdfaaed39, 0x25dc8042, 0x7ee403f4, 0x2ad69cc9, 0x6c4b3009, 0x429037ed, 0x0293f875, 0x1a69dced, 0xab120198, 0x61c01d88, 0xcf2e43dc, 
    0xfc3c00ef, 0xc049a270, 0xdbbea582, 0x0d592601, 0xc3c9a8dd, 0x5013d143, 0x19a47bbb, 0xf89253dd, 0x0a9901dc, 0x38900ecd, 0xb2dec9d7, 0xc2b91230, 
    0xb8e0106f, 0x976404cb, 0x5d83c3f3, 0x6e8086fd, 0x5c9ab007, 0xf50354f6, 0xe7e72002, 0x4bc870ca, 0xab49736f, 0xc137c6e0, 0xa9aa6ff3, 0xbff84f2f, 
    0x673e6e20, 0xf6e3c7e0, 0x618fe05a, 0x39ca2a00, 0x93ca03b4, 0x3a9d2728, 0xbbebba41, 0xce0e3681, 0x6e29ec05, 0x111eca83, 0xfdfe7ec1, 0xa7c8a75b, 
    0xac6bc3ab, 0x72a5bc25, 0x9f612c1c, 0x378ec05e, 0x7202b157, 0x789e5a82, 0x5256bc0e, 0xcb900996, 0x10721105, 0x00823ce0, 0x69ab59fb, 0x39c72084, 
    0xf5e37b25, 0xd1794700, 0x538d0637, 0x9a2bff4f, 0xce0d43a4, 0xa6da7ed2, 0xd7095132, 0xf5ad6232, 0x9aaa8e9c, 0xd8d1d3ed, 0x058940a1, 0x21f00d64, 
    0x89a5c9de, 0x021b3f24, 0x77a97aac, 0x714be65a, 0x5e2d57ae, 0x27e3610f, 0x28809288, 0x36b9559f, 0xd00e347a, 0x0094e385, 0x565d034d, 0x7f52d5f2, 
    0x9aea81de, 0x5e804909, 0x010d7f0a, 0x8f0d3fb1, 0xbbce23bc, 0x375e85ac, 0x01fa03b9, 0xc0526c3a, 0xf7866870, 0x9d46d804, 0x158ebf64, 0x7bd534c5, 
    0xd80cf202, 0x410ee80f, 0x79419915, 0x74a844ae, 0x94119881, 0xcbbcc0fc, 0xa263d471, 0x013d0269, 0x67f6a0f8, 0x3e4474d0, 0xd1e50cb5, 0x56fd0e60, 
    0xc4c0fd4c, 0x940629ff, 0xe18a7a16, 0xcca0330f, 0xb8ed50b7, 0x6935778b, 0x3735c791, 0x3909eb94, 0x0be36620, 0x0ac0d7aa, 0xefe942c9, 0xf0092727, 
    0x5c020ee2, 0x0246da53, 0xa24be8bc, 0xa891ab94, 0xd012c7e2, 0x9c115954, 0xde0dac8e, 0x555dc022, 0x59e84f77, 0xbed2cf80, 0xe9af2cda, 0x4b600716, 
    0x8955bd80, 0x7098c3f3, 0x25a8466a, 0x4ddbf26a, 0x5f554753, 0xf4890f28, 0x886a27ab, 0x54a00413, 0x0a157ca9, 0x52909a80, 0x7122a312, 0x0024a75c, 
    0xe6d72935, 0xecde29cf, 0x025de009, 0x7995a6aa, 0x4a180491, 0x013df0d8, 0xe009edba, 0xd40019dc, 0x45b36b2a, 0x0122eb0d, 0x6e80a79f, 0x746590f5, 
    0xd1a6dd49, 0xc05954b6, 0x83d4b957, 0xa00fe5b1, 0x59695ad7, 0xcff8433d, 0x44a0f340, 0xdd226c73, 0x5537f08c, 0xe1e89c32, 0x431056af, 0x233eb000, 
    0x60773f40, 0xed7e490a, 0xc160091f, 0x12829db5, 0x43fbe6cf, 0x0a6b26c2, 0xd5f0f35a, 0xfc09fda8, 0x73525f8c, 0x2ea38cf9, 0x32bc410b, 0x94a60a22, 
    0x1f62a42b, 0x5f290034, 0x07beaa91, 0x1e8ccb40, 0x17d6b0f9, 0xa2a017c9, 0x4c79a610, 0xa1de6525, 0xe975029f, 0xe063585f, 0x6246cfbb, 0x04acad44, 
    0xe6a05138, 0xd03d8434, 0xc9950013, 0x5d4c809e, 0xfd26932d, 0x739213ac, 0xe260d8ef, 0xe4164617, 0x16fc60aa, 0x1d0b21e7, 0x445004b4, 0x13fd1b59, 
    0x56b0f804, 0xaa936a3a, 0x335459c1, 0xb37f8caa, 0x06b68e03, 0x14d5eb01, 0x8300c78c, 0x9674792a, 0x20ba791b, 0x4d88024d, 0xef747354, 0x451e673e, 
    0xc4dafc9a, 0xe53b9cd1, 0x32b4011a, 0x3d702c0f, 0x09bc0b40, 0x220d277d, 0x47eb7809, 0x8a946500, 0x7a28c4bd, 0x96e00f99, 0xc04365da, 0x05edcf46, 
    0x7dee2c27, 0xe6020b7f, 0x159ecedf, 0xcbdb00ff, 0x516bb9e3, 0xd0716161, 0xeba75956, 0xf17fc22b, 0x5c578beb, 0xfe474a09, 0xc1750a87, 0xe384c189, 
    0x5df54e26, 0xa6f76b79, 0xd4b172be, 0x3e8d5ceb, 0x832d90ec, 0x180368e7, 0x354c724d, 0x1a8b1412, 0x8de07be9, 0xaf009efe, 0x4616c621, 0x2860eb01, 
    0x244f1404, 0xc3de724b, 0x6497a802, 0xab2f4419, 0x4e02910d, 0xe3ecf410, 0x7a6404a8, 0x8c72b112, 0xde5bc706, 0xd4f8ffe9, 0x50176344, 0x7b49fe7d, 
    0x02c1d88c, 0x25634a40, 0x194804f7, 0x03b76d84, 0x392bde58, 0xdeebad27, 0xc160c021, 0xa97a72db, 0xa8040b83, 0x78804f3e, 0x046b9433, 0x178cc824, 
    0x62800897, 0x7010370b, 0x21cfe7e4, 0x8053ec40, 0xf9d60526, 0xae9d353f, 0x069b40c7, 0x80496f14, 0x57e682b3, 0x6e0273e0, 0x974e2e28, 0x60ab7c3d, 
    0x2025ba33, 0x507b3a8c, 0x12b70173, 0xd095c400, 0xee012d96, 0x6e194c9a, 0xe5933f89, 0x43b70102, 0xf30306aa, 0xc5802189, 0x53c077c3, 0x86029009, 
    0xa0c1e780, 0xa4c04c1f, 0x93dbd580, 0xf8149809, 0x06021893, 0x3060c183, 0x83060c18, 0x183060c1, 0xc183060c, 0x0c183060, 0x60c18306, 0xfe0c1830, 
    0x0cb69501, 0x7a40d9df, 0x000000dd, 0x4e454900, 0x6042ae44, 0x00000082, 
};

static const unsigned int proggy_clean_13_fnt_size = 4647;
static const unsigned int proggy_clean_13_fnt_data[4648/4] =
{
    0x03464d42, 0x00001a01, 0x40000d00, 0x01006400, 0x00000000, 0x50000101, 0x67676f72, 0x656c4379, 0x02006e61, 0x0000000f, 0x000a000d, 0x00800100, 
    0x01000001, 0x03000000, 0x00000016, 0x676f7270, 0x635f7967, 0x6e61656c, 0x5f33315f, 0x6e702e30, 0xd0040067, 0x00000011, 0x2e000000, 0x07000e00, 
    0x00000d00, 0x07000000, 0x010f0000, 0x36000000, 0x05003800, 0x01000d00, 0x07000000, 0x020f0000, 0x86000000, 0x07000e00, 0x00000d00, 0x07000000, 
    0x030f0000, 0x07000000, 0x06001c00, 0x01000d00, 0x07000000, 0x040f0000, 0x15000000, 0x06001c00, 0x01000d00, 0x07000000, 0x050f0000, 0x23000000, 
    0x06001c00, 0x01000d00, 0x07000000, 0x060f0000, 0x31000000, 0x06001c00, 0x01000d00, 0x07000000, 0x070f0000, 0xfc000000, 0x03003800, 0x02000d00, 
    0x07000000, 0x080f0000, 0x54000000, 0x05003800, 0x01000d00, 0x07000000, 0x090f0000, 0x4d000000, 0x06001c00, 0x01000d00, 0x07000000, 0x0a0f0000, 
    0xa8000000, 0x06001c00, 0x01000d00, 0x07000000, 0x0b0f0000, 0x6a000000, 0x04004600, 0x00000d00, 0x07000000, 0x0c0f0000, 0x74000000, 0x04004600, 
    0x00000d00, 0x07000000, 0x0d0f0000, 0x88000000, 0x04004600, 0x03000d00, 0x07000000, 0x0e0f0000, 0x65000000, 0x04004600, 0x03000d00, 0x07000000, 
    0x0f0f0000, 0x36000000, 0x07000e00, 0x00000d00, 0x07000000, 0x100f0000, 0x5a000000, 0x05003800, 0x00000d00, 0x07000000, 0x110f0000, 0x60000000, 
    0x05003800, 0x00000d00, 0x07000000, 0x120f0000, 0xe4000000, 0x03004600, 0x01000d00, 0x07000000, 0x130f0000, 0xe0000000, 0x03004600, 0x01000d00, 
    0x07000000, 0x140f0000, 0x66000000, 0x05003800, 0x00000d00, 0x07000000, 0x150f0000, 0x6c000000, 0x05003800, 0x00000d00, 0x07000000, 0x160f0000, 
    0x72000000, 0x05003800, 0x00000d00, 0x07000000, 0x170f0000, 0xd8000000, 0x03004600, 0x00000d00, 0x07000000, 0x180f0000, 0xcc000000, 0x03004600, 
    0x01000d00, 0x07000000, 0x190f0000, 0xc8000000, 0x03004600, 0x02000d00, 0x07000000, 0x1a0f0000, 0x78000000, 0x05003800, 0x00000d00, 0x07000000, 
    0x1b0f0000, 0x84000000, 0x05003800, 0x00000d00, 0x07000000, 0x1c0f0000, 0x00000000, 0x15000000, 0xf9000d00, 0x070000ff, 0x1d0f0000, 0xb0000000, 
    0x15000000, 0xf9000d00, 0x070000ff, 0x1e0f0000, 0x2c000000, 0x15000000, 0xf9000d00, 0x070000ff, 0x200f0000, 0x9a000000, 0x15000000, 0xf9000d00, 
    0x070000ff, 0x210f0000, 0x0c000000, 0x01005400, 0x03000d00, 0x07000000, 0x220f0000, 0xbc000000, 0x03004600, 0x02000d00, 0x07000000, 0x230f0000, 
    0x4e000000, 0x07000e00, 0x00000d00, 0x07000000, 0x240f0000, 0x8a000000, 0x05003800, 0x01000d00, 0x07000000, 0x250f0000, 0xa6000000, 0x07000e00, 
    0x00000d00, 0x07000000, 0x260f0000, 0xf4000000, 0x06000e00, 0x01000d00, 0x07000000, 0x270f0000, 0x06000000, 0x01005400, 0x03000d00, 0x07000000, 
    0x280f0000, 0xb8000000, 0x03004600, 0x02000d00, 0x07000000, 0x290f0000, 0xb4000000, 0x03004600, 0x02000d00, 0x07000000, 0x2a0f0000, 0x90000000, 
    0x05003800, 0x01000d00, 0x07000000, 0x2b0f0000, 0x96000000, 0x05003800, 0x01000d00, 0x07000000, 0x2c0f0000, 0xe8000000, 0x02004600, 0x01000d00, 
    0x07000000, 0x2d0f0000, 0x9c000000, 0x05003800, 0x01000d00, 0x07000000, 0x2e0f0000, 0x04000000, 0x01005400, 0x02000d00, 0x07000000, 0x2f0f0000, 
    0xa2000000, 0x05003800, 0x01000d00, 0x07000000, 0x300f0000, 0xae000000, 0x05003800, 0x01000d00, 0x07000000, 0x310f0000, 0xd8000000, 0x05003800, 
    0x01000d00, 0x07000000, 0x320f0000, 0xfa000000, 0x05000000, 0x01000d00, 0x07000000, 0x330f0000, 0x31000000, 0x05002a00, 0x01000d00, 0x07000000, 
    0x340f0000, 0x3f000000, 0x06001c00, 0x01000d00, 0x07000000, 0x350f0000, 0x37000000, 0x05002a00, 0x01000d00, 0x07000000, 0x360f0000, 0x3d000000, 
    0x05002a00, 0x01000d00, 0x07000000, 0x370f0000, 0x43000000, 0x05002a00, 0x01000d00, 0x07000000, 0x380f0000, 0x49000000, 0x05002a00, 0x01000d00, 
    0x07000000, 0x390f0000, 0x4f000000, 0x05002a00, 0x01000d00, 0x07000000, 0x3a0f0000, 0x02000000, 0x01005400, 0x03000d00, 0x07000000, 0x3b0f0000, 
    0xfa000000, 0x02004600, 0x01000d00, 0x07000000, 0x3c0f0000, 0x77000000, 0x06001c00, 0x00000d00, 0x07000000, 0x3d0f0000, 0x7e000000, 0x06001c00, 
    0x01000d00, 0x07000000, 0x3e0f0000, 0x85000000, 0x06001c00, 0x01000d00, 0x07000000, 0x3f0f0000, 0x55000000, 0x05002a00, 0x01000d00, 0x07000000, 
    0x400f0000, 0xae000000, 0x07000e00, 0x00000d00, 0x07000000, 0x410f0000, 0xe0000000, 0x06001c00, 0x01000d00, 0x07000000, 0x420f0000, 0xa1000000, 
    0x06001c00, 0x01000d00, 0x07000000, 0x430f0000, 0x5b000000, 0x05002a00, 0x01000d00, 0x07000000, 0x440f0000, 0xaf000000, 0x06001c00, 0x01000d00, 
    0x07000000, 0x450f0000, 0x61000000, 0x05002a00, 0x01000d00, 0x07000000, 0x460f0000, 0x67000000, 0x05002a00, 0x01000d00, 0x07000000, 0x470f0000, 
    0x38000000, 0x06001c00, 0x01000d00, 0x07000000, 0x480f0000, 0x8c000000, 0x06001c00, 0x01000d00, 0x07000000, 0x490f0000, 0xa0000000, 0x03004600, 
    0x02000d00, 0x07000000, 0x4a0f0000, 0x97000000, 0x04004600, 0x01000d00, 0x07000000, 0x4b0f0000, 0xb6000000, 0x06001c00, 0x01000d00, 0x07000000, 
    0x4c0f0000, 0x6d000000, 0x05002a00, 0x01000d00, 0x07000000, 0x4d0f0000, 0x1e000000, 0x07000e00, 0x00000d00, 0x07000000, 0x4e0f0000, 0x23000000, 
    0x06002a00, 0x01000d00, 0x07000000, 0x4f0f0000, 0xed000000, 0x06000e00, 0x01000d00, 0x07000000, 0x500f0000, 0x73000000, 0x05002a00, 0x01000d00, 
    0x07000000, 0x510f0000, 0x00000000, 0x06001c00, 0x01000d00, 0x07000000, 0x520f0000, 0x0e000000, 0x06001c00, 0x01000d00, 0x07000000, 0x530f0000, 
    0x1c000000, 0x06001c00, 0x01000d00, 0x07000000, 0x540f0000, 0x66000000, 0x07000e00, 0x00000d00, 0x07000000, 0x550f0000, 0x2a000000, 0x06001c00, 
    0x01000d00, 0x07000000, 0x560f0000, 0x6e000000, 0x07000e00, 0x00000d00, 0x07000000, 0x570f0000, 0x76000000, 0x07000e00, 0x00000d00, 0x07000000, 
    0x580f0000, 0x46000000, 0x06001c00, 0x01000d00, 0x07000000, 0x590f0000, 0x7e000000, 0x07000e00, 0x00000d00, 0x07000000, 0x5a0f0000, 0x54000000, 
    0x06001c00, 0x01000d00, 0x07000000, 0x5b0f0000, 0x9c000000, 0x03004600, 0x02000d00, 0x07000000, 0x5c0f0000, 0x79000000, 0x05002a00, 0x01000d00, 
    0x07000000, 0x5d0f0000, 0xdc000000, 0x03004600, 0x02000d00, 0x07000000, 0x5e0f0000, 0x7f000000, 0x05002a00, 0x01000d00, 0x07000000, 0x5f0f0000, 
    0xc6000000, 0x07000e00, 0x00000d00, 0x07000000, 0x600f0000, 0xfd000000, 0x02004600, 0x02000d00, 0x07000000, 0x610f0000, 0x85000000, 0x05002a00, 
    0x01000d00, 0x07000000, 0x620f0000, 0x8b000000, 0x05002a00, 0x01000d00, 0x07000000, 0x630f0000, 0x91000000, 0x05002a00, 0x01000d00, 0x07000000, 
    0x640f0000, 0x97000000, 0x05002a00, 0x01000d00, 0x07000000, 0x650f0000, 0x9d000000, 0x05002a00, 0x01000d00, 0x07000000, 0x660f0000, 0xa3000000, 
    0x05002a00, 0x01000d00, 0x07000000, 0x670f0000, 0xa9000000, 0x05002a00, 0x01000d00, 0x07000000, 0x680f0000, 0xaf000000, 0x05002a00, 0x01000d00, 
    0x07000000, 0x690f0000, 0xee000000, 0x02004600, 0x02000d00, 0x07000000, 0x6a0f0000, 0x92000000, 0x04004600, 0x01000d00, 0x07000000, 0x6b0f0000, 
    0xb5000000, 0x05002a00, 0x01000d00, 0x07000000, 0x6c0f0000, 0xfd000000, 0x02002a00, 0x02000d00, 0x07000000, 0x6d0f0000, 0x8e000000, 0x07000e00, 
    0x00000d00, 0x07000000, 0x6e0f0000, 0xbb000000, 0x05002a00, 0x01000d00, 0x07000000, 0x6f0f0000, 0xc1000000, 0x05002a00, 0x01000d00, 0x07000000, 
    0x700f0000, 0xc7000000, 0x05002a00, 0x01000d00, 0x07000000, 0x710f0000, 0xcd000000, 0x05002a00, 0x01000d00, 0x07000000, 0x720f0000, 0xd3000000, 
    0x05002a00, 0x01000d00, 0x07000000, 0x730f0000, 0xd9000000, 0x05002a00, 0x01000d00, 0x07000000, 0x740f0000, 0x7e000000, 0x04004600, 0x02000d00, 
    0x07000000, 0x750f0000, 0xdf000000, 0x05002a00, 0x01000d00, 0x07000000, 0x760f0000, 0xe5000000, 0x05002a00, 0x01000d00, 0x07000000, 0x770f0000, 
    0xbe000000, 0x07000e00, 0x00000d00, 0x07000000, 0x780f0000, 0xeb000000, 0x05002a00, 0x01000d00, 0x07000000, 0x790f0000, 0xf1000000, 0x05002a00, 
    0x01000d00, 0x07000000, 0x7a0f0000, 0xf7000000, 0x05002a00, 0x01000d00, 0x07000000, 0x7b0f0000, 0x00000000, 0x05003800, 0x01000d00, 0x07000000, 
    0x7c0f0000, 0x00000000, 0x01005400, 0x03000d00, 0x07000000, 0x7d0f0000, 0x06000000, 0x05003800, 0x01000d00, 0x07000000, 0x7e0f0000, 0x16000000, 
    0x07000e00, 0x00000d00, 0x07000000, 0x7f0f0000, 0x58000000, 0x15000000, 0xf9000d00, 0x070000ff, 0x810f0000, 0x16000000, 0x15000000, 0xf9000d00, 
    0x070000ff, 0x8d0f0000, 0x00000000, 0x15000e00, 0xf9000d00, 0x070000ff, 0x8f0f0000, 0xc6000000, 0x15000000, 0xf9000d00, 0x070000ff, 0x900f0000, 
    0x6e000000, 0x15000000, 0xf9000d00, 0x070000ff, 0x9d0f0000, 0x84000000, 0x15000000, 0xf9000d00, 0x070000ff, 0xa00f0000, 0xdc000000, 0x15000000, 
    0xf9000d00, 0x070000ff, 0xa10f0000, 0x0a000000, 0x01005400, 0x03000d00, 0x07000000, 0xa20f0000, 0x0c000000, 0x05003800, 0x01000d00, 0x07000000, 
    0xa30f0000, 0x12000000, 0x05003800, 0x01000d00, 0x07000000, 0xa40f0000, 0x96000000, 0x07000e00, 0x00000d00, 0x07000000, 0xa50f0000, 0x5e000000, 
    0x07000e00, 0x00000d00, 0x07000000, 0xa60f0000, 0x08000000, 0x01005400, 0x03000d00, 0x07000000, 0xa70f0000, 0x18000000, 0x05003800, 0x01000d00, 
    0x07000000, 0xa80f0000, 0xac000000, 0x03004600, 0x02000d00, 0x07000000, 0xa90f0000, 0x56000000, 0x07000e00, 0x00000d00, 0x07000000, 0xaa0f0000, 
    0x8d000000, 0x04004600, 0x01000d00, 0x07000000, 0xab0f0000, 0x1e000000, 0x05003800, 0x01000d00, 0x07000000, 0xac0f0000, 0xfb000000, 0x04000e00, 
    0x01000d00, 0x07000000, 0xad0f0000, 0x42000000, 0x15000000, 0xf9000d00, 0x070000ff, 0xae0f0000, 0x3e000000, 0x07000e00, 0x00000d00, 0x07000000, 
    0xaf0f0000, 0x26000000, 0x07000e00, 0x00000d00, 0x07000000, 0xb00f0000, 0x6f000000, 0x04004600, 0x01000d00, 0x07000000, 0xb10f0000, 0x24000000, 
    0x05003800, 0x01000d00, 0x07000000, 0xb20f0000, 0x79000000, 0x04004600, 0x01000d00, 0x07000000, 0xb30f0000, 0x83000000, 0x04004600, 0x01000d00, 
    0x07000000, 0xb40f0000, 0xeb000000, 0x02004600, 0x03000d00, 0x07000000, 0xb50f0000, 0x46000000, 0x07000e00, 0x00000d00, 0x07000000, 0xb60f0000, 
    0xe6000000, 0x06000e00, 0x01000d00, 0x07000000, 0xb70f0000, 0xc0000000, 0x03004600, 0x02000d00, 0x07000000, 0xb80f0000, 0xf7000000, 0x02004600, 
    0x03000d00, 0x07000000, 0xb90f0000, 0xc4000000, 0x03004600, 0x01000d00, 0x07000000, 0xba0f0000, 0x60000000, 0x04004600, 0x01000d00, 0x07000000, 
    0xbb0f0000, 0x2a000000, 0x05003800, 0x01000d00, 0x07000000, 0xbc0f0000, 0x1c000000, 0x06002a00, 0x01000d00, 0x07000000, 0xbd0f0000, 0xc4000000, 
    0x06001c00, 0x01000d00, 0x07000000, 0xbe0f0000, 0x9e000000, 0x07000e00, 0x00000d00, 0x07000000, 0xbf0f0000, 0x30000000, 0x05003800, 0x01000d00, 
    0x07000000, 0xc00f0000, 0x9a000000, 0x06001c00, 0x01000d00, 0x07000000, 0xc10f0000, 0x93000000, 0x06001c00, 0x01000d00, 0x07000000, 0xc20f0000, 
    0x70000000, 0x06001c00, 0x01000d00, 0x07000000, 0xc30f0000, 0x69000000, 0x06001c00, 0x01000d00, 0x07000000, 0xc40f0000, 0x62000000, 0x06001c00, 
    0x01000d00, 0x07000000, 0xc50f0000, 0x5b000000, 0x06001c00, 0x01000d00, 0x07000000, 0xc60f0000, 0xf2000000, 0x07000000, 0x00000d00, 0x07000000, 
    0xc70f0000, 0xbd000000, 0x06001c00, 0x01000d00, 0x07000000, 0xc80f0000, 0x3c000000, 0x05003800, 0x01000d00, 0x07000000, 0xc90f0000, 0x42000000, 
    0x05003800, 0x01000d00, 0x07000000, 0xca0f0000, 0x48000000, 0x05003800, 0x01000d00, 0x07000000, 0xcb0f0000, 0x4e000000, 0x05003800, 0x01000d00, 
    0x07000000, 0xcc0f0000, 0xa4000000, 0x03004600, 0x02000d00, 0x07000000, 0xcd0f0000, 0xb0000000, 0x03004600, 0x02000d00, 0x07000000, 0xce0f0000, 
    0xa8000000, 0x03004600, 0x02000d00, 0x07000000, 0xcf0f0000, 0xfc000000, 0x03001c00, 0x02000d00, 0x07000000, 0xd00f0000, 0xce000000, 0x07000e00, 
    0x00000d00, 0x07000000, 0xd10f0000, 0xcb000000, 0x06001c00, 0x01000d00, 0x07000000, 0xd20f0000, 0xd2000000, 0x06001c00, 0x01000d00, 0x07000000, 
    0xd30f0000, 0xd9000000, 0x06001c00, 0x01000d00, 0x07000000, 0xd40f0000, 0x2a000000, 0x06002a00, 0x01000d00, 0x07000000, 0xd50f0000, 0xe7000000, 
    0x06001c00, 0x01000d00, 0x07000000, 0xd60f0000, 0xee000000, 0x06001c00, 0x01000d00, 0x07000000, 0xd70f0000, 0x7e000000, 0x05003800, 0x01000d00, 
    0x07000000, 0xd80f0000, 0xf5000000, 0x06001c00, 0x01000d00, 0x07000000, 0xd90f0000, 0x00000000, 0x06002a00, 0x01000d00, 0x07000000, 0xda0f0000, 
    0x07000000, 0x06002a00, 0x01000d00, 0x07000000, 0xdb0f0000, 0x0e000000, 0x06002a00, 0x01000d00, 0x07000000, 0xdc0f0000, 0x15000000, 0x06002a00, 
    0x01000d00, 0x07000000, 0xdd0f0000, 0xd6000000, 0x07000e00, 0x00000d00, 0x07000000, 0xde0f0000, 0xa8000000, 0x05003800, 0x01000d00, 0x07000000, 
    0xdf0f0000, 0xde000000, 0x07000e00, 0x00000d00, 0x07000000, 0xe00f0000, 0xb4000000, 0x05003800, 0x01000d00, 0x07000000, 0xe10f0000, 0xba000000, 
    0x05003800, 0x01000d00, 0x07000000, 0xe20f0000, 0xc0000000, 0x05003800, 0x01000d00, 0x07000000, 0xe30f0000, 0xc6000000, 0x05003800, 0x01000d00, 
    0x07000000, 0xe40f0000, 0xcc000000, 0x05003800, 0x01000d00, 0x07000000, 0xe50f0000, 0xd2000000, 0x05003800, 0x01000d00, 0x07000000, 0xe60f0000, 
    0xb6000000, 0x07000e00, 0x00000d00, 0x07000000, 0xe70f0000, 0xde000000, 0x05003800, 0x01000d00, 0x07000000, 0xe80f0000, 0xe4000000, 0x05003800, 
    0x01000d00, 0x07000000, 0xe90f0000, 0xea000000, 0x05003800, 0x01000d00, 0x07000000, 0xea0f0000, 0xf0000000, 0x05003800, 0x01000d00, 0x07000000, 
    0xeb0f0000, 0xf6000000, 0x05003800, 0x01000d00, 0x07000000, 0xec0f0000, 0xf1000000, 0x02004600, 0x02000d00, 0x07000000, 0xed0f0000, 0xf4000000, 
    0x02004600, 0x02000d00, 0x07000000, 0xee0f0000, 0xd0000000, 0x03004600, 0x02000d00, 0x07000000, 0xef0f0000, 0xd4000000, 0x03004600, 0x02000d00, 
    0x07000000, 0xf00f0000, 0x00000000, 0x05004600, 0x01000d00, 0x07000000, 0xf10f0000, 0x06000000, 0x05004600, 0x01000d00, 0x07000000, 0xf20f0000, 
    0x0c000000, 0x05004600, 0x01000d00, 0x07000000, 0xf30f0000, 0x12000000, 0x05004600, 0x01000d00, 0x07000000, 0xf40f0000, 0x18000000, 0x05004600, 
    0x01000d00, 0x07000000, 0xf50f0000, 0x1e000000, 0x05004600, 0x01000d00, 0x07000000, 0xf60f0000, 0x24000000, 0x05004600, 0x01000d00, 0x07000000, 
    0xf70f0000, 0x2a000000, 0x05004600, 0x01000d00, 0x07000000, 0xf80f0000, 0x30000000, 0x05004600, 0x01000d00, 0x07000000, 0xf90f0000, 0x36000000, 
    0x05004600, 0x01000d00, 0x07000000, 0xfa0f0000, 0x3c000000, 0x05004600, 0x01000d00, 0x07000000, 0xfb0f0000, 0x42000000, 0x05004600, 0x01000d00, 
    0x07000000, 0xfc0f0000, 0x48000000, 0x05004600, 0x01000d00, 0x07000000, 0xfd0f0000, 0x4e000000, 0x05004600, 0x01000d00, 0x07000000, 0xfe0f0000, 
    0x54000000, 0x05004600, 0x01000d00, 0x07000000, 0xff0f0000, 0x5a000000, 0x05004600, 0x01000d00, 0x07000000, 0x000f0000, 
};

namespace ImGui
{

void GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size)
{
	if (fnt_data) *fnt_data = (const void*)proggy_clean_13_fnt_data;
	if (fnt_size) *fnt_size = proggy_clean_13_fnt_size;
	if (png_data) *png_data = (const void*)proggy_clean_13_png_data;
	if (png_size) *png_size = proggy_clean_13_png_size;
}

};

//-----------------------------------------------------------------------------
