//Activates any HTML controls for an editor
function GHOST_Text_Editor(editorid, mode, parsetype, parsesmilies, initial_text)
{
	this.editorid = editorid;
	this.wysiwyg_mode = parseInt(mode, 10) ? 1 : 0;
	this.initialized = false;
	this.parsetype = (typeof parsetype == 'undefined' ? 'nonforum' : parsetype);
	this.parsesmilies = (typeof parsesmilies == 'undefined' ? 1 : parsesmilies);
	this.popupmode = (typeof GHOST_menu == 'undefined' ? false : true);
	this.controlbar = fetch_object(this.editorid + '_controls');
	this.textobj = fetch_object(this.editorid + '_textarea');
	this.buttons = new Array();
	this.popups = new Array();
	this.fontstate = null;
	this.sizestate = null;
	this.colorstate = null;
	this.clipboard = '';
	this.disabled = false;
	this.history = new GHOST_History();
	this.influx = 0;

	// =============================================================================
	// GHOST_Text_Editor methods

	/**
	* Editor initialization wrapper
	*/
	this.init = function()
	{
		if (this.initialized)
		{
			return;
		}

		this.textobj.disabled = false;

		if (this.tempiframe)
		{
			this.tempiframe.parentNode.removeChild(this.tempiframe);
		}

		this.set_editor_contents(initial_text);

		this.set_editor_functions();

		this.init_controls();

		this.init_smilies(fetch_object(this.editorid + '_smiliebox'));

		if (typeof smilie_window != 'undefined' && !smilie_window.closed)
		{
			this.init_smilies(smilie_window.document.getElementById('smilietable'));
		}

		this.initialized = true;
	};
    //+++++++++++++++++++++++++++++++++++++++++
	/**
	* Check if we need to refocus the editor window
	*/
	this.check_focus = function()
	{
		if (!this.editwin.hasfocus)
		{
			this.editwin.focus();
		}
	}

	/**
	* Init button controls for the editor
	*/
	this.init_controls = function()
	{
		var controls = new Array();

		if (this.controlbar == null)
		{
			return;
		}

		var buttons = fetch_tags(this.controlbar, 'div');
		for (var i = 0; i < buttons.length; i++)
		{
			if (buttons[i].className == 'imagebutton' && buttons[i].id)
			{
				controls[controls.length] = buttons[i].id;
			}
		}
		for (var i = 0; i < controls.length; i++)
		{
			var control = fetch_object(controls[i]);

			if (control.id.indexOf(this.editorid + '_cmd_') != -1)
			{
				this.init_command_button(control);
			}
			else if (control.id.indexOf(this.editorid + '_popup_') != -1)
			{
				this.init_popup_button(control);
			}
		}

		set_unselectable(this.controlbar);
	};

	/**
	* Init Smilies
	*/
	this.init_smilies = function(smilie_container)
	{
		if (smilie_container != null)
		{
			var smilies = fetch_tags(smilie_container, 'img');
			for (var i = 0; i < smilies.length; i++)
			{
				if (smilies[i].id && smilies[i].id.indexOf('_smilie_') != false)
				{
					smilies[i].style.cursor = pointer_cursor;
					smilies[i].editorid = this.editorid;
					smilies[i].onclick = GHOST_Text_Editor_Events.prototype.smilie_onclick;
					smilies[i].unselectable = 'on';
				}
			}
		}
	}

	/**
	* Init command button (b, i, u etc.)
	*
	* @param	object	Current HTML button node
	*/
	this.init_command_button = function(obj)
	{
		obj.cmd = obj.id.substr(obj.id.indexOf('_cmd_') + 5);
		obj.editorid = this.editorid;
		this.buttons[obj.cmd] = obj;

		if (obj.cmd == 'switchmode')
		{
			if (AJAX_Compatible)
			{
				obj.state = this.wysiwyg_mode ? true : false;
				this.set_control_style(obj, 'button', this.wysiwyg_mode ? 'selected' : 'normal');
			}
			else
			{
				obj.parentNode.removeChild(obj);
			}
		}
		else
		{
			obj.state = false;
			obj.mode = 'normal';
		}

		// event handlers
		obj.onclick = obj.onmousedown = obj.onmouseover = obj.onmouseout = GHOST_Text_Editor_Events.prototype.command_button_onmouseevent;
	}

	/**
	* Init popup button (forecolor, fontname etc.)
	*
	* @param	object	Current HTML button node
	*/
	this.init_popup_button = function(obj)
	{
		obj.cmd = obj.id.substr(obj.id.indexOf('_popup_') + 7);

		if (this.popupmode)
		{
			// register popup menu control
			GHOST_menu.register(obj.id, true);
			GHOST_menu.menus[obj.id].open_steps = 5;

			obj.editorid = this.editorid;
			obj.state = false;
			this.buttons[obj.cmd] = obj;

			if (obj.cmd == 'fontname')
			{
				this.fontout = fetch_object(this.editorid + '_font_out');
				this.fontout.innerHTML = obj.title;
				this.fontoptions = {'' : this.fontout};

				for (var option in fontoptions)
				{
					var div = document.createElement('div');
					div.id = this.editorid + '_fontoption_' + fontoptions[option];
					div.style.width = this.fontout.style.width;
					div.style.display = 'none';
					div.innerHTML = fontoptions[option];
					this.fontoptions[fontoptions[option]] = this.fontout.parentNode.appendChild(div);
				}
			}
			else if (obj.cmd == 'fontsize')
			{
				this.sizeout = fetch_object(this.editorid + '_size_out');
				this.sizeout.innerHTML = obj.title;
				this.sizeoptions = {'' : this.sizeout};

				for (var option in sizeoptions)
				{
					var div = document.createElement('div');
					div.id = this.editorid + '_sizeoption_' + sizeoptions[option];
					div.style.width = this.sizeout.style.width;
					div.style.display = 'none';
					div.innerHTML = sizeoptions[option];
					this.sizeoptions[sizeoptions[option]] = this.sizeout.parentNode.appendChild(div);
				}
			}

			// extend onmouseover
			obj._onmouseover = obj.onmouseover;
			// extend onclick
			obj._onclick = obj.onclick;

			// event handlers
			obj.onmouseover = obj.onmouseout = obj.onclick = GHOST_Text_Editor_Events.prototype.popup_button_onmouseevent;

			// extend menu show
			GHOST_menu.menus[obj.id]._show = GHOST_menu.menus[obj.id].show;
			GHOST_menu.menus[obj.id].show = GHOST_Text_Editor_Events.prototype.popup_button_show;
		}
		else
		{
			this.build_select(obj);
		}
	}

	 

	/**
	* Init menu controls for the editor
	*
	* @param	object	HTML menu node
	*/
	this.init_popup_menu = function(obj)
	{
		if (this.disabled)
		{
			return;
		}

		switch (obj.cmd)
		{
			case 'fontname':
			{
				var menu = this.init_menu_container('fontname', '200px', '250px', 'auto');
				this.build_fontname_popup(obj, menu);
				break;
			}
			case 'fontsize':
			{
				var menu = this.init_menu_container('fontsize', 'auto', 'auto', 'visible');
				this.build_fontsize_popup(obj, menu);
				break;
			}
			case 'forecolor':
			{
				var menu = this.init_menu_container('forecolor', 'auto', 'auto', 'visible');
				this.build_forecolor_popup(obj, menu);
				break;
			}
		}

		this.popups[obj.cmd] = this.controlbar.appendChild(menu);

		set_unselectable(menu);
	};

	/**
	* Init Menu Container DIV
	*
	* @param	string	Command string (forecolor, fontname etc.)
	* @param	string	CSS width for the menu
	* @param	string	CSS height for the menu
	* @param	string	CSS overflow for the menu
	*
	* @return	object	Newly created menu element
	*/
	this.init_menu_container = function(cmd, width, height, overflow)
	{
		var menu = document.createElement('div');

		menu.id = this.editorid + '_popup_' + cmd + '_menu';
		menu.className = 'GHOST_menu_popup';
		menu.style.display = 'none';
		menu.style.cursor = 'default';
		menu.style.padding = '3px';
		menu.style.width = width;
		menu.style.height = height;
		menu.style.overflow = overflow;

		return menu;
	}

	// عرض الخطوط بقائمه منسدله بشكل هتمل
	this.build_fontname_popup = function(obj, menu)
	{
		for (var n in fontoptions)
		{
			var option = document.createElement('div');
			option.innerHTML = '<font face="' + fontoptions[n] + '">' + fontoptions[n] + '</font>';
			option.className = 'ofont';
			option.style.textAlign = 'left';
			option.title = fontoptions[n];
			option.cmd = obj.cmd;
			option.controlkey = obj.id;
			option.editorid = this.editorid;
			option.onmouseover = option.onmouseout = option.onmouseup = option.onmousedown = GHOST_Text_Editor_Events.prototype.menuoption_onmouseevent;
			option.onclick = GHOST_Text_Editor_Events.prototype.formatting_option_onclick;
			menu.appendChild(option);
		}
	}

	// عرض الاحجام بقائمه منسدله بشكل هتمل
	this.build_fontsize_popup = function(obj, menu)
	{
		for (var n in sizeoptions)
		{
			var option = document.createElement('div');
			option.innerHTML = '<font size="' + sizeoptions[n] + '">' + sizeoptions[n] + '</font>';
			option.className = 'osize';
			option.style.textAlign = 'center';
			option.title = sizeoptions[n];
			option.cmd = obj.cmd;
			option.controlkey = obj.id;
			option.editorid = this.editorid;
			option.onmouseover = option.onmouseout = option.onmouseup = option.onmousedown = GHOST_Text_Editor_Events.prototype.menuoption_onmouseevent;
			option.onclick = GHOST_Text_Editor_Events.prototype.formatting_option_onclick;
			menu.appendChild(option);
		}
	}

	// عرض الالوان بقائمه منسدله بشكل هتمل
	this.build_forecolor_popup = function(obj, menu)
	{
		var colorout = fetch_object(this.editorid + '_color_out');
		colorout.editorid = this.editorid;
		colorout.onclick = GHOST_Text_Editor_Events.prototype.colorout_onclick;

		var table = document.createElement('table');
		table.cellPadding = 0;
		table.cellSpacing = 0;
		table.border = 0;

		var i = 0;
		for (var hex in coloroptions)
		{
			if (i % 8 == 0)
			{
				var tr = table.insertRow(-1);
			}
			i++;

			var div = document.createElement('div');
			div.style.backgroundColor = coloroptions[hex];

			var option = tr.insertCell(-1);
			option.style.textAlign = 'center';
			option.className = 'ocolor';
			option.appendChild(div);
			option.cmd = obj.cmd;
			option.editorid = this.editorid;
			option.controlkey = obj.id;
			option.colorname = coloroptions[hex];
			option.id = this.editorid + '_color_' + coloroptions[hex];
			option.onmouseover = option.onmouseout = option.onmouseup = option.onmousedown = GHOST_Text_Editor_Events.prototype.menuoption_onmouseevent;
			option.onclick = GHOST_Text_Editor_Events.prototype.coloroption_onclick;
		}

		menu.appendChild(table);
	}


	/**
	* Menu Context
	*
	* @param	object	The menu container object
	* @param	string	The state of the control
	*/
	this.menu_context = function(obj, state)
	{
		if (this.disabled)
		{
			return;
		}

		switch (obj.state)
		{
			case true: // selected menu is open
			{
				this.set_control_style(obj, 'button', 'down');
				break;
			}

			default:
			{
				switch (state)
				{
					case 'mouseout':
					{
						this.set_control_style(obj, 'button', 'normal');
						break;
					}
					case 'mousedown':
					{
						this.set_control_style(obj, 'popup', 'down');
						break;
					}
					case 'mouseup':
					case 'mouseover':
					{
						this.set_control_style(obj, 'button', 'hover');
						break;
					}
				}
			}
		}
	};

	/**
	* Button Context
	*
	* @param	object	The button object
	* @param	string	Incoming event type
	* @param	string	Control type - 'button' or 'menu'
	*/
	this.button_context = function(obj, state, controltype)
	{
		if (this.disabled)
		{
			return;
		}

		if (typeof controltype == 'undefined')
		{
			controltype = 'button';
		}

		switch (obj.state)
		{
			case true: // selected button
			{
				switch (state)
				{
					case 'mouseover':
					case 'mousedown':
					case 'mouseup':
					{
						this.set_control_style(obj, controltype, 'down');
						break;
					}
					case 'mouseout':
					{
						this.set_control_style(obj, 'button', 'selected');
						break;
					}
				}
				break;
			}

			default: // not selected
			{
				switch (state)
				{
					case 'mouseover':
					case 'mouseup':
					{
						this.set_control_style(obj, controltype, 'hover');
						break;
					}
					case 'mousedown':
					{
						this.set_control_style(obj, controltype, 'down');
						break;
					}
					case 'mouseout':
					{
						this.set_control_style(obj, controltype, 'normal');
						break;
					}
				}
				break;
			}
		}
	};
    //--------------------------------------------------------
	/**
	* Set Control Style
	*
	* @param	object	The object to be styled
	* @param	string	Control type - 'button' or 'menu'
	* @param	string	The mode to use, corresponding to the istyles array
	*/
	this.set_control_style = function(obj, controltype, mode)
	{
		if (obj.mode != mode)
		{
			obj.mode = mode;

			// construct the name of the appropriate array key from the istyles array
			istyle = 'pi_' + controltype + '_' + obj.mode;

			// set element background, color, padding and border
			if (typeof istyles != 'undefined' && typeof istyles[istyle] != 'undefined')
			{
				obj.style.background = istyles[istyle][0];
				obj.style.color = istyles[istyle][1];
				if (controltype != 'menu')
				{
					obj.style.padding = istyles[istyle][2];
				}
				obj.style.border = istyles[istyle][3];

				var tds = fetch_tags(obj, 'td');
				for (var i = 0; i < tds.length; i++)
				{
					switch (tds[i].className)
					{
						// set the right-border for popup_feedback class elements
						case 'popup_feedback':
						{
							tds[i].style.borderRight = (mode == 'normal' ? istyles['pi_menu_normal'][3] : istyles[istyle][3]);
						}
						break;

						// set the border colour for popup_pickbutton class elements
						case 'popup_pickbutton':
						{
							tds[i].style.borderColor = (mode == 'normal' ? istyles['pi_menu_normal'][0] : istyles[istyle][0]);
						}
						break;

						// set the left-padding and left-border for alt_pickbutton elements
						case 'alt_pickbutton':
						{
							if (obj.state)
							{
								tds[i].style.paddingLeft = istyles['pi_button_normal'][2];
								tds[i].style.borderLeft = istyles['pi_button_normal'][3];
							}
							else
							{
								tds[i].style.paddingLeft = istyles[istyle][2];
								tds[i].style.borderLeft = istyles[istyle][3];
							}
						}
					}
				}
			}
		}
	};
    //--------------------------------------------------------
	// اختيار نوع ولون وحجم الخط من القائمة المنسدله
	this.format = function(e, cmd, arg)
	{
		e = do_an_e(e);

		if (this.disabled)
		{
			return false;
		}

		if (cmd != 'redo')
		{
			this.history.add_snapshot(this.get_editor_contents());
		}

		if (cmd == 'switchmode')
		{
			switch_editor_mode(this.editorid);
			return;
		}
		else if (cmd.substr(0, 6) == 'resize')
		{
			this.resize_editor(parseInt(cmd.substr(9), 10) * (parseInt(cmd.substr(7, 1), 10) == '1' ? 1 : -1));
			return;
		}

		this.check_focus();

		if (cmd.substr(0, 4) == 'wrap')
		{
			var ret = this.wrap_tags(cmd.substr(6), (cmd.substr(4, 1) == '1' ? true : false));
		}
		else if (this[cmd])
		{
			var ret = this[cmd](e);
		}
		else
		{
			try
			{
				var ret = this.apply_format(cmd, false, (typeof arg == 'undefined' ? true : arg));
			}
			catch(e)
			{
				this.handle_error(cmd, e);
				var ret = false;
			}
		}

		if (cmd != 'undo')
		{
			this.history.add_snapshot(this.get_editor_contents());
		}

		this.set_context(cmd);

		this.check_focus();

		return ret;
	};
    //--------------------------------------------------------
	// ادخال رابط الصورة 
	this.insertimage = function(e, img)
	{
		if (typeof img == 'undefined')
		{
			img = this.show_prompt(GHOST_phrase['enter_image_url'], 'http://');
		}
		if (img = this.verify_prompt(img))
		{
			return this.apply_format('insertimage', false, img);
		}
		else
		{
			return false;
		}
	};
    //--------------------------------------------------------
	// اكواد الهتمل والبي اتش بي
	this.wrap_tags = function(tagname, useoption, selection)
	{
		tagname = tagname.toUpperCase();


		if (typeof selection == 'undefined')
		{
			selection = this.get_selection();
			if (selection === false)
			{
				selection = '';
			}
			else
			{
				selection = new String(selection);
			}
		}

		if (useoption === true)
		{
			var option = this.show_prompt(construct_phrase(GHOST_phrase['enter_tag_option'], ('<' + tagname + '>')), '');
			if (option = this.verify_prompt(option))
			{
				var opentag = '<' + tagname + '="' + option + '"' + '>';
			}
			else
			{
				return false;
			}
		}
		else if (tagname == "COLOR")
		{
			var opentag = '<FONT COLOR="' + useoption + '"' + '>';
		}
		else if (tagname == "SIZE")
		{
			var opentag = '<FONT SIZE="' + useoption + '"' + '>';
		}
		else if (tagname == "FONT")
		{
			var opentag = '<FONT FACE="' + useoption + '"' + '>';
		}
		else if (tagname == "LEFT" || tagname == "CENTER" || tagname == "RIGHT" || tagname == "JUSTIFY")
		{
			var opentag = '<p align="' + tagname + '"' + ' dir=rtl' + '>';
		}
		else if (useoption !== false)
		{
			var opentag = '<' + tagname + '="' + useoption + '"' + '>';
		}
		else
		{
			var opentag = '<' + tagname + '>';
		}

		var closetag = '</' + tagname + '>';

		if (tagname == "SIZE" || tagname == "FONT" || tagname == "COLOR")
		{
			var closetag = '</FONT>';
		}
		
		if (tagname == "LEFT" || tagname == "CENTER" || tagname == "RIGHT" || tagname == "JUSTIFY")
		{
			var closetag = '</p>';
		}
		
		if (tagname == "A HREF")
		{
			var closetag = '</A>';
		}
		
		if (tagname == 'IMG BORDER="0" SRC')
		{
			var closetag = ' ';
		}
		
		var text = opentag + selection + closetag;

		this.insert_text(text, opentag.vBlength(), closetag.vBlength());

		return false;
	};
    //--------------------------------------------------------


	/**
	* Handle Error
	*
	* @param	string	Command name
	* @param	event	Event object
	*/
	this.handle_error = function(cmd, e)
	{
	};

	/**
	* Show JS Prompt and filter result
	*
	* @param	string	Text for the dialog
	* @param	string	Default value for the dialog
	*
	* @return	string
	*/
	this.show_prompt = function(dialogtxt, defaultval)
	{
		return PHP.trim(new String(prompt(dialogtxt, defaultval)));
	};

	/**
	* Verify the return value of a javascript prompt
	*
	* @param	string	String to be checked
	*
	* @return	mixed	False on fail, string on success
	*/
	this.verify_prompt = function(str)
	{
		switch(str)
		{
			case 'http://':
			case 'null':
			case 'undefined':
			case 'false':
			case '':
			case null:
			case false:
				return false;

			default:
				return str;
		}
	};

	// التحكم بطول بيانات الموضوع
	this.resize_editor = function(change)
	{
		var newheight = parseInt(this.editbox.style.height, 10) + change;

		if (newheight >= 100)
		{
			this.editbox.style.height = newheight + 'px';
		}
	};

	/**
	* Destroy Popup
	*/
	this.destroy_popup = function(popupname)
	{
		this.popups[popupname].parentNode.removeChild(this.popups[popupname]);
		this.popups[popupname] = null;
	}



	// =============================================================================
	// WYSIWYG editor
	// =============================================================================
	if (this.wysiwyg_mode)
	{
		/**
		* Disables the editor
		*
		* @param	string	Initial text for the editor
		*/
		this.disable_editor = function(text)
		{
			var hider = fetch_object(this.editorid + '_hider');
			if (hider)
			{
				hider.parentNode.removeChild(hider);
			}

			var div = document.createElement('div');
			div.id = this.editorid + '_hider';
			div.className = 'wysiwyg';
			div.style.border = '2px inset';
			div.style.width = this.editbox.style.width;
			div.style.height = this.editbox.style.height;
			var childdiv = document.createElement('div');
			childdiv.style.margin = '8px';
			childdiv.innerHTML = text;
			div.appendChild(childdiv);
			this.editbox.parentNode.appendChild(div);

			// and hide the real editor
			this.editbox.style.width = '0px';
			this.editbox.style.height = '0px';
			this.editbox.style.border = 'none';

			this.disabled = true;
		};

		/**
		* Enables the editor
		*
		* @param	string	Initial text for the editor
		*/
		this.enable_editor = function(text)
		{
			if (typeof text != 'undefined')
			{
				this.set_editor_contents(text);
			}

			var hider = fetch_object(this.editorid + '_hider');
			if (hider)
			{
				hider.parentNode.removeChild(hider);
			}

			this.disabled = false;
		};

		/**
		* Puts the text into the editor
		*
		* @param	string	Text to write
		*/
		this.write_editor_contents = function(text, doinit)
		{
			if (text == '' && is_moz)
			{
				text = '<br />';
			}
			if (this.editdoc && this.editdoc.initialized)
			{
				this.editdoc.body.innerHTML = text;
			}
			else
			{
				if (doinit) { this.editdoc.designMode = 'on'; }
				this.editdoc = this.editwin.document; // See: http://msdn.microsoft.com/workshop/author/dhtml/overview/XpSp2Compat.asp#caching
				this.editdoc.open('text/html', 'replace');
				this.editdoc.write(text);
				this.editdoc.close();
				if (doinit) { this.editdoc.body.contentEditable = true; }

				this.editdoc.initialized = true;

				this.set_editor_style();
			}

			this.set_direction();
		}

		/**
		* Put the text into the editor
		*/
		this.set_editor_contents = function(initial_text)
		{
			if (fetch_object(this.editorid + '_iframe'))
			{
				this.editbox = fetch_object(this.editorid + '_iframe');
			}
			else
			{
				var iframe = document.createElement('iframe')
				if (is_ie && window.location.protocol == 'https:')
				{
					// workaround for IE throwing insecure page warnings
					iframe.src = 'clientscript/index.html';
				}
				this.editbox = this.textobj.parentNode.appendChild(iframe);
				this.editbox.id = this.editorid + '_iframe';
				this.editbox.tabIndex = 1;
			}

			if (!is_ie)
			{
				this.editbox.style.border = '2px inset';
			}
			this.editbox.style.width = this.textobj.style.width;
			this.editbox.style.height = this.textobj.style.height;
			this.textobj.style.display = 'none';

			this.editwin = this.editbox.contentWindow;
			this.editdoc = this.editwin.document;

			this.set_direction();

			this.write_editor_contents((typeof initial_text == 'undefined' ?  this.textobj.value : initial_text), true);

			if (this.editdoc.dir == 'rtl')
			{
			//	this.editdoc.execCommand('justifyright', false, null);
			}
			this.spellobj = this.editdoc.body;

			this.editdoc.editorid = this.editorid;
			this.editwin.editorid = this.editorid;
		};

		/**
		* Sets the text direction for the editor
		*/
		this.set_direction = function()
		{
			this.editdoc.dir = this.textobj.dir;
		};

		/**
		* Set the CSS style of the editor
		*/
		this.set_editor_style = function()
		{
			if (document.styleSheets['GHOST_css'])
			{
				this.editdoc.createStyleSheet().cssText = document.styleSheets['GHOST_css'].cssText + ' p { margin: 0px; }';
				this.editdoc.body.className = 'wysiwyg';
			}
		};

		/**
		* Init Editor Functions
		*/
		this.set_editor_functions = function()
		{
			this.editdoc.onmouseup = GHOST_Text_Editor_Events.prototype.editdoc_onmouseup;
			this.editdoc.onkeyup = GHOST_Text_Editor_Events.prototype.editdoc_onkeyup;

			if (this.editdoc.attachEvent)
			{
				this.editdoc.body.attachEvent("onresizestart", GHOST_Text_Editor_Events.prototype.editdoc_onresizestart);
			}

			this.editwin.onfocus = GHOST_Text_Editor_Events.prototype.editwin_onfocus;
			this.editwin.onblur = GHOST_Text_Editor_Events.prototype.editwin_onblur;
		};

		/**
		* Set Context
		*/
		this.set_context = function(cmd)
		{
			for (var i in contextcontrols)
			{
				var obj = fetch_object(this.editorid + '_cmd_' + contextcontrols[i]);
				if (obj != null)
				{
					state = this.editdoc.queryCommandState(contextcontrols[i]);
					//alert (contextcontrols[i] + ' ' + state + ' ' + obj.state);
					if (obj.state != state)
					{
						obj.state = state;
						this.button_context(obj, (obj.cmd == cmd ? 'mouseover' : 'mouseout'));
					}
				}
			}

			this.set_font_context();

			this.set_size_context();

			this.set_color_context();
		};

		/**
		* Set Font Context
		*/
		this.set_font_context = function(fontstate)
		{
			if (this.buttons['fontname'])
			{
				if (typeof fontstate == 'undefined')
				{
					fontstate = this.editdoc.queryCommandValue('fontname');
				}
				switch (fontstate)
				{
					case '':
					{
						if (!is_ie && window.getComputedStyle)
						{
							fontstate = this.editdoc.body.style.fontFamily;
						}
					}
					break;

					case null:
					{
						fontstate = '';
					}
					break;
				}

				if (fontstate != this.fontstate)
				{
					this.fontstate = fontstate;
					var thingy = PHP.ucfirst(this.fontstate, ',');

					if (this.popupmode)
					{
						for (var i in this.fontoptions)
						{
							this.fontoptions[i].style.display = (i == thingy ? '' : 'none');
						}
					}
					else
					{
						for (var i = 0; i < this.buttons['fontname'].options.length; i++)
						{
							if (this.buttons['fontname'].options[i].value == thingy)
							{
								this.buttons['fontname'].selectedIndex = i;
								break;
							}
						}
					}
				}
			}
		};

		/**
		* Set Size Context
		*/
		this.set_size_context = function(sizestate)
		{
			if (this.buttons['fontsize'])
			{
				if (typeof sizestate == 'undefined')
				{
					sizestate = this.editdoc.queryCommandValue('fontsize');
				}
				switch (sizestate)
				{
					case null:
					case '':
					{
						if (is_moz)
						{
							sizestate = this.translate_fontsize(this.editdoc.body.style.fontSize);
						}
					}
					break;
				}
				if (sizestate != this.sizestate)
				{
					this.sizestate = sizestate;

					if (this.popupmode)
					{
						for (var i in this.sizeoptions)
						{
							this.sizeoptions[i].style.display = (i == this.sizestate ? '' : 'none');
						}
					}
					else
					{
						for (var i = 0; i < this.buttons['fontsize'].options.length; i++)
						{
							if (this.buttons['fontsize'].options[i].value == this.sizestate)
							{
								this.buttons['fontsize'].selectedIndex = i;
								break;
							}
						}
					}
				}
			}
		};

		/**
		* Set Color Context
		*/
		this.set_color_context = function(colorstate)
		{
			if (this.buttons['forecolor'])
			{
				if (typeof colorstate == 'undefined')
				{
					colorstate = this.editdoc.queryCommandValue('forecolor');
				}
				if (colorstate != this.colorstate)
				{
					if (this.popupmode)
					{
						var obj = fetch_object(this.editorid + '_color_' + this.translate_color_commandvalue(this.colorstate));
						if (obj != null)
						{
							obj.state = false;
							this.button_context(obj, 'mouseout', 'menu');
						}

						this.colorstate = colorstate;

						elmid = this.editorid + '_color_' + this.translate_color_commandvalue(colorstate);
						var obj = fetch_object(elmid);
						if (obj != null)
						{
							obj.state = true;
							this.button_context(obj, 'mouseout', 'menu');
						}
					}
					else
					{
						this.colorstate = colorstate;

						colorstate = this.translate_color_commandvalue(this.colorstate);

						for (var i = 0; i < this.buttons['forecolor'].options.length; i++)
						{
							if (this.buttons['forecolor'].options[i].value == colorstate)
							{
								this.buttons['forecolor'].selectedIndex = i;
								break;
							}
						}
					}
				}
			}
		};

		/**
		* Function to translate the output from queryCommandState('forecolor') into something useful
		*
		* @param	string	Output from queryCommandState('forecolor')
		*
		* @return	string
		*/
		this.translate_color_commandvalue = function(forecolor)
		{
			return this.translate_silly_hex((forecolor & 0xFF).toString(16), ((forecolor >> 8) & 0xFF).toString(16), ((forecolor >> 16) & 0xFF).toString(16));
		};

		/**
		* Function to translate a hex like F AB 9 to #0FAB09 and then to coloroptions['#0FAB09']
		*
		* @param	string	Red value
		* @param	string	Green value
		* @param	string	Blue value
		*
		* @return	string	Option from coloroptions array
		*/
		this.translate_silly_hex = function(r, g, b)
		{
			return coloroptions['#' + (PHP.str_pad(r, 2, 0) + PHP.str_pad(g, 2, 0) + PHP.str_pad(b, 2, 0)).toUpperCase()];
		};

		/**
		* Apply Formatting
		*/
		this.apply_format = function(cmd, dialog, argument)
		{
			this.editdoc.execCommand(cmd, (typeof dialog == 'undefined' ? false : dialog), (typeof argument == 'undefined' ? true : argument));
			return false;
		};

		/**
		* Insert Link
		*/
		this.createlink = function(e, url)
		{
			return this.apply_format('createlink', is_ie, (typeof url == 'undefined' ? true : url));
		};


		/**
		* Get Editor Contents
		*/
		this.get_editor_contents = function()
		{
			return this.editdoc.body.innerHTML;
		};

		/**
		* Get Selected Text
		*/
		this.get_selection = function()
		{
			var range = this.editdoc.selection.createRange();
			if (range.htmlText && range.text)
			{
				return range.htmlText;
			}
			else
			{
				var do_not_steal_this_code_html = '';
				for (var i = 0; i < range.length; i++)
				{
					do_not_steal_this_code_html += range.item(i).outerHTML;
				}
				return do_not_steal_this_code_html;
			}
		};
 

		/**
		* Prepare Form For Submit
		*/
		this.prepare_submit = function(subjecttext, minchars)
		{
			this.textobj.value = this.get_editor_contents();

			return validatemessage(stripcode(this.textobj.value, true), subjecttext, minchars);
		}
	}
	// =============================================================================
	// Standard editor
	// =============================================================================
	else
	{
		this.disable_editor = function(text)
		{
			if (typeof text != 'undefined')
			{
				this.editbox.value = text;
			}
			this.editbox.disabled = true;

			this.disabled = true;
		};

		this.enable_editor = function(text)
		{
			if (typeof text != 'undefined')
			{
				this.editbox.value = text;
			}
			this.editbox.disabled = false;

			this.disabled = false;
		};

		/**
		* Writes contents to the <textarea>
		*
		* @param	object	<textarea>
		* @param	string	Initial text
		*/
		this.write_editor_contents = function(text)
		{
			this.textobj.value = text;
		}

		/**
		* Put the text into the editor
		*/
		this.set_editor_contents = function(initial_text)
		{
			var iframe = this.textobj.parentNode.getElementsByTagName('iframe')[0];
			if (iframe)
			{
				this.textobj.style.display = '';
				this.textobj.style.width = iframe.style.width;
				this.textobj.style.height = iframe.style.height;

				iframe.style.width = '0px';
				iframe.style.height = '0px';
				iframe.style.border = 'none';
			}

			this.editwin = this.textobj;
			this.editdoc = this.textobj;
			this.editbox = this.textobj;
			this.spellobj = this.textobj;

			if (typeof initial_text != 'undefined')
			{
				this.write_editor_contents(initial_text);
			}

			this.editdoc.editorid = this.editorid;
			this.editwin.editorid = this.editorid;

			this.history.add_snapshot(this.get_editor_contents());
		};

		/**
		* Set the CSS style of the editor
		*/
		this.set_editor_style = function()
		{
		};

		/**
		* Init Editor Functions
		*/
		this.set_editor_functions = function()
		{
			if (this.editdoc.addEventListener)
			{
				this.editdoc.addEventListener('keypress', GHOST_Text_Editor_Events.prototype.editdoc_onkeypress, false);
			}

			this.editwin.onfocus = GHOST_Text_Editor_Events.prototype.editwin_onfocus;
			this.editwin.onblur = GHOST_Text_Editor_Events.prototype.editwin_onblur;
		};

		/**
		* Set Context
		*/
		this.set_context = function()
		{
		};

		/**
		* Apply formatting
		*/
		this.apply_format = function(cmd, dialog, argument)
		{
			// undo & redo array pops

			switch (cmd)
			{
				case 'bold':
				case 'italic':
				case 'underline':
				{
					this.wrap_tags(cmd.substr(0, 1), false);
					return;
				}

				case 'justifyleft':
				case 'justifycenter':
				case 'justifyright':
				case 'justifyjustify':
				{
					this.wrap_tags(cmd.substr(7), false);
					return;
				}
				
				case 'ltor':
				{
					this.wrap_tags(cmd.substr(0,4), false);
					return;
				}
				
				case 'fontname':
				{
					this.wrap_tags('font', argument);
					return;
				}

				case 'fontsize':
				{
					this.wrap_tags('size', argument);
					return;
				}

				case 'forecolor':
				{
					this.wrap_tags('color', argument);
					return;
				}

				case 'createlink':
				{
					var sel = this.get_selection();
					if (sel)
					{
						this.wrap_tags('url', argument);
					}
					else
					{
						this.wrap_tags('url', argument, argument);
					}
					return;
				}
                 // اذا وضعنا false
                 // [] xxx []
                 // وبدون false
                 // [ xxx]
				case 'insertimage':
				{
					this.wrap_tags('img border="0" src', argument);
					return;
				}

				case 'removeformat':
				return;
			}

			//alert('cmd :: ' + cmd + '\ndialog :: ' + dialog + '\nargument :: ' + argument);
		};

		this.undo = function()
		{
			this.history.add_snapshot(this.get_editor_contents());
			this.history.move_cursor(-1);
			if ((str = this.history.get_snapshot()) !== false)
			{
				this.editdoc.value = str;
			}
		};

		this.redo = function()
		{
			this.history.move_cursor(1);
			if ((str = this.history.get_snapshot()) !== false)
			{
				this.editdoc.value = str;
			}
		};

		/**
		* Strip a simple tag...
		*/
		this.strip_simple = function(tag, str, iterations)
		{
			var opentag = '[' + tag + ']';
			var closetag = '[/' + tag + ']';

			if (typeof iterations == 'undefined')
			{
				iterations = -1;
			}

			while ((startindex = PHP.stripos(str, opentag)) !== false && iterations != 0)
			{
				iterations --;
				if ((stopindex = PHP.stripos(str, closetag)) !== false)
				{
					var text = str.substr(startindex + opentag.length, stopindex - startindex - opentag.length);
					str = str.substr(0, startindex) + text + str.substr(stopindex + closetag.length);
				}
				else
				{
					break;
				}
			}

			return str;
		};

		/**
		* Strip a tag with an option
		*/
		this.strip_complex = function(tag, str, iterations)
		{
			var opentag = '<' + tag + '=';
			var closetag = '</' + tag + '>';

			if (typeof iterations == 'undefined')
			{
				iterations = -1;
			}

			while ((startindex = PHP.stripos(str, opentag)) !== false && iterations != 0)
			{
				iterations --;
				if ((stopindex = PHP.stripos(str, closetag)) !== false)
				{
					var openend = PHP.stripos(str, ']', startindex);
					if (openend !== false && openend > startindex && openend < stopindex)
					{
						var text = str.substr(openend + 1, stopindex - openend - 1);
						str = str.substr(0, startindex) + text + str.substr(stopindex + closetag.length);
					}
					else
					{
						break;
					}
				}
				else
				{
					break;
				}
			}

			return str;
		};

		/**
		* Remove Formatting
		*/
		this.removeformat = function(e)
		{
			var simplestrip = new Array('b', 'i', 'u');
			var complexstrip = new Array('font', 'color', 'size');

			var str = this.get_selection();
			if (str === false)
			{
				return;
			}

			// simple stripper
			for (var tag in simplestrip)
			{
				str = this.strip_simple(simplestrip[tag], str);
			}

			// complex stripper
			for (var tag in complexstrip)
			{
				str = this.strip_complex(complexstrip[tag], str);
			}

			this.insert_text(str);
		};

		/**
		* Insert Link
		*/
		this.createlink = function(e, url)
		{
			this.prompt_link('a href', url, GHOST_phrase['enter_link_url'], 'http://');
		};
 
 

		/**
		* Insert Smilie
		*/
		this.insert_smilie = function(e, smilietext)
		{
			this.check_focus();

			smilietext += ' ';

			return this.insert_text(smilietext, smilietext.length, 0);
		};

		/**
		* Wrapper for Link / Email Link insert
		*/
		this.prompt_link = function(tagname, value, phrase, iprompt)
		{
			if (typeof value == 'undefined')
			{
				value = this.show_prompt(phrase, iprompt);
			}
			if ((value = this.verify_prompt(value)) !== false)
			{
				if (this.get_selection())
				{
					this.apply_format('unlink');
					this.wrap_tags(tagname, value);
				}
				else
				{
					this.wrap_tags(tagname, value, value);
				}
			}
			return true;
		};

		/**
		* Insert Ordered List
		*/
		this.insertorderedlist = function(e)
		{
			this.insertlist(GHOST_phrase['insert_ordered_list'], '1');
		};

		/**
		* Insert Unordered List
		*/
		this.insertunorderedlist = function(e)
		{
			this.insertlist(GHOST_phrase['insert_unordered_list'], '');
		};

		/**
		* Insert List
		*/
		this.insertlist = function(phrase, listtype)
		{
			var opentag = '<ul' + (listtype ? ('=' + listtype) : '') + '>\n';
			var closetag = '</ul>';

			if (txt = this.get_selection())
			{
				var regex = new RegExp('([\r\n]+|^[\r\n]*)(?!\\[\\*\\]|\\[\\/?list)(?=[^\r\n])', 'gi');
				txt = opentag + PHP.trim(txt).replace(regex, '</li>$1<li>') + '</li>\n' + closetag;
				this.insert_text(txt, txt.vBlength(), 0);
			}
			else
			{
				this.insert_text(opentag + closetag, opentag.length, closetag.length);

				while (listvalue = prompt(GHOST_phrase['enter_list_item'], ''))
				{
					listvalue = '<li>' + listvalue + '</li>\n';
					this.insert_text(listvalue, listvalue.vBlength(), 0);
				}
			}
		};


		/**
		* Get Editor Contents
		*/
		this.get_editor_contents = function()
		{
			return this.editdoc.value;
		};

		/**
		* Get Selected Text
		*/
		this.get_selection = function()
		{
			if (typeof(this.editdoc.selectionStart) != 'undefined')
			{
				return this.editdoc.value.substr(this.editdoc.selectionStart, this.editdoc.selectionEnd - this.editdoc.selectionStart);
			}
			else if (document.selection && document.selection.createRange)
			{
				return document.selection.createRange().text;
			}
			else if (window.getSelection)
			{
				return window.getSelection() + '';
			}
			else
			{
				return false;
			}
		};

		/**
		* Paste HTML
		*/
		this.insert_text = function(text, movestart, moveend)
		{
			this.check_focus();

			if (typeof(this.editdoc.selectionStart) != 'undefined')
			{
				var opn = this.editdoc.selectionStart + 0;

				this.editdoc.value = this.editdoc.value.substr(0, this.editdoc.selectionStart) + text + this.editdoc.value.substr(this.editdoc.selectionEnd);

				if (movestart === false)
				{
					// do nothing
				}
				else if (typeof movestart != 'undefined')
				{
					this.editdoc.selectionStart = opn + movestart;
					this.editdoc.selectionEnd = opn + text.vBlength() - moveend;
				}
				else
				{
					this.editdoc.selectionStart = opn;
					this.editdoc.selectionEnd = opn + text.vBlength();
				}
			}
			else if (document.selection && document.selection.createRange)
			{
				var sel = document.selection.createRange();
				sel.text = text.replace(/\r?\n/g, '\r\n');

				if (movestart === false)
				{
					// do nothing
				}
				else if (typeof movestart != 'undefined')
				{
					sel.moveStart('character', -text.vBlength() +movestart);
					sel.moveEnd('character', -moveend);
				}
				else
				{
					sel.moveStart('character', -text.vBlength());
				}
				sel.select();
			}
			else
			{
				// failed - just stuff it at the end of the message
				this.editdoc.value += text;
			}
		};

		/**
		* Prepare Form For Submit
		*/
		this.prepare_submit = function(subjecttext, minchars)
		{
			return validatemessage(this.textobj.value, subjecttext, minchars);
		}
	}

	// gentlemen, start your engines...
	this.init();
}

