// -------------------------------------------------------------------------------
// --- описание класса rButton
// -------------------------------------------------------------------------------
	function rButton(name, type, action, title){ // Команды RE
		this.classType = "button";
		this.name		= name;							// имя команды (имя картинки в директории ./img/re_NAME.gif)
		this.type		= type;							// режим в котором кнопка активна
		this.action	= action;						// функция обработчик
		this.title	= title;						// подпись
		this.button = null							// собственно кнопки как объект
	}
	function rSelect(name, type, action, values, titles){ // Команды RE
		this.classType = "select";
		this.name		= name;							// имя команды (имя картинки в директории ./img/re_NAME.gif)
		this.type		= type;							// режим в котором кнопка активна
		this.action	= action;						// функция обработчик
		this.titles	= titles;						// значения
		this.values	= values;						// подписи
		this.button = null							// собственно кнопки как объект

	}
// -------------------------------------------------------------------------------
// --- описание класса rPanel
// -------------------------------------------------------------------------------
	var orPanel=null;
	function rPanel(){ // Панель инструментов RE
		this.commands = Array( 
			new rButton('inserttable',				rTypeRich,						rActionExtend|rActionText,'Вставить таблицу'),
			new rButton('mergeright',					rTypeRich,						rActionExtend|rActionText,'Объединить ячейку с правой'),
			new rButton('mergedown',					rTypeRich,						rActionExtend|rActionText,'Объединить ячейку с нижней'),
			new rButton('mergenone',					rTypeRich,						rActionExtend|rActionText,'Отменить объединение ячеек'),
		new rButton('spacer',rTypeNone),
			new rButton('deleterow',					rTypeRich,						rActionExtend|rActionText,'Удалить строку'),
			new rButton('insertrow',					rTypeRich,						rActionExtend|rActionText,'Втавить строку'),
		new rButton('spacer',rTypeNone),
			new rButton('createlink',					rTypeRich,						rActionExtend|rActionText,'Вставить ссылку'),
			new rButton('imageproperties',		rTypeRich,						rActionExtend|rActionObject,'Свойства изображения'),
			new rButton('forecolor',					rTypeRich,						rActionExtend|rActionText,'Цвет текста'),
			new rButton('bgcolor',						rTypeRich,						rActionExtend|rActionText,'Цвет фона ячейки'),
		new rButton('spacer',rTypeNone),
			new rButton('libraryfiles',				rTypeRich|rTypeText,	rActionExtend,'Библиотека файлов'),
			new rButton('libraryimages',			rTypeRich|rTypeText,	rActionExtend,'Библиотека картинок'),
		new rButton('spacer',rTypeNone),
			new rButton('showspecial',				rTypeRich,						rActionExtend,'Разметка документа'),
			new rButton('clearformat',				rTypeRich,						rActionExtend|rActionText,'Очистка стилей'),
		new rButton('spacer',rTypeNone),
			new rButton('html',								rTypeRich|rTypeText,	rActionExtend,'Режим редактирования'),
		new rButton('break',rTypeNone),
			new rButton('bold',								rTypeRich,						rActionBasic,'Полужирный [ctrl + b]'),
			new rButton('italic',							rTypeRich,						rActionBasic,'Курсив [ctrl + i]'),
			new rButton('underline',					rTypeRich,						rActionBasic,'Подчеркнутый [ctrl + u]'),
			new rButton('strikethrough',			rTypeRich,						rActionBasic,'Зачеркнутый'),
		new rButton('spacer',rTypeNone),
			new rButton('subscript',					rTypeRich,						rActionBasic,'Подстрочный'),
			new rButton('superscript',				rTypeRich,						rActionBasic,'Надстрочный'),
		new rButton('spacer',rTypeNone),
			new rButton('justifynone',				rTypeRich,						rActionBasic,'По левому краю'),
			new rButton('justifycenter',			rTypeRich,						rActionBasic,'По центру'),
			new rButton('justifyright',				rTypeRich,						rActionBasic,'По правому краю'),
			new rButton('justifyfull',				rTypeRich,						rActionBasic,'По ширине'),
		new rButton('spacer',rTypeNone),
			new rButton('insertorderedlist',	rTypeRich,						rActionBasic,'Нумерация'),
			new rButton('insertunorderedlist',rTypeRich,						rActionBasic,'Маркеры'),
		new rButton('spacer',rTypeNone),
			new rButton('outdent',						rTypeRich,						rActionBasic,'Уменьшить отступ'),
			new rButton('indent',							rTypeRich,						rActionBasic,'Увеличить отступ'),
		new rButton('break',rTypeNone),
			new	rSelect('formatblock',				rTypeRich,						rActionExtend|rActionText,Array("","<p>","Normal","<h1>","<h2>","<h3>","<h4>","<h5>"),Array("","Параграф","Нормальный","Заголовок 1","Заголовок 2","Заголовок 3","Заголовок 4","Заголовок 5"))
		);
		// свойство : Разметка документа
		this.showspecial = false;
		// метод : инициализация панели инструментов RE
		this.initialize = rPanel_initialize;
		// метод : нажатие кнопки на панели
		this.action = rPanel_action;
		// метод : обновить состояние кнопок на панеле
		this.update = rPanel_update;
		// создаем едиственную копию себя самого и инициализируем ее
		if(orPanel==null){
			orPanel = this;
			orPanel.initialize();
		}
	}
