

/* Shop.js */

function BeginRequestHandler(sender, args) {
	try {
		args.get_request().set_userContext(args.get_postBackElement().id);
	}
	catch (e) {
	}
}

function EndRequestHandlerCustomerSaleDetails(sender, args) {
	try {
		if (args.get_error() == undefined) {
			var sName = args.get_response().get_webRequest().get_userContext();
			if (sName == "ctl00_ctl00_cphBC_cphC_tabStartpage_pnlCustomerSales_btnShowCustomerSaleDetails") {
				ResizeCustomerSalesLayer();
			}
			else {
				//alert("EndRequestHandlerCustomerSaleDetails (" + sName + ")");
			}
		}
	}
	catch (e) {
	}
}

function EndRequestHandlerArticleDetails(sender, args) {
	try {
		if (args.get_error() == undefined) {
			var sName = args.get_response().get_webRequest().get_userContext();
			if (sName == "ctl00_ctl00_cphAD_btnShowArticleDetails") {
				ResizeArtileDetails();
			}
			else {
				//alert("EndRequestHandlerArticleDetails (" + sName + ")");
			}
		}
	}
	catch (e) {
	}
}

function ResizeArtileDetails() {
	//alert('1: ' + document.getElementById('divArticleLayer'));
	if (document.getElementById('divArticleLayer') != undefined) {
		var PanelHeight = $(".ArticleLayer").height(); // Layegröße des öffnenden Fensters
		var PanelWidth = $(".ArticleLayer").width(); // Layegröße des öffnenden Fensters
		var BrowserWidth = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth); // Browserfenstergröße unterschiedlich im IE und FF
		var BrowserHeight = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight); // Browserfenstergröße

		if (BrowserHeight < 600) {
			//alert('Layergroesse: ' + PanelHeight);
			//alert('Fenstergroesse: ' + BrowserHeight);
			$(".ArticleLayer").height(BrowserHeight - 150);
			//$(".ArticleLayer").css('position','absolute');
			//alert($(".ArticleLayer").height());
		}

		PanelHeight = $(".ArticleLayer").height();
		PanelWidth = $(".ArticleLayer").width();
		// Positionierung
		$(".ArticleLayer").css('top', '100px');
		$(".ArticleLayer").css('left', (BrowserWidth / 2) - (PanelWidth / 2) + 'px');

		document.getElementById('divArticleLayer').style.display = 'block';

		$("ul.css-tabs").tabs("div.css-panes > div"); // Höhe des Layers
	} else {
		//alert('2: ' + document.getElementById('divArticleLayer'));
		window.setTimeout('ResizeArtileDetails()', 200);
	}
}

function ResizeCustomerSalesLayer() {
	if (document.getElementById('divCustomerSale') != undefined) {
		var PanelHeight = $(".ArticleLayerCustomerSale").height(); // Layegröße des öffnenden Fensters	
		var PanelWidth = $(".ArticleLayerCustomerSale").width(); // Layegröße des öffnenden Fensters
		var BrowserWidth = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth); // Browserfenstergröße	
		var BrowserHeight = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);
		//alert('w' + BrowserWidth + ' h' + BrowserHeight);
		//alert('w' + PanelWidth + ' h' + PanelHeight);
		//alert((BrowserHeight / 2) - (PanelHeight / 2));

		if (BrowserHeight < 700) {
			$(".ArticleLayerCustomerSale").height(BrowserHeight - 150);
		}

		PanelHeight = $(".ArticleLayerCustomerSale").height();
		PanelWidth = $(".ArticleLayerCustomerSale").width();
		// Positionierung
		$(".ArticleLayerCustomerSale").css('top', '100px');
		//$(".ArticleLayerCustomerSale").css('top', (BrowserHeight / 2) - (PanelHeight / 2) + 'px');
		$(".ArticleLayerCustomerSale").css('left', (BrowserWidth / 2) - (PanelWidth / 2) + 'px');
		//$('divCustomerSale').show();
		//alert('1: '+document.getElementById('divCustomerSale'));
		document.getElementById('divCustomerSale').style.display = 'block';
	} else {
		//alert('2: ' + document.getElementById('divCustomerSale'));
		window.setTimeout('ResizeCustomerSalesLayer()', 200);
	}
}

function ShowCustomerSales(ID) {
	//alert('hier');
	document.getElementById('divCustomerSaleBlack' + ID).style.visibility = 'visible';
	document.getElementById('divCustomerSale' + ID).style.visibility = 'visible';
	document.getElementById('divCustomerSaleBlack' + ID).style.display = 'inline';
	document.getElementById('divCustomerSale' + ID).style.display = 'block';
	
}

function HideCustomerSales(ID) {
	document.getElementById('divCustomerSaleBlack' + ID).style.visibility = 'hidden';
	document.getElementById('divCustomerSale' + ID).style.visibility = 'hidden';
	document.getElementById('divCustomerSaleBlack' + ID).style.display = 'none';
	document.getElementById('divCustomerSale' + ID).style.display = 'none';
}

function SetCurrentPriceAndTotalizePreOrder(SourceElementsName, IDPrefix, ResultElementID, PriceElementID, QuantityElement, CurrentPriceElementID) {
	var CurrentTotal = 0;
	//alert(PriceElementID);
	//alert(document.getElementById(PriceElementID).value);
	CurrentTotal = parseFloat(QuantityElement.value) * parseFloat(document.getElementById(PriceElementID).value);
	document.getElementById(CurrentPriceElementID).value = CurrentTotal;
	//alert(CurrentTotal);
	TotalizePreOrder(SourceElementsName, IDPrefix, ResultElementID);
}

function TotalizePreOrder(SourceElementsName, IDPrefix, ResultElementID) {
	var current;
	var currentID;
	var totalamount = 0;
	//alert(document.getElementsByName('ArticlePriceCurrent').length);
	for (var i = 0; i < document.getElementsByName(SourceElementsName).length; i++) {
		current = document.getElementsByName(SourceElementsName)[i]
		currentID = current.id.replace(IDPrefix, '')
		totalamount = totalamount + parseFloat(current.value);
		//alert(parseFloat(current.value) + ' - ' + current.id + ' - ' + current.name + ' - ' + currentID);
	}
	//alert('totalamount: ' + totalamount);
	document.getElementById(ResultElementID).innerHTML = totalamount.toFixed(2).replace('.',',');
}


function ShowCustomerSaleDetails(CustomerSaleCurrentNoteID) {
	document.getElementById('ctl00_ctl00_cphBC_cphC_tabStartpage_pnlCustomerSales_hidCustomerSaleCurrentNoteID').value = CustomerSaleCurrentNoteID;
	__doPostBack('ctl00$ctl00$cphBC$cphC$tabStartpage$pnlCustomerSales$btnShowCustomerSaleDetails', '');
	//window.setTimeout('ResizeCustomerSalesLayer()', 200);
}

function ShowArticleDetailsExt(ArticleNo, ShowAddToBasket, PreOrderArticle, PreOrderStartDate, DisplayOrderArticle) {

	document.getElementById('ctl00_ctl00_cphAD_hidArticleDetailsArticleNumber').value = ArticleNo;
	document.getElementById('ctl00_ctl00_cphAD_hidPreOrderArticle').value = PreOrderArticle;
	document.getElementById('ctl00_ctl00_cphAD_hidDisplayOrderArticle').value = DisplayOrderArticle;
	document.getElementById('ctl00_ctl00_cphAD_hidPreOrderStartDate').value = PreOrderStartDate;
	document.getElementById('ctl00_ctl00_cphAD_hidShowAddToBasket').value = ShowAddToBasket;
	__doPostBack('ctl00$ctl00$cphAD$btnShowArticleDetails', '');
	//window.setTimeout('ResizeArtileDetails()', 100);
}

function ShowArticleDetails(ArticleNo, DisplayOrderArticle) {
	document.getElementById('ctl00_ctl00_cphAD_hidArticleDetailsArticleNumber').value = ArticleNo;
	document.getElementById('ctl00_ctl00_cphAD_hidPreOrderArticle').value = '0';
	document.getElementById('ctl00_ctl00_cphAD_hidDisplayOrderArticle').value = DisplayOrderArticle;
	document.getElementById('ctl00_ctl00_cphAD_hidPreOrderStartDate').value = '';
	document.getElementById('ctl00_ctl00_cphAD_hidShowAddToBasket').value = '1';
	__doPostBack('ctl00$ctl00$cphAD$btnShowArticleDetails', '');
	//window.setTimeout('ResizeArtileDetails();', 100);
}


function LoadInvoice(rid, docno) 
	{
	var string;
	var adresse = '/shop/download/loadinvoice/'+rid+'/'+docno+'.pdf';
	var win = window.open(adresse, 'rechnung', 'width=350,height=160,resizable=yes,scrollbars=no,screenX=300,screenY=200');
	win.focus();
	}

function LabelPrinterCalibrate(PrinterID, TypeElement) {
	//alert('test');
	var LabelType = document.getElementById(TypeElement);
	//alert('/shop/download/labelprinter/' + LabelType[LabelType.selectedIndex].value + '/' + PrinterID + '/0/0/calibrate/calibrate.pdf');
	var win2 = window.open('/shop/download/labelprinter/' + LabelType[LabelType.selectedIndex].value + '/' + PrinterID + '/0/0/calibrate/calibrate.pdf');
}

function LabelPrinterCheck(PrinterID,TypeElement,XOffsetElement,YOffsetElement)
	{
	var LabelType = document.getElementById(TypeElement);
	var XOffsetElement = document.getElementById(XOffsetElement);
	var YOffsetElement = document.getElementById(YOffsetElement);
	//alert('/shop/download/labelprinter/' + LabelType[LabelType.selectedIndex].value + '/' + PrinterID + '/' + XOffsetElement.value + '/' + YOffsetElement.value + '/check/check.pdf');
	var win2 = window.open('/shop/download/labelprinter/' + LabelType[LabelType.selectedIndex].value + '/' + PrinterID + '/' + XOffsetElement.value + '/' + YOffsetElement.value + '/check/check.pdf');
	}

function LabelPrinterGenerate(PrinterElement,Type,Price,Border) 
	{
		var Printer = document.getElementById(PrinterElement);
		
		//alert('/shop/download/label/' + Type + '/' + Printer[Printer.selectedIndex].value + '/' + Price + '/' + Border + '/Label/Etiketten.pdf');
		var win2 = window.open('/shop/download/label/' + Type + '/' + Printer[Printer.selectedIndex].value + '/' + Price + '/' + Border + '/Label/Etiketten.pdf');
	}

	function SetCheckArticle(CheckboxElement) {
		var type = document.getElementById(CheckboxElement);

		type.checked = true;
	}

function MouseOutColor(obj, color) 
{
	// aktive Farbe ermitteln
	var ac_color = obj.style.backgroundColor;
	ac_color = '#CCA0A0'; 
	//if (obj.value.length > 0) 
	//{
	//if (color.length > 0) 
	//{
		//if (obj.value.length > 0) 
		//{
			return ac_color;
		//}

	//	else 
	//	{
	//		if (obj.value.length > 0) 
	//		{
	//			return ac_color;
	//		}
	//		
	//	}
	//}
	//}
	//else
	//{ return '#ffffff'; } 
}

//ArticleID -> ArticleNr
function ShowArtikelDetails(ArticleNr)
	{
	//var adresse = '/shop/article/' + ArticleID + '/details.html';
		//var win = window.open(adresse, 'dennit' + ArticleID, 'width=700,height=490,resizable=0,scrollbars=yes');

		var adresse = '/shop/article/' + ArticleNr + '/details.html';
		var win = window.open(adresse, 'dennit' + ArticleNr, 'width=700,height=490,resizable=0,scrollbars=yes');

	win.focus();
	}

function PrintOrderArchivDetails(OrderID, Year)
	{
	var adresse = '/shop/archive/orderprint/' + OrderID + '/' + Year + '/print.html';
	var win = window.open(adresse, 'dennit' + OrderID, 'width=700,height=800,resizable=yes,scrollbars=yes');
	win.focus();
}

