define(['cla_angular', './html_editor.html'], function (angular, template) {
	var moduleName = 'cla.core.html_editor';
	try {
		var module = angular.module(moduleName);
	} catch(err) {
		// named module does not exist, so create one
		var module = angular.module(moduleName, []);
	}

	module.directive('claHtmlEditor', htmlEditor);

	htmlEditor.$inject = ['$timeout'];
	function htmlEditor($timeout) {
		var link = function(scope, iElement, iAttrs, ctrl)
		{
			// Make sure this only gets included once. Apparently it doesn't like require
			if (window.CKEDITOR === undefined)
			{
				$('head').append('<script src="/lib/ckeditor/ckeditor.js"></script>' +
					'<script type="text/javascript" src="/lib/ckfinder/ckfinder.js"></script>\n' +
					'<script type="text/javascript" src="/lib/ckeditor/adapters/jquery.js"></script>\n' +
					'<script type="text/javascript">\n' +
					'  jQuery(function(){\n' +
					'    CKEDITOR.disableAutoInline = true;\n' +
					'  });\n' +
					'</script>');
			}

			// Initialise control token
			scope.internalControl = scope.control || {};
			scope.application = scope.application || 'pages_text_component';

			scope.changeFunc = function()
			{
				var value = ctrl.editorObj.getData();
				angular.element(iElement).find('textarea').html(value);
				ctrl.$setViewValue(value);
			};

			// Create the CKEdit instance
			scope.internalControl.onOpen = function()
			{
				var $textarea = angular.element(iElement).find('textarea');

				// CKEditor is bad at syncing data between the source, normal view and textarea so provide a way for
				// outside controls to prompt us for that.
				$textarea.on('do-sync', scope.changeFunc);

				// CKEditor can open popups inside popups so keep count of how many are open to suppress the claro popover auto-close
				ctrl.popupRefCount = 0;

				ctrl.editorObj = ctrl.ckeditor = window.CKEDITOR.replace($textarea[0], {customConfig: '/intranet/common/ckeditor/editor_config.php?application=' + scope.application});
				// Note ctrl.editorObj is a DOM element, not a jQuery object

				ctrl.editorObj.on('instanceReady', function()
				{
					ctrl.editorObj.on('change', scope.changeFunc);
					ctrl.editorObj.on('key', scope.changeFunc);
					ctrl.editorObj.on('dataReady', scope.changeFunc);
					ctrl.editorObj.on('paste', scope.changeFunc);
					ctrl.editorObj.on('pasteState', scope.changeFunc);
					ctrl.editorObj.on('blur', scope.changeFunc);
					ctrl.editorObj.on('selectionChange', scope.changeFunc);
				});

				ctrl.editorObj.on('dialogShow', function()
				{
					ctrl.popupRefCount++;
					if (ctrl.popupRefCount === 1)
						window.cla.pagesEdit.popoverAutoClose = false;
				});
				ctrl.editorObj.on('dialogHide', function()
				{
					$timeout(function()
					{
						ctrl.popupRefCount--;
						if (ctrl.popupRefCount === 0)
							window.cla.pagesEdit.popoverAutoClose = true;
					}, 0);
				});
			};

			// Destroy the CKEdit instance
			scope.internalControl.onClose = function()
			{
				scope.changeFunc();

				ctrl.editorObj.removeAllListeners();
				CKEDITOR.instances[ctrl.editorObj.name].destroy(true);
				ctrl.editorObj.container.remove();
				ctrl.editorObj = null;
			};
		};

		return {
			restrict: 'E',
			require: '^ngModel',
			templateUrl: template,
			scope: {
				ngModel: '=',
				control: '=',
				application: '@?'
			},
			link: link
		};
	}
});