// -------------------------------------------------------------------------------
// --- методы класса rPanel
// -------------------------------------------------------------------------------
	function rPanel_initialize(){ // инициализация панели инструментов RE
		if(orPanel==this){ // только одна панель может существовать в системе
			var html = "<div id='rPanel'>"; // вывод HTML кнопок с командами 
			for(var i=0; i<this.commands.length; i++){
				if(this.commands[i].name=='break'){
					html += '<br>';
				}else if(this.commands[i].name=='spacer'){
					html += '<img src="'+orPath.base+orPath.image+"re_"+this.commands[i].name+'.gif" width=5 height=16 border=0>';
				}else if(this.commands[i].name=='images'&&orImages==null){
				}else if(this.commands[i].name=='links'&&orLinks==null){
				}else if(this.commands[i].classType=='select'){
					html += '<select id="rPanel_'+this.commands[i].name+'" ';
					html += ' onChange="orPanel.action('+i+');">';
					for(var j=0; j<this.commands[i].values.length; j++){
						html += '<option value="'+this.commands[i].values[j]+'">'+this.commands[i].titles[j];
					}
					html += '</select>';
				}else{
					html += '<button id="rPanel_'+this.commands[i].name+'" ';
					html += ' onClick="orPanel.action('+i+');" ';
					html += ' onMouseOver="if(!this.disabled){ this.classNameReal = this.className; this.className = \'hover\';}"';
					html += ' onMouseOut="if(!this.disabled){ this.className = this.classNameReal;}"';
					html += '	title="'+this.commands[i].title+'">';
					html += '<img src="'+orPath.base+orPath.image+"re_"+this.commands[i].name+'.gif" width=16 height=16 border=0>';
					html += '</button>';
				}
			}
			html += "</div>";
			document.write(html);
			for(var i=0; i<this.commands.length; i++){ // собираем созданные объекты
				if(document.all['rPanel_'+this.commands[i].name]){
					this.commands[i].button = document.all['rPanel_'+this.commands[i].name];	
				}
			}
			this.update();
		}
	}
