// 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
 - window/style: add global alpha modifier (not just "fill_alpha")
 - 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.
 - input number: optional range min/max
 - input number: holding [-]/[+] buttons should increase the step non-linearly
 - input number: rename Input*() to Input(), Slider*() to Slider() ?
 - layout: clean up the InputFloat3/SliderFloat3/ColorEdit4 horrible layout code. item width should include frame padding, then we can have a generic horizontal layout helper.
 - add input4 helper (once above layout helpers are in they'll be smaller)
 - 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: add a stride parameter?
 - 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)
 - keyboard: full keyboard navigation and focus
 - misc: not thread-safe
 - 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: 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 = NULL, bool* out_held = NULL, 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* 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()
{
	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
	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;
	WindowRounding			= 10.0f;
	TreeNodeSpacing			= 22.0f;
	ColumnsMinSpacing		= 6.0f;				// Minimum space between two columns
	ScrollBarWidth			= 16.0f;

	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.60f, 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;
	bool					Collapsed;
	bool					Accessed;
	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 *= a; 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;
	Collapsed = 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];
		IM_ASSERT(child->Visible);	// Shouldn't be in this list if we are not active this frame
		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* ini = g.Settings[i];
		fprintf(f, "[%s]\n", ini->Name);
		fprintf(f, "Pos=%d,%d\n", (int)ini->Pos.x, (int)ini->Pos.y);
		fprintf(f, "Size=%d,%d\n", (int)ini->Size.x, (int)ini->Size.y);
		fprintf(f, "Collapsed=%d\n", ini->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;

				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
			window->NextScrollY -= g.IO.MouseWheel * window->FontSize() * 5.0f;
		}
	}

	// 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++)
		g.Windows[i]->Visible = false;

	// Create implicit window
	// We will only render it if the user has added something to it.
	IM_ASSERT(g.CurrentWindowStack.empty());	// No window should be open at the beginning of the frame!
	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];
			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
		// When 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));
	}

	// 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)
			continue;
		if (window->Flags & ImGuiWindowFlags_ChildWindow)
			continue;
		window->AddToRenderList();
	}

	// Render tooltip
	if (g.Tooltip[0])
	{
		// Use a dummy window to render the tooltip
		ImGui::Begin("##Tooltip", NULL, ImVec2(0,0), 0.0f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_Tooltip);
		ImGuiWindow* window = GetCurrentWindow();
		//window->DrawList->Clear();
		ImGui::PushClipRect(ImVec4(-9999,-9999,+9999,+9999), false);
		const ImVec2 text_size = CalcTextSize(g.Tooltip, NULL, false);
		const ImVec2 pos = g.IO.MousePos + ImVec2(32,16);
		const ImGuiAabb bb(pos - g.Style.FramePadding*2, pos + text_size + g.Style.FramePadding*2);
		ImGui::RenderFrame(bb.Min, bb.Max, window->Color(ImGuiCol_TooltipBg), false, g.Style.WindowRounding);
		ImGui::RenderText(pos, g.Tooltip, NULL, false);
		ImGui::PopClipRect();
		ImGui::End();
		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(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 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)
	{
		if (flags & ImGuiWindowFlags_ChildWindow)
		{
			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)
	{
		// New windows appears in front
		if (window->LastFrameDrawn < current_frame - 1)
			ImGui::FocusWindow(window);

		window->DrawList->Clear();
		window->Visible = true;
		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;
			}
		}

		// 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);
		}
		window->ItemWidthDefault = (float)(int)(window->Size.x > 0.0f ? window->Size.x * 0.65f : 250.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->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
			ImU32 resize_col = 0;
			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);
				resize_col = window->Color(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip);

				const 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.Expand(ImVec2(-3,-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);
					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);
			RenderText(window->Pos + style.FramePadding + ImVec2(window->FontSize() + style.ItemInnerSpacing.x, 0), name);
			if (open)
				ImGui::CloseWindowButton(open);
		}
	}
	else
	{
		// 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));
	}

	// Innter 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, title_bar_aabb.Max.y+0.5f, window->Aabb().Max.x-1.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;
	}

	// Return collapsed so that user can perform an early out optimisation
	return !window->Collapsed;
}

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, 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(ImVec2 pos)
{
	ImGuiWindow* window = GetCurrentWindow();
	window->Pos = 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(ImVec2 p)
{
	ImGuiWindow* window = GetCurrentWindow();
	window->DC.CursorPos = window->Pos + p;
}

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->Collapsed)
		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 TextUnformatted(const char* text, const char* text_end)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->Collapsed)
		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->Collapsed)
		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->Collapsed)
		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 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 (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->Collapsed)
		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, 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->Collapsed)
		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);

	// 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);

	// 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);
	//RenderFrame(bb.Min, bb.Max, col, false);

	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->Collapsed)
		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);
	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->Collapsed)
		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->Collapsed)
		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;
}

bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format, float power)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->Collapsed)
		return false;

	const ImGuiStyle& style = g.Style;

	bool value_changed = false;
	ImGui::PushID(label);

	const int components = 2;
	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)));

	ImGui::PushItemWidth(w_item_one);
	value_changed |= ImGui::SliderFloat("##X", &v[0], v_min, v_max, display_format, power);
	ImGui::SameLine(0, 0);
	ImGui::PopItemWidth();
	ImGui::PushItemWidth(w_item_last);
	value_changed |= ImGui::SliderFloat("##Y", &v[1], v_min, v_max, display_format, power);
	ImGui::SameLine(0, 0);
	ImGui::PopItemWidth();

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

	ImGui::PopID();
	return value_changed;
}

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

	const ImGuiStyle& style = g.Style;

	bool value_changed = false;
	ImGui::PushID(label);

	const int components = 3;
	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)));

	ImGui::PushItemWidth(w_item_one);
	value_changed |= ImGui::SliderFloat("##X", &v[0], v_min, v_max, display_format, power);
	ImGui::SameLine(0, 0);
	value_changed |= ImGui::SliderFloat("##Y", &v[1], v_min, v_max, display_format, power);
	ImGui::SameLine(0, 0);
	ImGui::PopItemWidth();

	ImGui::PushItemWidth(w_item_last);
	value_changed |= ImGui::SliderFloat("##Z", &v[2], v_min, v_max, display_format, power);
	ImGui::SameLine(0, 0);
	ImGui::PopItemWidth();

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

	ImGui::PopID();
	return value_changed;
}

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

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)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->Collapsed)
		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++)
		{
			v_min = ImMin(v_min, values[i]);
			v_max = ImMax(v_max, values[i]);
		}
		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 = values[(v_idx + values_offset) % values_count];
		const float v1 = values[(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 = values[(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);

	while (t0 < 1.0f)
	{
		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 = values[(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)
{
	ImGui::Plot(ImGuiPlotType_Lines, label, values, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size);
}

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)
{
	ImGui::Plot(ImGuiPlotType_Histogram, label, values, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size);
}

void Checkbox(const char* label, bool* v)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->Collapsed)
		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->Collapsed)
		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->Collapsed)
		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->Collapsed)
		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;
}

bool InputFloat2(const char* label, float v[2], int decimal_precision)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->Collapsed)
		return false;

	const ImGuiStyle& style = g.Style;

	bool value_changed = false;
	ImGui::PushID(label);

	const int components = 2;
	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)));

	ImGui::PushItemWidth(w_item_one);
	value_changed |= ImGui::InputFloat("##X", &v[0], 0, 0, decimal_precision);
	ImGui::SameLine(0, 0);
	ImGui::PopItemWidth();
	ImGui::PushItemWidth(w_item_last);
	value_changed |= ImGui::InputFloat("##Y", &v[1], 0, 0, decimal_precision);
	ImGui::SameLine(0, 0);
	ImGui::PopItemWidth();

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

	ImGui::PopID();
	return value_changed;
}

bool InputFloat3(const char* label, float v[3], int decimal_precision)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->Collapsed)
		return false;

	const ImGuiStyle& style = g.Style;

	bool value_changed = false;
	ImGui::PushID(label);

	const int components = 3;
	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)));

	ImGui::PushItemWidth(w_item_one);
	value_changed |= ImGui::InputFloat("##X", &v[0], 0, 0, decimal_precision);
	ImGui::SameLine(0, 0);
	value_changed |= ImGui::InputFloat("##Y", &v[1], 0, 0, decimal_precision);
	ImGui::SameLine(0, 0);
	ImGui::PopItemWidth();

	ImGui::PushItemWidth(w_item_last);
	value_changed |= ImGui::InputFloat("##Z", &v[2], 0, 0, decimal_precision);
	ImGui::SameLine(0, 0);
	ImGui::PopItemWidth();

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

	ImGui::PopID();
	return value_changed;
}

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->Collapsed)
		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;

	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(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);
	const bool hovered = (g.HoveredWindow == window) && (g.HoveredId == 0) && IsMouseHoveringBox(bb);
	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);
			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->Collapsed)
		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];
	
	const ImU32 col32 = ImConvertColorFloat4ToU32(col);
	RenderFrame(bb.Min, bb.Max, col32, 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->Collapsed)
		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->Collapsed)
		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->Collapsed)
		return;

	ItemSize(ImVec2(0,0));
}

static void ItemSize(ImVec2 size, ImVec2* adjust_start_offset)
{
	ImGuiState& g = GImGui;
	ImGuiWindow* window = GetCurrentWindow();
	if (window->Collapsed)
		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->Collapsed)
		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(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->Collapsed)
		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->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);

			// 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)
{
	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;
		}
		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 = (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("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();
		}

		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");

		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 vec2b[3] = { 0.10f, 0.20f };
		//ImGui::InputFloat2("input float2", vec2b);

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

		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", 3.0f);
		static float angle = 0.0f;
		ImGui::SliderAngle("angle", &angle);

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

		static float vec3a[3] = { 0.10f, 0.20f, 0.30f };
		ImGui::SliderFloat3("slider float3", vec3a, 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;
}

};

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