RPGUI = (function() {

/**
* init rpgui.
* this is the first file included in the compiled js.
*/

// rpgui global namespace
var RPGUI = RPGUI || {};

// lib version
RPGUI.version = 1.03;

// author
RPGUI.author = "Ronen Ness";

// if true, will init rpgui as soon as page loads
// if you set to false you need to call RPGUI.init(); yourself.
RPGUI.init_on_load = true;
window.addEventListener("load", function()
{
	if (RPGUI.init_on_load) {RPGUI.init();}
});

// init RPGUI and everything related
RPGUI.init = function()
{
	if (RPGUI._was_init) {throw "RPGUI was already init!";}
	for (var i = 0; i < RPGUI.__init_list.length; ++i)
	{
		RPGUI.__init_list[i]();
	}
	RPGUI._was_init = true;
}

// list of functions to run as part of the init process
RPGUI.__init_list = [];

// add a function to be called as part of the init process.
// note: order is preserve. you may use this function to init things after RPGUI is fully loaded, since
// all RPGUI will have its init functions during the inclusion of the script.
RPGUI.on_load = function(callback)
{
	// if was already init call immediately
	if (RPGUI._was_init) {callback();}
	
	// add to init list
	RPGUI.__init_list.push(callback);
}
/**
* Used to provide unified, easy javascript access to customized elements.
*/


// different callbacks for different methods and types
RPGUI.__update_funcs = {};
RPGUI.__create_funcs = {};
RPGUI.__get_funcs = {}
RPGUI.__set_funcs = {};

// create a customized rpgui element ("list", "dropbox", etc.)
// note: this function expect the original html element.
RPGUI.create = function(element, rpgui_type)
{
    // call the creation func and set type
    if (RPGUI.__create_funcs[rpgui_type])
    {
        element.dataset['rpguitype'] = rpgui_type;
        RPGUI.__create_funcs[rpgui_type](element);
    }
    // not a valid type? exception.
    else
    {
        throw "Not a valid rpgui type! options: " + Object.keys(RPGUI.__create_funcs);
    }
}

// update an element after you changed it manually via javascript.
// note: this function expect the original html element.
RPGUI.update = function(element)
{
    // if have update callback for this type, use it
    var type = element.dataset['rpguitype']
    if (RPGUI.__update_funcs[type])
    {
        RPGUI.__update_funcs[type](element);
    }
    // if not, use the default (firing update event)
    else
    {
        RPGUI.fire_event(element, "change");
    }
}


// set & update the value of an element.
// note: this function expect the original html element.
RPGUI.set_value = function(element, value)
{
    // if have set value callback for this type, use it
    var type = element.dataset['rpguitype'];
    if (RPGUI.__set_funcs[type])
    {
        RPGUI.__set_funcs[type](element, value);
    }
    // if not, use the default (setting "value" member)
    else
    {
        element.value = value;
    }

    // trigger update
    RPGUI.update(element);
}



// get the value of an element.
// note: this function expect the original html element.
RPGUI.get_value = function(element)
{
    // if have get value callback for this type, use it
    var type = element.dataset['rpguitype'];
    if (RPGUI.__get_funcs[type])
    {
        return RPGUI.__get_funcs[type](element);
    }
    // if not, use the default (getting the "value" member)
    else
    {
        return element.value;
    }
}
/**
* This script generate the rpgui checkbox class.
* This will replace automatically every <input> element that has the "rpgui-checkbox" class.
*/


// class name we will convert to special checkbox
var _checkbox_class = "rpgui-checkbox";

// create a rpgui-checkbox from a given element.
// note: element must be <input> of type "checkbox" for this to work properly.
RPGUI.__create_funcs["checkbox"] = function(element)
{
	RPGUI.add_class(element, _checkbox_class);
	create_checkbox(element);
};

// set function to set value of the checkbox
RPGUI.__set_funcs["checkbox"] = function(elem, value)
{
	elem.checked = value;
};

// set function to get value of the checkbox
RPGUI.__get_funcs["checkbox"] = function(elem)
{
	return elem.checked;
};

// init all checkbox elements on page load
RPGUI.on_load(function()
{
	// get all the input elements we need to upgrade
	var elems = document.getElementsByClassName(_checkbox_class);

	// iterate the selects and upgrade them
	for (var i = 0; i < elems.length; ++i)
	{
		RPGUI.create(elems[i], "checkbox");
	}
});

// upgrade a single "input" element to the beautiful checkbox class
function create_checkbox(elem)
{
	// get next sibling, assuming its the checkbox label.
	// this object will be turned into the new checkbox.
	var new_checkbox = elem.nextSibling;

	// validate
	if (!new_checkbox || new_checkbox.tagName !== "LABEL")
	{
		throw "After a '" + _checkbox_class + "' there must be a label!";
	}

	// copy all event listeners and events
	RPGUI.copy_event_listeners(elem, new_checkbox);

	// do the click event for the new checkbox
	(function(elem, new_checkbox)
	{
		new_checkbox.addEventListener("click", function()
		{
			if (!elem.disabled)
			{
				RPGUI.set_value(elem, !elem.checked);
			}

		});
	})(elem, new_checkbox);
}

/**
* Init rpgui content and what's inside.
*/

// init all the rpgui containers and their children
RPGUI.on_load(function()
{
	// get all containers and iterate them
	var contents = document.getElementsByClassName("rpgui-content");
	for (var i = 0; i < contents.length; ++i)
	{
		// get current container and init it
		var content = contents[i];

		// prevent dragging
		RPGUI.prevent_drag(content);

		// set default cursor
		RPGUI.set_cursor(content, "default");
	}
});

/**
* This script add the dragging functionality to all elements with "rpgui-draggable" class.
*/


// element currently dragged
var _curr_dragged = null;
var _curr_dragged_point = null;
var _dragged_z = 1000;

// class name we consider as draggable
var _draggable_class = "rpgui-draggable";

// set element as draggable
// note: this also add the "rpgui-draggable" css class to the element.
RPGUI.__create_funcs["draggable"] = function(element)
{
	// prevent forms of default dragging on this element
	element.draggable = false;
	element.ondragstart = function() {return false;}

	// add the mouse down event listener
	RPGUI.add_class(element, _draggable_class);
	element.addEventListener('mousedown', mouseDown);
};

// init all draggable elements (objects with "rpgui-draggable" class)
RPGUI.on_load(function()
{
	// init all draggable elements
	var elems = document.getElementsByClassName(_draggable_class);
	for (var i = 0; i < elems.length; ++i)
	{
		RPGUI.create(elems[i], "draggable");
	}

	// add mouseup event on window to stop dragging
	window.addEventListener('mouseup', mouseUp);
});

// stop drag
function mouseUp(e)
{
	_curr_dragged = null;
	window.removeEventListener('mousemove', divMove);
}

// start drag
function mouseDown(e){

	// set dragged object and make sure its really draggable
	var target = e.target || e.srcElement;
	if (!RPGUI.has_class(target, _draggable_class)) {return;}
		
	_curr_dragged = target;
	
	// set holding point
	var rect = _curr_dragged.getBoundingClientRect();
	_curr_dragged_point = {x: rect.left-e.clientX, y: rect.top-e.clientY};

	// add z-index to top this element
	target.style.zIndex = _dragged_z++;
	
	// begin dragging
	window.addEventListener('mousemove', divMove, true);

}

// dragging
function divMove(e){
	if (_curr_dragged)
	{
		_curr_dragged.style.position = 'absolute';
		_curr_dragged.style.left = (e.clientX + _curr_dragged_point.x) + 'px';
		_curr_dragged.style.top = (e.clientY + _curr_dragged_point.y) + 'px';
	}
}

/**
 * This script generate the rpgui progress-bar class.
 * This will replace automatically every <div> element that has the "rpgui-progress" class.
 */


// class name we will convert to special progress
var _progress_class = "rpgui-progress";

// create a rpgui-progress from a given element.
// note: element must be <input> of type "range" for this to work properly.
RPGUI.__create_funcs["progress"] = function(element)
{
	RPGUI.add_class(element, _progress_class);
	create_progress(element);
};

// set function to set value of the progress bar
// value should be in range of 0 - 1.0
RPGUI.__set_funcs["progress"] = function(elem, value)
{
	// get trackbar and progress bar elements
	var track = RPGUI.get_child_with_class(elem, "rpgui-progress-track");
	var progress = RPGUI.get_child_with_class(track, "rpgui-progress-fill");

	// get the two edges
	var edge_left = RPGUI.get_child_with_class(elem, "rpgui-progress-left-edge");
	var edge_right = RPGUI.get_child_with_class(elem, "rpgui-progress-right-edge");

	// set progress width
	progress.style.left = "0px";
	progress.style.width = (value * 100) + "%";
};

// init all progress elements on page load
RPGUI.on_load(function()
{
	// get all the select elements we need to upgrade
	var elems = document.getElementsByClassName(_progress_class);

	// iterate the selects and upgrade them
	for (var i = 0; i < elems.length; ++i)
	{
		RPGUI.create(elems[i], "progress");
	}
});

// upgrade a single "input" element to the beautiful progress class
function create_progress(elem)
{
	// create the containing div for the new progress
	progress_container = elem;

	// insert the progress container
	RPGUI.insert_after(progress_container, elem);

	// create progress parts (edges, track, thumb)

	// track
	var track = RPGUI.create_element("div");
	RPGUI.add_class(track, "rpgui-progress-track");
	progress_container.appendChild(track);

	// left edge
	var left_edge = RPGUI.create_element("div");
	RPGUI.add_class(left_edge, "rpgui-progress-left-edge");
	progress_container.appendChild(left_edge);

	// right edge
	var right_edge = RPGUI.create_element("div");
	RPGUI.add_class(right_edge, "rpgui-progress-right-edge");
	progress_container.appendChild(right_edge);

	// the progress itself
	var progress = RPGUI.create_element("div");
	RPGUI.add_class(progress, "rpgui-progress-fill");
	track.appendChild(progress);

	// set color
	if (RPGUI.has_class(elem, "blue")) {progress.className += " blue";}
	if (RPGUI.has_class(elem, "red")) {progress.className += " red";}
	if (RPGUI.has_class(elem, "green")) {progress.className += " green";}

	// set starting default value
	var starting_val = elem.dataset.value !== undefined ? parseFloat(elem.dataset.value) : 1;
	RPGUI.set_value(elem, starting_val);
}

/**
* This script generate the rpgui radio class.
* This will replace automatically every <input> element that has the "rpgui-radio" class.
*/


// class name we will convert to special radio
var _radio_class = "rpgui-radio";

// create a rpgui-radio from a given element.
// note: element must be <input> of type "radio" for this to work properly.
RPGUI.__create_funcs["radio"] = function(element)
{
	RPGUI.add_class(element, _radio_class);
	create_radio(element);
};

// set function to set value of the radio
RPGUI.__set_funcs["radio"] = function(elem, value)
{
	elem.checked = value;
};

// set function to get value of the radio button
RPGUI.__get_funcs["radio"] = function(elem)
{
	return elem.checked;
};

// init all radio elements on page load
RPGUI.on_load(function()
{
	// get all the input elements we need to upgrade
	var elems = document.getElementsByClassName(_radio_class);

	// iterate the selects and upgrade them
	for (var i = 0; i < elems.length; ++i)
	{
		RPGUI.create(elems[i], "radio");
	}
});

// upgrade a single "input" element to the beautiful radio class
function create_radio(elem)
{
	// get next sibling, assuming its the radio label.
	// this object will be turned into the new radio.
	var new_radio = elem.nextSibling;

	// validate
	if (!new_radio || new_radio.tagName !== "LABEL")
	{
		throw "After a '" + _radio_class + "' there must be a label!";
	}

	// copy all event listeners and events
	RPGUI.copy_event_listeners(elem, new_radio);

	// do the click event for the new radio
	(function(elem, new_radio)
	{
		new_radio.addEventListener("click", function()
		{
			if (!elem.disabled)
			{
				RPGUI.set_value(elem, true);
			}
		});
	})(elem, new_radio);
}

/**
* This script generate the rpgui dropdown <select>.
* This will replace automatically every <select> element that has the "rpgui-dropdown" class.
*/


// class name we will convert to dropdown
var _dropdown_class = "rpgui-dropdown";

// create a rpgui-dropdown from a given element.
// note: element must be <select> with <option> tags that will turn into the items
RPGUI.__create_funcs["dropdown"] = function(element)
{
	RPGUI.add_class(element, _dropdown_class);
	create_dropdown(element);
};

// init all dropdown elements on page load
RPGUI.on_load(function()
{
	// get all the select elements we need to upgrade
	var elems = document.getElementsByClassName(_dropdown_class);

	// iterate the selects and upgrade them
	for (var i = 0; i < elems.length; ++i)
	{
		RPGUI.create(elems[i], "dropdown");
	}
});

// upgrade a single "select" element to the beautiful dropdown
function create_dropdown(elem)
{
	// prefix to add arrow down next to selection header
	var arrow_down_prefix = "<label>&#9660;</label> ";

	// create the paragraph that will display the select_header option
	var select_header = RPGUI.create_element("p");
	if (elem.id) {select_header.id = elem.id + "-rpgui-dropdown-head"};
	RPGUI.add_class(select_header, "rpgui-dropdown-imp rpgui-dropdown-imp-header");
	RPGUI.insert_after(select_header, elem);

	// create the list to hold all the options
	var list = RPGUI.create_element("ul");
	if (elem.id) {list.id = elem.id + "-rpgui-dropdown"};
	RPGUI.add_class(list, "rpgui-dropdown-imp");
	RPGUI.insert_after(list, select_header);

	// set list top to be right under the select header
	var header_rect = select_header.getBoundingClientRect();
	list.style.position = "absolute";

	// set list width (-14 is to compensate borders)
	list.style.width = (header_rect.right - header_rect.left - 14) + "px";
	list.style.display = "none";

	// now hide the original select
	elem.style.display = "none";

	// iterate over all the options in this select
	for (var i = 0; i < elem.children.length; ++ i)
	{
		// if this child is not option, skip
		var option = elem.children[i];
		if (option.tagName != "OPTION") continue;

		// add the new option as list item
		var item = RPGUI.create_element("li");
		item.innerHTML = option.innerHTML;
		list.appendChild(item);

		// copy all event listeners from original option to the new item
		RPGUI.copy_event_listeners(option, item);

		// set option callback (note: wrapped inside namespace to preserve vars)
		(function(elem, option, item, select_header, list)
		{
			// when clicking the customized option
			item.addEventListener('click', function()
			{
				// set the header html and hide the list
				select_header.innerHTML = arrow_down_prefix + option.innerHTML;
				list.style.display = "none";

				// select the option in the original selection
				option.selected = true;
				RPGUI.fire_event(elem, "change");
			});

		})(elem, option, item, select_header, list);
	}

	// now set list and header callbacks
	// create a namespace to preserve variables
	(function(elem, list, select_header)
	{
		// when clicking the selected header show / hide the options list
		select_header.onclick = function()
		{
			if (!elem.disabled)
			{
				var prev = list.style.display;
				list.style.display = prev == "none" ? "block" : "none";
			}
		}

		// when mouse leave the options list, hide it
		list.onmouseleave = function()
		{
			list.style.display = "none";
		}

	})(elem, list, select_header);

	// lastly, listen to when the original select changes and update the customized list
	(function(elem, select_header, list)
	{
		// the function to update dropdown
		_on_change = function()
		{
			// set the header html and hide the list
			if (elem.selectedIndex != -1)
			{
				select_header.innerHTML = arrow_down_prefix + elem.options[elem.selectedIndex].text;
			}
			else
			{
				select_header.innerHTML = arrow_down_prefix;
			}
			list.style.display = "none";
		}

		// register the update function and call it to set initial state
		elem.addEventListener('change', _on_change);
		_on_change();
		
	})(elem, select_header, list);
}

/**
* This script generate the rpgui list <select>.
* This will replace automatically every <select> element that has the "rpgui-list" class.
*/


// class name we will convert to list
var _list_class = "rpgui-list";

// create a rpgui-list from a given element.
// note: element must be <select> with <option> tags that will turn into the items
RPGUI.__create_funcs["list"] = function(element)
{
	RPGUI.add_class(element, _list_class);
	create_list(element);
};

// init all list elements on page load
RPGUI.on_load(function()
{
	// get all the select elements we need to upgrade
	var elems = document.getElementsByClassName(_list_class);

	// iterate the selects and upgrade them
	for (var i = 0; i < elems.length; ++i)
	{
		RPGUI.create(elems[i], "list");
	}
});

// upgrade a single "select" element to the beautiful list
function create_list(elem)
{
	// default list size is 3
	if (!elem.size) elem.size = 3;

	// create the list to hold all the options
	var list = RPGUI.create_element("ul");
	if (elem.id) {list.id = elem.id + "-rpgui-list"};
	RPGUI.add_class(list, "rpgui-list-imp");
	elem.parentNode.insertBefore(list, elem.nextSibling);

	// now hide the original select
	elem.style.display = "none";

	// iterate over all the options in this select
	var all_items = [];
	for (var i = 0; i < elem.children.length; ++ i)
	{
		// if this child is not option, skip
		var option = elem.children[i];
		if (option.tagName != "OPTION") continue;

		// add the new option as list item
		var item = RPGUI.create_element("li");
		item.innerHTML = option.innerHTML;
		list.appendChild(item);

		// set dataset value
		item.dataset['rpguivalue'] = option.value;

		// add to list of all items
		all_items.push(item);

		// copy all event listeners from original option to the new item
		RPGUI.copy_event_listeners(option, item);

		// set option callback (note: wrapped inside namespace to preserve vars)
		(function(elem, option, item, list, all_items)
		{
			// when clicking the customized option
			item.addEventListener('click', function()
			{
				// select the option in the original selection
				if (!elem.disabled)
				{
					option.selected = true;
					RPGUI.fire_event(elem, "change");
				}
			});

		})(elem, option, item, list, all_items);
	}

	// if got any items set list height based on the size param
	if (all_items.length && elem.size)
	{
		
		// get the actual height of a single item in list
		var height = all_items[0].offsetHeight;

		// set list height based on size
		list.style.height = (height * elem.size) + "px";
		
	}
	
	// lastly, listen to when the original select changes and update the customized list
	(function(elem, all_items)
	{
		// handle value change
		elem.addEventListener('change', function()
		{
			_on_change(this);
		});
		function _on_change(elem)
		{
			for (var i = 0; i < all_items.length; ++i)
			{
				var item = all_items[i];
				if (item.dataset['rpguivalue'] == elem.value)
				{
					RPGUI.add_class(item, "rpgui-selected");
				}
				else
				{
					RPGUI.remove_class(item, "rpgui-selected");
				}
			}
		}

		// call the on-change on init to set initial state
		_on_change(elem);

	})(elem, all_items);
}

/**
* This script generate the rpgui slider class.
* This will replace automatically every <input> element that has the "rpgui-slider" class.
*/


// class name we will convert to special slider
var _slider_class = "rpgui-slider";

// create a rpgui-slider from a given element.
// note: element must be <input> of type "range" for this to work properly.
RPGUI.__create_funcs["slider"] = function(element)
{
	RPGUI.add_class(element, _slider_class);
	create_slider(element);
};

// init all slider elements on page load
RPGUI.on_load(function()
{
	// get all the select elements we need to upgrade
	var elems = document.getElementsByClassName(_slider_class);

	// iterate the selects and upgrade them
	for (var i = 0; i < elems.length; ++i)
	{
		RPGUI.create(elems[i], "slider");
	}
});

// upgrade a single "input" element to the beautiful slider class
function create_slider(elem)
{
	// check if should do it golden slider
	var golden = RPGUI.has_class(elem, "golden") ? " golden" : "";

	// create the containing div for the new slider
	var slider_container = RPGUI.create_element("div");
	if (elem.id) {slider_container.id = elem.id + "-rpgui-slider"};
	RPGUI.copy_css(elem, slider_container);
	RPGUI.add_class(slider_container, "rpgui-slider-container" + golden);

	// insert the slider container
	RPGUI.insert_after(slider_container, elem);

	// set container width based on element original width
	slider_container.style.width = elem.offsetWidth + "px";

	// create slider parts (edges, track, thumb)

	// track
	var track = RPGUI.create_element("div");
	RPGUI.add_class(track, "rpgui-slider-track" + golden);
	slider_container.appendChild(track);

	// left edge
	var left_edge = RPGUI.create_element("div");
	RPGUI.add_class(left_edge, "rpgui-slider-left-edge" + golden);
	slider_container.appendChild(left_edge);

	// right edge
	var right_edge = RPGUI.create_element("div");
	RPGUI.add_class(right_edge, "rpgui-slider-right-edge" + golden);
	slider_container.appendChild(right_edge);

	// thumb (slider value show)
	var thumb = RPGUI.create_element("div");
	RPGUI.add_class(thumb, "rpgui-slider-thumb" + golden);
	slider_container.appendChild(thumb);

	// hide original slider
	elem.style.display = "none";

	// copy events from original slider to container.
	// this will handle things like click, mouse move, mouse up, etc.
	// it will not handle things like "onchange".
	RPGUI.copy_event_listeners(elem, slider_container);

	// now set events (wrap them in anonymous function to preserve local vars)
	var state = {mouse_down: false};
	(function(elem, slider_container, thumb, track, state, right_edge, left_edge)
	{
		// get the range of the original slider (min and max)
		var min = parseFloat(elem.min);
		var max = parseFloat(elem.max);

		// calculate edges width and track actual width
		var edges_width = right_edge.offsetWidth + left_edge.offsetWidth;
		var track_width = track.offsetWidth - edges_width;

		// set state if moving slider or not
		slider_container.addEventListener('mouseup', function(e)
		{
			state.mouse_down = false;
		});
		window.addEventListener('mouseup', function(e)
		{
			state.mouse_down = false;
		});
		track.addEventListener('mousedown', function(e)
		{
			state.mouse_down = true;
			slide(e.offsetX || e.layerX);
		});
		slider_container.addEventListener('mousedown', function(e)
		{
			state.mouse_down = true;
		});

		// handle clicking on edges (set to min / max)
		left_edge.addEventListener('mousedown', function(e)
		{
			set_value(min);
		});
		right_edge.addEventListener('mousedown', function(e)
		{
			set_value(max);
		});
		left_edge.addEventListener('mousemove', function(e)
		{
			if (state.mouse_down) set_value(min);
		});
		right_edge.addEventListener('mousemove', function(e)
		{
			if (state.mouse_down) set_value(max);
		});

		// handle sliding
		function slide(pos)
		{
			// calc new slider value
			var new_val = min + Math.round((pos / track_width) * (max-min)) - 1;

			// set thumb position
			set_value(new_val);
		}

		// setting value
		function set_value(new_val)
		{
			if (!elem.disabled &&
				elem.value != new_val)
			{
				RPGUI.set_value(elem, new_val);
			}
		}

		// moving the slider
		track.addEventListener('mousemove', function(e)
		{
			if (state.mouse_down && !elem.disabled)
			{
				slide(e.offsetX || e.layerX);
			}
		});


		// when original slider value change update thumb position
		elem.addEventListener("change", function(e)
		{
			_onchange();
		});
		function _onchange()
		{
			// get the range of the original slider (min and max)
			var step = track_width / (max-min);
			var relative_val = Math.round(parseFloat(elem.value) - min);
			thumb.style.left = (Math.floor(edges_width * 0.25) + (relative_val * step)) + "px";
		}

		// call "_onchange()" to init the thumb starting position
		_onchange();

	})(elem, slider_container, thumb, track, state, right_edge, left_edge);

}
/**
* Some helpers and utils.
*/


// create and return html element for rpgui internal mechanisms
// element is string, element type (like "div" or "p")
RPGUI.create_element = function(element)
{
    // create element
    element = document.createElement(element);

    // return element
    return element;
};

// set cursor for given element
// element is element to set.
// cursor is string, what cursor to use (default / point / .. see cursor.css for more info ).
RPGUI.set_cursor = function(element, cursor)
{
    RPGUI.add_class(element, "rpgui-cursor-" + cursor);
};

// prevent element dragging
RPGUI.prevent_drag = function(element)
{
    /*
    // this code was removed because I found a cross-browser way to cover it all via css.
    element.draggable=false;
    element.ondrop=function(){return false;}
    element.ondragstart=function(){return false;}
    */
};

// copy the style of one element into another
RPGUI.copy_css = function(from, to)
{
    to.style.cssText = from.style.cssText;
};

// check if element have class
RPGUI.has_class = function(element, cls)
{
    return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
};

// add class to element (but only if don't already have it)
RPGUI.add_class = function(element, cls)
{
    if (!RPGUI.has_class(element, cls))
    {
        element.className += " " + cls;
    }
};

// get child element with classname
RPGUI.get_child_with_class = function(elem, cls)
{
    for (var i = 0; i < elem.childNodes.length; i++)
    {
        if (RPGUI.has_class(elem.childNodes[i], cls))
        {
          return elem.childNodes[i];
        }
    }
};

// remove a class from an element
RPGUI.remove_class = function(element, cls)
{
    element.className = (' ' + element.className + ' ').replace(cls, "");
    element.className = element.className.substring(1, element.className.length-1);
};

// fire event from element
// type should be string like "change", "click", "mouseup", etc.
RPGUI.fire_event = function(element, type)
{
    // firing the event properly according to StackOverflow
    // http://stackoverflow.com/questions/2856513/how-can-i-trigger-an-onchange-event-manually
    if ("createEvent" in document) {
        var evt = document.createEvent("HTMLEvents");
        evt.initEvent(type, false, true);
        element.dispatchEvent(evt);
    }
    else {
        element.fireEvent("on" + type);
    }
};

// copy all event listeners from one element to the other
RPGUI.copy_event_listeners = function(from, to)
{
    // copy all event listeners
    if (typeof getEventListeners == "function")
    {
        var events = getEventListeners(from);
        for(var p in events) {
            events[p].forEach(function(ev) {
                // {listener: Function, useCapture: Boolean}
                to.addEventListener(p, ev.listener, ev.useCapture);
            });
        }
    }

    // now copy all attributes that start with "on"
    for (attr in from)
    {
        if (attr.indexOf("on") === 0)
        {
            to[attr] = from[attr];
        }
    }
};

// insert one html element after another given element
RPGUI.insert_after = function(to_insert, after_element)
{
    after_element.parentNode.insertBefore(to_insert, after_element.nextSibling);
};
return RPGUI;})();