// =============================================================================
// Editor event handler functions

/**
* Class containing editor event handlers
*/
function GHOST_Text_Editor_Events()
{
}

// صور الابتسامات في صندوق الابتسامات
GHOST_Text_Editor_Events.prototype.smilie_onclick = function(e)
{
	GHOST_Editor[this.editorid].insert_smilie(e,
		this.alt,
		this.src,
		this.id.substr(this.id.lastIndexOf('_') + 1)
	);

	if (typeof smilie_window != 'undefined' && !smilie_window.closed)
	{
		smilie_window.focus();
	}

	return false;
};
//----------------------------------------------------------------------
// Handles a mouse event on a command button 
GHOST_Text_Editor_Events.prototype.command_button_onmouseevent = function(e)
{
	e = do_an_e(e);

	if (e.type == 'click')
	{
		GHOST_Editor[this.editorid].format(e, this.cmd, false, true);
	}

	GHOST_Editor[this.editorid].button_context(this, e.type);
};
//----------------------------------------------------------------------
// Handles a mouse event on a popup controller button
GHOST_Text_Editor_Events.prototype.popup_button_onmouseevent = function(e)
{
	e = do_an_e(e);

	if (e.type == 'click')
	{
		this._onclick(e);
		GHOST_Editor[this.editorid].menu_context(this, 'mouseover');
	}
	else
	{
		GHOST_Editor[this.editorid].menu_context(this, e.type);
	}
};