function PrintOrderReservationDetails(Link) {
	var adresse = Link;
	var win = window.open(adresse, 'dennit', 'width=900,height=900,resizable=0,scrollbars=yes');
	win.focus();
}

function SetUniqueRadioButton(nameregex, current)   
	{
	re = new RegExp(nameregex);   
	for(i = 0; i < document.forms[0].elements.length; i++) 
		{ 
		elm = document.forms[0].elements[i] 
		if (elm.type == 'radio') 
			{ 
			if (re.test(elm.name)) 
				{ 
				elm.checked = false; 
				} 
			} 
		} 
	current.checked = true;
	}

	function ShowProductWheelFlash(Mode, CategoryID, Level1ID, Level2ID, KatalogartID) {
		var params = { wmode: "transparent" };
		var attributes = {};
		swfobject.embedSWF("/flash/Viewsion_ProductWheel.swf", "divProductWheel", "795", "350", "8.0.0", "", { xml_url: "/shop/xml/articlelist/productwheel/" + Mode + "/" + CategoryID + "/" + Level1ID + "/" + Level2ID + "/" + KatalogartID + "/list.xml", set_speed: "1", set_accel: "1", set_col: "0x7CAA00" }, params, attributes);
	}

	function ShowProductWheelFlashCampaign(CampaignNumber) {
		var params = { wmode: "transparent" };
		var attributes = {};
		swfobject.embedSWF("/flash/Viewsion_ProductWheel.swf", "divProductWheel", "795", "350", "8.0.0", "", { xml_url: "/shop/xml/articlelist/productwheel/campaign/" + CampaignNumber + "/list.xml", set_speed: "1", set_accel: "1", set_col: "0x7CAA00" }, params, attributes);
	}

var currentProductWheelArticleDetail = '';

//ArticleID -> ArticleNr
function showProductWheelArticleDetails(ArticleNr) {
	hideProductWheelArticleDetails();
	//d = document.getElementById('divArtikelDetails' + ArticleID);
	d = document.getElementById('divArtikelDetails' + ArticleNr);
	d.style.visibility = 'visible';
	//currentProductWheelArticleDetail = 'divArtikelDetails' + ArticleID;
	currentProductWheelArticleDetail = 'divArtikelDetails' + ArticleNr;
	}

function hideProductWheelArticleDetails() {
	if (currentProductWheelArticleDetail != '') {
		d = document.getElementById(currentProductWheelArticleDetail);
		d.style.visibility = 'hidden';
		currentProductWheelArticleDetail = '';
		}
	}

function swapLayers(id) {
	var cur_lyr; // holds id of currently visible layer
	if (cur_lyr) hideLayer(cur_lyr);
	showLayer(id);
	cur_lyr = id;
	}

function showLayer(id) {
	var lyr = getElemRefs(id);
	if (lyr && lyr.css) lyr.css.visibility = "visible";
	}

function hideLayer(id) {
	var lyr = getElemRefs(id);
	if (lyr && lyr.css) lyr.css.visibility = "hidden";
	}

function swapLayersDisplay(id) {
	var cur_lyr; // holds id of currently visible layer
	if (cur_lyr) hideLayerDisplay(cur_lyr);
	showLayerDisplay(id);
	cur_lyr = id;
	}

function showLayerDisplay(id) {
	var lyr = getElemRefs(id);
	if (lyr && lyr.css) lyr.css.display = "block";
	}

function hideLayerDisplay(id) {
	var lyr = getElemRefs(id);
	if (lyr && lyr.css) lyr.css.display = "none";
	}

function getElemRefs(id) {
	var el = (document.getElementById) ? document.getElementById(id) : (document.all) ? document.all[id] : (document.layers) ? document.layers[id] : null;
	if (el) el.css = (el.style) ? el.style : el;
	return el;
	}

function changeimg(bildname, dateiname) {
	document.images[bildname].src = dateiname;
}

function CheckAll(fmobj) {
	for (var i = 0; i < fmobj.elements.length; i++) {
		var e = fmobj.elements[i];
		if ((e.type == 'checkbox') && (!e.disabled)) {
			e.checked = true;
		}
	}
}

function ChangeValueQuantity(event, TypeID) {
	//event = event || window.event;
	var charCode = event.keyCode;
	
	if (charCode == 13) {
		__doPostBack(TypeID, '');
	}
}
//function DesignModeRichTextBox(RichTextBox1) {
//	document.getElementById(RichTextBox1).readOnly = false;
//	document.getElementById(RichTextBox1).disabled = false;
//}

function FormatRichTextBox(RichTextBox1) {

	var rteCp = new TRTEConstructorParameter();
	rteCp.siteURL = '';
	rteCp.adminURL = '';
	rteCp.documentContainer = window;
	rteCp.documentForm = document.forms[0];
	rteCp.editorPlaceHolderID = RichTextBox1;
	rteCp.editorWidth = 420;
	rteCp.editorHeight = 400;
	rteCp.cssstyle = '';
	rteCp.urlImage = '/image/TEditor/image';
	rteCp.urlCss = '/image/TEditor/css';
	rteCp.urlFilterEnabled = (1 == 1);
	rteCp.textBold = 'Fett';
	rteCp.textItalic = 'Kursiv';
	rteCp.textUnderline = 'Unterstrichen';
	rteCp.textLeftAlignment = 'Linksb&uuml;ndig';
	rteCp.textCenteredAlignment = 'Zentriert';
	rteCp.textRightAlignment = 'Rechtsb&uuml;ndig';
	rteCp.textUnorderedList = 'Ungeordnete Liste';
	rteCp.textOrderedList = 'Geordnete Liste';
	rteCp.textOutdent = 'Einr&uuml;ckung aufheben';
	rteCp.textIndent = 'Einr&uuml;cken';
	rteCp.textAssignTextColor = 'Textfarbe festlegen';
	rteCp.textAssignBackgroundColor = 'Hintergrundfarbe festlegen';
	rteCp.textRemoveFormat = 'Formatierungen entfernen';
	//	rteCp.textInsertLink = 'Link einf&uuml;gen oder bearbeiten';
	//	rteCp.textInsertImage = 'Bild einf&uuml;gen oder bearbeiten';
//	rteCp.textToggleCode = 'Zwischen HTML Code und Designer wechseln';
	rteCp.textTextColor = 'Textfarbe';
	rteCp.textBackgroundColor = 'Hintergrundfarbe';

	var rte_RichTextBox1 = new TRTEControl(rteCp);

		rte_RichTextBox1.showLinkConfigurationDialog = function(sender, link, modify, processText) {
		href = prompt('Bitte geben Sie die URL des Links an.', 'http://');
		if (href) {
			text = prompt('Bitte geben Sie einen Linknamen an.', 'Untitled link');
			if (text) {
				title = prompt('Bitte geben Sie eine Linkbeschreibung an oder lassen Sie das Feld leer.', '');
				sender.applyLinkConfiguration(link, modify, processText, href, text, '' + title);
			}
		}
	}
	rte_RichTextBox1.showImageConfigurationDialog = function(sender, image, modify) {
		src = prompt('Bitte geben Sie die URL des Bildes an.', 'http://');
		if (src) {
			alt = prompt('Bitte geben Sie eine Bildbeschreibung an oder lassen Sie das Feld leer.', '');
			sender.applyImageConfiguration(image, modify, src, alt);
		}
	}
	rteCp.innerHTML = '';
									
	}

//ArticleID -> ArticleNr
function ExecuteAJAXCallAddArticleToOrderblock(OrderblockID, ArticleNr, spanid) {
	document.getElementById(spanid).style.visibility = 'hidden';
	document.getElementById(spanid).style.display = 'none';
	$.ajax({
		//url: "/shop/Orderblock/AddArticleToOrderblock.ashx?OrderblockID=" + OrderblockID + "&ArticleID=" + ArticleID, 
		url: "/shop/Orderblock/AddArticleToOrderblock.ashx?OrderblockID=" + OrderblockID + "&ArticleNr=" + ArticleNr, 
		dataType: 'json', 
		success: Callback_AJAXCall 
		});
	}

function Callback_AJAXCall(data) {
	//alert("Callback_AJAXCall: " & data);
}

/* TEditor.js */