// --- 
	function rPanel_action(command){ // нажатие кнопки на панеле инструментов RE
		if(orTextActive!=null){
			var sRange = null;
			var mode = orTextActive.type; // состояние активного поля редактирования
			orTextActive.editor.focus();
			if((this.commands[command].type & mode) != 0){
				if(mode == rTypeRich){	// если режим позволяет, то достаем, что выделено
					orTextActive.edocument.document.body.focus();
					sRange = orTextActive.edocument.document.selection.createRange();
				}
				if(this.commands[command].action==rActionBasic){
					switch(this.commands[command].name){
					// --- нижний индекс
						case 'subscript':
							if(sRange.queryCommandState('superscript')) sRange.execCommand('superscript');
							sRange.execCommand('subscript');
						break;
					// --- верхний индекс
						case 'superscript': 
							if(sRange.queryCommandState('subscript')) sRange.execCommand('subscript');
							sRange.execCommand('superscript');
						break;
					// --- стандартные команды
						default:
							if(sRange.queryCommandEnabled(this.commands[command].name)) 
							sRange.execCommand(this.commands[command].name);
						break;
					}
				}else if((this.commands[command].action & rActionExtend) == rActionExtend){
					switch(this.commands[command].name){
					// --- разметка документа
						case 'showspecial':
							this.showspecial = !this.showspecial;
						break;
					// --- переключение режимов
						case 'html':
							orTextActive.tswitch((mode==rTypeText)?rTypeRich:rTypeText);
							this.update();
						break;
					// --- другие команды
						default:
							if((this.commands[command].action & rActionText) == rActionText){
								if(sRange==null || sRange.length==1) break;							
							}else	if((this.commands[command].action & rActionObject) == rActionObject){
								if(sRange==null || sRange.length!=1) break;							
							}
							eval("rAction_"+this.commands[command].name+"(sRange);");
						break;
					}
				}
				orTextActive.synchro();	
			}	
		}
	}
// --- 
	function rPanel_update(){ // обновить состояние кнопок на панеле инструментов RE
		var mode = (orTextActive!=null)?orTextActive.type:rTypeNone; // состояние активного поля редактирования
		// Обновляем состояния кнопок с командами
		for(var i=0; i<this.commands.length; i++){
			if(this.commands[i].button!=null){
				if((this.commands[i].type & mode) == 0){
					this.commands[i].button.disabled = true;
					this.commands[i].button.classNameReal = 'lock';
				}else{
					this.commands[i].button.disabled = false;
					if(this.commands[i].name=="html") // --- переключение режимов
						this.commands[i].button.classNameReal = (mode==rTypeText)?"down":"";
					else if(this.commands[i].name=="showspecial"){ // --- разметка документа
						this.commands[i].button.classNameReal = (this.showspecial)?"down":"";
						orTextActive.edocument.document.body.className = (this.showspecial)?"richedit showspecial":"richedit";
					}else
						this.commands[i].button.classNameReal = "";
				}
				this.commands[i].button.className = this.commands[i].button.classNameReal;
			}
		}
	}
// -------------------------------------------------------------------------------
// --- Функции обработчики нажатия кнопок панели
// -------------------------------------------------------------------------------
// --- очистка стилей
	function rAction_clearformat(sRange){
		var orDocument = orTextActive.edocument.document;
		rClearObjectFormat(sRange.parentElement(),orDocument);
	}
// --- цвет ячейки
	function rAction_bgcolor(sRange){	
		var elmTD = rGetParent(sRange.parentElement(),"TD");
		if(elmTD!=null)	// выделена одна ячейка
		var color = elmTD.bgColor;
		elmTD.bgColor =	rGetColorer(color);
	}
// --- цвет текста
	function rAction_formatblock(sRange){	
		var value = document.getElementById("rPanel_formatblock").value;
		if(value=="Normal"){
			sRange.execCommand('formatblock',false, "<p>");		
			var oObject = rGetParent(sRange.parentElement(),"P");
			oObject.outerHTML = oObject.innerHTML;
		}else{
			sRange.execCommand('formatblock',false, value);
		}
		document.getElementById("rPanel_formatblock").selectedIndex = 0;
	}

// --- цвет текста
	function rAction_forecolor(sRange){	
		if(!sRange.queryCommandEnabled("forecolor")) return;
		var color = sRange.queryCommandValue("forecolor");
		color = (color)?toHex(colorToRGB(color)):"";
		color =	rGetColorer(color);
		sRange.execCommand("forecolor",false,color);
	}
// --- вставка ссылки
	function rAction_createlink(sRange){
		window.showModalDialog(orPath.base+"richedit.createlink.html",sRange,"dialogWidth:295px; dialogHeight:165px; resizable: no; help: no; status: no; scroll: no;");
	}
// --- свойства изображения
	function rAction_imageproperties(sRange){
		if(sRange.item(0).tagName.toUpperCase() != "IMG") return;
		window.showModalDialog(orPath.base+"richedit.imageproperties.html",sRange,"dialogWidth:295px; dialogHeight:175px; resizable: no; help: no; status: no; scroll: no;");
	}
