//id of active editor
var active_rich = null;

//prevent error messaging
window.onerror = no_error;

//context menu parser
function parse_context_ie5(){
var mode;
var sel;
var r;
var td;
var form;

	eval('mode = '+active_rich.name+'_rich_mode;'); //current mode

	//do nothing in source text editing mode
	if(!mode) return;

	sel = active_rich.document.selection;
	r = sel.createRange();

	if(sel.type == 'Control'){

		switch(r(0).tagName){
			case 'TABLE':
				show_dialog("CreateTable"); //edit table
				break;
			case 'IMG':
				show_dialog("CreateImage"); //edit image
				break;
			case 'OBJECT':
				show_dialog("CreateFlash"); //edit flash
				break;
			case 'INPUT':
				switch(r(0).type.toUpperCase()){
					case 'HIDDEN':
						show_dialog("CreateHidden"); //edit hidden field
						break;
					case 'TEXT':
					case 'PASSWORD':
						show_dialog("CreateText");//edit common input field
						break;
					case 'BUTTON':
					case 'RESET':
					case 'SUBMIT':
						show_dialog("CreateButton"); //edit button
						break;
					case 'CHECKBOX':
						show_dialog("CreateCheckBox"); //edit checkbox
						break;
					case 'RADIO':
						show_dialog("CreateRadio"); //edit radio button
						break;
					default:
						break;
				}
				break;
			case 'TEXTAREA':
				show_dialog("CreateTextArea"); //edit text area
				break;
			case 'SELECT':
				show_dialog("CreateSelect"); //edit list box
				break;
			default:
				break;
		}

	}else{

		if(r.parentElement){ //edit table cell
			td = get_previous_object(r.parentElement(),'TD');
			if(td != null) show_dialog("EditCell", td);

			form = get_previous_object(r.parentElement(),'FORM');
			if(form != null) show_dialog("CreateForm");
		}

	}

	change_toolbar_state(); //set new states of toolbar buttons

}

//parses toolbar button press event
function do_action(action,value){
var mode;
var sel;
var r;
var is_control;
var found;
var button_object;

	if (is_editable_regs() && !inside_editable_reg() &&
		action != 'FullScreen') return;

	eval('mode = '+active_rich.name+'_rich_mode;'); //current mode

	if (!is_editable_regs()) active_rich.focus(); //set focus on active editor
	re_hide_lists(); //hide all dropdowns

//in source mode buttons do not work
//	if(!mode) return;

	//hide popup menu if exists
	if (rich_popup) rich_popup.hide();

	button_object = get_button_object(action);
	if(!active_button(button_object)){ //button is inactive
		return;
	}

	//check if any control element is active, e.g. image or table
	sel = active_rich.document.selection;
	r = sel.createRange();
	if(sel.type == 'Control') is_control = true;
	else is_control = false;

	found = true;
	switch(action){
		case 'Cut':					//cut
		case 'Copy':				//copy
		case 'Undo':				//undo previous action
		case 'Redo':				//redo last cancelled action
			break;
		case 'Paste':				//paste
			eval('var clean_paste = '+active_rich.name+'_clean_paste;');
			if (mode && clean_paste) {
				do_action('PasteWord');
				found = false;
			}
			break;
		case 'Bold':				//set/unset bold style
		case 'Italic':				//set/unset italic style
		case 'Underline':			//set/unset undeline style
		case 'Strikethrough':		//set/unset strikethrough style
		case 'SuperScript':			//set/unset superscript style
		case 'SubScript':			//set/unset subscript style
		case 'JustifyFull':			//justify full
		case 'InsertOrderedList':	//insert ordered list
		case 'InsertUnorderedList':	//insert unordered list
		case 'Outdent':				//decrease indention
		case 'Indent':				//increase indention
		case 'InsertHorizontalRule'://insert horizontal line
		case 'RemoveFormat':        //remove text formatting
			if(is_control) found = false;
			break;
		case 'JustifyLeft':			//justify left
		case 'JustifyCenter':		//justify center
		case 'JustifyRight':		//justify right
			break;
		case 'FormatBlock':			//set paragraph style
		case 'FontName':			//set font
			if(is_control) found = false;
			break;
		case 'FontSize':            //set font size
			if(is_control) found = false;
				else {

					//make RE setting size=3 attribute
					//otherwise it will be just removed
					if (value == 3) {
						var fobj = null;
						if (r.parentElement) {
							fobj = get_previous_object(r.parentElement(),'FONT');
						}

						//text inside a font tag and no text selected or text
						//selected contains the whole html text of the font tag
						if (fobj && (r.htmlText == "" || fobj.outerHTML == r.htmlText)) {
							fobj.setAttribute('size', 3);
						} else r.pasteHTML("<font size=3>" + r.htmlText + "</font>");
						found = false;
					}

					if (value == "") value = 3; //remove font tag
				}
			break;
		case 'ClassName':           //set class
			set_class(value);
			found = false;
			break;
		case 'ForeColor':           //set foreground color
		case 'BackColor':           //set background color
			if(is_control){
				found = false;
				break;
			}
			var cur_color = active_rich.document.queryCommandValue(action);
			if (String(cur_color).indexOf('#') < 0) cur_color = dec2hex(cur_color);
			value = pick_color(null, cur_color);
			break;
		case 'InsertRow':           //insert row in table
			if(is_control) break;

			var ins_to = insert_to('insert_row');
			if (ins_to != null) insert_row(ins_to);
			found = false;
			break;
		case 'DeleteRow':           //delete row from table
			if(is_control) break;
			delete_row();
			found = false;
			break;
		case 'InsertColumn':        //insert column in table
			if(is_control) break;

			var ins_to = insert_to('insert_column');
			if (ins_to != null) insert_column(ins_to);
			found = false;
			break;
		case 'DeleteColumn':        //delete column from table
			if(is_control) break;
			delete_column();
			found = false;
			break;
		case 'PasteWord':           //paste text from MSWord
			paste_word();
			found = false;
			break;
		case 'SwitchBorders':       //show invisible table borders
			switch_borders(true);
			found = false;
			break;
		case 'InsertChar':          //insert a special character
			if(is_control) break;
			insert_char();
			found = false;
			break;
		case 'InsertCell':          //insert cell
			if(is_control) break;
			insert_cell();
			found = false;
			break;
		case 'DeleteCell':          //delete cell
			if(is_control) break;
			delete_cell();
			found = false;
			break;
		case 'MergeCells':          //merge cells
			found = false;
			if(is_control) break;
			merge_cells();
			break;
		case 'MergeCellsDown':      //merge cells vert
			found = false;
			if(is_control) break;
			merge_cells_down();
			break;
		case 'SplitCell':           //split cell
			found = false;
			if(is_control) break;
			split_cell();
			break;
		case 'SplitCellDown':      //split cell vert
			found = false;
			if(is_control) break;
			merge_cells_down(true);
			break;
		case 'FullScreen':          //switch on/off fullscreen mode
			full_screen(get_editor_name(button_object));
			found = false;
			break;
		case 'InsertSnippet':      //show snippet popup menu/insert a snippet
			if(value) insert_snippet(value);
			found = false;
			break;
		case 'AbsolutePosition':	//switch on/off absolute positioning
			active_rich.document.execCommand("2D-Position", false, true);
			break;
		default:
			found = false;
			break;
	}

	if (found) active_rich.document.execCommand(action, false, value);

	change_toolbar_state(); //set new states of toolbar buttons

}

//changes states of toolbar buttons, when they are pressed/released
function mouse_down(down){
var element;
var mode;
var name;
var obj;

	element = window.event.srcElement;

	if(element && element.tagName=='IMG'){
		name = get_editor_name(element);
		eval('mode = '+name+'_rich_mode;'); //current mode

		if(!active_button(element)){ //button is inactive
			eval('obj = '+name+'_id;'); //editor of the current button
			if(obj) obj.focus();
			return;
		}

		if(down){ //pressed
			element.className = 're_mouse_down';
		}else{ //released
			element.className = 're_mouse_up';
		}

	}

}

//changes state of toolbar button, when mouse is over it
function mouse_over(over){
var element;
var name;
var mode;
var obj;
var id_name;
var acrion_name;
var old_active_rich;
var button_name;
var changing_button;
var mode_name;

	element = window.event.srcElement;

	if(element && element.tagName=='IMG'){
		name = get_editor_name(element);
		eval('mode = '+name+'_rich_mode;'); //current mode

		eval('obj = '+name+'_id;'); //editor of the current button
		if(!obj) return;

		//in source mode toolbar buttons do not work
//    if(!mode) return;

		if(!active_button(element)) return; //button is inactive

		if(over){ //mouse is over button
			element.className = 're_mouse_over';
		}else{    //mouse is moved from the button
			id_name = String(element.id);
			action_name = id_name.substring(0,id_name.length-name.length-1);

			if(action_name == 'SwitchBorders' ||
				action_name == 'FullScreen' ||
				action_name == 'AbsolutePosition'){//switch borders button

				if(action_name == 'SwitchBorders') mode_name = 'border';
					else if (action_name == 'AbsolutePosition') mode_name = 'abspos';
						else mode_name = 'full_screen';

				eval('border_mode = '+obj.name+'_rich_'+mode_name+'_mode;');
				old_active_rich = active_rich;
				active_rich = obj;
				set_state(action_name, border_mode);
				active_rich = old_active_rich;
			}else{//common buttons

				button_name = (id_name.split('_'))[0];
				if(button_name == 'Bold' || button_name == 'Italic' ||
				button_name == 'Underline'|| button_name == 'Strikethrough' ||
				button_name == 'SuperScript' || button_name == 'SubScript' ||
				button_name == 'JustifyLeft' || button_name == 'JustifyCenter' ||
				button_name == 'JustifyRight' || button_name == 'JustifyFull' ||
				button_name == 'InsertOrderedList' ||
				button_name == 'InsertUnorderedList'){
					//button changing its state accordingly to text formatting
					changing_button = true;
				}else{
					changing_button = false;
				}
				if(!changing_button ||
					!obj.document.queryCommandValue(action_name)){
					element.className = 're_mouse_out';
				}else{ //do button pressed
					element.className = 're_mouse_down';
				}

			}

		}

	}

}