function TEditor()
{
	//private
	    var self = this;
		var designTool = 0;
		var htmlHelper = null;
		var rootDocument = null;
		var rootContainer = null; //window or frame, needed for key event readout
		var designMode = true;
		var guideLinesEnabled = false; //should editor set guidelines to new inserted objects
		var htmlCode = ''; //holds html code since last OnHTMLCodeChanged was called
		var initializeRunning = true;

		function getUniqueDOMID(baseName)
		{
			var baseCounter = 1;

			while (rootDocument.getElementById(baseName+'_'+baseCounter) || rootDocument.getElementsByName(baseName+'_'+baseCounter)[0])
			{
				baseCounter++;			
			}

			return baseName+'_'+baseCounter;
		}

		function getEditorElementFromSelection(rootDocument)
		{
			var object = null;
			var result = null;
			var type = "";
			var range = null;

			if (rootDocument.selection)
			{
				type = rootDocument.selection.type;

				if (type == "Text" || type == "None") //None is returned when changing cursor with keyboard
				{
					object = rootDocument.selection.createRange();
					range = object;
				}
				else
				if (type == "Control") //handle control range object
				{
					object = rootDocument.selection.createRange();
					range = object;

					var controls = object;
					if (controls.length > 0)
					{
						object = controls.item(0);
					}
				}
			}
			else
			{
				//mozilla
				selection = rootContainer.getSelection();
				if (selection.rangeCount > 0)
				{
					object = selection.getRangeAt(0);
					range = object;
					type = "Text";

					var fragment = object.cloneContents();

					if (fragment.firstChild && fragment.lastChild)
					{
						if ((fragment.firstChild === fragment.lastChild) && fragment.firstChild.tagName)
						{
							object = fragment.firstChild;
							type = "Control";
						}
					}
				}
			}

			if (object)
			{	
				result = new TEditorElement();
				result.initialize(rootDocument,object,type,self,range);
			}

			return result;	
		}

	//public
		this.selectedObject = new TEditorElement; //TEditorElement;
		this.blockEvents = false;
		this.htmlCodeEditable = false;

		//event functions
		this.registerEvent = function(object,eventName,eventHandler)
		{
			if (object)
			{
				//object.preventDefault;
				//alert(object.attachEvent);
				if (object.attachEvent) 
				{ return object.attachEvent('on'+eventName,eventHandler); } else
				{ return object.addEventListener(eventName,eventHandler,false); }
			}
			else
			{
				return false;
			}
		}
		
		this.unregisterEvent = function(object,eventName,eventHandler)
		{
			if (object)
			{
				if (object.detachEvent) 
				{ return object.detachEvent('on'+eventName,eventHandler); } else
				{ return object.removeEventListener(eventName,eventHandler,false); }
			}
		}

		//checks wether selected object is control or not
		this.selectedControl = function()
		{
			var result = null;

			if (this.selectedObject.isValid())
			{
				if (this.selectedObject.isControl())
				{
					result = this.selectedObject.getObject();	
				}
			}

			return result;
		}

		//updates selectedObject property
		this.refreshSelection = function()
		{
			this.handleElementSelectNotification(rootDocument);
		}

		//handles the selection of an object and stores a reference of the object to private variable and raises event
		this.handleElementSelectNotification = function(rootDocument)
		{
			var typeChanged = true;
			var idChanged = true;
			var obj = getEditorElementFromSelection(rootDocument);

			if (obj)
			{
				if (obj && this.selectedObject.isValid())
				{
					//handle selection changed between different selection types like Control and Text
					typeChanged = (obj.getType() != this.selectedObject.getType()) || (obj.getType() == "Control" && obj.getID() != this.selectedObject.getID());
					idChanged = (obj.getID() != this.selectedObject.getID());
				}
			
				this.selectedObject.assign(obj);

				if ( !this.blockEvents && (
						(obj.getType() != "Control") || 
						(obj.getType() == "Control" && (idChanged || typeChanged)) //we need this comparision to ensure the user can resize controls
					)
				) { this.OnElementSelected(this.selectedObject,typeChanged); }
			}
		}

		//enables or disables usage of guidelines
		this.enableGuideLines = function(value)
		{
			if (guideLinesEnabled != value)
			{
				guideLinesEnabled = value;
				this.setGuideLines(null,value);
			}
		}

		//returns if guidlines are enabled for DOM element or if undefined passed of editor
		this.getGuideLines = function(elementDOM)
		{
			if (elementDOM)
			{
				return elementDOM.style.borderStyle == 'dashed';
			}
			else
			{
				return guideLinesEnabled;
			}	
		}

		//shows or hides guidelines of and DOM element or if undefined passed of all DOM table elements
		this.setGuideLines = function(elementDOM,visible)
		{
			if (elementDOM)
			{
				if (visible)
				{
					if (elementDOM.style.borderStyle != 'dashed')	
					{ 
						elementDOM.style.borderStyle = 'dashed';
						elementDOM.style.borderWidth = '1';
						elementDOM.style.borderColor = '#AAAAAA';
					}
				}
				else
				{
					if (elementDOM.style.borderStyle == 'dashed')	
					{
						elementDOM.style.borderStyle = '';
						elementDOM.style.borderWidth = '';
						elementDOM.style.borderColor = '';
					}
				}
			}
			else
			{
				var tables = rootDocument.getElementsByTagName('table');
				var c = 0;
				while (c <= tables.length-1)
				{
					this.setGuideLines(tables[c],visible);
					c++;
				}

				var td = rootDocument.getElementsByTagName('td');	
				var c = 0;
				while (c <= td.length-1)
				{
					this.setGuideLines(td[c],visible);
					c++;
				}
			}
		}

		this.filterHTMLCode = function(value)
		{
			var result = value;
			
			//override to filter HTML code to your needs

			return result;
		}

		//is design mode enabled?
		this.getDesignMode = function()
		{
			return designMode;
		}

		//enables or disabled design mode
		this.setDesignMode = function(value)
		{
			if (value != designMode)
			{
				if (value == false)
				{
					//show html code
					this.selectedObject.reset();

					if (document.all)
					{
						rootDocument.body.innerText = this.filterHTMLCode(rootDocument.body.innerHTML);
					}
					else
					{
						rootDocument.body.textContent = this.filterHTMLCode(rootDocument.body.innerHTML);
					}

					rootDocument.body.className = 'bodyEditorHTMLMode';

					if (!this.htmlCodeEditable)
					{
						rootDocument.body.contentEditable = false;
						if (!document.all) { 
							rootDocument.designMode = 'off';
						}
					}

					designTool = 0;
				} 
				else					
				{
					//edit document in design mode
					
					if (!initializeRunning)
					{
						rootDocument.body.innerHTML = this.filterHTMLCode((document.all)?rootDocument.body.innerText:rootDocument.body.textContent);
					}

					rootDocument.body.contentEditable = true;
					if (!document.all) { 
						rootDocument.designMode = 'on'; //only needed for firefox 2, causes not working script in ie, http://devedge-temp.mozilla.org/viewsource/2003/midas/01/index_en.html
					}

					rootDocument.body.className = 'bodyEditorDesignMode';
				}
	
				designMode = value;
			}

			this.setNotifications(value);
			if (!this.blockEvents) { this.OnDesignerChanged(true); }
		}

		this.setDesignTool = function(value)
		{
			if (value != designTool)
			{
				designTool = value;
				if (!this.blockEvents) { this.OnDesignerChanged(false); }
			}
		}

		this.getDesignTool = function()
		{
			var result;

			//wenn kein designmodus oder kein element selektiert dann auch keine palette
			if (this.getDesignMode() && this.selectedObject.isValid()) { result = designTool; }  else { result = 0; }

			return result;
		}


		this.getDocumentHTMLCode = function()
		{
			var result = "";

			if (!this.getDesignMode())
			{
				result = (document.all)?rootDocument.body.innerText:rootDocument.body.textContent;		
			} 
			else					
			{
				result = rootDocument.body.innerHTML;
			}

			return result;
		}
		
		this.getDocumentFormFields = function()
		{
			var result = new Array();

			elements = rootDocument.getElementsByTagName('input');
			for (c=0;c<=elements.length-1;c++) { result.push(elements[c]); }

			elements = rootDocument.getElementsByTagName('select');
			for (c=0;c<=elements.length-1;c++) { result.push(elements[c]); }

			elements = rootDocument.getElementsByTagName('textarea');
			for (c=0;c<=elements.length-1;c++) { result.push(elements[c]); }

			return result;
		}

		this.getDocument = function()
		{
			return rootDocument;
		}

		this.getContainer = function()
		{
			return rootContainer;
		}

		this.raiseHTMLCodeChanged = function()
		{
			currentHTMLCode = this.getDocumentHTMLCode();

			if (htmlCode != currentHTMLCode)
			{
				htmlCode = currentHTMLCode;
				if (!this.blockEvents) { this.OnHTMLCodeChanged(); }
			}
		}
		
		this.onMouseUpHandler = function(eventObject)
		{
			var event = eventObject;
			var keyCode = null;

			if (!event) { event = rootContainer.event; }

			if ((document.all && !window.opera && event.button == 1) || ((!document.all || window.opera) && event.button == 0)) //allow left mouse button only
			{
				if (!getEditorElementFromSelection(rootDocument))
				{
					//alert('Bitte klicken Sie zuerst an eine freie Stelle im Formular bevor Sie zum ersten mal ein Element ausww&auml;hlen.');
					//alert(document.elementFromPoint(event.x, event.y).outerHTML)
					//document.elementFromPoint(event.x, event.y).setActive();
					//document.elementFromPoint(event.x, event.y).focus();
					self.selectElement(null);
				}
				else
				{
				    self.refreshSelection();
				}
			}
		}
		
		this.onKeyUpHandler = function(eventObject)
		{
		    var event = eventObject;
		    var keyCode = null;

		    if (!event) { event = rootContainer.event; }
		    if (event.which) { keyCode = event.which; } else { keyCode = event.keyCode; }

		    if (keyCode)	
		    {
			    //http://msdn.microsoft.com/workshop/author/dhtml/reference/events/onkeyup.asp
    			
			    self.OnKeyUp(keyCode);
			    if (
				    keyCode == 13 || 	//enter
				    keyCode == 46 || 	//delete
				    keyCode == 37 || 	//left
				    keyCode == 38 || 	//up
				    keyCode == 39 || 	//right
				    keyCode == 40 || 	//bottom
				    keyCode == 36 || 	//pos
				    keyCode == 35 || 	//end
				    keyCode == 34 || 	//pgdn
				    keyCode == 33		//pgup
			    ) 	{ self.refreshSelection(); }
			    else 	
				{ self.raiseHTMLCodeChanged(); }
		    }
		}

		this.setNotifications = function(value)
		{
			if (value)
			{
				//register notifications
				this.registerEvent(rootDocument.body,'mouseup',this.onMouseUpHandler);
				this.registerEvent(rootDocument.body,'keyup',this.onKeyUpHandler);
			}
			else
			{
				//unregister notifications
				this.unregisterEvent(rootDocument.body,'mouseup', this.onMouseUpHandler);
				this.unregisterEvent(rootDocument.body,'keyup', this.onKeyUpHandler);
			}
		}
	
		//first method that should be called, container is window or frame
		this.initialize = function(container,enableDesignMode,enableGuideLines,designTool)
		{
			htmlHelper = new THTMLHelper;
			rootContainer = container;
			rootDocument = rootContainer.document;

			rootDocument.body.MultipleSelection = false;

			designMode = !enableDesignMode;

			this.setDesignMode(enableDesignMode);
			this.enableGuideLines(enableGuideLines);
			this.setDesignTool(designTool);

			initializeRunning = false;
		}

		//inserts object nearby an existing element passed to parameter nearestElement
		this.insertElement = function(nearestElement,elementID)
		{
			var result = null;

			if (nearestElement.getObject().execCommand)
			{
				var location = nearestElement.getObject();
				var uniqueID = getUniqueDOMID(elementID);

				if (elementID == 'upload') { location.execCommand('InsertInputImage',false,uniqueID); } else
				if (elementID == 'text') { location.execCommand('InsertInputText',false,uniqueID); } else
				if (elementID == 'hidden') { location.execCommand('InsertInputHidden',false,uniqueID); } else
				if (elementID == 'password') { location.execCommand('InsertInputPassword',false,uniqueID); } else
				if (elementID == 'dropdown') { location.execCommand('InsertSelectDropdown',false,uniqueID); } else
				if (elementID == 'submit') { location.execCommand('InsertInputSubmit',false,uniqueID); } else
				if (elementID == 'reset') { location.execCommand('InsertInputReset',false,uniqueID); } else
				if (elementID == 'textarea') { location.execCommand('InsertTextArea',false,uniqueID); } else
				if (elementID == 'checkbox') { location.execCommand('InsertInputCheckbox',false,uniqueID); } else
				if (elementID == 'radio') { location.execCommand('InsertInputRadio',false,uniqueID); } else
				if (elementID == 'file') { location.execCommand('InsertInputFileUpload',false,uniqueID); } else
				if (elementID == 'button') { location.execCommand('InsertInputButton',false,uniqueID); } else
				if (elementID == 'table') { 
					elementArray = htmlHelper.createTable(rootDocument);

					this.setGuideLines(elementArray[0],this.getGuideLines(null)); //table
					this.setGuideLines(elementArray[3],this.getGuideLines(null)); //tcell

					nearestElement.getObject().pasteHTML(elementArray[0].outerHTML); 
				}

				result = getEditorElementFromSelection(rootDocument);
				if (elementID == 'checkbox') { result.setValue(1); }
				if (elementID == 'upload') { result.setSource('/images/controls/upload.gif'); }

				if (result)
				{
					if (!this.blockEvents) { this.OnElementInserted(result,elementID); }
					this.refreshSelection();
				}
			}

			return result;
		}

		this.selectElement = function(element)
		{
			if (element) 
			{
				element.select();
			} 
			else
			{
				if (rootDocument.selection)
				{
					rootDocument.selection.empty();
				}
				this.selectedObject.reset();
			}

			this.refreshSelection();
		}

		this.deleteElement = function(element)
		{
			if (element)
			{
				//todo,element direkt l&ouml;schen
			}
			else
			{
				if (rootDocument.selection) 
				{
					if (this.selectedObject)
					{
						var elementID = this.selectedObject.getID();

						this.selectedObject.select();
						rootDocument.selection.createRange().select();
						rootDocument.selection.createRange().execCommand('Delete',false,null);
						
						this.selectElement(null);
						if (!this.blockEvents) { this.OnElementDeleted(elementID); }
					}
				}
			}
		}
				
		//events, override to customize handling
		//typeChanged means that previously selected element had another type
		this.OnElementSelected = function(element,typeChanged)
		{
			
		}

		this.OnElementInserted = function(element,elementID)
		{

		}

		this.OnElementDeleted = function(elementID)
		{
			
		}

		this.OnDesignerChanged = function(refreshProperties)
		{
	
		}

		this.OnKeyDown = function(keyCode)
		{
			return true; //don't cancel event chain		
		}

		this.OnKeyUp = function(keyCode)
		{
	
		}

		this.OnHTMLCodeChanged = function()
		{

		}
}


/* TEditorElement.js */