/**
* Overrides the show() function from the GHOST_menu system
*
* @param	object	Control object
* @param	boolean	Show instantly?
*/
GHOST_Text_Editor_Events.prototype.popup_button_show = function(obj, instant)
{
	if (typeof GHOST_Editor[obj.editorid].popups[obj.cmd] == 'undefined' || GHOST_Editor[obj.editorid].popups[obj.cmd] == null)
	{
		GHOST_Editor[obj.editorid].init_popup_menu(obj);
	}
	else if (obj.cmd == 'attach' && (typeof GHOST_Attachments == 'undefined' || !GHOST_Attachments.has_attachments()))
	{
		return fetch_object('manage_attachments_button').onclick();
	}
	this._show(obj, instant);
};

/**
* Handles a selection from a formatting <select> menu
*/
GHOST_Text_Editor_Events.prototype.formatting_select_onchange = function(e)
{
	var arg = this.options[this.selectedIndex].value;
	if (arg != '')
	{
		GHOST_Editor[this.editorid].format(e, this.cmd, arg);
	}
	this.selectedIndex = 0;
};

/**
* Handles a selection from the smilies <select> menu
*/
GHOST_Text_Editor_Events.prototype.smilieselect_onchange = function(e)
{
	if (this.options[this.selectedIndex].value != '')
	{
		GHOST_Editor[this.editorid].insert_smilie(e,
			this.options[this.selectedIndex].value,
			this.options[this.selectedIndex].smiliepath,
			this.options[this.selectedIndex].smilieid
		);
	}
	this.selectedIndex = 0;
};