//change current editor mode
function change_mode(){
var mode;
var active_mode;
var border_mode;
var i;
var text;
var button_id_parts;
var button_name;
var editror_name;
var full_screen_mode;

	eval('mode = '+active_rich.name+'_rich_mode;'); //current mode
	eval('active_mode = '+active_rich.name+'_rich_active_mode;'); //active mode
	//current border mode
	eval('border_mode = '+active_rich.name+'_rich_border_mode;');
	//current fullscreen mode
	eval('full_screen_mode = '+active_rich.name+'_rich_full_screen_mode;');

	text = get_rich_content(active_rich, true);

	if(mode){ //switch in source mode

		//set font and text colors for source code
		active_rich.document.body.runtimeStyle.fontFamily = 'Courier';
		active_rich.document.body.runtimeStyle.fontSize = '12px';
		active_rich.document.body.runtimeStyle.bgColor = '#FFFFFF';
		active_rich.document.body.runtimeStyle.color = '#000000';
		active_rich.document.body.runtimeStyle.background = '#FFFFFF';

		//do toolbar buttons inactive
		for(i=0;i<document.images.length;i++){

			button_id_parts = document.images(i).id.match(/([^_]+)_(.+)$/);
			if(button_id_parts){
				button_name = button_id_parts[1];
				editor_name = button_id_parts[2];
				if(editor_name == active_rich.name){
					if(button_name != 'Cut' && button_name != 'Copy' &&
					button_name !=  'Paste' && button_name != 'Help' &&
					button_name != 'Preview' && button_name != 'Find' &&
					button_name != 'Save'){
						show_button(button_name, false);
					}

				}
			}

		}

		//do all select elements inactive
		show_select('FormatBlock', false);
		show_select('FontName', false);
		show_select('FontSize', false);
		show_select('ClassName', false);

		eval(active_rich.name+'_rich_mode = false;');

	}else{ //switch in wysiwyg mode

		//unset font and text colors for source code
		active_rich.document.body.runtimeStyle.cssText = "";

		//do toolbar buttons active
		for(i=0;i<document.images.length;i++){

			button_id_parts = document.images(i).id.match(/([^_]+)_(.+)$/);
			if(button_id_parts){
				button_name = button_id_parts[1];
				editor_name = button_id_parts[2];
				if(editor_name == active_rich.name){
					show_button(button_name, true);
				}
			}

		}

		//redraw 'show borders' button
		set_state('SwitchBorders', border_mode);

		//redraw 'full screen' button
		set_state('FullScreen', full_screen_mode);

		//do all select elements active
		show_select('FormatBlock', true);
		show_select('FontName', true);
		show_select('FontSize', true);
		show_select('ClassName', true);

		eval(active_rich.name+'_rich_mode = true;');

	}

	set_rich_content(active_rich, text); //set new content

	if(active_mode || mode){
		//do fullscreen mode button active/inactive
		show_button('FullScreen', full_screen_mode || document.all.rich_fs_iframe.style.display!='');
	}

	set_state('FullScreen', full_screen_mode);

	if(active_mode) change_toolbar_state(); //refresh toolbar buttons states

	active_rich.focus();
}

//changes current states of toolbar buttons
//according to style of text in current position of cursor
function change_toolbar_state(what){
var mode;
var active_mode;
var full_screen_mode;

	eval('active_mode = '+active_rich.name+'_rich_active_mode;'); //if active mode
	eval('mode = '+active_rich.name+'_rich_mode;'); //current mode
	//current fullscreen mode
	eval('full_screen_mode = '+active_rich.name+'_rich_full_screen_mode;');

	set_state('FullScreen', full_screen_mode);

	//in source mode toolbar buttons do not work
	if(!mode){
		if(active_mode){
			//make only clipboard buttons active/inactive
			show_clipboard_buttons();
		} 
		return;
	}

	var sel = active_rich.document.selection;
	var r = sel.createRange();

	if(!what || what == "ClassName")			set_style("ClassName", get_class());
	if (sel.type != 'Control') {
//	if(!what || what == "FormatBlock")         set_style("FormatBlock", active_rich.document.queryCommandValue('FormatBlock'));
		if(!what || what == "FontName")				set_style("FontName", String(active_rich.document.queryCommandValue('FontName')).toLowerCase());
		if(!what || what == "FontSize")				set_style("FontSize", active_rich.document.queryCommandValue('FontSize'));

		if(!what || what == "Bold")					set_state("Bold", active_rich.document.queryCommandValue('Bold'));
		if(!what || what == "Italic")				set_state("Italic", active_rich.document.queryCommandValue('Italic'));
		if(!what || what == "Underline")			set_state("Underline", active_rich.document.queryCommandValue('Underline'));
		if(!what || what == "Strikethrough")		set_state("Strikethrough", active_rich.document.queryCommandValue('Strikethrough'));
		if(!what || what == "SuperScript")			set_state("SuperScript", active_rich.document.queryCommandValue('SuperScript'));
		if(!what || what == "SubScript")			set_state("SubScript", active_rich.document.queryCommandValue('SubScript'));
		if(!what || what == "JustifyLeft")			set_state("JustifyLeft", active_rich.document.queryCommandValue('JustifyLeft'));
		if(!what || what == "JustifyCenter")		set_state("JustifyCenter", active_rich.document.queryCommandValue('JustifyCenter'));
		if(!what || what == "JustifyRight")			set_state("JustifyRight", active_rich.document.queryCommandValue('JustifyRight'));
		if(!what || what == "JustifyFull")			set_state("JustifyFull", active_rich.document.queryCommandValue('JustifyFull'));
		if(!what || what == "InsertOrderedList")	set_state("InsertOrderedList", active_rich.document.queryCommandValue('InsertOrderedList'));
		if(!what || what == "InsertUnorderedList")	set_state("InsertUnorderedList", active_rich.document.queryCommandValue('InsertUnorderedList'));
	}

	//current border mode
	eval('var abspos_mode = '+active_rich.name+'_rich_abspos_mode;');
	var is_abs = false;
	if (sel.type == 'Control') {
		if (r(0).style.position == 'absolute') is_abs = true;
	} else {
		if(!what || what == "FormatBlock") set_style("FormatBlock", get_font_block(r.parentElement()));
	}

	if(active_mode){
		show_active_buttons();//make all buttons active/inactive
	}

	if (is_abs || !active_mode) set_state('AbsolutePosition', is_abs);
	eval(active_rich.name+'_rich_abspos_mode = is_abs;');

}

//changes state of button 'what' to value
function set_state(what, value){
var element;

	//object to change
	eval('element = document.all.'+what+'_'+active_rich.name+';');

	if(element){
		if(value){	//pressed
			element.className = 're_mouse_down';
		}else{		//released
			element.className = 're_mouse_out';
		}
	}

}

//changes state of select element 'what' in value
function set_style(what, value){
var element;
var param = null;

	//correct format block name
	param = String(value).match(/Heading (.+)/);
	if(param) value = '<H'+param[1]+'>';

	if(value == 'Normal') value = '<P>';
	if(value == 'Formatted') value = '<PRE>';

	//object to change
	eval('element = document.all.'+what+'_'+active_rich.name+';');
	if(element) element.value = value;
}

//show dialog window to pick color
function pick_color(name, color){
	if(!name) var name = active_rich.name; //name of current editor

	return showModalDialog(rich_path+"pick_color"+rich_dialog_ext+"?lang="+eval(name+"_lang")+"&110903t", color,
			"dialogWidth:445px; dialogHeight:140px; status:no; scroll:no; help:no");
}

//show dialog window to create/edit objects (table, image)
function show_dialog(action, object){
var mode;
var sel;
var r;
var is_control;
var attrib;
var parameters;
var link_text;
var element;
var link;
var i;
var param;
var outerHTML = '';
var text_class;
var element_type;
var button_object;

	if (is_editable_regs() && !inside_editable_reg() &&
		!(action == 'Help' || action == 'Preview' || action == 'Save')) return;

	eval('mode = '+active_rich.name+'_rich_mode;'); //current mode

	if (!is_editable_regs()) active_rich.focus(); //set focus on active editor

	//hide popup menu if exists
	if(rich_popup) rich_popup.hide();

	//in source mode toolbar dialog buttons do not work
	if(!mode &&
		!(action == 'Help' || action == 'Preview' || action == 'Find'
			|| action == 'Save')) return;

	//check, if any control element is active (i.e. image or table)
	sel = active_rich.document.selection;
	r = sel.createRange();
	if(sel.type == 'Control') {
		is_control = true;
		if(r.commonParentElement) element = r.commonParentElement();
			else return;
	} else is_control = false;

	switch(action){
		case "CreateTable": //create table
			if(is_control && element.tagName != 'TABLE') break;
			show_table_dialog();
			break;

		case "EditCell": //edit table cell
			var attrib = new Array();
			attrib['parent_win'] = window;
			showModalDialog(rich_path+"dialog_cell"+rich_dialog_ext+"?lang="+eval(active_rich.name+"_lang")+"&re_ext="+rich_dialog_ext+"&110903g", attrib,
					"dialogWidth:310px; dialogHeight:180px; status:no; scroll:no; help:no");
			break;

		case "CreateImage": //create image
			if(is_control && element.tagName != 'IMG') break;
			show_image_dialog("");
			break;

		case "CreateFlash": //create flash
			if(is_control && element.tagName != 'OBJECT') break;
			show_flash_dialog("");
			break;

		case "CreateLink": //create reference
			if(r.parentElement){ //check, if text is inside a reference
				link = get_previous_object(r.parentElement(),'A');
			}else{
				if(r.commonParentElement){ //check, if control is inside a reference
					link = get_previous_object(r.commonParentElement(),'A');
				}else link = null;
			}

			//cursor is not inside a link
			if (!link && !is_control && sel.type != 'Text') break;

			if(!link && !is_control){
				link_text = r.htmlText;
				if(link_text.match(/<\/?A/i)) break; //there is a link inside
			}

			if (!link || link.innerHTML != "") show_link_dialog("");
			break;

		case "CreateAnchor":
			if (r.parentElement) {
				link = get_previous_object(r.parentElement(),'A');
				if (link && link.href != '') break; //cursor is inside a link
			}

			if (r.htmlText == "" || link ||
				is_control && element.tagName == 'A' && element.href=='') show_object_dialog('anchor');
			break;

		case "EditLink": //edit reference

			attrib = get_link(object); //get values of image attributes
			parameters = show_link_dialog(attrib);

			if(parameters) edit_object(object, parameters);
			break;

		case "Help": //show help window

			var name = active_rich.name;
			var lang = eval(name+"_lang");
			window.open(rich_path+"lang/help_"+lang+rich_dialog_ext+"?lang="+lang,"re_help_"+lang,
						"toolbar=0,scrollbars=yes,resizable=yes");
			break;

		case "Preview": //preview of the current editor content
			var pre_window;
			var editor_content;
        
			var name = active_rich.name;
        
			//current page mode
			eval('page_mode = '+name+'_rich_page_mode;');
			//default stypesheets
			eval('var rich_css = '+name+'_rich_css;');
        
			editor_content = get_rich_content(active_rich);

			try {
				pre_window = window.open('', '', 'toolbar=yes,location=yes,status=yes,menubar=yes,scrollbars=yes,resizable=yes,titlebar=1');
				pre_window.document.write(editor_content);
				pre_window.document.close();
			}catch (e) {}
        
			//add default stylesheets to preview page (disappear if refresh it)
			for (i in rich_css) {
				pre_window.document.createStyleSheet(rich_css[i]);
			}
        
			break;

		case "Find":
			var lang = eval(active_rich.name+"_lang");
			showModelessDialog(rich_path+"dialog_find"+rich_dialog_ext+"?lang="+lang+"&browser=&t", active_rich,
			"dialogWidth:190px; dialogHeight:70px; scroll:no; status:no; help:no;");
			break;

		case "CreateForm": //create form
			if(!is_control){
				show_form_dialog(null, "form");
			}
			break;

		case "CreateHidden": //create hidden field
			if(is_control && (element.tagName != 'INPUT' ||
				element.type.toUpperCase() != 'HIDDEN')){
				break;
			}
			show_form_dialog(null, "hidden");
			break;

		case "CreateText": //create text field
			if(is_control && (element.tagName != 'INPUT' ||
				element.type.toUpperCase() != 'TEXT' &&
				element.type.toUpperCase() != 'PASSWORD')){
				break;
			}
			show_form_dialog(null, "text");
			break;

		case "CreateTextArea": //create text area
			if(is_control && element.tagName != 'TEXTAREA') break;
			show_form_dialog(null, "textarea");
			break;

		case "CreateButton": //create button
			if(is_control && (element.tagName != 'INPUT' ||
				element.type.toUpperCase() != 'BUTTON' &&
				element.type.toUpperCase() != 'RESET' &&
				element.type.toUpperCase() != 'SUBMIT')) break;
			show_form_dialog(null, "button");
			break;

		case "CreateCheckBox": //create checkbox
		case "CreateRadio":   //create radiobutton
			if(action == 'CreateCheckBox'){
				element_type = 'checkbox';
				action = 'EditCheckBox';
			}else{
				element_type = 'radio';
				action = 'EditRadio';
			}

			if(is_control && (element.tagName != 'INPUT' ||
				element.type.toUpperCase() != element_type.toUpperCase())){
				break;
			}

			show_form_dialog(null, element_type);
			break;

		case "CreateSelect": //create list element
			if (is_control && element.tagName != 'SELECT') break;
			show_form_dialog(null, "select");
			break;

		case "InsertSnippet": //insert a snippet
			if(!is_control && r.parentElement){
				show_form_dialog(null, "snippet");
			}
			break;

		case "PageProperties": //page properties
			show_page_dialog();
			break;

		default:
			break;
	}

}