function TEditorElement()
{
	//private
		var self = this;
		var htmlHelper = null; //THTMLHelper
		var object = null;
		var objectDocument = null;
		var range = null;
		var type = ""; //selection type e.g. "Control"
		var objectEnclosingTableCell = null;
		var valid = false;
		var editor = null;

		function OnChanged()
		{
			if (editor)
			{
				editor.raiseHTMLCodeChanged();
			}
		}

		//returns parent object 
		function getParentObject(obj)
		{
			if (object.tagName) 
			{
				//if tagName defined then DHTML object like TD,DIV,...
				return object.parentNode;
			}
			else
			{
				//if tagName not defined then object is a Range
				if (object.parentElement || object.startContainer)
				{
					return (document.all)?range.parentElement():range.startContainer.parentNode;
				}
				else
				{
					return false;
				}
			}	
		}

		//if necessary creates tag and gets tag object enclosing current object
		function getEnclosedTag(tagName,forceCreate)
		{
			var parentObject = getParentObject(object);
			if (parentObject)
			{
				var c = 0;
				var found = false;
				while (c <= tagName.length-1 && !found)
				{
					if (parentObject.tagName.toLowerCase() == tagName[c].toLowerCase())
					{
						found = true;
					}
					else
					{
						c++;
					}
				}

				if (!found && forceCreate)
				{
					c--;

					if (object.insertAdjacentHTML)
					{
						object.insertAdjacentHTML('beforeBegin', '<'+tagName[c].toLowerCase()+'></'+tagName[c].toLowerCase()+'>');	
						parentObject = object.previousSibling;
						parentObject.appendChild(object);
					}
					else
					{	
						object.execCommand('FormatBlock',false,'<'+tagName[c].toLowerCase()+'>');
						parentObject = object.parentElement();
					}			
				}
			}
		
			return parentObject;
		}

		function getEnclosedStyle(htmlAttribute)
		{
			parentObject = getEnclosedTag(new Array('div','p','font'),false);
			if (parentObject) { return parentObject.getAttribute(htmlAttribute,0); } else { return ''; }
		}

		function setEnclosedStyle(tag,htmlAttribute,value)
		{
			parentObject = getEnclosedTag(new Array(tag),true);
			if (parentObject) 
			{
				parentObject.setAttribute(htmlAttribute,value,0);
				parentObject.outerHTML = parentObject.outerHTML; //to ensure that dom object refreshes itself after value assigned
			}
		}

		function setFormat(styleID,styleValue)
		{
			if (object)
			{
				var execObject = (object.execCommand)?object:objectDocument;

				//second process properties depending on object type
				if (type == "Text")
				{
					if (styleID == "Class" || styleID == "Style") 
					{ 		
						var collapsed = (document.all)?range.text=='':range.collapsed;

						//we have to first check common anchestor in fuckin firefox because it returns parent node as common anchestor
						//when selection over multiple format tags else it returns it in parentNode

						var outerObject = (document.all)?range.parentElement():(range.commonAncestorContainer.tagName?range.commonAncestorContainer:range.commonAncestorContainer.parentNode);
						var outerObjectText = (document.all)?outerObject.innerText:outerObject.textContent;
						var rangeText = (document.all)?range.text:range.toString();

						//first we check wether we should assign stuff directly to element enclosing selection
						if (collapsed || outerObjectText == rangeText) 
						{
							//do nothing, we process outer object directly
						}
						else
						{
							execObject.execCommand('RemoveFormat',false,'');
							execObject.execCommand('FontName',false,'selected');
							
							var generatedTagName = (document.all)?'font':'span';
							var createdObject = null;

							//todo: we have to search node with recursion or complete dokument to ensure processing of elements that were not inserted in the same level (e.g. when formating a string inside an existing format tag, browser splits tags, not same level!)
							var i = 0;
							while (i <= outerObject.childNodes.length-1 && !createdObject)
							{
								var childNode = outerObject.childNodes[i];
								if (childNode.tagName)
								{
									if (childNode.tagName.toLowerCase() == generatedTagName.toLowerCase())
									{
										if (childNode.style.fontFamily == 'selected' || childNode.face == 'selected')
										{
											createdObject = childNode;
										}
									}
								}
								i++;
							}

							createdObject.removeAttribute('style',0);
							createdObject.removeAttribute('face',0);

							outerObject = createdObject;
						}

						switch (styleID)
						{
							case "Class" : outerObject.className = styleValue; break;
							case "Style" : outerObject.style.cssText = styleValue; break;
						}

						OnChanged();
					} else
					if (styleID == "FontSize") { execObject.execCommand('FontSize',false,styleValue); OnChanged(); } else
					if (styleID == "FontName") { execObject.execCommand('FontName',false,styleValue); OnChanged(); } else
					if (styleID == "ForeColor") { execObject.execCommand('ForeColor',false,styleValue); OnChanged(); } else
					if (styleID == "BackColor") { execObject.execCommand((document.all && !window.opera)?'BackColor':'hilitecolor',false,styleValue); OnChanged(); } else
					if (styleID == "Bold") { execObject.execCommand('Bold',false,null); OnChanged(); } else
					if (styleID == "Italic") { execObject.execCommand('Italic',false,null); OnChanged(); } else
					if (styleID == "Underline") { execObject.execCommand('Underline',false,null); OnChanged(); } else
					if (styleID == "Sub") { execObject.execCommand('Superscript',false,null); OnChanged(); } else
					if (styleID == "Sup") { execObject.execCommand('Subscript',false,null); OnChanged(); } else
					if (styleID == "Alignment") { execObject.execCommand('Justify'+styleValue.substr(0,1).toUpperCase()+styleValue.substr(1,styleValue.length),false,null); OnChanged(); }
				
				}
				else if (type == "Control")
				{
				//http://msdn.microsoft.com/en-us/library/ms531169(VS.85).aspx - Command 
					if (styleID == "Class") { object.className = styleValue; OnChanged(); } else
					if (styleID == "FontSize") { object.style.fontSize = styleValue; OnChanged(); } else
					if (styleID == "FontName") { object.style.fontFamily = styleValue; OnChanged(); } else
					if (styleID == "ForeColor") { object.style.color = styleValue; OnChanged(); } else
					if (styleID == "BackColor") { object.style.background = styleValue; OnChanged(); } else
					if (styleID == "Bold") { object.style.fontWeight = styleValue==1?'bold':'normal'; OnChanged(); } else 
					if (styleID == "Italic") { object.style.fontStyle = styleValue==1?'italic':'normal'; OnChanged(); } else 
					if (styleID == "Underline") { object.style.textDecorationUnderline = (styleValue == 1); OnChanged(); } else
					if (styleID == "Sub") { object.style.textDecorationUnderline = (styleValue == 1); OnChanged(); } else
					if (styleID == "Sup") { object.style.textDecorationUnderline = (styleValue == 1); OnChanged(); } else
					if (styleID == "Alignment") { setEnclosedStyle("div","align",styleValue); }
				}			
			}
		}

		function getFormat(styleID)
		{
			result = null;
			result = '';

			//second process properties depending on object type
			if (type == "Text")
			{
				if (styleID == "Class" || styleID == "Style") {
					parentObject = (document.all)?range.parentElement():(range.commonAncestorContainer.tagName?range.commonAncestorContainer:range.commonAncestorContainer.parentNode);
						
					switch (styleID)
					{
						case "Class" : result = parentObject.className; break;
						case "Style" : result = parentObject.style.cssText; break;
					}

				} else
				if (styleID == "FontSize") { 
					result = object.queryCommandValue('FontSize');
					//if (!result) { result = object.queryCommandValue('FontSize'); } 
				} else
				if (styleID == "FontName") { 
					result = getEnclosedStyle('face');
					if (!result) { result = object.queryCommandValue('FontName'); } 
				} else
				if (styleID == "ForeColor") { 
					//object returns value where bytes order is inverted, using function to invert order and shift 8 bits right to get the hex color code
					//e.g. returns #EFCDAB
					//     -> bigEndianToLittleEndian = #ABCDEF00
					//     -> #ABCDEF00 >> 8 = #FFABCDEF
					//     -> #FFABCDEF & #00FFFFFF = #ABCDEF
					result = int2Hex (((bigEndianToLittleEndian(object.queryCommandValue('ForeColor'))>> 8 )&0x00FFFFFF));
				} else
				if (styleID == "BackColor") { 
					result = int2Hex (((bigEndianToLittleEndian(object.queryCommandValue('BackColor'))>> 8 )&0x00FFFFFF));
				} else
				if (styleID == "Bold") { result =(object.queryCommandValue)?object.queryCommandValue('Bold'):false; } else
				if (styleID == "Italic") { result =(object.queryCommandValue)?object.queryCommandValue('Italic'):false; } else
				if (styleID == "Underline") { result =(object.queryCommandValue)?object.queryCommandValue('Underline'):false; } else
				if (styleID == "Alignment") 
				{	
					if (object.queryCommandValue)
					{	
						if (object.queryCommandValue('JustifyLeft')) { result = 'left'; } else
						if (object.queryCommandValue('JustifyCenter')) { result = 'center'; } else
						if (object.queryCommandValue('JustifyRight')) { result = 'right'; }
					}
					else
					{
						result = 'left';	
					}
				}
			}
			else if (type == "Control")
			{
				if (styleID == "Class") { result = object.className; } else
				if (styleID == "FontSize") { result = object.style.fontSize; } else
				if (styleID == "FontName") { result = object.style.fontFamily; } else
				if (styleID == "ForeColor") { result = object.style.color; } else
				if (styleID == "BackColor") { result = object.style.bgcolor; } else
				if (styleID == "Bold") { result = object.style.fontWeight == 'bold'; } else
				if (styleID == "Italic") { result = object.style.fontStyle == 'italic'; } else
				if (styleID == "Underline") { result = object.style.textDecorationUnderline; } else
				if (styleID == "Alignment") { result = getEnclosedStyle("align"); }
			}

			return result;
		}

		function int2Hex(value)
		{
			result = '';
			digits = '0123456789ABCDEF';
			
			//groesstes vielfache ermitteln
			factor = 16;
			while (factor < value)
			{
				factor *= 16;
			}

			//solange zahl mit vielfachen dividieren bis wert < 16
			while (value > 15)		
			{
				naturalpart = Math.floor(value / factor);
				decimalpart = (value % factor);

				result += digits.charAt(naturalpart);
				value  -= naturalpart*factor;
		
				//vielfache um basis 16 verringern um an naechste hex stelle zu kommen
				factor = factor / 16;
			}

			if (result.substr(0,1) == '0') { result = result.substr(1,result.length); }

			while (factor >= 16)
			{
				result += "0";
				factor = factor / 16;
			}
		
			result += digits.charAt(value);

			while ((result.length % 2 > 0) || (result.length < 6))
			{
				result = '0'+result;	
			}

			return '#'+result;
		}

		function bigEndianToLittleEndian(value)
		{
			byte1 = (value >> 24) & 0x000000FF;
			byte2 = (((value >> 16) & 0x000000FF) << 8) & 0x0000FF00;
			byte3 = (((value >> 8) & 0x000000FF) << 16) & 0x00FF0000;
			byte4 = ((value & 0x000000FF) << 24) & 0xFF000000;

			return byte1+byte2+byte3+byte4;
		}

	//public
		this.isValid = function()
		{
			return valid;
		}

		this.getAttributeValue = function(attributeName)
		{ 
			var result = '';
			if(object) 
			{ 
				if (object.getAttribute)
				{
					result = object.getAttribute(attributeName,0);
					if (result == null) { result = ''; }
				}
			}

			//avoid DOM bug, dom returns "on" when no value attribute is set
			if(attributeName.toLowerCase() == 'value' && result.toLowerCase() == 'on') { result = ''; }

			return result;
		}

		this.setAttributeValue = function(attributeName,value)
		{
			var result = false;
			if(object) 
			{ 
				if (object.getAttribute) 
				{
					object.setAttribute(attributeName,value,0); 
					OnChanged();

					result = true;
				}
			}

			return result;
		}

		this.getType = function()
		{
			result = type;
			//if (objectEnclosingTableCell) { result = 'TableCellText'; }
			
			return result;
		}

		//returns the value of the type= attribute of an input tag
		this.getInputType = function()
		{
			var result = '';

			if (object.type)
			{
				result = object.type;
			}

			return result;
		}

		this.getObjectType = function()
		{
			result = '';
			if (object.nodeName) { result = object.nodeName; }

			return result;
		}

		this.executeCommand = function(commandID,commandValue)
		{
			value = commandValue == '' ? 'selected' : commandValue;

			var execObject = (object.execCommand)?object:objectDocument;

			execObject.execCommand(commandID,false,value);

			if (commandID == 'FontName' && commandValue == '')
			{
				parentObject = getEnclosedTag(new Array('font'),true);
				if (parentObject)
				{
					if (parentObject.ownerDocument)
					{
						fontArray = parentObject.ownerDocument.all.tags("FONT");
						for (i=0; i<fontArray.length; i++)
						{
							if (fontArray[i].face == value)
							{
								fontArray[i].outerHTML = fontArray[i].outerHTML.replace(/ face=selected/i,"");
							}
						}
					}
				}
			}
		}

		//functions to manipulate shape of editor elements
		this.addTableCell = function(position)
		{ 
			if (this.canModifyTable())
			{	
				tdArray = htmlHelper.addTableCell(objectEnclosingTableCell,position);
				if (tdArray)
				{
					for (c=0;c<=tdArray.length-1;c++) { editor.setGuideLines(tdArray[c],editor.getGuideLines(null)); }
					OnChanged();
				}
			}
		}

		//deletes the current active table cell
		this.deleteTableCell = function()
		{		
			if (this.canModifyTable())
			{	
				if (htmlHelper.deleteTableCell(objectEnclosingTableCell,objectEnclosingTableCell.cellIndex))
				{
					editor.refreshSelection();
					OnChanged();
				}
				else
				{
					alert('Die Spalte konnte nicht gel&ouml;scht werden. \n\nM&ouml;glicherweise befinden sich Formularelemente in der aktuellen Spalte. Bitte entfernen Sie diese vorher.');
				}
			}	
		}

		this.addTableRow = function(position) 
		{ 
			if (this.canModifyTable())
			{
				tdArray = htmlHelper.addTableRow(objectEnclosingTableCell,position);
				if (tdArray)
				{
					for (c=0;c<=tdArray.length-1;c++) { editor.setGuideLines(tdArray[c],editor.getGuideLines(null)); }
					OnChanged();
				}
			}
		}

		//deletes the current active table cell
		this.deleteTableRow = function()
		{		
			if (this.canModifyTable())
			{	
				errorDescription = '';
				if (htmlHelper.deleteTableRow(objectEnclosingTableCell,objectEnclosingTableCell.parentElement.rowIndex,errorDescription))
				{
					editor.refreshSelection();
					OnChanged();
				}
				else
				{
					alert('Die Zeile konnte nicht gel&ouml;scht werden. \n\nM&ouml;glicherweise befinden sich Formularelemente in der aktuellen Zeile. Bitte entfernen Sie diese vorher.');
				}
			}	
		}

		this.removeFormat = function() 
		{ 
			if (object)
			{
				var execObject = (object.execCommand)?object:objectDocument;
			
				if (type == "Text")
				{	
					execObject.execCommand('removeFormat',null,null);
				}
				else if (type == "Control")
				{
					object.removeAttribute('style',0);
					object.removeAttribute('className',0);
				}

				OnChanged();
			}
		}

		this.addOption = function(value,text) { if (htmlHelper.addOption(object,value,text)) { OnChanged(); } }
		this.deleteOption = function() { if (htmlHelper.deleteOption(object)) { OnChanged(); } }
		this.updateOption = function(value,text) { if (htmlHelper.updateOption(object,object.selectedIndex,value,text)) { OnChanged(); } }
		this.moveOption = function(offset) { if (htmlHelper.moveOption(object,object.selectedIndex,offset)) { OnChanged(); } }
		this.getSelectedIndex = function() { if (object.selectedIndex >= 0) { return object.selectedIndex; } else { return -1; } }
		this.getOption = function(index) { if (object.selectedIndex >= 0) { return object.options(index); } else { return null; } }

		this.getFontName = function() { return getFormat("FontName"); }
		this.setFontName = function(value) { setFormat("FontName",value); }
		this.getFontSize = function() { return getFormat("FontSize"); }
		this.setFontSize = function(value) { setFormat("FontSize",value); }
		this.getForeColor = function() { return getFormat("ForeColor"); }
		this.setForeColor = function(value) { setFormat("ForeColor",value); }
		this.getBackColor = function() { return getFormat("BackColor"); }
		this.setBackColor = function(value) { setFormat("BackColor",value); }
		this.getClass = function() { return getFormat("Class"); }
		this.setClass = function(value) { setFormat("Class",value); }
		this.getStyle = function() { return getFormat("Style"); }
		this.setStyle = function(value) { setFormat("Style",value); }
		this.getAlignment = function() { return getFormat("Alignment"); }
		this.setAlignment = function(value) { setFormat("Alignment",value); }
		this.setBold = function(value) { setFormat("Bold",value); }
		this.getBold = function() { return getFormat("Bold"); }
		this.setItalic = function(value) { setFormat("Italic",value); }
		this.getItalic = function() { return getFormat("Italic"); }
		this.setUnderline = function(value) { setFormat("Underline",value); }
		this.getUnderline = function() { return getFormat("Underline"); }
		
		this.setSub = function(value) { setFormat("Sub",value); }
		this.getSub = function() { return getFormat("Sub"); }
		
		this.setSup = function(value) { setFormat("Sup",value); }
		this.getSup = function() { return getFormat("Sup"); }
		
		this.setEditable = function(value) { if (object) { object.contentEditable = value; OnChanged(); } } 
		this.select = function() 
		{ 
			if (object) { 
				if (this.isControl()) 
				{
					object.setActive();
				}
				if (object.focus) object.focus(); 
			}
		}
		
		this.getID = function() { return this.getAttributeValue('id'); }
		this.setID = function(value) { return this.setAttributeValue('id',value); }
		this.getValue = function() { return this.getAttributeValue('value'); }
		this.setValue = function(value) { return this.setAttributeValue('value',value); }
		this.getSource = function() { return this.getAttributeValue('src'); }
		this.setSource = function(value) { return this.setAttributeValue('src',value); }

		this.isControl = function() { return (type == "Control"); }
		this.canModifyTable = function() { return (objectEnclosingTableCell != null); }
		
		//call this method first and pass a selected object and the appropriate selection type
		this.initialize = function(domDocument, domObject,selectionType,editorObject,selectionRange)
		{
		   	editor = editorObject;
			htmlHelper = new THTMLHelper;
			object = domObject;
			objectDocument = domDocument;
			range = selectionRange;

			type = selectionType; 	
			if (type == "None") { type = "Text"; } 

			objectEnclosingTableCell = null;
			if (type == "Text")
			{
				var obj = getParentObject(object);
				if (obj)
				{
					var tableFound = (obj.tagName == 'TD');

					while (!tableFound && obj.tagName != 'BODY' && obj.parentNode)
					{
						obj = obj.parentNode;
						tableFound = (obj.tagName == 'TD');			
					}

					if (tableFound) { objectEnclosingTableCell = obj; }
				}
			}

			valid = true;
		}

		this.assign = function(source)
		{
			this.initialize(source.getDocument(), source.getObject(),source.getType(),source.getEditor(),source.getRange());	
		}

		this.reset = function()
		{
			valid = false;
		}	

		this.getObject = function()
		{
			return object;
		}

		this.getDocument = function()
		{
			return objectDocument;
		}

		this.getEditor = function()
		{
			return editor;
		}

		this.getRange = function()
		{
			return range;
		}
}


