/**
 * Wrapper for CKEditor HTML WYSIWYG library.
 */

var ss = ss || {};
ss.editorWrappers = ss.editorWrappers || {};
ss.editorWrappers.CKEditor = (function() {

	var instance;

	return {
		init: function(config) {
			if(!ss.editorWrappers.CKEditor.initialized) {
				ss.editorWrappers.CKEditor.initialized = true;
			}
		},
		/**
		 * @return Mixed Implementation specific object
		 */
		getInstance: function() {
			return this.instance;
		},
		/**
		 * Invoked when a content-modifying UI is opened.
		 */
		onopen: function() {
		},
		/**
		 * Invoked when a content-modifying UI is closed.
		 */
		onclose: function() {
		},
		/**
		 * Write the HTML back to the original text area field.
		 */
		save: function() {
			this.getInstance().updateElement();
		},
		/**
		 * Create a new instance based on a textarea field.
		 *
		 * Please proxy the events from your editor implementation into JS events
		 * on the textarea field. For events that do not map directly, use the 
		 * following naming scheme: editor<event>.
		 *
		 * @param String
		 * @param Object Implementation specific configuration
		 * @param Function
		 */
		create: function(domID, config) {
			// TODO Replace TinyMCE config with CKEditor config
			config = {
				extraPlugins: 'ssbuttons',
				removeButtons: 'Image,Link'
			};

			this.instance = CKEDITOR.replace(domID, config);

			// TODO Trigger jQuery changetracker as needed
		},
		/**
		 * Redraw the editor contents
		 */
		repaint: function() {
			// tinyMCE.execCommand("mceRepaint");
		},
		/**
		 * @return boolean
		 */
		isDirty: function() {
			return this.getInstance().checkDirty();
		},
		/**
		 * HTML representation of the edited content.
		 * 
		 * Returns: {String}
		 */
		getContent: function() {
			return this.getInstance().getData();
		},
		/**
		 * DOM tree of the edited content
		 * 
		 * Returns: DOMElement
		 */
		getDOM: function() {
			return this.getInstance().document.$;
		},
		/**
		 * Returns: DOMElement
		 */
		getContainer: function() {
			return this.getInstance().container.$;
		},
		/**
		 * Get the closest node matching the current selection.
		 * 
		 * Returns: {jQuery} DOMElement
		 */
		getSelectedNode: function() {
			return this.getInstance().getSelection().getSelectedElement();
		},
		/**
		 * Select the given node within the editor DOM
		 * 
		 * Parameters: {DOMElement}
		 */
		selectNode: function(node) {
			this.getInstance().getSelection().selectElement(node);
		},
		/**
		 * Replace entire content
		 * 
		 * @param String HTML
		 * @param Object opts
		 */
		setContent: function(html, opts) {
			// TODO Replace rather than insert
			this.getInstance().insertHtml(html, 'html');
		},
		/**
		 * Insert content at the current caret position
		 * 
		 * @param String HTML
		 */
		insertContent: function(html, opts) {
			this.getInstance().insertHtml(html, 'html');
		},
		/**
		 * Replace currently selected content
		 * 
		 * @param {String} html
		 */
		replaceContent: function(html, opts) {
			// TODO Replace rather than insert
			this.getInstance().insertHtml(html, 'html');
		},
		/**
		 * Insert or update a link in the content area (based on current editor selection)
		 * 
		 * Parameters: {Object} attrs
		 */
		insertLink: function(attrs, opts) {
			// this.getInstance().execCommand("mceInsertLink", false, attrs, opts);
		},
		/**
		 * Remove the link from the currently selected node (if any).
		 */
		removeLink: function() {
			// this.getInstance().execCommand('unlink', false);
		},
		/**
		 * Strip any editor-specific notation from link in order to make it presentable in the UI.
		 * 
		 * Parameters: 
		 *  {Object} 
		 *  {DOMElement}
		 */
		cleanLink: function(href, node) {
			// TODO
			return href;

			// var cb = tinyMCE.settings['urlconverter_callback'];
			// if(cb) href = eval(cb + "(href, node, true);");

			// // Turn into relative
			// if(href.match(new RegExp('^' + tinyMCE.settings['document_base_url'] + '(.*)$'))) {
			// 	href = RegExp.$1;
			// }
			
			// // Get rid of TinyMCE's temporary URLs
			// if(href.match(/^javascript:\s*mctmp/)) href = '';

			// return href;
		},
		/**
		 * Creates a bookmark for the currently selected range,
		 * which can be used to reselect this range at a later point.
		 * @return {mixed}
		 */
		createBookmark: function() {
			return this.getInstance().getSelection().createBookmarks();
		},
		/**
		 * Selects a bookmarked range previously saved through createBookmark().
		 * @param  {mixed} bookmark
		 */
		moveToBookmark: function(bookmark) {
			this.getInstance().getSelection().selectBookmarks(bookmark);
			// this.getInstance().focus();
		},
		/**
		 * Removes any selection & de-focuses this editor
		 */
		blur: function() {
			// this.getInstance().selection.collapse();
		},
		/**
		 * Add new undo point with the current DOM content.
		 */
		addUndo: function() {
			// this.getInstance().undoManager.add();
		}
	};
});