//search among parents an object with tag tag_name
function get_previous_object(obj,tag_name) {
  if(obj){

    //to prevent search outside editor
    if(obj.className == "re_editor") return null;

    if(obj.tagName != tag_name){
      obj = get_previous_object(obj.parentNode, tag_name);
    }
  }
  return(obj);
}

var re_font_blocks = 'P,H1,H2,H3,H4,H5,H6,PRE,';
//search among parents for a font block tag
function get_font_block(obj) {
	if(obj){
		//to prevent search outside editor
		if(obj.className == "re_editor" || !obj.tagName) return '<P>';

		var tag_name = obj.tagName.toUpperCase();
		//if P tag is inside of one of H tags then current block is H not P
		if(re_font_blocks.indexOf(tag_name + ',') < 0 || tag_name == 'P'){
			return get_font_block(obj.parentNode);
		}
		return('<' + tag_name + '>');
	}
	return('<P>');
}

//inserts row into current table just after current row
function insert_row(ins_to){
var range;
var tr;
var table;
var row;
var i;
var curr_colspan;

	range = active_rich.document.selection.createRange();

	tr = get_previous_object(range.parentElement(),'TR');
	table = get_previous_object(tr,'TABLE');

	if(table != null){

		eval('var border_mode = '+active_rich.name+'_rich_border_mode;');

		row = table.insertRow(tr.rowIndex+ins_to); //create new row
		for(i=0;i<tr.cells.length;i++){ //fill the row with columns
			var cell = row.insertCell(i);

			if (border_mode) cell.runtimeStyle.border = '1px dashed #CCCCCC';

			var attr = new Array('width', 'height', 'vAlign', 'bgColor');
			var j;
			for (j in attr) {
				var attr_value = eval('tr.cells(i).getAttribute("'+attr[j]+'")');
				eval('if(attr_value) cell.setAttribute("'+attr[j]+'", attr_value)');
			}

			//take colspan values from the previous row cells
			curr_colspan = tr.cells(i).colSpan;
			if(curr_colspan > 1){
				cell.colSpan = curr_colspan;
			}
		}

	}

}

//deletes current row from current table
function delete_row(){
var range;
var tr;
var table;

	range = active_rich.document.selection.createRange();

	tr = get_previous_object(range.parentElement(),'TR');
	table = get_previous_object(tr,'TABLE');

	if(table != null){
		if(table.rows.length <= 1){
			table.removeNode(true); //it is the last row - delete whole table
		}else{
			table.deleteRow(tr.rowIndex); //delete row
		}
	}

}

//insert column in current table just after current column
function insert_column(ins_to){
var range;
var td;
var table;
var i;
var curr_rowspan;
var cell_index;
var rowspan_index;
var curr_index;

	range = active_rich.document.selection.createRange();

	td = get_previous_object(range.parentElement(),'TD');
	table = get_previous_object(td,'TABLE');

	if(table != null){

		curr_index = td.cellIndex;
		//insert new cells in each row
		for(i=0;i<table.rows.length;i++){

			if(curr_index+ins_to > table.rows(i).cells.length){
				cell_index = table.rows(i).cells.length;
			}else{
				cell_index = curr_index+ins_to;
			}

			if(curr_index < table.rows(i).cells.length){
				rowspan_index = curr_index;
			}else{
				rowspan_index = table.rows(i).cells.length-1;
			}

			var j = -1;
			var attr = new Array('width', 'height', 'vAlign', 'bgColor');

			//take rowspan values from current column cells
			if (rowspan_index<0) curr_rowspan = 1;
				else {
					var tr = table.rows(i).cells(rowspan_index);
					curr_rowspan = tr.rowSpan;

					for (j in attr) {
						eval('var '+attr[j]+'=tr.getAttribute("'+attr[j]+'")');
					}
				}

			var cell = table.rows(i).insertCell(cell_index);

			eval('var border_mode = '+active_rich.name+'_rich_border_mode;');

			if (border_mode) cell.runtimeStyle.border = '1px dashed #CCCCCC';

			if(j != -1){
				for (j in attr) {
					eval('if('+attr[j]+') cell.setAttribute("'+attr[j]+'", '+attr[j]+')');
				}
			}

			if(curr_rowspan > 1){
				cell.rowSpan = curr_rowspan;
				i += curr_rowspan-1; //next curr_rowspan-1 cells are from another column
			}

		}

	}

}

//delete current column from current table
function delete_column(){
var range;
var td;
var table;
var i;
var tr;
var cell_index;

	range = active_rich.document.selection.createRange();

	td = get_previous_object(range.parentElement(),'TD');
	table = get_previous_object(td,'TABLE');

	if (table != null) {
		cell_index = td.cellIndex;

		//insert new cells in each row
		for (i=0;i<table.rows.length;i++) {

			tr = table.rows(i);
			if (tr.cells.length<=1) {
				//last cell in a row -- delete the row
				tr.removeNode(true);
				i--;
			} else {
				if (cell_index < tr.cells.length) {
					if (tr.cells(cell_index).rowSpan>1) {
						i+=tr.cells(cell_index).rowSpan-1;
					}
					tr.deleteCell(cell_index);
				}
			}

		}

		if (table.rows.length == 0) {
			//there are no rows - delete table
			table.removeNode(true);
		}

	}

}

//insert cell in current table just after current cell
function insert_cell(){
var range;
var td;
var tr;

  range = active_rich.document.selection.createRange();

  td = get_previous_object(range.parentElement(),'TD');
  tr = get_previous_object(td,'TR');

  if(tr != null){
    //insert new cell after current one
    var cell = tr.insertCell(td.cellIndex+1);

	eval('var border_mode = '+active_rich.name+'_rich_border_mode;');
	if (border_mode) cell.runtimeStyle.border = '1px dashed #CCCCCC';

  }

}

//delete current cell from current table
function delete_cell(){
var range;
var td;
var table;
var tr;

  range = active_rich.document.selection.createRange();

  td = get_previous_object(range.parentElement(),'TD');
  tr = get_previous_object(range.parentElement(),'TR');
  table = get_previous_object(td,'TABLE');

  if(table != null){

    if(tr.cells.length<=1){
      //it is the last cell in the row - delete row
      table.deleteRow(tr.rowIndex); //delete row

      if(table.rows.length == 0){
        //there are no rows - delete table
        table.removeNode(true);
      }
    }else{
      tr.deleteCell(td.cellIndex);
    }

  }

}

//merge cells
function merge_cells(){ 
var range;
var td;
var tr;
var next_td;

  range = active_rich.document.selection.createRange();

  td = get_previous_object(range.parentElement(),'TD');
  tr = get_previous_object(range.parentElement(),'TR');

  //check if the current cell is not last in the row
  if(tr != null && td.cellIndex < tr.cells.length-1){ 
    //increase current cell colspan value by next cell colspan value
    //and delete the next cell
    next_td = tr.cells(td.cellIndex+1);
    td.innerHTML += next_td.innerHTML; 
    td.colSpan += next_td.colSpan;
    tr.deleteCell(td.cellIndex+1); 
  } 

} 

//split cell
function split_cell(){
var range;
var td;
var tr;

	range = active_rich.document.selection.createRange();

	td = get_previous_object(range.parentElement(),'TD');
	tr = get_previous_object(range.parentElement(),'TR');

	//split cells with colSpan > 1 only
	if(tr != null && td.colSpan > 1){
		td.colSpan--;
		var cell = tr.insertCell(td.cellIndex+1);
		cell.rowSpan = td.rowSpan;

		eval('var border_mode = '+active_rich.name+'_rich_border_mode;');
		if (border_mode) cell.runtimeStyle.border = '1px dashed #CCCCCC';
	}

} 

//merge/split cells down
function merge_cells_down(split_cell){ 
var next_td;

var range = active_rich.document.selection.createRange();

var td = get_previous_object(range.parentElement(),'TD');
var tr = get_previous_object(range.parentElement(),'TR');
var table = get_previous_object(td,'TABLE');

	//check if the current cell is not last in the row
	if (!(tr != null && (td.rowSpan > 1 && split_cell ||
				tr.rowIndex+td.rowSpan < table.rows.length && !split_cell)))
		return;

	var split_inc = split_cell?1:0;

	//find index of current td calculated using colspan values
	var i;
	var real_cell = 0;
	var real_cell2 = 0;
	for (i=0; i<tr.cells.length&&i<td.cellIndex; i++) {
		real_cell += tr.cells(i).colSpan;
		var inc = tr.cells(i).rowSpan-td.rowSpan+split_inc;
		real_cell2 += inc>0?tr.cells(i).colSpan:0;
	}

	var tr2 = table.rows(tr.rowIndex+td.rowSpan-split_inc);
	if (!tr2) return;
	var tr2_cells = tr2.cells;

	//find td in the row below to merge with current one
	for (i=0; i<tr2_cells.length; i++) {
		if (real_cell2 >= real_cell) break;
		real_cell2 += tr2_cells(i).colSpan;
	}

	if (!split_cell) {
		try {
			var td2 = tr2_cells(i);
		} catch(e){
			return;
		}

		if (!td2) return;
		td.innerHTML += td2.innerHTML;
		td.rowSpan += td2.rowSpan;
		tr2.deleteCell(i);
	} else {
		td.rowSpan--;
		try {
			var cell = tr2.insertCell(i);
		} catch(e){
			return;
		}

		if (!cell) return;

		cell.colSpan = td.colSpan;
		eval('var border_mode = '+active_rich.name+'_rich_border_mode;');
		if (border_mode) cell.runtimeStyle.border = '1px dashed #CCCCCC';
	}

} 

//show dialog window to create/edit table
function show_table_dialog(attrib){
	return show_object_dialog('table', attrib);

}

//show dialog window to create/edit image
function show_image_dialog(attrib, name){
	return show_object_dialog('image', attrib, name);
}

//show dialog window to create/edit flash
function show_flash_dialog(attrib, name){
	return show_object_dialog('flash', attrib, name);
}

//show dialog window to create/edit reference
function show_link_dialog(attrib, name){
	return show_object_dialog('link', attrib, name);
}

//show dialog window to edit page properties
function show_page_dialog(attrib){
	return show_object_dialog('page', attrib);
}