/* THTMLHelper.js */

function THTMLHelper()
{
	this.createTable = function(document)
	{
		var table	= document.createElement('table');
		var tbody	= document.createElement('tbody');
		var trow	= document.createElement('tr');
		var tcell	= document.createElement('td');
		tcell.innerText = 'Tabellentext';

		table.appendChild(tbody);
		tbody.appendChild(trow);
		trow.appendChild(tcell);

		return new Array(table,tbody,trow,tcell);
	}	

	//adds cell next to existing TD object and returns array of td objects created on success
	this.addTableCell = function(objTD,position)
	{ 
		var result = null;

		if (objTD)
		{	
			td = objTD;

			tr = this.getParent(td,new Array('TR'));
			if (tr)
			{
				table = this.getParent(tr,new Array('TABLE','TBODY'));
				if (table)
				{			
					if (position == 'left')
					{
						tdIndex = td.cellIndex;
					}		
					else
					{
						tdIndex = td.cellIndex+1;
						if (tdIndex > tr.cells.length) { tdIndex = tr.cells.length; }		
					}

					trList = table.rows;

					result = new Array();
				
					c = 0;
					while (c <= trList.length-1)
					{
						td = trList.item(c).insertCell(tdIndex);
						td.text = '';	

						result.push(td);
										
						c++;
					}
				}
			}	
		}

		return result;
	}

	//adds row next to existing TD object and returns array of td objects created on success
	this.addTableRow = function(objTD,position) 
	{ 
		var result = null;

		if (objTD)
		{
			tr = this.getParent(objTD,new Array('TR'));
			if (tr)
			{
				table = this.getParent(tr,new Array('TABLE','TBODY'));
				if (table)
				{
					if (position == 'top')
					{
						trIndex = tr.rowIndex;
					}
					else
					{
						trIndex = tr.rowIndex+1;
						if (trIndex > table.rows.length) { trIndex = table.rows.length; }		
					}

					trNew = table.insertRow(trIndex);

					result = new Array();
				
					tdList = tr.cells;
					c = 0;
					while (c <= tdList.length-1)
					{
						td = tdList.item(c).cloneNode(false);
						td.innerText = '';
			
						result.push(td);
								
						trNew.appendChild(td);
						c++;
					}
				}
			}
		}

		return result;
	}

	//returns the next table cell object selected after deleting
	this.deleteTableCell = function(objTD,index,errorDescription)
	{
		var result = null;

		if (objTD)
		{	
			td = objTD;
			
			tr = this.getParent(td,new Array('TR'));
			if (tr)
			{
				table = this.getParent(tr,new Array('TABLE','TBODY'));
				if (table)
				{
					//loop trough all cells to determine if controls are inside, then abort action
					abort = false;
					r = 0;

					while (r <= table.rows.length-1)
					{
						if (table.rows.item(r).cells.length >= 0 && index <= table.rows.item(r).cells.length-1)
						{
							i = 0;
							while (i <= table.rows.item(r).cells.item(index).childNodes.length-1)
							{
								abort = abort || this.containsControl(table.rows.item(r).cells.item(index));
						
								i++;
							}
						}
	
						r++;
					}

					if (!abort)
					{
						if (tr.cells.length > 1) //to avoid that invisible table is created
						{
							if (td.previousSibling) { result = td.previousSibling; } else 
									{ result = td.nextSibling; }
		
							trList = table.rows;
								
							c = 0;
							while (c <= trList.length-1)
							{
								if (index >= 0 && index <= trList.item(c).cells.length-1)
								{
									trList.item(c).deleteCell(index);
								}
		
								c++;
							}
						}
					}
				}
			}
		}

		return result;	
	}

	//returns the next table row object selected after deleting
	this.deleteTableRow = function(objTD,index)
	{
		var result = null;

		if (objTD)
		{
			tr = this.getParent(objTD,new Array('TR'));
			if (tr)
			{
				//loop trough all cells to determine if controls are inside, then abort action
				abort = false;
				c = 0;
				while (c <= tr.cells.length-1)
				{
					i = 0
					while (i <= tr.cells.item(c).childNodes.length-1)
					{
						abort = abort || this.containsControl(tr.cells.item(c));
			
						i++;
					}

					c++;
				}

				if (!abort)
				{
					table = this.getParent(tr,new Array('TABLE','TBODY'));
					if (table)
					{
						if (table.rows.length > 1) //to avoid that invisible table is created
						{
							if (tr.previousSibling) { result = tr.previousSibling; } else 
										{ result = tr.nextSibling; }
								if (index >= 0 && index <= table.rows.length-1)
							{
								table.deleteRow(index);
							}
						}
					}
				}
			}
		}

		return result;	
	}

	//returns true if controls are detected in childen collection
	this.containsControl = function(obj)
	{
		var result = false;

		if (obj)
		{
			if (obj.childNodes)
			{
				var i = 0;
				while (i <= obj.childNodes.length-1)
				{
					if (obj.childNodes.item(i))
					{
						if (
							obj.childNodes.item(i).tagName == 'INPUT'  || 
							obj.childNodes.item(i).tagName == 'SELECT' ||
							obj.childNodes.item(i).tagName == 'TEXTAREA'
						)
						{
							result = true;
						}
						else
						{
							result = result || this.containsControl(obj.childNodes.item(i));
						}
					}
		
					i++;
				}


			}
		}
	
		return result;
	}
	
	//returns specific parent (equal to given tag name) from the parent queue
	this.getParent = function(obj, parentTagNameArray)
	{
		var result = null;
		var abort = true;
		var p = obj.parentElement;

		if (p)
		{ 
			abort = false; 
			c = 0;
			while (c <= parentTagNameArray.length-1 && !abort)
			{
				if (parentTagNameArray[c] == p.tagName)
				{
					abort = true; 
					result = p;	
				}

				c++;
			}

		} 
		else
		{
			abort = true;
		} 

		while (!abort)	
		{
			if (p.parentElement)
			{
				p = p.parentElement;
			
				abort = false; 
				c = 0;
				while (c <= parentTagNameArray.length-1 && !abort)
				{
					if (parentTagNameArray[c] == p.tagName)
					{
						abort = true; 
						result = p;	
					}

					c++;
				}
			}
			else
			{ 
				abort = true; 
			}
		}

		return result;
	}
	
	this.addOption = function(objSelect,value,text)
	{
		var result = null;
		
		if (objSelect)
		{
			var option = objSelect.ownerDocument.createElement('OPTION');
			option.value = value;
			option.innerText = text;	

			objSelect.appendChild(option);
			
			var c = 0;
			var i = -1;
			while (c <= objSelect.options.length-1 && i == -1)
			{
				if (objSelect.options(c) == option) { i = c; }
				c++;
			}

			if (i != -1) { objSelect.selectedIndex = i; }
			
			result = option;
		}
		
		return result;
	}

	this.deleteOption = function(objSelect)
	{
		var result = false;

		if (objSelect.selectedIndex >= 0)
		{
			var i = objSelect.selectedIndex;
			objSelect.options.remove(i);
			this.setSelectedIndex(objSelect,i);

			result = true;	
		}

		return result;
	}

	this.updateOption = function(objSelect,index,value,text)
	{
		var result = null;
		
		if (index >= 0 && index <= objSelect.options.length-1)
		{
			objSelect.options(index).value = value;
			objSelect.options(index).innerText = text;
			objSelect.selectedIndex = index;

			result = true;	
		}

		return result;
	}

	this.moveOption = function(objSelect,index,offset)
	{
		var result = null;
		var i = index+offset;

		if (i < 0) { i = 0; }
		if (i > objSelect.options.length-1) { i = objSelect.options.length-1; }

		if (i >= 0 && i <= objSelect.options.length-1 && index >= 0 && index <= objSelect.options.length-1)
		{
			var value = objSelect.options(index).value;
			var text = objSelect.options(index).innerText;

			objSelect.options(index).value = objSelect.options(i).value;
			objSelect.options(index).innerText = objSelect.options(i).innerText;

			objSelect.options(i).value = value;
			objSelect.options(i).innerText = text;

			objSelect.selectedIndex = i;

			result = true;	
		}

		return result;	
	}

	this.setSelectedIndex = function(objSelect,index)
	{
		var i = index;
		if (i > objSelect.options.length-1) { i = objSelect.options.length-1; }

		objSelect.selectedIndex = i;
	}
}

