/***************************************************************
*  Copyright notice
*
*  (c) 2007-2010 Tobias Liebig <mail_typo3@etobi.de>
*  All rights reserved
*
*  This script is part of the TYPO3 project. The TYPO3 project is
*  free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  The GNU General Public License can be found at
*  http://www.gnu.org/copyleft/gpl.html.
*  A copy is found in the textfile GPL.txt and important notices to the license
*  from the author is found in LICENSE.txt distributed with these scripts.
*
*
*  This script is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/* t3editor.js uses the Codemirror editor.
 */

T3editor = T3editor || {};

// collection of all t3editor instances on the current page
T3editor.instances = {};

// path to the editor ext dir
// can be overwritten in class.tx_t3editor.php
T3editor.PATH_t3e = "../../../sysext/t3editor/";
T3editor.PATH_codemirror = "../../../contrib/codemirror/js/";


function T3editor(textarea) {
	var self = this;

		// memorize the textarea
	this.textarea = $(textarea);
	var textareaDim = $(this.textarea).getDimensions();
	this.textarea.hide();

		// outer wrap around the whole t3editor
	this.outerdiv = new Element("DIV", {
		"class": "t3e_wrap"
	});

		// place the div before the textarea
	this.textarea.parentNode.insertBefore(this.outerdiv, $(this.textarea));

	this.outerdiv.update(T3editor.template);

	this.modalOverlay = this.outerdiv.down('.t3e_modalOverlay');
	this.modalOverlay.setStyle(this.outerdiv.getDimensions());
	this.modalOverlay.setStyle({
		opacity: 0.8
	});

	this.mirror_wrap = this.outerdiv.down('.t3e_iframe_wrap');
	this.statusbar_wrap = this.outerdiv.down('.t3e_statusbar_wrap');
	this.statusbar_title = this.outerdiv.down('.t3e_statusbar_title');
	this.statusbar_status = this.outerdiv.down('.t3e_statusbar_status');

	this.statusbar_title.update( this.textarea.readAttribute('alt') );
	this.statusbar_status.update( '' );

		// setting options
	var options = {
		height: ( textareaDim.height ) + 'px',
		width: ( textareaDim.width + this.adjustWidth ) + 'px',
		content: $(this.textarea).value,
		parserfile: T3editor.parserfile,
		stylesheet: T3editor.stylesheet,
		path: T3editor.PATH_codemirror,
		outerEditor: this,
		saveFunction: this.saveFunction.bind(this),
		initCallback: this.init.bind(this),
		autoMatchParens: true,
		lineNumbers: true,
		onChange: this.onChange.bind(this)
	};

		// get the editor
	this.mirror = new CodeMirror(this.mirror_wrap, options);
	$(this.outerdiv).fire('t3editor:init', {t3editor: this});
}