//show dialog window to create/edit various objects
function show_object_dialog(object, attrib, name){
var w;
var h;

	if(!object) return;
	if(!name) var name = active_rich.name; //name of current editor

	switch(object){
		case 'table':
			w = 350;
			h = 430;
			break;
		case 'image':
			w = 410;
			h = 440;
			break;
		case 'flash':
			w = 410;
			h = 440;
			break;
		case 'link':
			w = 410;
			h = 440;
			break;
		case 'page':
			w = 350;
			h = 430;
			break;
		case 'anchor':
			w = 200;
			h = 100;
			break;
		default:
			return;
	}

	//transmit browser object
	if (!attrib) {
		var attrib = new Array();
//		attrib['editing_mode'] = false;
	} //else attrib['editing_mode'] = true;
	attrib['parent_win'] = window;

	return showModalDialog(rich_path+"dialog_"+object+rich_dialog_ext+"?files_path="+eval(name+"_files_path")+"&files_url="+eval(name+"_files_url")+"&lang="+eval(name+"_lang")+"&name="+name+"&re_ext="+rich_dialog_ext+"&"+rich_sess_param+"&110903lqqwwwwwwawwwwwwz", attrib,
                           "dialogWidth:"+w+"px; dialogHeight:"+h+"px; status:no; scroll:no; help:no");

}

//show dialog window to create/edit form
function show_form_dialog(attrib, action){
var w;
var h;

	switch(action){
		case 'form':
			w = 331;
			h = 170;
			break;
		case 'text':
			w = 243;
			h = 305;
			break;
		case 'textarea':
			w = 250;
			h = 295;
			break;
		case 'button':
			w = 253;
			h = 210;
			break;
		case 'hidden':
			w = 300;
			h = 170;
			break;
		case 'checkbox':
			w = 253;
			h = 215;
			break;
		case 'radio':
			w = 253;
			h = 215;
			break;
		case 'snippet':
			w = 305;
			h = 343;
			break;
		default:
			w = 200;
			h = 200;
			break;
	}

	//transmit browser object
	if (!attrib) {
		var attrib = new Array();
//		attrib['editing_mode'] = false;
	} //else attrib['editing_mode'] = true;
	attrib['parent_win'] = window;

	return showModalDialog(rich_path+"dialog_form"+rich_dialog_ext+"?action="+action+"&browser=&lang="+eval(active_rich.name+"_lang")+"&110903b", attrib,
			"dialogWidth:"+w+"px; dialogHeight:"+h+"px; status:no; scroll:no; help:no");

}

//saves text of all editors in textarea objects (for form submit)
function save_in_textarea_all(){
var i;
var name;
var text;

	for(i=0;i<document.all.length;i++){
		if(document.all(i).className == 're_editor'){
			name = document.all(i).name;

			//delete editable regions' div tags
			eval('var ed_regs = '+name+'_editable_regions;');
			if (ed_regs) {
				eval('var divs = '+name+'_id.document.body.getElementsByTagName("DIV");');
				var div_length = divs.length;
    
				for (var j=0; j<div_length; j++) {
					if (divs[j].name == "re_editable_region") {
						divs[j].removeNode(false);
    
						//we removed one node => array divs changed
						j--;
						div_length--;
					}
				}
			}

			eval("text=get_rich_content("+name+"_id)");
			eval("document.all['"+name+"_area_id'].value=text");

		  }
	}
}

//find all document stylesheet rules and add their names to select object
function set_stylesheet_rules(){
//asdf.document.body.innerText = asdf.document.body.outerHTML;
var rule_values = new Array();
var rule_found = false;
var sheets;
var sheets_num;
var i,j,k;
var rules;
var rules_num;
var rule_value;
var rule_found;
var rules_select;
var option;
var old_rule_value;

	sheets = active_rich.document.styleSheets;
	sheets_num = sheets.length;

	//select object
	eval('rules_select = document.all.ClassName_'+active_rich.name+';');

  //there are some stylesheets
  if(sheets_num > 0){

    for(i=0;i<sheets_num;i++){
      rules = sheets(i).rules;
      rules_num = rules.length;

      for(j=0;j<rules_num;j++){
        rule_value = rules(j).selectorText;
        //in rules of the type 'td.toolbar span.delimiter{...}'
        //ignore all chars after space char
        rule_value = (rule_value.split(' '))[0];

        //rules MUST have '.' in their names, as it is user defined rules
        if(rule_value.indexOf(".") >= 0){

          //there is ':' char found in the rule name
          if(rule_value.indexOf(":") >= 0){

            //there are both '.' and ':' chars in the rule name
            rule_value = rule_value.substring(rule_value.indexOf(".")+1,rule_value.indexOf(":"));

          }else{

            //name begins with '.'
            if(rule_value.indexOf(".") == 0){
              rule_value = rule_value.substring(1,rule_value.length);
            }else{
              //name do not begins with '.'
              if(rule_value.indexOf(".") > 0){
                rule_value = rule_value.substring(rule_value.indexOf(".")+1,rule_value.length);
              }
            }

          }

          //prevent adding the the same rule names
          for(k=0;k<rule_values.length;k++){
            if(rule_value == rule_values[k]){
              rule_found = true;
              break;
            }
          }

          //new rule
          if(rule_found != true){
            rule_values[rule_values.length] = rule_value;
          }
          rule_found = false;

        }

      }

    }

    if(rules_select){

      //store selecter rule name
	  var sindx = rules_select.selectedIndex;
      if (sindx > 0) old_rule_value = rules_select[rules_select.selectedIndex].value;

      //delete old classes from the select object, except first
      while(rules_select.options[1] != null){
        rules_select.options[1].removeNode(true);
      }
  
      for(i=0;i<rule_values.length;i++){
        if(rule_values[i] != ''){
          option = document.createElement("option");
          option.value = rule_values[i];
          option.text = rule_values[i];
          rules_select.add(option);
        }
      }

      if (sindx > 0) rules_select.value = old_rule_value;

    }

  } else {
	//delete old classes from the select object, except first
	while(rules_select.options[1] != null){
		rules_select.options[1].removeNode(true);
	}
  }

}

//set class attribute for current text or control element
function set_class(rule_value){
var sel = active_rich.document.selection;
var range = sel.createRange();
var is_set;
var object;
var parentTagName;

	if(sel.type == "Control"){
		object = range.commonParentElement();
	}else{

		if(range.parentElement != null){

			parentTagName = range.parentElement().tagName.toUpperCase();
    
			if(range.htmlText == ""){
				object = range.parentElement();
			}else{
				if(parentTagName=="SPAN" || parentTagName=="A"){
    
					object = range.parentElement();
    
				}else{
					if(rule_value != ""){
						try{
							range.pasteHTML("<span class=" + rule_value + ">" + range.htmlText + "</span>");
						}catch(error){
							//do nothing on error, just prevent error message to user
						}
					}
					is_set = true
				}

			}

			if(rule_value == "" && parentTagName == "SPAN"){
				object.removeNode(false);
				is_set = true;
			}

		}

	}

	if(object != null && is_set != true && object.tagName != 'BODY'){
		object.className = rule_value;
	}

}

//get class attribute for current text cursor position
function get_class(){
var sel = active_rich.document.selection;
var range = sel.createRange();
var object = null;

	if(sel.type == "Control"){
		object = range.commonParentElement();
	}else{
		object = range.parentElement();
	}

	if(object != null){

	//to prevent search outside editor
	if(object.className == "re_editor") return "";

		//search class name among parents
		while(object.className == ""){
			object = object.parentElement;
			if(object == null) return "";
		}

		return object.className;
	}
	return "";
}

function clean_code(code) {    
	// get rid of silly space tags
	code = code.replace(/&nbsp;/gi, "");
	// gets rid of all xml stuff... <xml>,<\xml>,<?xml> or <\?xml>
	code = code.replace(/<\\?\??xml[^>]*>/gi, "");
	// get rid of ugly colon tags <a:b> or </a:b>
	code = code.replace(/<\/?\w+:[^>]*>/gi, "");
	// removes all empty <p> tags
	code = code.replace(/<p([^>])*>(&nbsp;|\s)*<\/p>/gi,"");
	// removes all span tags
	code = code.replace(/<\/?span[^>]*>/gi,"");
	// removes all Class attributes on a tag eg. '<p class=asdasd>xxx</p>' returns '<p>xxx</p>'
	code = code.replace(/<([\w]+) class=([^ |>]*)([^>]*)/gi, "<$1$3");
	// removes all style attributes eg. '<tag style="asd asdfa aasdfasdf" something else>' returns '<tag something else>'
	code = code.replace(/<([^>]+) style="([^"]*)"([^>]*)/gi, "<$1$3");

	return code
}

//paste MSWord formatted text from clipboard
function paste_word(){
var sel = active_rich.document.selection.createRange();
var temp_obj;

  if(sel.parentElement){
    //paste in temporary element
    temp_obj = rich_temp_iframe;
    temp_obj.focus();
    temp_obj.document.execCommand("SelectAll");
    temp_obj.document.execCommand("Paste");


    sel.pasteHTML(clean_code(temp_obj.document.body.innerHTML));
  }

	//current border mode
	eval('var border_mode = '+active_rich.name+'_rich_border_mode;');
	set_borders(border_mode);

	if(!is_editable_regs()) active_rich.focus(); //set focus on active editor

}

//show/hide borders of invisible objects
function set_borders(border_mode){
var tables = active_rich.document.body.getElementsByTagName("TABLE");
var forms = active_rich.document.body.getElementsByTagName("FORM");
var anchors = active_rich.document.body.getElementsByTagName("A");
var page_mode;
var i,j,k;
var width;
var height;
var rows;
var cells;

	eval('page_mode = '+active_rich.name+'_rich_page_mode;'); //current page mode

	for(i=0;i<tables.length;i++){

		if(border_mode){
			tables[i].runtimeStyle.border = '1px dashed #CCCCCC';
		}else{

			width = tables[i].style.width;
			height = tables[i].style.height;

			var abspos = tables[i].style.position;
			var top = null;
			var left = null;
			if (abspos == 'absolute') {
				top = tables[i].style.top;
				left = tables[i].style.left;
			}

			tables[i].runtimeStyle.cssText = '';

			if(width) tables[i].style.width = width;
			if(height) tables[i].style.height = height;

			if (abspos == 'absolute') {
				tables[i].style.position = abspos;
				tables[i].style.top = top;
				tables[i].style.left = left;
			}
		 }

		rows = tables[i].rows;
		for(j=0;j<rows.length;j++){
			cells = rows[j].cells;
			for(k=0;k<cells.length;k++){
				if(border_mode){
					cells[k].runtimeStyle.border = '1px dashed #CCCCCC';
				}else{
					cells[k].runtimeStyle.cssText = '';
				}
			}
		}

	}

	//show form borders
	for(i=0;i<forms.length;i++){
		if(border_mode){
			forms[i].runtimeStyle.border = '1px dotted #FF0000';
		}else{
			forms[i].runtimeStyle.cssText = '';
		}
	}

	if(!page_mode){
//		active_rich.document.body.innerHTML = '<body>'+active_rich.document.body.innerHTML+'</body>';
	}else{
//		active_rich.document.body.innerHTML = active_rich.document.documentElement.outerHTML;
	}

	//show anchors
	for(i=0;i<anchors.length;i++){
		if(border_mode){
			if (anchors[i].href == "") {
				anchors[i].runtimeStyle.width = '20px';
				anchors[i].runtimeStyle.height = '20px';
				anchors[i].runtimeStyle.backgroundRepeat = 'no-repeat';
				anchors[i].runtimeStyle.backgroundImage = 'url('+rich_path+'images/anchor.gif)';
			}
		}else{
			anchors[i].runtimeStyle.cssText = "";
		}
	}

	//show editable regions
var divs = active_rich.document.body.getElementsByTagName("DIV");
	for (i=0;i<divs.length;i++) {
		if (divs[i].id == 're_editable_region') {
			if(border_mode) divs[i].runtimeStyle.border = "1px solid #00FF00";
				else divs[i].runtimeStyle.cssText = '';
		}
	}

}