// --- вставка таблицы
	function rAction_inserttable(sRange){
		window.showModalDialog(orPath.base+"richedit.inserttable.html",sRange,"dialogWidth:478px; dialogHeight:243px; resizable: no; help: no; status: no; scroll: no;");
	}
// --- библиотека файлов
	function rAction_libraryfiles(sRange){	
		if(orLinks.url){
			wrLinks = window.open(orLinks.url+'&d='+orLinks.upload, "richfiles", "width=285px,height=215,status=no,scrollbars=no,resizable=no");
		}else{
			wrLinks = window.open(orPath.base+'richedit.libraryfiles.phtml?d='+orLinks.upload, "richfiles", "width=285px,height=215,status=no,scrollbars=no,resizable=no");
		}
		wrLinks.focus();
	}
// --- библиотека изображений
	function rAction_libraryimages(sRange){
		if(orImages.url){
			wrImages = window.open(orImages.url+'&d='+orImages.upload+'&h='+orImages.height+'&w='+orImages.width, "richimages", "status=no,scrollbars=1,resizable=no,width=780,height=320");
		}else{
			wrImages = window.open(orPath.base+'richedit.libraryimages.phtml?d='+orImages.upload+'&h='+orImages.height+'&w='+orImages.width, "richimages", "status=no,scrollbars=1,resizable=no,width=780,height=320");
		}
		wrImages.focus();
	}
// --- удаление строки
	function rAction_deleterow(sRange){
		var elmTR = rGetParent(sRange.parentElement(),"TR");
		if(elmTR!=null){	// выделена одна строка
			var elmTABLE = rGetParent(elmTR,"TABLE");		// ищем родительский TABLE
			if(elmTABLE.rows.length==1){							
			// --- удаляем таблицу целиком
				elmTABLE.removeNode(true);
			}else{
			// --- исправляем rowSpan строки снизу удаляемой строки
				if(elmTABLE.rows[elmTR.rowIndex+1]){
					var mTABLE = new rMatrix(elmTABLE);  
					var mPos = mTABLE.position(elmTR.cells[0]); 
					var rowPos = mPos.row;
					var newTR	 = elmTABLE.rows[elmTR.rowIndex+1].cloneNode(false);
					var cellIndex = -1;
					for(var i=0; i<mTABLE.mcols; i++){
						if(cellIndex !=	mTABLE.matrix[rowPos+1][i]){
							cellIndex =	mTABLE.matrix[rowPos+1][i];
							if(rowPos==0 || mTABLE.matrix[rowPos-1][i]!=cellIndex){
								var newTD = elmTABLE.cells[cellIndex].cloneNode(true);
								if(mTABLE.matrix[rowPos][i]==cellIndex) newTD.setAttribute("rowSpan",elmTABLE.cells[cellIndex].rowSpan-1);
								newTR.appendChild(newTD);
							}					
						}
					}
				elmTABLE.rows[elmTR.rowIndex+1].parentNode.replaceChild(newTR,elmTABLE.rows[elmTR.rowIndex+1]);
				}
			// --- исправляем rowSpan строк ссверху удаляемой строки
				for(var i=0; i<elmTR.rowIndex; i++){
					var tempTR = elmTABLE.rows(i);
					for(var j=0; j<tempTR.cells.length; j++){
						if(tempTR.cells(j).rowSpan>(elmTR.rowIndex - i)) tempTR.cells(j).rowSpan--;
					}
				}
			// --- удаляем строку 
				elmTABLE.deleteRow(elmTR.rowIndex);
			}
		}
	}
// --- вставка строки
	function rAction_insertrow(sRange){
		var elmTR = rGetParent(sRange.parentElement(),"TR");
		if(elmTR!=null){	// выделена одна строка
			var elmTABLE = rGetParent(elmTR,"TABLE");		// ищем родительский TABLE
      var newTR = elmTABLE.insertRow(elmTR.rowIndex+1);
			// --- вставляем строку по образу и подобию
      for(var i=0; i<elmTR.cells.length; i++){
        if (elmTR.cells(i).rowSpan>1) 
					elmTR.cells(i).rowSpan++;
        else{
          var newTD = elmTR.cells(i).cloneNode();
          newTR.appendChild(newTD);
        }
      }
			// --- исправляем rowSpan строк ссверху вставленой строки
      for(var i=0; i<elmTR.rowIndex; i++){
        var tempTR = elmTABLE.rows(i);
        for(var j=0; j<tempTR.cells.length; j++){
          if(tempTR.cells(j).rowSpan>(elmTR.rowIndex - i)) tempTR.cells(j).rowSpan++;
        }
      }
		}
	}
