function ToolBarButton(title, alt, onclick, $hidden, prefix)
{
	this.Title = title || '';
	this.TranslateLink = false;
	this.CheckTitleModule();
	this.Alt = RemoveTranslationLink(alt || '');
	if (this.Alt != alt) {
		this.TranslateLink = alt || '';
		this.TranslateLink = this.TranslateLink.replace(/&lt;a href=&quot;(.*?)&quot;.*&gt;(.*?)&lt;\/a&gt;/g, '$1');
	}

	if (this.Alt.match(/(.*)::(.*)/)) {
		this.Alt = RegExp.$1;
		this.Label = RegExp.$2
	}
	else {
		this.Label = this.Alt;
	}


	if ( $.isFunction(onclick) ) {
		this.onClick = onclick;
	}
	else {
		this.onClick = function() {
			this.runFunction(this.Title);
		}
	}

	this.imgObject = null;
	this.Enabled = true;
	this.Hidden = $hidden ? true : false;
	this.ToolBar = null;
	this.Prefix = prefix ? prefix : '';
	this.Separator = false;

	// all buttons are read-only until page is fully loaded!
	this.ReadOnly = true;
}

ToolBarButton.prototype.CheckTitleModule = function()
{
	if (this.Title.match(/([^:]+):(.*)$/)) {
		// has module set directly
		this.Title = RegExp.$2;
		this.Module = RegExp.$1.toLowerCase();

		if (this.Module == 'in-portal') {
			this.Module = 'core';
		}
	}
	else {
		// use default module
		this.Module = 'core';
	}
}

ToolBarButton.prototype.IconsPath = function($module_path)
{
	if ( $module_path === undefined ) {
		$module_path = this.Module;
	}

	if ( $module_path != 'core' ) {
		$module_path = 'modules/' + $module_path;
	}

	return this.ToolBar.IconPath.replace('#MODULE#', $module_path) + 'toolbar/';
}

ToolBarButton.prototype.GetHTML = function() {
	var add_style = this.ToolBar.ButtonStyle ? 'style="' + this.ToolBar.ButtonStyle + '"' : '',
		o = '<div class="toolbar-button" id="' + this.GetToolID('div') + '" ' + add_style + '>';

	o += '<img class="' + this.Module + '-toolbar-sprite" id="' + this.GetToolID() + '" width="' + this.ToolBar.IconSize.w + '" height="' + this.ToolBar.IconSize.h + '" src="' + this.IconsPath('core') + '../spacer.gif" title="' + this.Alt + '&nbsp;">';

	if ( this.ToolBar.UseLabels ) {
		o += '<br/>' + this.Label;
	}

	o += '</div>'

	return o;
}

ToolBarButton.prototype.GetToolID = function(item) {
	if ( item === undefined ) {
		item = 'tool';
	}

	if ( this.Prefix == '' ) {
		return item == 'tool' ? this.Module + '-tb-' + this.Title : item + '_' + this.Title;
	}

	return item + '_[' + this.Prefix + '][' + this.Title + ']'
}

ToolBarButton.prototype.Init = function() {

	img = document.getElementById(this.GetToolID());
	this.imgObject = img;
	this.Container = document.getElementById(this.GetToolID('div')) ? document.getElementById(this.GetToolID('div')) : false;
	this.Container.btn =  this;
	img.btn = this;

	this.SetOnMouseOver();
	this.SetOnMouseOut();
	this.SetOnClick();
	this.SetOnRightClick()
	if (this.Hidden) this.Hide();
}