/* TList.js */

function TList()
{
	//private
		var self = this;
		var elementList = new Array();

	//public
		this.count = function()
		{
			return elementList.length;
		}
		
		this.clear = function()
		{
			while (elementList.length > 0)
			{
				elementList.pop();
			}	
		}

		this.add = function(value)
		{
			elementList.push(value);
		}

		this.get = function(index)
		{
			return elementList[index];		
		}

		this.findById = function(value)
		{
			var c = 0;
			var result = null;

			while (c <= elementList.length-1 && result === null)
			{
				if (elementList[c].id === value)
				{
					result = elementList[c];	
				}
				
				c++;
			}

			return result;
		}

		this.find = function(value)
		{
			var c = 0;
			var result = null;

			while (c <= elementList.length-1 && result === null)
			{
				if (elementList[c].determineFindValue() === value)
				{
					result = elementList[c];	
				}
				
				c++;
			}

			return result;
		}
}


/* TRTEConstructorParameter.js */

function TRTEConstructorParameter()
{
	this.documentContainer = null;
	this.documentForm = null;
	this.editorPlaceHolderID = 'RichTextField';
	this.editorWidth = 500;
	this.editorHeight = 300;
	this.cssstyle = '';
	this.urlImage = '/image/TEditor/image/';
	this.urlCss = '/image/TEditor/css/';
	this.siteURL = '';
	this.adminURL = '/image';
	this.urlFilterEnabled = true;
}


		

		

/* TRTEControl.js */