/**
* Handles a selection from the attachment <select> menu
*/
GHOST_Text_Editor_Events.prototype.attachselect_onchange = function(e)
{
	var arg = this.options[this.selectedIndex].value;
	if (arg != '')
	{
		GHOST_Editor[this.editorid].wrap_tags('attach', false, arg);
	}
	this.selectedIndex = 0;
};

/**
* Handles a mouse over event for the attachment <select> menu
*/
GHOST_Text_Editor_Events.prototype.attachselect_onmouseover = function(e)
{
	if (this.options.length <= 2)
	{
		GHOST_Editor[this.editorid].build_attachments_popup(this);
		return true;
	}
};

/**
* Handles a mouse event on a menu option
*/
GHOST_Text_Editor_Events.prototype.menuoption_onmouseevent = function(e)
{
	e = do_an_e(e);
	GHOST_Editor[this.editorid].button_context(this, e.type, 'menu');
};

/**
* Handles a click on a formatting option in the font/size menus
*/
GHOST_Text_Editor_Events.prototype.formatting_option_onclick = function(e)
{
	GHOST_Editor[this.editorid].format(e, this.cmd, this.firstChild.innerHTML);
	GHOST_menu.hide();
};

/**
* Handles a click on a color option in the color menu
*/
GHOST_Text_Editor_Events.prototype.coloroption_onclick = function(e)
{
	fetch_object(this.editorid + '_color_bar').style.backgroundColor = this.colorname;
	GHOST_Editor[this.editorid].format(e, this.cmd, this.colorname);
	GHOST_menu.hide();
};