//change border mode
function switch_borders(change){
var border_mode;

	//current border mode
	eval('border_mode = '+active_rich.name+'_rich_border_mode;');

	if(change){//change border visibility
		border_mode = border_mode==true?false:true;
		set_state('SwitchBorders', border_mode);
		eval(active_rich.name+'_rich_border_mode = border_mode;');
	}

	set_borders(border_mode);

}

//insert a special character
function insert_char(){
	showModalDialog(rich_path+"dialog_char"+rich_dialog_ext+"?lang="+eval(active_rich.name+"_lang")+"&110903v", window,
		"dialogWidth:450px; dialogHeight:300px; status:no; scroll:no; help:no");
}

//color html tags in source code
function color_source(code){

	var parameter = /=("[^\"]*"|'[^\']*'|[^\"\'\s\&]*)(\s|&gt;)/gi;
	code = code.replace(parameter,"=<font color=#0000F0>$1</font>$2");

	var html_tag = /(&lt;([^&]*)&gt;)/gi;
	code = code.replace(html_tag,"<font color=\"#000080\">$1</font>");

	var img_tag = /<font color=\"#000080\">(&lt;IMG([^&]*)&gt;)<\/font>/gi;
	code = code.replace(img_tag,"<font color=\"#800080\">$1</font>");

	var table_tag = /<font color=\"#000080\">(&lt;[\/]?(table|tbody|th|tr|td){1}([^&]*)&gt;)<\/font>/gi;
	code = code.replace(table_tag,"<font color=\"#008080\">$1</font>");

	var link_tag = /<font color=\"#000080\">(&lt;[\/]?a([^&]*)&gt;)<\/font>/gi;
	code = code.replace(link_tag,"<font color=\"#008000\">$1</font>");

	var object_tag = /<font color=\"#000080\">(&lt;[\/]?object([^&]*)&gt;)<\/font>/gi;
	code = code.replace(object_tag,"<font color=\"#808000\">$1</font>");

	var param_tag = /<font color=\"#000080\">(&lt;[\/]?param([^&]*)&gt;)<\/font>/gi;
	code = code.replace(param_tag,"<font color=\"#B00000\">$1</font>");

	var comment_tag = /(&lt;\!--([^&]*)&gt;)/gi;
	code = code.replace(comment_tag,"<font color=#808080>$1</font>");

	var form_tag = /(&lt;[\/]?(form|input|textarea|select)([^&]*)&gt;)/gi;
	code = code.replace(form_tag,"<font color=#FF8000>$1</font>");

	var script_tag = /(&lt;[\/]?script([^&]*)&gt;)/gi;
	code = code.replace(script_tag,"<font color=#800000>$1</font>");

	return code;
}

//show/hide button 'what'
function show_button(what, show){
var element;

	//get button element
	eval('element = document.all.'+what+'_'+active_rich.name+';');

	if(!element) return; //the button is absent

	if(show){
		element.className = '';
	}else{
		element.className = 're_mouse_over';

		element.className = 're_img_off';
	}

}

//show/hide select control 'what'
function show_select(what, show){
var element;

	eval('element = document.all.'+what+'_'+active_rich.name);

	if(!element) return; //the button is absent
	element.disabled=!show;

}

//get editor name of button 'element'
function get_editor_name(element){
var pos;
var button_id_parts;

	if(!element) return '';

	button_id_parts = element.id.match(/([^_]+)_(.+)$/);
	if(button_id_parts) return button_id_parts[2];
	return '';
}

//show/hide buttons depending on the current cursor position
function show_active_buttons(){
var sel;
var range;
var is_control;
var i;
var text_button = Array('Bold', 'Italic', 'Underline', 'Strikethrough',
						'SuperScript', 'SubScript', 'JustifyLeft',
						'JustifyCenter', 'JustifyRight', 'JustifyFull',
						'InsertOrderedList', 'InsertUnorderedList',
						'Indent', 'Outdent', 'RemoveFormat',
						'ForeColor', 'BackColor', 'PasteWord', 'InsertChar');
var button_length = text_button.length;
var text_select = Array('FormatBlock', 'FontName', 'FontSize');
var select_length = text_select.length;
var td;
var tr;
var table;
var table_button = Array('InsertRow', 'DeleteRow', 'InsertColumn',
						'DeleteColumn', 'InsertCell', 'DeleteCell');
var table_length = table_button.length;
var form_button = Array('CreateText', 'CreateTextArea', 'CreateButton', 'CreateSelect',
						'CreateHidden', 'CreateCheckBox', 'CreateRadio');
var form_length = form_button.length;
var visible;
var element;

var create_table = false;
var create_image = false;
var create_flash = false;

var create_textfield = false;
var create_textarea = false;
var create_button = false;
var create_select = false;
var create_hidden = false;
var create_checkbox = false;
var create_radio = false;

var prev_is_control;
var full_screen_mode;

	if(!active_rich) return;

	sel = active_rich.document.selection;
	range = sel.createRange();
	if(sel.type == 'Control') is_control = true;
		else is_control = false;

	//if previous  selection was a control
	eval('prev_is_control = '+active_rich.name+'_prev_is_control;');
	//store current is_control value
	eval(active_rich.name+'_prev_is_control = '+is_control+';');

	if(!is_control){ //no controls are selected
		show_button('CreateLink', range.htmlText&&sel.type=='Text'?true:false);

		td = get_previous_object(range.parentElement(),'TD');
		tr = get_previous_object(td,'TR');
		table = get_previous_object(tr,'TABLE');
    
		//do cell buttons active/inactive
		for(i=0;i<table_length;i++){
			show_button(table_button[i], td?true:false);
		}
    
		//do MergeCells button active/inactive
		visible = tr && td.cellIndex<tr.cells.length-1;
		show_button('MergeCells', visible);
		//do SplitCell button active/inactive
		visible = tr && td.colSpan > 1;
		show_button('SplitCell', visible);

		//merge/split down
		show_button('MergeCellsDown',table&&tr.rowIndex+td.rowSpan<table.rows.length);
		show_button('SplitCellDown', td && td.rowSpan > 1);
    
		//redraw 'create control' buttons only if they actually changed
		//to accelerate editor
		if(prev_is_control != is_control){
			show_button('CreateTable', true);
			show_button('CreateImage', true);
			show_button('CreateFlash', true);
			show_button('InsertHorizontalRule', true);
			show_button('CreateForm', true);
			show_button('InsertSnippet', true);
			show_button('AbsolutePosition', false);
    
			//do form controls active
			for(i=0;i<form_length;i++){
				show_button(form_button[i], true);
			}
		}

	}else{ //a control element selected

		//do cell buttons inactive
		for(i=0;i<table_length;i++){
			show_button(table_button[i], false);
		}
		//do MergeCells button inactive
		show_button('MergeCells', false);
		show_button('SplitCell', false);
		show_button('MergeCellsDown', false);
		show_button('SplitCellDown', false);
   
		element = range.commonParentElement(); //the selected control element
		if(element){
			switch(element.tagName){
				case 'TABLE':
					create_table = true;
					break;
				case 'IMG':
					create_image = true;
					break;
				case 'OBJECT':
					create_flash = true;
					break;
				case 'INPUT':
					switch(element.type.toUpperCase()){
						case 'HIDDEN':
							create_hidden = true;
							break;
						case 'TEXT':
						case 'PASSWORD':
							create_textfield = true;
							break;
						case 'BUTTON':
						case 'RESET':
						case 'SUBMIT':
							create_button = true;
							break;
						case 'CHECKBOX':
							create_checkbox = true;
							break;
						case 'RADIO':
							create_radio = true;
							break;
						default:
						break;
					}
					break;
				case 'TEXTAREA':
					create_textarea = true;
					break;
				case 'SELECT':
					create_select = true;
					break;
				default:
					break;
			}
			show_button('CreateTable', create_table);
			show_button('CreateImage', create_image);
			show_button('CreateFlash', create_flash);
			show_button('CreateLink', true);
			show_button('InsertHorizontalRule', false);
			show_button('InsertSnippet', false);
			show_button('AbsolutePosition', true);

			//change states of form buttons
			show_button('CreateForm', false);
			show_button('CreateHidden', create_hidden);
			show_button('CreateText', create_textfield);
			show_button('CreateTextArea', create_textarea);
			show_button('CreateButton', create_button);
			show_button('CreateSelect', create_select);
			show_button('CreateCheckBox', create_checkbox);
			show_button('CreateRadio', create_radio);

		}

	}

	//redraw text buttons and selects only if they actually changed
	//to accelerate editor
	if(prev_is_control != is_control){
	//do text buttons active/inactive
		for(i=0;i<button_length;i++){
			show_button(text_button[i], !is_control);
		}

		//do selects active/inactive
		for(i=0;i<select_length;i++){
			show_select(text_select[i], !is_control);
		}

	}

	//make clipboard buttons active/inactive
	show_clipboard_buttons();

	//undo and redo buttons
	visible = active_rich.document.queryCommandEnabled('Undo');
	show_button('Undo', visible);
	visible = active_rich.document.queryCommandEnabled('Redo');
	show_button('Redo', visible);

	//current fullscreen mode
	eval('full_screen_mode = '+active_rich.name+'_rich_full_screen_mode;');

	if (!full_screen_mode &&
		document.all.rich_fs_iframe.style.display == '') {
		//do fullscreen mode button inactive if necessary
		show_button('FullScreen', false);
	}

}

//make clipboard buttons active/inactive
function show_clipboard_buttons(){
var cut_copy_visible;
var paste_visible;
var success = true;

	if(!active_rich) return;

	//cut, copy and paste buttons
	try{
		cut_copy_visible = active_rich.document.queryCommandEnabled('Cut');
		paste_visible = active_rich.document.queryCommandEnabled('Paste');
	}catch(error){
		cut_copy_visible = false;
		paste_visible = false;
		success = false;
	}

	if(success){
		show_button('Copy', cut_copy_visible);
		show_button('Cut', cut_copy_visible);
		show_button('Paste', paste_visible);
		show_button('PasteWord', paste_visible);
	}
}

//check if button 'element' is active
function active_button(element){
//  if(element && element.name != 'off') return true;
	if(element && element.className != 're_img_off') return true;
	return false;
}

//get object of button 'what'
function get_button_object(what){
var obj;

	//get button element
	eval('obj = document.all.'+what+'_'+active_rich.name+';');
	return obj;
}

//switch on/off fullscreen mode
function full_screen(editor_name){
var full_screen_mode;
var i;
var obj;
var table_name = editor_name+'_table_id';
var div_name = editor_name+'_div_id';

	//current border mode
	eval('full_screen_mode = '+active_rich.name+'_rich_full_screen_mode;');

	if(!active_button(get_button_object('FullScreen')) ||
		(!full_screen_mode && document.all.rich_fs_iframe.style.display == '')){
		return;
	}

	full_screen_mode = full_screen_mode==true?false:true;
	set_state('FullScreen', full_screen_mode);
	eval(active_rich.name+'_rich_full_screen_mode = full_screen_mode;');

	if(full_screen_mode){

		document.getElementById(div_name).runtimeStyle.position = "Absolute";
		document.getElementById(div_name).runtimeStyle.zIndex = "999";
		document.getElementById(div_name).runtimeStyle.posTop = 0;
		document.getElementById(div_name).runtimeStyle.posLeft = 0;
		document.getElementById(div_name).runtimeStyle.width = document.body.clientWidth - 0;
		document.getElementById(div_name).runtimeStyle.height = document.body.offsetHeight - 4;

		document.getElementById(table_name).runtimeStyle.position = "Absolute";
		document.getElementById(table_name).runtimeStyle.zIndex = "999";
		document.getElementById(table_name).runtimeStyle.posTop = 0;
		document.getElementById(table_name).runtimeStyle.posLeft = 0;
		document.getElementById(table_name).runtimeStyle.width = document.body.clientWidth - 0;
		document.getElementById(table_name).runtimeStyle.height = document.body.offsetHeight - 4;

		document.all.rich_fs_iframe.style.display = '';
		document.getElementById('rich_fs_iframe').runtimeStyle.position = "Absolute";
		document.getElementById('rich_fs_iframe').runtimeStyle.zIndex = "998";
		document.getElementById('rich_fs_iframe').runtimeStyle.posTop = 0;
		document.getElementById('rich_fs_iframe').runtimeStyle.posLeft = 0;
		document.getElementById('rich_fs_iframe').runtimeStyle.width = document.body.clientWidth - 0;
		document.getElementById('rich_fs_iframe').runtimeStyle.height = document.body.offsetHeight - 4;
	}else{
		document.getElementById(table_name).runtimeStyle.cssText = "";
		document.getElementById(div_name).runtimeStyle.cssText = "";

		document.all.rich_fs_iframe.style.display = 'none';
	}

	active_rich.focus();

}

//show snippet popup menu
function parse_context(){
var i;
var innerHTML = '';
var event;
var sel;
var range;
var mode;
var element;
var td;
var tr;
var link_name;
var flag = false;
var flag2 = false;
var do_hr = false;
var width = 0;
var height = 4;
var td_height = 20;
var hr_height = 4;
var char_width = 8;//13
var max_chars = 0;
var chars;
var lang;

	if (is_editable_regs() && !inside_editable_reg()) return;

	if(!rich_popup) return;

	sel = active_rich.document.selection;
	range = sel.createRange();

	eval('mode = '+active_rich.name+'_rich_mode;'); //current mode
	eval('lang = '+active_rich.name+'_lang;'); //language
	eval('var dir = '+active_rich.name+'_rich_dir;'); //direction of language
	eval('var mb = '+active_rich.name+'_rich_mb;'); //if multibyte language
	if (mb != '') char_width = 13;

	eval('var rich_cx = rich_cx_'+lang);
	eval('var rich_cx_item = rich_cx_item_'+lang);
	eval('var rich_cx_name = rich_cx_name_'+lang);
	eval('var rich_cx_image = rich_cx_image_'+lang);
	eval('var rich_cx_length = rich_cx_length_'+lang);

	//cut, copy and paste items
	try{
		if(active_rich.document.queryCommandEnabled('Cut')){
			if(get_button_object('Cut')){
				innerHTML += get_popup_menu_item(rich_cx['CUT'], 'Cut', 'cut');
				max_chars=Math.max(max_chars, rich_cx['CUT'].length);
				height += td_height;
			}
			if(get_button_object('Copy')){
				innerHTML += get_popup_menu_item(rich_cx['COPY'], 'Copy', 'copy');
				max_chars=Math.max(max_chars, rich_cx['COPY'].length);
				height += td_height;
			}
    
			do_hr = true;
		}
		if(active_rich.document.queryCommandEnabled('Paste')){
			if(get_button_object('Paste')){
				innerHTML += get_popup_menu_item(rich_cx['PASTE'], 'Paste', 'paste');
				max_chars=Math.max(max_chars, rich_cx['PASTE'].length);
				height += td_height;
			}
			if(range.parentElement && get_button_object('PasteWord')){
				innerHTML += get_popup_menu_item(rich_cx['PASTEWORD'], 'PasteWord', 'paste_word');
				max_chars=Math.max(max_chars, rich_cx['PASTEWORD'].length);
				height += td_height;
			}
    
			do_hr = true;
		}
	}catch(error){
	}

	if(mode){ //only clipboard items are visible in source mode

		if(sel.type != 'Control'){ //no controls are selected
			var link = get_previous_object(range.parentElement(),'A');
  
			var do_image = get_button_object('CreateImage');
			var do_link = (link || sel.type == 'Text' &&
							!String(range.htmlText).match(/<\/?A/i)) &&
							get_button_object('CreateLink');
			var do_table = get_button_object('CreateTable');
			var do_flash = get_button_object('CreateFlash');
			var do_form = get_previous_object(range.parentElement(),'FORM') &&
							get_button_object('CreateForm');

			//insert control items
			if(do_image || do_link || do_table || do_flash || do_form){
				if(do_hr){
					innerHTML += get_popup_menu_item('<HR>');
					height += hr_height;
				}
				do_hr = true;
			}
			if(do_image){
				innerHTML += get_popup_menu_item(rich_cx['ADDIMAGE'], 'CreateImage', 'image', null, true);
				max_chars=Math.max(max_chars, rich_cx['ADDIMAGE'].length);
				height += td_height;
			}
			if(do_link){
				if(link){
					link_name = rich_cx['EDITLINK']; //if link exists - edit it
					chars = rich_cx['EDITLINK'].length;
				}else{
					link_name = rich_cx['ADDLINK'];
					chars = rich_cx['ADDLINK'].length;
				}
				innerHTML += get_popup_menu_item(link_name, 'CreateLink', 'link', null, true);
				max_chars=Math.max(max_chars, chars);
				height += td_height;
			}
			if(do_flash){
				innerHTML += get_popup_menu_item(rich_cx['ADDFLASH'], 'CreateFlash', 'flash', null, true);
				max_chars=Math.max(max_chars, rich_cx['ADDFLASH'].length);
				height += td_height;
			}
			if(do_form){
				innerHTML += get_popup_menu_item(rich_cx['EDITFORM'], 'CreateForm', 'form', null, true);
				max_chars=Math.max(max_chars, rich_cx['EDITFORM'].length);
				height += td_height;
			}
    
			if(do_table){
				innerHTML += get_popup_menu_item(rich_cx['ADDTABLE'], 'CreateTable', 'table', null, true);
				max_chars=Math.max(max_chars, rich_cx['ADDTABLE'].length);
				height += td_height;
    
				td = get_previous_object(range.parentElement(),'TD');
				tr = get_previous_object(td,'TR');
				table = get_previous_object(td,'TABLE');
    
				if(td){
					innerHTML += get_popup_menu_item(rich_cx['EDITCELL'], 'EditCell', null, null, true);
					max_chars=Math.max(max_chars, rich_cx['EDITCELL'].length);
					height += td_height;
    
					//add cell items
					for(i=0;i<rich_cx_length;i++){
						if(get_button_object(rich_cx_item[i])){
							//first common table button
							if(i<=3 && do_hr && !flag2){
								innerHTML += get_popup_menu_item('<HR>');
								height += hr_height;
								flag2 = true;
							}
							//common table buttons passed
							if(i>3 && do_hr && !flag){
								innerHTML += get_popup_menu_item('<HR>');
								height += hr_height;
								flag = true;
							}
							innerHTML += get_popup_menu_item(rich_cx_name[i],
										rich_cx_item[i], rich_cx_image[i]);
							max_chars=Math.max(max_chars, rich_cx_name[i].length);
							height += td_height;
							do_hr = true;
						}
					}
    
				}
    
				//add MergeCells item
				if(tr && td.cellIndex<tr.cells.length-1 &&
					get_button_object('MergeCells')){
					if(!flag){
						innerHTML += get_popup_menu_item('<HR>');
						height += hr_height;
						flag = true;
					}
					innerHTML += get_popup_menu_item(rich_cx['MERGE'], 'MergeCells', 'mergecells');
					max_chars=Math.max(max_chars, rich_cx['MERGE'].length);
					height += td_height;
				}
				//add SplitCell item
				if(tr && td.colSpan > 1 && get_button_object('SplitCell')){
					if(!flag){
						innerHTML += get_popup_menu_item('<HR>');
						height += hr_height;
					}
					innerHTML += get_popup_menu_item(rich_cx['SPLIT'], 'SplitCell', 'splitcell');
					max_chars=Math.max(max_chars, rich_cx['SPLIT'].length);
					height += td_height;
				}
    
				//add Merge/Split down items
				if(table && tr.rowIndex+td.rowSpan<table.rows.length &&
					get_button_object('MergeCellsDown')){
					if(!flag){
						innerHTML += get_popup_menu_item('<HR>');
						height += hr_height;
						flag = true;
					}
					innerHTML += get_popup_menu_item(rich_cx['MERGEDOWN'], 'MergeCellsDown', 'mergecellsdown');
					max_chars=Math.max(max_chars, rich_cx['MERGEDOWN'].length);
					height += td_height;
				}

				if(td && td.rowSpan > 1 && get_button_object('SplitCellDown')){
					if(!flag){
						innerHTML += get_popup_menu_item('<HR>');
						height += hr_height;
					}
					innerHTML += get_popup_menu_item(rich_cx['SPLITDOWN'], 'SplitCellDown', 'splitcelldown');
					max_chars=Math.max(max_chars, rich_cx['SPLITDOWN'].length);
					height += td_height;
				}

			}
      
		}else{//a control selected
			if(get_button_object('CreateLink')){
				if(do_hr){
					innerHTML += get_popup_menu_item('<HR>');
					height += hr_height;
				}
				//check, if control is inside a reference
				var link = get_previous_object(range.commonParentElement(),'A');
				var action = 'CreateLink';
				if(link){
					if (link.href == "") {
						link_name = rich_cx['EDITANCHOR'];
						action = 'CreateAnchor';
					} else link_name = rich_cx['EDITLINK'];
				}else link_name = rich_cx['ADDLINK'];
				innerHTML += get_popup_menu_item(link_name, action, 'link', null, true);
				max_chars=Math.max(max_chars, link_name.length);
				height += td_height;
				do_hr = true;
			}
    
			element = range.commonParentElement(); //the selected control element
			var tag_name = element.tagName;
			if(tag_name == 'INPUT') tag_name = element.type.toUpperCase();

			//insert the control's 'Edit' item
			if(rich_cx[tag_name] && get_button_object(rich_cx[tag_name][1])){
				if(do_hr){
					innerHTML += get_popup_menu_item('<HR>');
					height += hr_height;
				}
				innerHTML += get_popup_menu_item(rich_cx[tag_name][0],
					rich_cx[tag_name][1], rich_cx[tag_name][2], null, true);
				max_chars=Math.max(max_chars, rich_cx[tag_name][0].length);
				height += td_height;
				do_hr = true;
			}
  
		}

	}

	//show the popup context window
	if(innerHTML != ''){

		//form the final popup menu code
		innerHTML = get_popup_menu_body(innerHTML);

		active_rich.frameWindow = active_rich;
		event = active_rich.frameWindow.event;

		//set width of content in popup window
		width = max_chars*char_width+40;

		//set popup content and show the menu
		rich_popup.document.body.innerHTML = innerHTML;
		rich_popup.document.body.dir = dir;
		rich_popup.show(event.clientX, event.clientY, width, height,
						active_rich.document.body);
	}

}

//get html code of popup item with name 'name'
//if the item is chosen, an event action is generated with value 'value'
//ie if is_dialog null or false do_action(action,value) called
//otherwise show_dialog(action) called
function get_popup_menu_item(name, action, img_name, value, is_dialog){
var code = '';

	code += '<tr>';
	if(name != '<HR>'){
		code += '<td id="rich_cx_'+action+'" onclick="eval(\'var active_mode = parent.\'+parent.active_rich.name+\'_rich_active_mode;\'); if(active_mode) parent.show_active_buttons(); parent.';
		if(is_dialog){
			code += 'show_dialog(\''+action+'\')';
		}else{
			code += 'do_action(\''+action+'\'';
			if(value != null) code += ',\''+value+'\'';
			code += '); if(parent.rich_popup) parent.rich_popup.hide();';
		}
		code += '" style="cursor:hand; font-family:Courier; font-size:13px;"';
		code += ' onmouseover="parent.context_over(this, true);"';
		code += ' onmouseout="parent.context_over(this);">';
	}else{
		code += '<td>';
	}

	code += '<nobr>';
	if(img_name){
		code += '<img src="'+rich_path+'images/'+img_name+'.gif" width="20" height="20" alt="'+name+'" align="absmiddle" hspace="4">';
	}else{
		code += '<img src="'+rich_path+'images/space.gif" width="20" height="1" hspace="4">';
	}

	if(name != '<HR>'){
		code += name;
	}else{
		code += '<br><img src="'+rich_path+'images/space.gif" width="100%" height="1" style="BACKGROUND-COLOR: buttonshadow"><br>';
		code += '<img src="'+rich_path+'images/space.gif" width="100%" height="1" style="BACKGROUND-COLOR: buttonhighlight"><br>';
	}

	code += '<img src="'+rich_path+'images/space.gif" width="8" height="1"></nobr>';
	code += '</td></tr>';

	return code;
}

//add to popup content innerHTML outer code
function get_popup_menu_body(innerHTML){
var code = '';

	code += '<table cellspacing="0" cellpadding="0" border="0" style="BORDER-LEFT: 1px solid buttonface; BORDER-RIGHT: 1px solid black; BORDER-TOP: 1px solid buttonface; BORDER-BOTTOM: 1px solid black;" bgcolor="buttonface" width="100%" height="100%">';
	code += '<tr><td>';
	code += '<table id="popup_table" cellspacing="0" cellpadding="0" border="0" style="BORDER-LEFT: 1px solid buttonhighlight; BORDER-RIGHT: 1px solid buttonshadow; BORDER-TOP: 1px solid buttonhighlight; BORDER-BOTTOM: 1px solid buttonshadow;" bgcolor="buttonface" width="100%" height="100%">';
	code += innerHTML;
	code += '</table>';
	code += '</td></tr>';
	code += '</table>';

	return code;
}

//highlight context menu item
function context_over(obj, over){
	if(over){
		obj.style.backgroundColor = 'Highlight';
		obj.style.color = 'HighlightText';
	}else{
		obj.style.backgroundColor = '';
		obj.style.color = '';
	}
}

//insert a snippet value in the editor
function insert_snippet(value){
var selection = active_rich.document.selection;
var range;
var snippets;
var border_mode;

	if(selection) range = selection.createRange();

	if(value && range && range.parentElement){

		var s_parts = value.match(/^([^_]*)_([0-9]+)$/);
		if(!s_parts) return;
		var s_group = s_parts[1];
		var s_value = s_parts[2];

		eval('snippets = '+active_rich.name+'_snippets;'); //array of snippets
		if(snippets && snippets[s_group] && snippets[s_group][s_value] &&	
			snippets[s_group][s_value][1]){
			range.pasteHTML(snippets[s_group][s_value][1]);

			//current border mode
			eval('border_mode = '+active_rich.name+'_rich_border_mode;');
			//make borders visible if necessary
			set_borders(border_mode);
		}

	}

}

//add to editor event handlers
function add_handlers(editor){
	if(rich_msie_version < 5.5){
		editor.document.oncontextmenu = function(){
			re_hide_lists();
			active_rich=editor;
			parse_context_ie5();
			return false;
		};
	}else{
		editor.document.oncontextmenu = function(){
			re_hide_lists();
			active_rich=editor;
			change_toolbar_state();
			parse_context();
			return false;
		};
	}
	editor.document.onkeyup = function(){
		var key_code = active_rich.event.keyCode;
		active_rich=editor;
		//change toolbar if move cursor using keyboard or press Enter/Del only
		if (key_code > 36 && key_code < 41 ||
			key_code == 8 || key_code == 13) {
			change_toolbar_state();
		}
	};
	editor.document.onclick = function(){
		re_hide_lists();
		active_rich=editor;
		if(!is_editable_regs()) active_rich.focus();
			else {
				var a_obj = get_previous_object(active_rich.frameWindow.event.srcElement, 'A');
				if (a_obj) {
					return false;
				}
			}

		change_toolbar_state();
	};
	editor.document.onselectionchange = function(){
		active_rich=editor;
		active_rich.document.execCommand("2D-Position", false, true);
	};
	editor.document.onmouseup = function(){
		re_hide_lists();
		active_rich = editor;
		active_rich.frameWindow = active_rich;
		if(active_rich.frameWindow.event.button != 2){
			change_toolbar_state();
		}
	};
	document.onclick = function(){
		re_hide_lists();
	};

	eval('var br_on_enter = '+active_rich.name+'_br_on_enter;'); //br mode
	editor.document.onkeydown = function(){
		if (is_editable_regs() && !inside_editable_reg()) return false;

		if (editor.event.keyCode == 9) return false;

		eval('var mode = '+active_rich.name+'_rich_mode;'); //current mode

		if (mode && (editor.event.ctrlKey && editor.event.keyCode == 86 ||
					editor.event.shiftKey && editor.event.keyCode == 45)) {

			eval('var clean_paste = '+active_rich.name+'_clean_paste;');
			if (clean_paste) {
				do_action('PasteWord');
				return false;
			}
		}

		if (br_on_enter || !mode) {

			active_rich = editor;
    
			var sel = active_rich.document.selection;
    
			if (sel.type == 'Control') return;
    
			if (active_rich.event.keyCode == 13) {
				var r = sel.createRange();
				if (!active_rich.event.shiftKey || !mode) {
					r.pasteHTML("<BR>");
    
					r.select();
					r.collapse(false);
    
					return false;
				} else {
    
					if (active_rich.document.queryCommandValue('InsertOrderedList') ||
						active_rich.document.queryCommandValue('InsertUnorderedList')) {

						var li = r.parentElement?get_previous_object(r.parentElement(),'LI'):null;
						if (li && li.innerHTML == '') {
							active_rich.document.execCommand("Outdent", false);
						} else {
							r.pasteHTML("<li></li>");
							r.moveStart("character", -1);
							r.collapse(true);
							r.select();
						}
    
					} else {
						r.pasteHTML("<P>&nbsp;</P>");

						r.moveStart("character", -1);
						r.moveStart("character", 1);
						r.collapse(true);
						r.select();
					}
					return false;
    
				}
    
			}

		} else return true;

	};
}

//delete base url from link
//if urls_only is set then delete base url from urls only not the whole text
function del_base_url(text, urls_only){
	var re_text = rich_base_url;
	var new_text = "";
	if (urls_only) {
		re_text = '((src|href|background)="?)' + re_text;
		new_text = "$1";
	}

var re = new RegExp(re_text, 'gi');
	RegExp.multiline = true;

	return text.replace(re, new_text);
}

//dont need to restore borders in change_mode - works faster
function get_rich_content(editor, dont_restore_borders) {

	if (!editor) return '';

var mode;
var editor_content;
var page_mode;
var border_mode;
var name;
var abs_path;
var old_active_rich = active_rich;

	active_rich = editor;

	eval('mode = '+active_rich.name+'_rich_mode;'); //current mode
	//get the current editor content
	name = active_rich.name;
	//current page mode
	eval('page_mode = '+name+'_rich_page_mode;');
	//current border mode
	eval('border_mode = '+active_rich.name+'_rich_border_mode;');
	//absolute paths
	eval('abs_path = '+active_rich.name+'_rich_absolute_path;');
var xhtml_mode = get_xhtml_mode(); //must be after 'active_rich = editor;'

	if (xhtml_mode) {
		//document lang
		eval('var doc_lang = '+active_rich.name+'_rich_doc_lang;');
		//document charset
		eval('var doc_charset = '+active_rich.name+'_rich_doc_charset;');
	}

	if(!mode){ //source code mode

		editor_content = active_rich.document.body.innerText;

	}else{

		if(border_mode){
			set_borders(false);
		}

		if(!page_mode){
			if (xhtml_mode) editor_content = get_xhtml(active_rich.document.body,
														doc_lang, doc_charset);
				else editor_content = active_rich.document.body.innerHTML;
		}else{
			if (xhtml_mode) editor_content = get_xhtml(active_rich.document,
														doc_lang, doc_charset);
				else editor_content = active_rich.document.documentElement.outerHTML;
			editor_content = delete_default_stylesheets(editor_content);
		}

		//fix link attributes
		var loc = String(document.location).replace('&', '&amp;').replace('?', '\\?');
		loc = loc.split('#');
		var re = new RegExp(loc[0]+'#', 'gi');
		RegExp.multiline = true;
		editor_content = editor_content.replace(re, '#');

		//convert &amp; to & otherwise src and href arributes could be spoiled
		var re = new RegExp('&amp;', 'gi');
		editor_content = editor_content.replace(re, '&');

		//change &#13;&#10; back to line break
		editor_content = editor_content.replace(/&#13;&#10;/g, '\n');

		//asp/php tags fix
		editor_content = editor_content.replace(/<!--re_php_tag_open/g, '<?php');
		editor_content = editor_content.replace(/re_php_tag_close-->/g, '?>');
		editor_content = editor_content.replace(/<!--re_asp_tag_open/g, '<%');
		editor_content = editor_content.replace(/re_asp_tag_close-->/g, '%>');

		editor_content = format_content(editor_content);

		if(!abs_path) editor_content = del_base_url(editor_content, 1);

		if(border_mode && !dont_restore_borders){
		    set_borders(true);
		}

	}

	active_rich = old_active_rich;

	return editor_content;
}

//add default seylesheet tags
function set_default_stylesheets(){
var i;

	//default stylesheets
	eval('var rich_css = '+active_rich.name+'_rich_css;');

	//add links to default stylesheets
	for (i in rich_css) {
		active_rich.document.createStyleSheet(rich_css[i]);
	}

}

//remove all default stylesheet tags
function delete_default_stylesheets(editor_content){
var i;
var name = active_rich.name;
var xhtml_mode = get_xhtml_mode();

//remove default stylesheets' tags
eval('var rich_css = '+name+'_rich_css;');

	if (xhtml_mode) var ch = " /";
		else var ch = "";

	//remove links to default stylesheets
	for (i in rich_css) {
		if (!xhtml_mode) var re = new RegExp('<link href="'+rich_css[i]+'" rel=stylesheet>','gi');
		var re2 = new RegExp('<link href="'+rich_css[i]+'" rel="stylesheet"'+ch+'>','gi');
		RegExp.multiline = true;

		editor_content=editor_content.replace(re2,'');

		if (xhtml_mode) {
			var re2 = new RegExp('<link style="" href="'+rich_css[i]+'" rel="stylesheet"'+ch+'>','gi');
			RegExp.multiline = true;

			editor_content=editor_content.replace(re2,'');
		}

		if (!xhtml_mode) editor_content=editor_content.replace(re,'');
	}

	return editor_content;
}

//return content of editor with name 'name' - user javascript API function
function get_rich(name) {
	if (!name) return '';

	return get_rich_content(get_editor_id(name));
}

//write html text to editor named 'name'
function set_rich(name, content) {
	if (!name) return;

	return set_rich_content(get_editor_id(name), content);
}

//get editor id by its name
function get_editor_id(name) {

	var ar_pos = name.indexOf("[");
	var id = '';
	if (ar_pos > 0) {
		var ar_end_pos;
		ar_end_pos = name.length-1;

		id = name.substring(ar_pos+1, ar_end_pos);
		name = name.substring(0, ar_pos);

		var parts = id.split('][');
		if (parts) {
			id = parts.join('_')
		} else id = '';
	}

	eval('var editor = '+name+'_ed'+id+'_id;'); //get editor's id

	return editor;
}

//write html text from variable content to editor
function set_rich_content(editor, content) {
	if (!editor) return;

var mode;
var page_mode;
var border_mode;
var old_active_rich = active_rich;

	active_rich = editor;
	eval('mode = '+active_rich.name+'_rich_mode;'); //current mode

	var name = active_rich.name;
	//current page mode
	eval('page_mode = '+name+'_rich_page_mode;');
	//current border mode
	eval('border_mode = '+active_rich.name+'_rich_border_mode;');

	if (!mode) { //source code mode
		active_rich.document.body.innerText = content;
		active_rich.document.body.innerHTML = color_source(active_rich.document.body.innerHTML);
	} else {
		//asp/php tags fix
		content = content.replace(/<\?php/gi, '<!--re_php_tag_open');
		content = content.replace(/\?>/g, 're_php_tag_close-->');
		content = content.replace(/<%/g, '<!--re_asp_tag_open');
		content = content.replace(/%>/g, 're_asp_tag_close-->');

		if (!page_mode) {
			content = '<body>'+content+'</body>';
		}

		active_rich.document.write(content);
		active_rich.document.close();

		add_handlers(active_rich);
		set_default_stylesheets();

		if(border_mode) {
			set_borders(true);
		}

		set_stylesheet_rules();
	}
 
	active_rich = old_active_rich;
//	active_rich.focus();
	return true;
}

function get_xhtml_mode(){

	//xhtml mode
	eval('var xhtml_mode = '+active_rich.name+'_rich_xhtml_mode;');

	try { //check if xhtml jscript function loaded
		var is_xhtml = get_xhtml?true:false;
	} catch(e) {
		var is_xhtml = false;
	}

	return xhtml_mode&&is_xhtml?true:false;
}

//convert color from decimal value to heximal
function dec2hex(num) {
var i;
var hex_num = '';
	for (i=1;i<=3;i++) {
		var cur_pair = num&0xff;
		var d1 = cur_pair>>4;
		var d2 = cur_pair&0x0f;

		hex_num += d1.toString(16)+d2.toString(16);
		num = num>>8;
	}
	return '#'+hex_num;
}

//determine where to insert row/column
function insert_to(action) {
var range = active_rich.document.selection.createRange();
	if (!get_previous_object(range.parentElement(),'TABLE')) return null;

	var lang = eval(active_rich.name+"_lang");

	var ins_data = showModalDialog(rich_path+"dialog_adv_table"+rich_dialog_ext+"?lang="+lang+"&action="+action+"&browser=&e",
		null, "dialogWidth:190px; dialogHeight:70px; scroll:no; status:no; help:no;");

	if (ins_data) return parseInt((String(ins_data[0]).split('='))[1]);

	return null;
}

//show items of list sel_obj
//if h2content then make all items visible (no vertical scrollbar)
function re_show_list(sel_obj, h2content){
var i;
var obj = document.getElementById(sel_obj.id + '_iframe');

	if (obj.style.display == '') { //hide list if open yet
		obj.style.display = 'none';
		return;
	}

	re_hide_lists();

	var obj_doc = eval(obj.id+'.document');

	//type of dropdown list
	var parts = String(obj.id).split('_');
	var type = parts[0];

	var style_text = '';

	if (type == 'ClassName') {
		//take styles of the current window
		var styles = active_rich.document.styleSheets;
		var sheets_num = styles.length;
	    for (i=0; i<sheets_num; i++) {
			style_text += styles[i].cssText;
		}
	}

//form content of the list
var content = '<html>'+
'<head><style type="text/css">'+style_text+'.re_list_over{background-color:Highlight;color:HighlightText}.re_list_out{background-color:##ffffff;color:#000000}</style>'+
'<body topmargin=0 leftmargin=0 rightmargin=0 bottommargin=0 style="border: 1px solid #000000; background:#ffffff">'+
'<div id="content_div" style="overflow:hidden; width=100%;">'+
'<table border="0" style="cursor:hand" cellspacing="0" width="100%">';

	var sel_len = sel_obj.options.length;
	var sel_opt = sel_obj.options;

	if (!sel_len) return;

	for (i=0;i<sel_len;i++) {
		content += '<tr><td onClick="parent.do_action(\''+type+'\', \''+sel_opt[i].value+'\');" onmouseover="this.className = \'re_list_over\'" onmouseout="this.className=\'re_list_out\'">';
		switch (type) {
			case 'FormatBlock':
				content += '<nobr>'+sel_opt[i].value+sel_opt[i].text+'</nobr>';
				break;
			case 'FontName':
				content += '<nobr><font face="'+sel_opt[i].value+'">'+sel_opt[i].text+'</font></nobr>';
				break;
			case 'FontSize':
				content += '&nbsp;&nbsp;&nbsp;&nbsp;<font size="'+sel_opt[i].value+'">'+sel_opt[i].text+'</font>&nbsp;&nbsp;&nbsp;&nbsp;';
				break;
			case 'ClassName':
				content += '<nobr><span class="'+sel_opt[i].value+'">'+(sel_opt[i].text!=''?sel_opt[i].text:'&nbsp;')+'</span></nobr>';
				break;
			default:
				break;
		}
		content += '</td></tr>';
	}

	content += '</table>'+
'</div>'+
'</body></html>';

	obj_doc.open();
	obj_doc.write(content);
	obj_doc.close();

var sel_pos = get_element_pos(sel_obj);
	obj.style.left = sel_pos[0] + 2 + 'px';
	obj.style.top = sel_pos[1] + sel_obj.offsetHeight + 2 + 'px';
	obj.style.display = "";

	var new_height = obj_doc.getElementById('content_div').offsetHeight;
	//for ClassName (h2content==false) list change height only if its too big
	//for content, heights of other lists should fit to its content
	if (h2content || new_height < obj.getAttribute('ini_height')) {
		obj.height = new_height+2;
	} else obj.height = obj.getAttribute('ini_height');

}

//get (left, top) coordinates of element obj
function get_element_pos(obj){
var pos = Array(0,0);
	while (obj) {

		//absolute positioned element => do not count its offset values
		if (obj.currentStyle.position == 'absolute') break;

		pos[0] += obj.offsetLeft;
		pos[1] += obj.offsetTop;
		obj = obj.offsetParent;
	}
	return pos;
}

//hide all selection list open
function re_hide_lists(){
var iframes = document.body.getElementsByTagName("IFRAME");
var i;

	for (i=0; i<iframes.length; i++) {
		var obj = iframes[i];
		if (obj.className == 're_list_iframe')
			if (obj.style.display == '') {
				obj.style.display = 'none';
				//make enable the appropriate list
				var list_id = String(obj.id).replace(/_iframe$/,'');
				var list = document.getElementById(list_id);
				list.disabled = false;
			}
	}
}

//show editable regions
function show_editable_regs(editor){
	if (!editor) editor = active_rich;

var divs = editor.document.body.getElementsByTagName("DIV");
var div_length = divs.length;

	for (var i=0; i<div_length; i++) {
		if (divs[i].id == "re_editable_region") {
			divs[i].contentEditable = true;
			divs[i].designMode = true;
		}
	}

}

function is_editable_regs(){
	eval('var ed_regs = '+active_rich.name+'_editable_regions;');
	return ed_regs;
}

function inside_editable_reg(){
	if(rich_msie_version < 5.5) return false;

var sel = active_rich.document.selection;
var r = sel.createRange();

	if (sel.type == 'Control') is_control = true;
		else is_control = false;

	var obj;
	if (is_control) obj = r.commonParentElement();
		else obj = r.parentElement();

	while (obj && obj.id != 're_editable_region') obj = obj.parentNode;

	if (obj) return true;
	return false;
}

//adds new lines and indents to some tags to make code more neat
function format_content(code){
var i;
var xhtml_mode = get_xhtml_mode();

var need_nl_before = /\<(div|p|table|tbody|thead|tr|td|th|title|script|comment|li|meta|h1|h2|h3|h4|h5|h6|hr|ul|ol|option|link|pre)[^\>]*\>/gi;
var need_nl_after = /\<\/(div|p|table|tbody|thead|tr|td|th|title|script|comment|li|meta|h1|h2|h3|h4|h5|h6|hr|ul|ol|option|link|br|pre)[^\>]*\>/gi;
var need_nl_both = /\<[\/]?(style|head|body|html)[^\>]*\>/gi;

	eval('var indent_char = '+active_rich.name+'_indent;');
var indent_inc = new RegExp();
	indent_inc.compile("^\<(head|table|tbody|thead|tr|ul|ol)[^\>]*\>", "i");
var indent_dec = new RegExp();
	indent_dec.compile("^\<\/(head|table|tbody|thead|tr|ul|ol)[^\>]*\>", "i");

var nl = /\s*[\r|\n]+\s*/g;

	code = code.replace(need_nl_before, "\n$&");
	code = code.replace(need_nl_after, "$&\n");
	code = code.replace(need_nl_both, "\n$&\n");

	var code_lines = code.split(nl);
	var new_code = "";
	var indent = "";
	var no_indent = false;
	for (i=0; i<code_lines.length; i++) {
		if (code_lines[i] == "") continue;

		if (new_code != "") new_code += "\n";

		if (indent_dec.exec(code_lines[i])) indent = indent.replace(indent_char, "");

		var new_line = code_lines[i];
		if (typeof(fix_entities) == "function" && !xhtml_mode) new_line = fix_entities(new_line);

		if (!no_indent) new_code += indent;
		new_code += new_line;

		//content inside textarea and pre must stay intact
		var low_line = new_line.toLowerCase();
		var k = low_line.lastIndexOf("<textarea");
		var k2 = low_line.lastIndexOf("</textarea");
		if (k > 0 && (k2 < 0 || k > k2)) no_indent = true;
		if (!no_indent && low_line.match(/\<pre/i)) no_indent = true;
		if (k2 > 0 && (k < 0 || k2 > k)) no_indent = false;
		if (no_indent && low_line.match(/\<\/pre/i)) no_indent = false;

		if (indent_inc.exec(code_lines[i]) && !no_indent) indent += indent_char;
	}

	return new_code;
}

//error message handler
function no_error(){
	return true;
}