function TRTEControl(parameter)
{
    //private
        var self = this;
	var constructorParameter = parameter;

		function toggleLayer(layerID)
		{
			var e = document.getElementById(layerID);
			e.style.display = (e.style.display!='block')?'block':'none';		
		}

		 function toHex(n) 
		{
			var result = n.toString(16);
			if (result.length==1) result = "0"+result;
			return result;
		}
		
		function renderColorSelection(document,complexity,onClickHandler)
		{
		    var sequenceOld, found, p, direction, shiftsteps, sequenceNew;
		    var output = '';
            var c = 0;
            var container = constructorParameter.documentContainer.document.createElement('div');
            
            //farbaenderungsschritte fuer r,g,b festlegen, es darf sich immer nur eine stelle (farbanteil) aendern
            var sequenceList = new Array('000', '100', '110', '010', '011', '001', '101', '100');

            sequenceOld = sequenceList[c++];
            
            var basecolor = new Object();
            basecolor.value = 0;
            
            while (c <= sequenceList.length-1)
            {
                sequenceNew = sequenceList[c];
                
                //stelle finden in der sich farbeanteil aendern soll
                found = false;
                p = -1;
                while (p < sequenceNew.length-1 && !found)
                {
                    p++;
                    found = sequenceNew.substr(p,1) != sequenceOld.substr(p, 1);
                }

                //zaehlrichtung und startbit im hexcode berechnen
                direction = 0+(sequenceOld.substr(p, 1) == '1' && sequenceNew.substr(p, 1) == '0');
                shiftsteps = (3 - (p+1)) * 8;

                //farbveraenderung rendern
                renderColorSegment(constructorParameter.documentContainer.document, container, basecolor, shiftsteps, direction, complexity, onClickHandler);
                
                sequenceOld = sequenceList[c];
                           
                c++;
            }
            
            return container;
        }
        
        function renderColorSegment(document, container, basecolor, shiftsteps, direction, complexity, onClickHandler)
        {
            var rowCount, offset, minPart, rowDifference, maxPart, c, multiplierBase, multiplierDirection, r, g, b, color, colorRed, colorGreen, colorBlue, loopCount, OutputColor, colorRows, colorColsDifference;
            var colorElement = null;
            var a = null;
            var column = null;

            //left shift nachbilden mit mulitplikation von 2
            c = shiftsteps;
            multiplierBase = 1;

            while (c > 0)
            {
                multiplierBase = multiplierBase * 2;
                c--;
            }
            
            //zaehlrichtung beachten
            multiplierDirection = 1 - 2 * direction;
            
            //fuer das durchlaufen der farben die noetigen variablen initialisieren
            colorRows = complexity;
            colorColsDifference = 255 / (complexity / 2);
            
            rowCount = Math.round(colorRows / 2);

            //kompletten farbanteil durchlaufen
            c = 0;
            while (c <= 255)
            {
                column = document.createElement('div');
                column.className = 'rteColorSelectionColumn';
                
                color = basecolor.value + (multiplierDirection * Math.round(c) * multiplierBase);

                colorRed = (color & 0xFF0000) / 65536;
                colorGreen = (color & 0x00FF00) / 256;
                colorBlue = (color & 0x0000FF);

                OutputColor = '';

                r = colorRed;
                g = colorGreen;
                b = colorBlue;

                //brighten from white to color
                minPart = r;
                if (minPart > g) { minPart = g; }
                if (minPart > b) { minPart = b; }

                rowDifference = (255 - minPart) / rowCount;
                
                offset = 0+!(container.childNodes.length == 0 && basecolor.value == 0);

                loopCount = 1+offset;
                while (loopCount <= rowCount)
                {
                    if (r + rowDifference < 255) { r = r + rowDifference; } else { r = 255; };
                    if (g + rowDifference < 255) { g = g + rowDifference; } else { g = 255; };
                    if (b + rowDifference < 255) { b = b + rowDifference; } else { b = 255; };
                    
                    //we must include style in createElement because dynamically adding style via jscript is not supported, ie throws error message
                    colorElement = document.createElement('div'); // style="background-color:#' + toHex(Math.round(r)) + toHex(Math.round(g)) + toHex(Math.round(b))+';"></div>');
		colorElement.style.backgroundColor = '#' + toHex(Math.round(r)) + toHex(Math.round(g)) + toHex(Math.round(b));

		self.prototype.registerEvent(colorElement,'mousedown', onClickHandler);

                    colorElement.className = 'rteColorSelectionCell';

			if (colorElement.insertAdjacentElement)
			{                  
		    		column.insertAdjacentElement('afterbegin',colorElement);
			}
			else
			{
				column.insertBefore(colorElement,column.firstChild);
			}

                   
                    loopCount++;
                }
                
                //brighten to color to black
                r = colorRed;
                g = colorGreen;
                b = colorBlue;

                maxPart = r;
                if (maxPart < g) { maxPart = g; }
                if (maxPart < b) { maxPart = b; }

                rowDifference = maxPart / rowCount;

                loopCount = 1;
                while (loopCount <= rowCount+offset)
                {
                    colorElement = document.createElement('div');
			colorElement.style.backgroundColor = '#' + toHex(Math.round(r)) + toHex(Math.round(g)) + toHex(Math.round(b));
		
			self.prototype.registerEvent(colorElement,'mousedown', onClickHandler);

                    colorElement.className = 'rteColorSelectionCell';
                    
                    column.appendChild(colorElement);

                    if (r - rowDifference > 0) { r = r - rowDifference; } else { r = 0; };
                    if (g - rowDifference > 0) { g = g - rowDifference; } else { g = 0; };
                    if (b - rowDifference > 0) { b = b - rowDifference; } else { b = 0; };
                    
                    loopCount++;
                }
                
                container.appendChild(column);

                c = c + colorColsDifference;
            }

            basecolor.value = basecolor.value + (multiplierDirection * 255 * multiplierBase);
        }

	function initialize()
	{
		self.prototype.initialize(constructorParameter.documentContainer.document.getElementById(constructorParameter.editorPlaceHolderID+'IFrame').contentWindow,true,false,0);
	}

	function refreshMenu()
	{
		var c = 0;
		var button;
		var buttonHTML = self.menu.button.findById('HTML');
		
		//process buttons
		while (c <= self.menu.button.count()-1)
		{
			button = self.menu.button.get(c);

			if (button.canModifyContent && button !== buttonHTML)
			{
				button.enabled = self.prototype.selectedObject.isValid() && !buttonHTML.active;
			}

			button.imageObject.parentNode.className = 'rteMenuButton'+(0+button.enabled)+''+(0+(button.active && button.enabled));
			button.imageObject.style.opacity = 1-0.7*(1-button.enabled);
			button.imageObject.style.filter = 'alpha(opacity='+(button.imageObject.style.opacity*100)+')';

			c++;
		}

		//process panels
		var panel;

		c = 0;
		while (c <= self.menu.panel.count()-1)
		{
			panel = self.menu.panel.get(c);

			if (panel.onRefresh && panel.visible)
			{
				panel.onRefresh(panel);
			}

			c++;
		}		
	}

	function menuButtonClicked(e)
	{
		var sender = (e.srcElement)?e.srcElement:e.target;

		//when button has e.g. padding then somethings click goes to link surrounding image, then get image
		if (sender.tagName.toLowerCase() == 'a')
		{
			sender = sender.firstChild;	
		}
		
		//get button object based on image
		var button = self.menu.button.find(sender);

		if (button.enabled)
		{
			//refresh internal selection state
			self.prototype.refreshSelection();

			/* to ensure something is selected 
			if (!self.prototype.selectedObject.isValid())
			{
				var selection = self.prototype.getDocument().selection;
				selection.empty();
			
				var r = self.prototype.getDocument().body.createTextRange();
				r.moveStart('character',0);
				r.moveEnd('character',1);
				r.select();
			}*/

			var selectedObject = self.prototype.selectedObject;
			var c,p;

			if (selectedObject.isValid() || button.id == 'HTML')
			{
				switch (button.id)
				{
						case 'BOLD' : selectedObject.setBold(!selectedObject.getBold());
					break;	case 'ITALIC' :	selectedObject.setItalic(!selectedObject.getItalic());
					break;	case 'UNDERLINE' : selectedObject.setUnderline(!selectedObject.getUnderline());
					break;	case 'LALIGN' : selectedObject.setAlignment('left');
					break;	case 'CALIGN' : selectedObject.setAlignment('center');
					break;	case 'RALIGN' : selectedObject.setAlignment('right');
					break;	case 'UL' : selectedObject.executeCommand('InsertUnorderedList','');
					break;	case 'OL' : selectedObject.executeCommand('InsertOrderedList','');
					break;	case 'INDENT' : selectedObject.executeCommand('Indent',null);
					break;	case 'OUTDENT' : selectedObject.executeCommand('Outdent',null);					
					
					break;	case 'SUB' : selectedObject.setSub(!selectedObject.getSub());
					break;	case 'SUP' : selectedObject.setSup(!selectedObject.getSup());					
					
					break;	case 'FORECOLOR':
						case 'BACKCOLOR' :

							var panel = self.menu.panel.find('COLORSELECTION');

							if (panel.container.style.display != 'block' || panel.data == (button.id == 'FORECOLOR'))
							{
								toggleLayer(panel.container.id);
							}
							
							if (panel.button) { panel.button.active = false; }

							panel.button = button;
							panel.data = (button.id == 'FORECOLOR');
							panel.caption.innerHTML = (panel.data)?'Text color':'Background color';
							panel.visible = panel.container.style.display == 'block';

							button.active = panel.visible;
							refreshMenu();

					break;	case 'REMOVEFORMAT' : selectedObject.removeFormat();
					break;	case 'HTML' : 

						button.active = !button.active;	

						selectedObject.reset();
						refreshMenu();

						self.prototype.setDesignMode(!self.prototype.getDesignMode());

					break;	case 'LINK' : 

						var range = self.prototype.selectedObject.getRange();
						var link = null;
						var modify = false;
						var processText = true;

						//first check wether control is selected that is child of link, propaply an image
						if (self.prototype.selectedObject.isControl())
						{
							var control = self.prototype.selectedObject.getObject();
							if (control.tagName.toLowerCase() == 'img')
							{
								var controlParent = (document.all)?control.parentElement:range.commonAncestorContainer;
								if (controlParent.tagName.toLowerCase() == 'a')
								{
									link = controlParent;
									modify = true;
									processText = false;
								}
							}	
						}

						//if nothing found check wether a link is surrounding the range
						if (!link)
						{
							var element = (document.all)?range.parentElement():range.startContainer.parentNode;
							if (element.tagName.toLowerCase() == 'a')
							{
								link = element;	
								modify = true;
							}
						}

						if (!modify)
						{
							link = self.prototype.getDocument().createElement('a');
							if (document.all)
							{
								link.innerText = range.text;
							}
							else
							{
								link.textContent = range.toString();
							}
						}

						self.showLinkConfigurationDialog(self,link,modify,processText);

					break;	case 'IMAGE' :
							
						var textRange = self.prototype.selectedObject.getObject();
						var image = null;
						var modify = false;

						if (self.prototype.selectedObject.isControl())
						{		
							if (self.prototype.selectedObject.getObject().tagName.toLowerCase() == 'img')
							{
								image = self.prototype.selectedObject.getObject();
								modify = true;
							}
						}
						
						if (!modify)
						{
							image = self.prototype.getDocument().createElement('img');

							var element = (document.all)?textRange.parentElement():textRange.startContainer.parentNode;
							if (element.tagName.toLowerCase() == 'a')
							{
								image.alt = (document.all)?element.innerText:element.textContent;
							}
							else
							{	
								image.alt = (document.all)?textRange.text:textRange.toString();	
							}
						}	

						self.showImageConfigurationDialog(self,image,modify);
				}
			}
		}
	}

	function initializeMenu(container)
	{
		self.menu.button.clear();
		self.menu.panel.clear();

		//define menu buttons
		var button;

		button = new TRTEMenuButton('BOLD');
		button.description = 'fett';
		button.imageFile = 'Bold.gif';
		self.menu.button.add(button);

		button = new TRTEMenuButton('ITALIC');
		button.description = 'kursiv';
		button.imageFile = 'Italic.gif';
		self.menu.button.add(button);

		button = new TRTEMenuButton('UNDERLINE');
		button.description = 'unterstrichen';
		button.imageFile = 'Underline.gif';
		self.menu.button.add(button);

		button = new TRTEMenuButton('LALIGN');
		button.description = 'linksb&uuml;ndig';
		button.imageFile = 'AlignLeft.gif';
		self.menu.button.add(button);

		button = new TRTEMenuButton('CALIGN');
		button.description = 'zentriert';
		button.imageFile = 'AlignCenter.gif';
		self.menu.button.add(button);

		button = new TRTEMenuButton('RALIGN');
		button.description = 'rechtsb&uuml;ndig';
		button.imageFile = 'AlignRight.gif';
		self.menu.button.add(button);

		button = new TRTEMenuButton('UL');
		button.description = 'unsortierte Liste';
		button.imageFile = 'UnorderedList.gif';
		self.menu.button.add(button);

		button = new TRTEMenuButton('OL');
		button.description = 'sortierte Liste';
		button.imageFile = 'OrderedList.gif';
		self.menu.button.add(button);

		button = new TRTEMenuButton('OUTDENT');
		button.description = 'ausr&uuml;cken';
		button.imageFile = 'Outdent.gif';
		self.menu.button.add(button);

		button = new TRTEMenuButton('INDENT');
		button.description = 'einr&uuml;cken';
		button.imageFile = 'Indent.gif';
		self.menu.button.add(button);

		button = new TRTEMenuButton('FORECOLOR');
		button.description = 'Textfarbe ausw&auml;hlen';
		button.imageFile = 'ForeColor.gif';
		self.menu.button.add(button);

		button = new TRTEMenuButton('BACKCOLOR');
		button.description = 'Hintergrundfarbe ausww&auml;hlen';
		button.imageFile = 'BackColor.gif';
		self.menu.button.add(button);

		button = new TRTEMenuButton('REMOVEFORMAT');
		button.description = 'Formatierung l&ouml;schen';
		button.imageFile = 'RemoveFormat.gif';
		self.menu.button.add(button);
		
		button = new TRTEMenuButton('SUB');
		button.description = 'hochgestellt';
		button.imageFile = 'Sub.gif';
		//self.menu.button.add(button);
		
		button = new TRTEMenuButton('SUP');
		button.description = 'tiefgestellt';
		button.imageFile = 'Sup.gif';
		//self.menu.button.add(button);

		// fallls benoetigt wieder reinnhemen
		button = new TRTEMenuButton('LINK');
		button.description = 'Link einf&uuml;gen / w&auml;ndern';
		button.imageFile = 'Link.gif';
		//self.menu.button.add(button);

		// fallls benoetigt wieder reinnhemen
		button = new TRTEMenuButton('IMAGE');
		button.description = 'Bild einf&uuml;gen / w&auml;ndern';
		button.imageFile = 'Image.gif';
		//self.menu.button.add(button);

		button = new TRTEMenuButton('HTML');
		button.description = 'HTML Ansicht';
		button.imageFile = 'SourceCode.gif';
		button.canAlterContent = false;
		self.menu.button.add(button);

		//insert menu to DOM
		var menu = constructorParameter.documentContainer.document.createElement('div');
		menu.className = 'rteMenu';

		var c = 0;
		var b;
            
           	while (c <= self.menu.button.count()-1)
           	{
			b = self.menu.button.get(c);
			b.onClick = menuButtonClicked;

               		var link = constructorParameter.documentContainer.document.createElement('a');

			link.className = 'rteMenuButton'+(0+b.active);
			link.href = 'javascript://'; //needs to be assigned for a correctly working css, we cannot set # because this alters the url, so we create a js dummy
        			
			self.prototype.registerEvent(link,'click',b.onClick);

    			var i = constructorParameter.documentContainer.document.createElement('img');
                	i.src = constructorParameter.urlImage+'/Button/'+b.imageFile; 

			if (b.imageWidth) { i.style.width = b.imageWidth; }
			if (b.imageHeight) { i.style.height = b.imageHeight; }
                
                	var a = parameter.documentContainer.document.createAttribute("border");
                	a.value = '0';
                
                	i.attributes.setNamedItem(a);
                
                	a = parameter.documentContainer.document.createAttribute("alt");
                	a.value = b.description;
                
                	i.attributes.setNamedItem(a);
            
                	link.appendChild(i);
                	menu.appendChild(link);

			b.imageObject = i;  

			c++;          
  		}
 
            	container.appendChild(menu);

		//created panels
		var panel;

		panel = new TRTEMenuPanel('COLORSELECTION');

		panel.container = constructorParameter.documentContainer.document.createElement('div');
            	panel.container.id = constructorParameter.editorPlaceHolderID+'_'+panel.id;
            	panel.container.className = 'rtePanel';
		panel.container.style.display = (panel.visible)?'block':'none';
		panel.onRefresh = refreshPanel;
		self.menu.panel.add(panel);
            
		var captionContainer = constructorParameter.documentContainer.document.createElement('div');
		captionContainer.className = 'rtePanelCaption';
            
		panel.caption = constructorParameter.documentContainer.document.createElement('div');
		panel.caption.className = 'rtePanelCaptionText';
		panel.caption.innerHTML = 'Color selection';

		captionContainer.appendChild(panel.caption);
            
            	var captionButton = constructorParameter.documentContainer.document.createElement('a')
            	captionButton.className = 'rtePanelCaptionCloseButton';
            	captionButton.href = 'javascript://';	
		self.prototype.registerEvent(captionButton,'click', hidePanel);	

           	captionContainer.appendChild(captionButton);

            	panel.container.appendChild(captionContainer);
           	panel.container.appendChild(renderColorSelection(constructorParameter.documentContainer.document,9,setColor));
                        
            	container.appendChild(panel.container);

		//refresh menu	
		refreshMenu();
	}

	function refreshPanel(panel)
	{
		var buttonHTML = self.menu.button.findById('HTML');
		var buttonEnabled = (panel.button)?panel.button.enabled:true; //set false branch to true to enable panels visible on page load

		panel.container.style.display = (panel.visible && buttonEnabled && !buttonHTML.active)?'block':'none';
	}

	function hidePanel(e)
	{
		var sender = (e.srcElement)?e.srcElement:e.target;
		var domPanel = sender.parentNode.parentNode;
		var domPanelId = domPanel.id.split('_');

		var objPanel = self.menu.panel.find(domPanelId[domPanelId.length-1]);

		if (objPanel.visible)
		{
			toggleLayer(objPanel.container.id);
		}

		objPanel.button.active = false;
		objPanel.data = '';
		objPanel.visible = false;

		refreshMenu();			
	}

	      function setColor(e)
		{
			var color = (e.srcElement)?e.srcElement.style.backgroundColor:e.target.style.backgroundColor;

			if (self.menu.panel.findById('COLORSELECTION').data)
			{
				self.prototype.selectedObject.setForeColor(color);
			}
			else
			{
				self.prototype.selectedObject.setBackColor(color);
			}
		}

	function filterHTMLCode(value)
	{
	    var HTML = value;
	    
	    if (constructorParameter.urlFilterEnabled) { HTML = self.filterURI(HTML,true); }
	    
		return HTML;
	}

    //public
	this.prototype = new TEditor(); //inheritance is represented by assigning a instance of the base class to "prototype"
	this.menu = new TRTEMenu();

		this.filterURI = function(value,usePrefix)
	{
		var result = value;
		var c = 0;
		var url = '';
		var regularExpression = null;
		var prefix = '';

		while (c <= 1)
		{
			switch (c)
			{
					case 0 : url = constructorParameter.adminURL; 
				break;	case 1 : url = constructorParameter.siteURL;
			}

			//replace href
			prefix = (usePrefix)?' href="':'';
			regularExpression = new RegExp(prefix+url+'/','gi');
			result = result.replace(regularExpression,prefix);

			//replace src
			prefix = (usePrefix)?' src="':'';
			regularExpression = new RegExp(prefix+url+'/','gi');
			result = result.replace(regularExpression,prefix);

			c++;	
		}

		return result;	
	}

	this.applyLinkConfiguration = function(link,modify,processText,href,text,title)
	{
		var range = self.prototype.selectedObject.getObject();

		link.href = href;
		
		if (document.all)
		{
			//todo: opera doesnt want to work at all here
			if (processText) { link.innerText = text; }
		
			if (!modify) 
			{ 
				//ensure that something is selected before execCommand is executed
				if (range.text.length == 0)
				{
					range.text = link.innerText;
					range.moveStart('character', -link.innerText.length);
				}

				range.execCommand('CreateLink',false,link.href);

				link = range.parentElement();

				range.collapse(true);
				range.select();
			}

			link.title = title;
		}
		else
		{
			if (processText) { link.textContent = text; }

			link.title = title;

			range.deleteContents();
			if (!modify) { range.insertNode(link); }
		}
	}

	this.applyImageConfiguration = function(image,modify,src,alt)
	{
		var range = self.prototype.selectedObject.getRange();
		var element = (document.all)?range.parentElement():range.startContainer.parentNode;

		if (!modify) 
		{ 	
			if (element.tagName.toLowerCase() == 'a')
			{
				if (document.all) { element.innerText = ''; } else { element.textContent = ''; }
			}
		}

		var altAttribute = self.prototype.getDocument().createAttribute('alt');
		altAttribute.value = alt;

		var borderAttribute = self.prototype.getDocument().createAttribute('border');
		borderAttribute.value = '0';

		image.src = src;

		if (document.all)
		{
			if (!modify) 
			{ 	
				range.execCommand('InsertImage',false,image.src);

				//now cover image in range to set additional properties later
				range.moveStart('character',-1);

				image = range.parentElement();
			}

			image.attributes.setNamedItem(altAttribute);
			image.attributes.setNamedItem(borderAttribute);
		}
		else
		{
			image.attributes.setNamedItem(altAttribute);
			image.attributes.setNamedItem(borderAttribute);

			range.deleteContents();
			range.insertNode(image)
		}
	}

	this.showLinkConfigurationDialog = function(sender,link,modify,processText)
	{
		//override this function to customize link configuration (to apply link configuration call applyLinkConfiguration())
	}

	this.showImageConfigurationDialog = function(sender,image,modify)
	{
		//override this function to customize image configuration (to apply link configuration call applyImageConfiguration())
	}

	this.saveContent = function(eventObject)
	{
		//if editor is in html mode set editor back to design mode to get html code correctly
		if (!self.prototype.getDesignMode())
		{
			self.prototype.setDesignMode(true);
		}

		var frame = window.frames[constructorParameter.editorPlaceHolderID+'IFrame'];
		//check innerText to have text only, doesnt works on all browsers
		var s = (constructorParameter.documentContainer.document.all)?frame.document.body.innerText:frame.document.body.textContent;

		//trim of leading and trailing spaces
		if (s.length > 0)
		{
			while (s.substr(0,1) == ' ')
			{
				s = s.substr(1,s.length);
			}
		}
		
		if (s.length > 0)
		{
			while (s.substr(s.length-1,1) == ' ')
			{
				s = s.substr(0,s.length-1);
			}
		}

		if (s.length > 0)
		{
			constructorParameter.documentContainer.document.getElementById(constructorParameter.editorPlaceHolderID).value = self.prototype.filterHTMLCode(frame.document.body.innerHTML);	
			
			//alert('ID: '+constructorParameter.editorPlaceHolderID);				
			//alert('Name: '+constructorParameter.documentContainer.document.getElementById(constructorParameter.editorPlaceHolderID).name);
			//alert('Object: '+constructorParameter.documentContainer.document.getElementById(constructorParameter.editorPlaceHolderID));
			//alert('Value: '+constructorParameter.documentContainer.document.getElementById(constructorParameter.editorPlaceHolderID).value);
			//alert('HTML: '+self.prototype.filterHTMLCode(frame.document.body.innerHTML));				
		}
		else
		 {
			constructorParameter.documentContainer.document.getElementById(constructorParameter.editorPlaceHolderID).value = '';
		}
			
	}

this.create = function(parameter)
        {
		self.prototype.htmlCodeEditable = true;
		self.prototype.OnElementSelected = refreshMenu;
		self.prototype.filterHTMLCode = filterHTMLCode;

//we must initialize editor in onload to get mozilla 2 workin, can't call prototype intialization directly
			self.prototype.registerEvent(window,'load', initialize);			
			//alert(parameter.documentForm);
			//alert(self.saveContent);
			// bei click wirds geschrieben			
			// submit geht hier nicht
			self.prototype.registerEvent(parameter.documentForm, 'click', self.saveContent);
			//self.prototype.registerEvent(parameter.documentForm, 'submit', self.saveContent);

            //build editor control on client side to save traffic and to handle events without javascript: or stuff like that
            var textarea = parameter.documentContainer.document.getElementById(parameter.editorPlaceHolderID);
		if (textarea)
	{
           var rteAttribute;
            
            var rteContainer = parameter.documentContainer.document.createElement('div');
            rteContainer.className = 'rteContainer';
		rteContainer.style.width = parameter.editorWidth+'px';

	initializeMenu(rteContainer);
  
            var rteContentContainer = parameter.documentContainer.document.createElement('div');
            
            var rteContent = parameter.documentContainer.document.createElement('iframe');
            rteContent.id = parameter.editorPlaceHolderID+'IFrame';
			rteContent.name = rteContent.id;
			if (parameter.cssstyle.lenght > 0)
			{
				rteContent.style.height = parameter.editorHeight+'px';
			}
            rteContent.className = 'rteContent';
            
			//alert(parameter.cssstyle);
						
            rteAttribute = parameter.documentContainer.document.createAttribute("frameborder");
            rteAttribute.value = '0';
            rteContent.attributes.setNamedItem(rteAttribute);
            rteContentContainer.appendChild(rteContent);
            rteContainer.appendChild(rteContentContainer);
            
            //rteAtrributeStyle = parameter.documentContainer.document.createAttribute("style");
			//rteAtrributeStyle.setAttribute("style",parameter.cssstyle);
			//rteContent.setAttribute("style",parameter.cssstyle);
			//rteContent.attributes.setNamedItem(rteAtrributeStyle);
            //rteContentContainer.appendChild(rteContent);
            //rteContainer.appendChild(rteContentContainer);			
						
			textarea.style.display = 'none';
			textarea.parentNode.insertBefore(rteContainer,textarea);

			iFrame = parameter.documentContainer.document.getElementById(rteContent.id);

            if (iFrame) //when iframe exists then browser handles the iframe internaly as a frame, so continue
            {
			//http://www.mozilla.org/editor/ie2midas.html

			var frame = window.frames[rteContent.id];
			var doc = frame.document.open('text/html', 'replace');
			//iFrame.setAttribute("style",parameter.cssstyle);

			//we can only include one css because ie doesnt end loading document (therefore no raising of onload event) when using more than 1 css, bug?!?
			var html = '<html>\n'+
					'<head>\n'+
						'<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">\n'+
						'<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">\n'+
						'<META HTTP-EQUIV="Expires" CONTENT="-1">\n'+
						'<link type="text/css" rel="stylesheet" href="'+parameter.urlCss+'/Content.css" />\n'+
					'</head>\n'+
					'<body class="bodyEditorDesignMode">'+parameter.documentContainer.document.getElementById(parameter.editorPlaceHolderID).value+'</body>\n</html>';

                	doc.write(html);
	                doc.close();

			
	    }  

	} 


       }

	self.create(parameter);
}


		

		