/**
* Handles a click on the color instant-select button
*/
GHOST_Text_Editor_Events.prototype.colorout_onclick = function(e)
{
	e = do_an_e(e);
	GHOST_Editor[this.editorid].format(e, 'forecolor', fetch_object(this.editorid + '_color_bar').style.backgroundColor);
	return false;
};

 
 

/**
* Sets editwin.hasfocus = true on focus
*/
GHOST_Text_Editor_Events.prototype.editwin_onfocus = function(e)
{
	this.hasfocus = true;
};

/**
* Sets editwin.hasfocus = false on blur
*/
GHOST_Text_Editor_Events.prototype.editwin_onblur = function(e)
{
	this.hasfocus = false;
};

/**
* Sets context and hides menus on mouse clicks in the editor
*/
GHOST_Text_Editor_Events.prototype.editdoc_onmouseup = function(e)
{
	GHOST_Editor[this.editorid].set_context();
	if (GHOST_Editor[this.editorid].popupmode)
	{
		GHOST_menu.hide();
	}
};

/**
* Sets context on key presses in the editor
*/
GHOST_Text_Editor_Events.prototype.editdoc_onkeyup = function(e)
{
	GHOST_Editor[this.editorid].set_context();
};

 


/**
* Save editor contents to textarea so if we hit back / forward its not lost
* Only appears to work with Firefox at the moment
*/
function save_iframe_to_textarea()
{
	for (var editorid in GHOST_Editor)
	{
		if (GHOST_Editor[editorid].wysiwyg_mode && GHOST_Editor[editorid].initialized)
		{
			GHOST_Editor[editorid].textobj.value = GHOST_Editor[editorid].get_editor_contents();
		}
	}
}