ToolBarButton.prototype.EditTitle = function() {
	if (this.TranslateLink !== false && !this.ReadOnly) {
		var $links = this.TranslateLink;

		$links = $links.split('::');
		var $i = 0;
		while ($i < $links.length) {
			var $link = $links[$i];
			if ($link.match(/(javascript:|http:\/\/)(.*)/)) {
				var $link_type = RegExp.$1;
				$link = RegExp.$2.replace(/&#[0]{0,1}39;/g, '"');
				if ($link_type == 'javascript:') {
					eval($link);
				}
				else {
					window.location.href = 'http://' + $link;
				}

				// edit one phrase at a time
				break;
			}
			$i++;
		}

		return false;
	}

	return true;
}

ToolBarButton.prototype.SetOnMouseOver = function() {
	this.Container.onmouseover = function() {
		$(this.btn.imgObject).addClass('hover');
		this.className = 'toolbar-button-over';
	};
}

ToolBarButton.prototype.SetOnMouseOut = function() {
	this.Container.onmouseout = function() {
		$(this.btn.imgObject).removeClass('hover');
		this.className = 'toolbar-button';
	};
}

ToolBarButton.prototype.runFunction = function($name) {
	if ( window[$name] !== undefined && $.isFunction( window[$name] ) ) {
		window[$name]();
	}
}

ToolBarButton.prototype.SetOnClick = function() {
	// we have SetOnMouseOut for this ???
	/*this.Container.onmouseout = function() {
		this.btn.imgObject.src = this.btn.IconsPath() + this.btn.ToolBar.IconPrefix + this.btn.Title + '.gif';
	};*/

	this.Container.inClick = false;
	if (typeof(this.onClick) != 'function') {
		this.Container.onclick = function() {
			if (this.inClick || this.btn.ReadOnly) return;
			this.inClick = true;

			this.runFunction(this.btn.Title);

			this.inClick = false;
		}
	}
	else {
		this.Container.onclick = function() {
			if (this.inClick || this.btn.ReadOnly) return;
			this.inClick = true;
			this.btn.onClick();
			this.inClick = false;
		}
	}

	// the following lines are correct, as long as mozilla understands 'pointer', but IE 'hand',
	// do not change the order of these lines!
	if (is.ie6up || is.gecko) {
		this.Container.style.cursor = 'pointer';
	}
	else {
		// somehow set cursor hand for IE 5/ 5.5
//		this.imgObject.style = 'cursor: hand';
	}
}

ToolBarButton.prototype.SetOnRightClick = function() {
	this.Container.oncontextmenu = function() {
		return this.btn.EditTitle();
	}
}


ToolBarButton.prototype.Disable = function() {
	if ( !this.Enabled ) return;

	$(this.imgObject).addClass('disabled');
	this.Container.onmouseover = null;
	this.Container.onmouseout = null;
	this.Container.onclick = null;
	this.Container.style.cursor = 'default';
	this.Enabled = false;
	this.Container.className = 'toolbar-button-disabled'
}

ToolBarButton.prototype.Enable = function() {
	if (this.Enabled) return;
	$(this.imgObject).removeClass('hover disabled');
	this.SetOnMouseOver();
	this.SetOnMouseOut();
	this.SetOnClick();
	this.Enabled = true;
	this.Container.className = 'toolbar-button'
}

ToolBarButton.prototype.Hide = function() {
	this.Container.style.display = 'none';
	this.Hidden = true;
}

ToolBarButton.prototype.Show = function() {
	this.Container.style.display = '';
	this.Hidden = false;
}

/* ----------- */

function ToolBarSeparator(title, $hidden) //extends ToolBarButton
{
	this.Title = title;
	this.Hidden = $hidden ? true : false;
	this.Separator = true;
}
ToolBarSeparator.prototype = new ToolBarButton;

ToolBarSeparator.prototype.GetHTML = function() {
	var add_style = this.ToolBar.ButtonStyle ? 'style="' + this.ToolBar.ButtonStyle + '"' : '';
	var padding = this.ToolBar.UseLabels ? '12px' : '2px'

	return '<div id="' + this.GetToolID('div') + '" class="toolbar-button" style="padding-top: ' + padding + '; height: 32px;" ' + add_style + '><img id="' + this.GetToolID() + '" src="' + this.IconsPath() + 'tool_divider.gif"></div>';
}

ToolBarSeparator.prototype.Init = function() {
	img = document.getElementById(this.Module + '-tb-' + this.Title);
	this.Container = document.getElementById(this.GetToolID('div')) ? document.getElementById(this.GetToolID('div')) : false;
	this.imgObject = img;
	img.btn = this;

	if (this.Hidden) {
		this.Hide();
	}
}

ToolBarSeparator.prototype.Enable = function() { }
ToolBarSeparator.prototype.Disable = function() { }

/* ----------- */

function ToolBarMarkup(title, html) //extends ToolBarButton
{
	this.Title = title;
	this.HTML = html;
}

ToolBarMarkup.prototype = new ToolBarButton;

ToolBarMarkup.prototype.GetHTML = function() {
	return this.HTML;
}

ToolBarMarkup.prototype.Init = function() { }
ToolBarMarkup.prototype.Enable = function() { }
ToolBarMarkup.prototype.Disable = function() { }

/* ----------- */

function ToolBar(icon_prefix, $module, $image_path)
{
	this.Module = $module ? $module : 'core';
	this.IconPrefix = icon_prefix ? icon_prefix : 'tool_';
	this.IconSize = {w:32,h:32};
	this.Buttons = {};
	this.UseLabels = typeof($use_toolbarlabels) != 'undefined' ? $use_toolbarlabels : false;

	if ( $image_path !== undefined ) {
		this.IconPath = $image_path;
	}
	else if ( typeof(img_path) != 'undefined' ) {
		this.IconPath = img_path;
	}
	else {
		this.IconPath = '';
//		alert('error: toolbar image path not set');
	}
}

ToolBar.prototype.AddButton = function(a_button)
{
	if ($visible_toolbar_buttons === true || in_array(a_button.Title, $visible_toolbar_buttons) || a_button.Separator) {
		a_button.ToolBar = this;
		this.Buttons[a_button.Title] = a_button;
	}
}

ToolBar.prototype._removeSeparators = function()
{
	// TODO: find a way to cut first and last separators from non-indexed array, like $new_buttons.
	var $separator = false;
	var $new_buttons = {};

	for (var $button_title in this.Buttons) {
		if ($separator && this.Buttons[$button_title].Separator) {
			continue;
		}

		$separator = this.Buttons[$button_title].Separator;
		$new_buttons[$button_title] = this.Buttons[$button_title];
	}

	this.Buttons = $new_buttons;
}

ToolBar.prototype.Render = function($container)
{
	// remove duplicate separators or separators at the end of button list
	this._removeSeparators();

	if ($container) {
		var tmp = '';
		for (var i in this.Buttons) {
			btn = this.Buttons[i];
			tmp += btn.GetHTML();
		}
		$container.innerHTML = tmp; // container will contain only buttons

		// init all buttons after because objects are not yet created directly after assigning to innerHTML
		for (var i in this.Buttons) {
			btn = this.Buttons[i];
			btn.Init();
		}
	}
	else {
		for (var i in this.Buttons) {
			btn = this.Buttons[i];
			document.write( btn.GetHTML() );
			btn.Init();
		}
	}

	var $me = this;

	$(document).ready(
		function () {
			for (var $button_name in $me.Buttons) {
				$me.Buttons[$button_name].ReadOnly = false;
			}
		}
	);
}

ToolBar.prototype.EnableButton = function(button_id) {
	if(this.ButtonExists(button_id)) this.Buttons[button_id].Enable();
}

ToolBar.prototype.DisableButton = function(button_id) {
	if(this.ButtonExists(button_id)) this.Buttons[button_id].Disable();
}

ToolBar.prototype.HideButton = function(button_id) {
	if(this.ButtonExists(button_id)) this.Buttons[button_id].Hide();
}

ToolBar.prototype.ShowButton = function(button_id) {
	if(this.ButtonExists(button_id)) this.Buttons[button_id].Show();
}

ToolBar.prototype.SetEnabled = function(button_id, $enabled) {
	var $ret = $enabled ? this.EnableButton(button_id) : this.DisableButton(button_id);
}

ToolBar.prototype.SetVisible = function(button_id, $visible) {
	var $ret = $visible ? this.ShowButton(button_id) : this.HideButton(button_id);
}

ToolBar.prototype.GetButtonImage = function(button_id) {
	if( this.ButtonExists(button_id) ) return this.Buttons[button_id].imgObject;
}

ToolBar.prototype.ButtonExists = function(button_id) {
	return typeof(this.Buttons[button_id]) == 'object';
}