/* TRTEMenu.js */

function TRTEMenu()
{
	//private
		var self = this;

	//public
		this.button = new TList();
		this.panel = new TList();
}


/* TRTEMenuButton.js */

function TRTEMenuButton(id)
{
	//private
		var self = this;

	//public
		this.imageObject = null;
		this.imageFile = '';
		this.imageWidth = null;
		this.imageHeight = null;
		this.description = '';
		this.onClick = null;
		this.active = false;
		this.enabled = true;
		this.canModifyContent = true;
		this.id = id;	

		this.determineFindValue = function() //implemented to be able to use TList.find()
		{
			return self.imageObject;
		}
}


/* TRTEMenuPanel.js */

function TRTEMenuPanel(id)
{
	//private
		var self = this;

	//public
		this.container = null;
		this.caption = null;
		this.visible = false;
		this.id = id;
		this.data = null;
		this.canModifyContent = true;
		this.button = null;
		this.onRefresh = null;

		this.determineFindValue = function() //implemented to be able to use TList.find()
		{
			return self.id;
		}
}


/* Validation.js */

function OnlyNumbersAndDecimalSeperatorAllowedKeys(evt)
	{
	var charCode = (evt.which) ? evt.which : event.keyCode
	if ((charCode > 31 && (charCode < 48 || charCode > 57)) && charCode != 44)
		return false;
	else
		return true;
	}

function OnlyNumbersAllowedKeys(evt) {
	var charCode = (evt.which) ? evt.which : event.keyCode;
	if (charCode > 31 && (charCode < 48 || charCode > 57))
		return false;
	else
		return true;
}

function CheckInRange(thisobject, RangeFrom, RangeTo) {
	var NewValue = thisobject.value;
	if (thisobject.value > RangeTo) {
		NewValue = RangeTo;
	}
	else {
		if (thisobject.value < RangeFrom)
			NewValue = 1;
	}
	if (NewValue != thisobject.value) {
		thisobject.value = NewValue;
		return false;
	}
	else
		return true;
}

function CheckMinimumQuantity(thisobject, RangeFrom) {
	var NewValue = thisobject.value;
	
	if (NewValue != '')
		if (NewValue != '0')
			if (NewValue < RangeFrom)
				NewValue = RangeFrom;
		
	if (NewValue != thisobject.value) {
		thisobject.value = NewValue;
		return false;
	}
	else
		return OnlyNumbersAllowedKeysExt(thisobject); ;
}

function OnlyNumbersAllowedKeysExt(thisInput)
	{
	var charCode;
	var myS = new String('');
	for (var i = 0; i < thisInput.value.length; i++) {
		myS = new String(thisInput.value.substring(i, i + 1));
		charCode = myS.charCodeAt(0);
		if (charCode > 31 && (charCode < 48 || charCode > 57)) {
			thisInput.value = thisInput.value.replace(myS, '');
		}
	}
	}
