function BB_Code(p) {
	if(	
		!p || 
		typeof p != 'object' ||
		!p.element ||
		!p.buttons ||
		!document.createElement // zu alter Browser
	) return;

	var textarea = p.element;
	var br = document.createElement("br");
	var nbsp = '\xA0';
	textarea.parentNode.insertBefore(br, textarea);
	var prev, obj;
	for(var i = 0; i < p.buttons.length; i++){
			var tmp = p.buttons[i];
			
			if(typeof tmp == 'object') {
				obj  = createButton(tmp);
				if(tmp.func) BB_Code.TagList[tmp.tag] = tmp.func;
			}
			if(tmp == '-' && prev) prev.style.marginRight = BB_Code.margin;
			prev = obj;
	}
    
    // workaround: wegen Webkit Browser
    // Wenn textarea den Focus verliert, geht auch die selection verloren.
	textarea.onblur = function() { 
		if(typeof this.selectionStart != 'undefined') {
				this.start = this.selectionStart;
				this.end = this.selectionEnd;
		};
    };

	// Private Funktionen

	function createButton(obj) {
		if(!obj.text) obj.text = obj.tag;
		var button = document.createElement('input');
		button.type = 'button';

		button.className = 'bb_button';
		button.value = obj.text;
		button.onclick = function() { 
			insertTag(obj.tag, this);
			return false;  
		};
        
		br.parentNode.insertBefore(button, br);
		if(obj.help) button.title = obj.help;
		return button;
	}
	
	function insertTag(tag, button) {
		if(!textarea) return false;
		textarea.focus();
		
		function getSelection() {
			if(typeof document.selection != 'undefined') {
				var range = document.selection.createRange();
				return range.text;
			} else if(typeof textarea.selectionStart != 'undefined') {
				var start = textarea.selectionStart;
				var end = textarea.selectionEnd;
				return textarea.value.substring(start, end);
			}
			// Keine Funktion verfügbar, um den ausgwählten Text zu ermitteln
			return window.prompt('Textinput:');
		}
        
		function insertText(t) {
			
            if(typeof document.selection != 'undefined') {
				
                var range = document.selection.createRange();

                range.text = t;
				
				if (t.length == 0) range.move('character', -1);
				else range.moveStart('character', t.length);
			
			} else if(typeof textarea.selectionStart != 'undefined') {

                var scrollPos = textarea.scrollTop;
                var start = textarea.start || textarea.selectionStart;
				var end = textarea.end || textarea.selectionEnd;

				textarea.value = textarea.value.substr(0, start) + t + textarea.value.substr(end);
				var pos = start + t.length;
				textarea.selectionStart = pos;
				textarea.selectionEnd = pos;
                textarea.scrollTop = scrollPos;
			} else {
				textarea.value += t;
			}
		}
		// markierten Text ermitteln
		var t = getSelection();
		// Tagfunktion aufrufen
		var tag_func = typeof BB_Code.TagList[tag] == 'function' ? tag : 'def';
		var new_text = BB_Code.TagList[tag_func](tag, t, button) 
		// Text einfügen
        
		insertText(new_text);
		return !!t;
	}

}
BB_Code.TagList = {
	def: function(tag, text, button, attr) {
		// Wurde ein Text markiert => Tag drumherum
		var start = '[' + tag + (attr || '') + ']';
		var end = '[/' + tag + ']';
		if(text) return start + text + end;
		
		// kein markierter Text -> den Button kennzeichnen
		// und nur den entsprechenden Tag einfügen
		button.value = button.value.indexOf('/') > -1 ? 
		button.value.substr(1) : '/' + button.value;
		return button.value.indexOf('/') > -1 ? start : end;
	}
};
BB_Code.margin = '.5em';