if (window.attachEvent)
{
	window.attachEvent('onbeforeunload', save_iframe_to_textarea);
}
else if(window.addEventListener)
{
	window.addEventListener('unload', save_iframe_to_textarea, true);
}


// #############################################################################
// Generic global editor variables

// خصائص الخط
var contextcontrols = new Array(
	'bold',
	'italic',
	'underline',
	'justifyleft',
	'justifycenter',
	'justifyright',
	'justifyjustify',
	'insertorderedlist',
	'insertunorderedlist'
);

// الوان النص 
var coloroptions = new Array();
coloroptions = {
	'#000000' : 'Black',
	'#A0522D' : 'Sienna',
	'#556B2F' : 'DarkOliveGreen',
	'#006400' : 'DarkGreen',
	'#483D8B' : 'DarkSlateBlue',
	'#000080' : 'Navy',
	'#4B0082' : 'Indigo',
	'#2F4F4F' : 'DarkSlateGray',
	'#8B0000' : 'DarkRed',
	'#FF8C00' : 'DarkOrange',
	'#808000' : 'Olive',
	'#008000' : 'Green',
	'#008080' : 'Teal',
	'#0000FF' : 'Blue',
	'#708090' : 'SlateGray',
	'#696969' : 'DimGray',
	'#FF0000' : 'Red',
	'#F4A460' : 'SandyBrown',
	'#9ACD32' : 'YellowGreen',
	'#2E8B57' : 'SeaGreen',
	'#48D1CC' : 'MediumTurquoise',
	'#4169E1' : 'RoyalBlue',
	'#800080' : 'Purple',
	'#808080' : 'Gray',
	'#FF00FF' : 'Magenta',
	'#FFA500' : 'Orange',
	'#FFFF00' : 'Yellow',
	'#00FF00' : 'Lime',
	'#00FFFF' : 'Cyan',
	'#00BFFF' : 'DeepSkyBlue',
	'#9932CC' : 'DarkOrchid',
	'#C0C0C0' : 'Silver',
	'#FFC0CB' : 'Pink',
	'#F5DEB3' : 'Wheat',
	'#FFFACD' : 'LemonChiffon',
	'#98FB98' : 'PaleGreen',
	'#AFEEEE' : 'PaleTurquoise',
	'#ADD8E6' : 'LightBlue',
	'#DDA0DD' : 'Plum',
	'#FFFFFF' : 'White'
};

