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 (typeof(onclick) == 'function') {
		this.onClick = onclick;
	}
	else {
		this.onClick = function() {
			if (eval('typeof('+this.Title+')') == 'function')
				eval(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()
{
	if (typeof(img_path) == 'undefined') {
		//alert('error: toolbar image path not set');
	}

	var $module_path = this.Module;

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

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

ToolBarButton.prototype.GetHTML = function() {
	var add_style = this.ToolBar.ButtonStyle ? 'style="'+this.ToolBar.ButtonStyle+'"' : '';
	var o = '<div class="toolbar-button" id="'+this.GetToolID('div')+'" '+add_style+'>'
	o += '<img id="' + this.GetToolID() + '" width="'+this.ToolBar.IconSize.w+'" height="'+this.ToolBar.IconSize.h+'" src="' + this.IconsPath() + this.ToolBar.IconPrefix + this.Title + '.gif" title="' + this.Alt + '&nbsp;">';
	if (this.ToolBar.UseLabels) o += '<br/>'+this.Label;
	o += '</div>'
	return o;
}

ToolBarButton.prototype.GetToolID = function(item) {
	if (!item) item = 'tool'
	return this.Prefix == '' ? item+'_' + this.Title : 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.MouseOverImg = new Image();
	this.MouseOverImg.src = this.IconsPath() + this.ToolBar.IconPrefix + this.Title + '_f2.gif';
	this.MouseOutImg = new Image();
	this.MouseOutImg.src = this.IconsPath() + this.ToolBar.IconPrefix + this.Title + '.gif';

	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.src = this.btn.MouseOverImg.src;
		this.className = 'toolbar-button-over';
	};
}

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

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;

			if (eval('typeof('+this.btn.Title+')') == 'function') {
				eval(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;

	if (typeof(this.DisabledImg) == 'undefined') {
		this.DisabledImg = new Image();
		this.DisabledImg.src = this.IconsPath() + this.ToolBar.IconPrefix + this.Title + '_f3.gif';
	}
	this.imgObject.src = this.DisabledImg.src;
	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.src = this.MouseOutImg.src;
	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>';

	var add_style = this.ToolBar.ButtonStyle ? 'style="'+this.ToolBar.ButtonStyle+'"' : '';
	return '<div id="'+this.GetToolID('div')+'" class="toolbar-button" style="border: 1px solid black; height: 100%;" '+add_style+'><img id="' + this.GetToolID() + '" src="' + this.IconsPath() + 'tool_divider.gif"></div>';
}

ToolBarSeparator.prototype.Init = function() {
	img = document.getElementById(this.ToolBar.IconPrefix + 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)
{
	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;
}

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';
}