T3editor.prototype = {
		saveFunctionEvent: null,
		saveButtons: null,
		updateTextareaEvent: null,
		adjustWidth: -30,
		disabled: false,

		init: function() {
			var textareaDim = $(this.textarea).getDimensions();
			// hide the textarea
			this.textarea.hide();

			this.attachEvents();
			this.resize(textareaDim.width + this.adjustWidth, textareaDim.height );

			this.modalOverlay.hide();
			$(this.outerdiv).fire('t3editor:initFinished', {t3editor: this});
		},

		attachEvents: function() {
			var that = this;

			// get the form object
			var form = $(this.textarea.form);
			this.saveButtons = form.getInputs('image', 'submit');

			// initialize ajax saving events
			this.saveFunctionEvent = this.saveFunction.bind(this);
			this.saveButtons.each(function(button) {
				Event.observe(button,'click',this.saveFunctionEvent);
			}.bind(this));

			this.updateTextareaEvent = this.updateTextarea.bind(this);

			Event.observe($(this.textarea.form), 'submit', this.updateTextareaEvent);

			Event.observe(this.mirror.win.document, 'keyup', function(event) {
				$(that.outerdiv).fire('t3editor:keyup', {t3editor: that, actualEvent: event});
			});
			Event.observe(this.mirror.win.document, 'keydown', function(event) {
				$(that.outerdiv).fire('t3editor:keydown', {t3editor: that, actualEvent: event});

				if ((event.ctrlKey || event.metaKey) && event.keyCode == 122) {
					that.toggleFullscreen();
					event.stop();
				}
			});
			Event.observe(this.mirror.win.document, 'click', function(event) {
				$(that.outerdiv).fire('t3editor:click', {t3editor: that, actualEvent: event});
			});
		},

		// indicates is content is modified and not safed yet
		textModified: false,

		// check if code in editor has been modified since last saving
		checkTextModified: function() {
			if (!this.textModified) {
				this.textModified = true;
			}
		},

		updateTextarea: function(event) {
			this.textarea.value = this.mirror.getCode();
		},

		onChange: function() {
			var that = this;
			this.checkTextModified();
			$(that.outerdiv).fire('t3editor:change', {t3editor: that});
		},

		saveFunction: function(event) {
			if (!T3editor.ajaxSavetype || T3editor.ajaxSavetype == '') {
				return;
			}
			this.modalOverlay.show();
			this.updateTextarea(event);

			if (event) {
				Event.stop(event);
			}

			var params = $(this.textarea.form).serialize(true);
			params = Object.extend( {t3editor_disableEditor: 'false'}, params);

			$(this.outerdiv).fire('t3editor:save', {parameters: params, t3editor: this});

		},

		// callback if saving was successful
		saveFunctionComplete: function(wasSuccessful) {
			if (wasSuccessful) {
				this.textModified = false;
			} else {
				alert(T3editor.lang.errorWhileSaving);
			}
			this.modalOverlay.hide();
		},

		// toggle between the textarea and t3editor
		toggleView: function(disable) {
			$(this.outerdiv).fire('t3editor:toggleView', {t3editor: this, disable: disable});
			this.disabled = disable;
			if (disable) {
				this.textarea.value = this.mirror.editor.getCode();
				this.outerdiv.hide();
				this.textarea.show();
				this.saveButtons.each(function(button) {
					Event.stopObserving(button,'click',this.saveFunctionEvent);
				}.bind(this));
				Event.stopObserving($(this.textarea.form), 'submit', this.updateTextareaEvent);

			} else {
				this.mirror.editor.importCode(this.textarea.value);
				this.textarea.hide();
				this.outerdiv.show();
				this.saveButtons.each(function(button) {
					this.saveFunctionEvent = this.saveFunction.bind(this);
					Event.observe(button,'click',this.saveFunctionEvent);
				}.bind(this));
				Event.observe($(this.textarea.form), 'submit', this.updateTextareaEvent);
			}
		},

		resize: function(width, height) {
			if (this.outerdiv) {
				newheight = (height - 1);
				newwidth = (width + 11);
				if (Prototype.Browser.IE) newwidth = newwidth + 8;

				$(this.outerdiv).setStyle({
					height: newheight + 'px',
					width: newwidth + 'px'
				});

				$(this.mirror_wrap.firstChild).setStyle({
					'height': ((height - 22) + 'px'),
					'width': ((width - 13) + 'px')
				});

				$(this.modalOverlay).setStyle(this.outerdiv.getDimensions());

			}

		},

		// toggle between normal view and fullscreen mode
		toggleFullscreen: function() {
			if (this.outerdiv.hasClassName('t3e_fullscreen')) {
				// turn fullscreen off

				// unhide the scrollbar of the body
				this.outerdiv.offsetParent.setStyle({
					overflow: ''
				});

				this.outerdiv.removeClassName('t3e_fullscreen');
				h = this.textarea.getDimensions().height;
				w = this.textarea.getDimensions().width;

			} else {
					// turn fullscreen on
				this.outerdiv.addClassName('t3e_fullscreen');
				h = this.outerdiv.offsetParent.getHeight();
				w = this.outerdiv.offsetParent.getWidth();

				// less scrollbar width
				w = w - 13;

				// hide the scrollbar of the body
				this.outerdiv.offsetParent.setStyle({
					overflow: 'hidden'
				});
				this.outerdiv.offsetParent.scrollTop = 0;
			}
			this.resize(w, h);
		}

} // T3editor.prototype


// ------------------------------------------------------------------------


/**
 * toggle between enhanced editor (t3editor) and simple textarea
 */
T3editor.toggleEditor = function(checkbox, index) {
	if (!Prototype.Browser.MobileSafari) {
		if (index == undefined) {
			if (top.TYPO3.BackendUserSettings) {
				top.TYPO3.BackendUserSettings.ExtDirect.set(
					'disableT3Editor',
					checkbox.checked,
					function(response) {}
				);
			}
			$$('textarea.t3editor').each(
				function(textarea, i) {
					T3editor.toggleEditor(checkbox, i);
				}
			);
		} else {
			if (T3editor.instances[index] != undefined) {
				var t3e = T3editor.instances[index];
				t3e.toggleView(checkbox.checked);
			} else if (!checkbox.checked) {
				var t3e = new T3editor($$('textarea.t3editor')[index], index);
				T3editor.instances[index] = t3e;
			}
		}
	}
}

// ------------------------------------------------------------------------

if (!Prototype.Browser.MobileSafari) {
	// everything ready: turn textarea's into fancy editors
	Event.observe(window, 'load',
		function() {
			$$('textarea.t3editor').each(
				function(textarea, i) {
					if ($('t3editor_disableEditor_' + (i + 1) + '_checkbox')
					&& !$('t3editor_disableEditor_' + (i + 1) + '_checkbox').checked) {
						var t3e = new T3editor(textarea);
						T3editor.instances[i] = t3e;
					}
				}
			);

			if (T3editor.ajaxSavetype != "") {
				Event.observe(document, 't3editor:save',
					function(event) {
						var params = Object.extend({
							ajaxID: "tx_t3editor::saveCode",
							t3editor_savetype: T3editor.ajaxSavetype
						}, event.memo.parameters);

						new Ajax.Request(
							T3editor.URL_typo3 + "ajax.php", {
								parameters: params,
								onComplete: function(ajaxrequest) {
									var wasSuccessful = ajaxrequest.status == 200
									&& ajaxrequest.headerJSON.result == true
									event.memo.t3editor.saveFunctionComplete(wasSuccessful);
								}
							}
						);
					}
				);
			}
		}
	);
}