// #############################################################################
// GHOST_History
// #############################################################################

function GHOST_History()
{
	this.cursor = -1;
	this.stack = new Array();
}

// =============================================================================
// GHOST_History methods

GHOST_History.prototype.move_cursor = function(increment)
{
	var test = this.cursor + increment;
	if (test >= 0 && this.stack[test] != null && typeof this.stack[test] != 'undefined')
	{
		this.cursor += increment;
	}
};

GHOST_History.prototype.add_snapshot = function(str)
{
	if (this.stack[this.cursor] == str)
	{
		return;
	}
	else
	{
		this.cursor++;
		this.stack[this.cursor] = str;

		if (typeof this.stack[this.cursor + 1] != 'undefined')
		{
			this.stack[this.cursor + 1] = null;
		}
	}
};

GHOST_History.prototype.get_snapshot = function()
{
	if (typeof this.stack[this.cursor] != 'undefined' && this.stack[this.cursor] != null)
	{
		return this.stack[this.cursor];
	}
	else
	{
		return false;
	}
};

/*======================================================================*\
|| ####################################################################
|| # Downloaded: 10:27, Sat Dec 5th 2005
|| # CVS: $RCSfile: GHOST_textedit.js,v $ - $Revision: 1.50 $
|| ####################################################################
\*======================================================================*/