// --- объединить ячейку с правой
	function rAction_mergeright(sRange){ 
		var elmTD = rGetParent(sRange.parentElement(),"TD");
		if(elmTD!=null){
			var elmTABLE = rGetParent(elmTD,"TABLE");
			var mTABLE = new rMatrix(elmTABLE);  
			var mPos = mTABLE.position(elmTD); 
			var nPos = mTABLE.nearest(mPos,'right');
			if(nPos){ 
				var nextTD	= elmTABLE.cells[mTABLE.index(nPos)];
				if(nPos.row==mPos.row && nextTD.rowSpan==elmTD.rowSpan){
					elmTD.innerHTML = elmTD.innerHTML+" "+nextTD.innerHTML;
					elmTD.colSpan = elmTD.colSpan+nextTD.colSpan;
					nextTD.parentNode.deleteCell(nextTD.cellIndex);
				}
			}
		}
	}
// --- объединить ячейку с нижней
	function rAction_mergedown(sRange){ 
		var elmTD = rGetParent(sRange.parentElement(),"TD");
		if(elmTD!=null){
			var elmTABLE = rGetParent(elmTD,"TABLE");
			var mTABLE = new rMatrix(elmTABLE);  
			var mPos = mTABLE.position(elmTD); 
			var nPos = mTABLE.nearest(mPos,'bottom');
			if(nPos){ 
				var nextTD	= elmTABLE.cells[mTABLE.index(nPos)];
				if(nPos.col==mPos.col && nextTD.colSpan==elmTD.colSpan){
					elmTD.innerHTML = elmTD.innerHTML+"<br>"+nextTD.innerHTML;
					elmTD.rowSpan = elmTD.rowSpan+nextTD.rowSpan;
					nextTD.parentNode.deleteCell(nextTD.cellIndex);
				}
			}
		}
	}
// --- снять объединение с ячеек
	function rAction_mergenone(sRange){ 
		var elmTD = rGetParent(sRange.parentElement(),"TD");
		if(elmTD!=null&&elmTD.colSpan*elmTD.rowSpan){
			var elmTABLE = rGetParent(elmTD,"TABLE");
			var mTABLE = new rMatrix(elmTABLE);  
			var mPos = mTABLE.position(elmTD);
			var colSpan = elmTD.colSpan; elmTD.colSpan = 1;
			var rowSpan = elmTD.rowSpan; elmTD.rowSpan = 1;
			for(var i=0;i<rowSpan;i++){
				if(i>0){
					var isReal = false;
					var colNum = -1;
					for(var j=0;j<mTABLE.mcols;j++){
						if(mTABLE.matrix[mPos.row+i][j]!=mTABLE.matrix[mPos.row+i-1][j]){
							isReal = true;
							if(j>colNum && j<mPos.col) colNum = j;
						}
					}
					if(colNum>=0 && colNum<mPos.col){
						var nTD = elmTABLE.cells[mTABLE.matrix[mPos.row+i][colNum]+i*colSpan-1];
						nTD.parentNode.replaceChild(elmTD.cloneNode(false),nTD.parentNode.insertCell(nTD.cellIndex+1));
						elmTD = nTD.parentNode.cells[nTD.cellIndex+1];
					}else{
						var nTR = (isReal)?elmTABLE.rows[elmTD.parentNode.rowIndex+1]:elmTABLE.insertRow(elmTD.parentNode.rowIndex+1);
						nTR.replaceChild(elmTD.cloneNode(false),nTR.insertCell(0));
						elmTD = nTR.cells[0];
					}
					mTABLE.matrix[mPos.row+i][mPos.col+j-1]
				}
				for(var j=1;j<colSpan;j++)
					elmTD.parentNode.replaceChild(elmTD.cloneNode(false),elmTD.parentNode.insertCell(elmTD.cellIndex+j));
			}
		}
	}


