/**
 * @author andrew
 * 
 * This file contains most of the javascript code to insert a ckeditor instance and perform associated functions such as saving content etc
 * There is no need to customise the ckeditor folder - except to disable the 'image' plugin which I haven't found a way to disable in code. This is simply a matter of renaming or deleting the ckeditor/pluigins/image folder. 
 * 
 * 
 */

	var editorInstance = false;
	var $contentContainer;
	var $ckeditorToolbar;
	var $blogToolbar;	
	var initialized = false;
	var savedContent = '';	//only these saved changes will be displayed when the editor is destroyed
	var contentId;
	
	//inserts a CK editor instance to replace the specified element id or object
	function insertEditor(id) {

		//validate the content id and get the content object
		switch (typeof id) {
			case 'undefined':
				alert('the content id or object was not supplied');
				return false;
			
			case 'object':
				$contentContainer = jQuery(id);
				//ensure that the element to be edited exists
				if (!$contentContainer.length) {
					alert('the specified content object does not exist');
					return false;
				}
				id = $contentContainer.attr('id');
				break;
				
			case 'string':
				$contentContainer = jQuery('#' + id);
				if (!$contentContainer.length) {
					alert('the specified content id does not exist');
					return false;
				}
		}

		
		if (id == contentId) {
			return;		//the editor is already open on this content
		} else {
			contentId = id;	//we'll need this for the save function 
		}	
		
		//only one editor instance permitted per page
		if (editorInstance) {
			// Destroy the editor.
			editorInstance.destroy();
			editorInstance = false;
			initialized = false;
		}

		
		//determine the initial dimensions of the ckeditor
		var height = $contentContainer.height();
		height = (height > 50) ? height : 100;	//min content height (takes care of empty content
			
		//hide/reveal the appropriate page elements for edit mode
		jQuery('.hideForEdit').css('visibility', 'hidden');
		jQuery('.showForEdit').css('visibility', 'visible');


		//create a textarea within a form to contain the content before replacing it with a ckeditor instance.  This is necessary for the save button to work.
		savedContent = $contentContainer.html();	//get the content inside the specified element
		savedContent = (jQuery.trim(savedContent).length) ? savedContent : 'Sample Content';	//This helps orientate the user for new content
		$contentContainer.html('<textarea id="replaceMe" name="replaceMe" style="height:'+height+'">'+savedContent+'</textarea>');


		//create a container for the detached shared toolbar
		if (!jQuery('#ckeditorToolbar').length) {
			jQuery('body').append('<div id="ckeditorToolbar"></div>');
			
			//set global ckeditor toolbar object
			$ckeditorToolbar = jQuery('#ckeditorToolbar');
		}

		//initialize the blog toolbar if it exists
		if ($blogToolbar == undefined) {
			//set global ckeditor toolbar object
			$blogToolbar = jQuery('#blogToolbar');
		}
		
		//prepare toolbars to fade in gracefully
		$ckeditorToolbar.add($blogToolbar).css({
			'opacity': 0,
			'display': '',
			'position': 'fixed',
			'visibility': 'visible',
			'top': $contentContainer.offset().top - jQuery(window).scrollTop() + 'px',
			'left': $contentContainer.offset().left + 'px'
		});	 
		

		//create the list of stylesheets by seaching the page <head> tag  
		var stylesheets = new Array();
		var i=0;
		jQuery('head > link[rel*="style"]').each(function()
        {
           	stylesheets[i] = this.href;
			i++;
        });
		stylesheets[i] = base_url+'css/ckeditor.css';


		//replace the <textarea id="replaceMe"> with an ckeditor instance (with specific attributes)
		CKEDITOR.replace('replaceMe', {
			customConfig : '',	//don't load the config file - we're going to set config right here
			removePlugins : 'elementspath,scayt,menubutton,image,forms',	//hide status bar, spell checker, and built in image dialog (scayt,menubutton,image,forms all affect the image dialog) ;
			//our custom image dialogs are much better than the built-in plugin.  Must also delete/rename the folder: ckeditor/plugins/image
			extraPlugins : 'ckeditor_image',	//built-in autogrow now works, use our custom (user friendly image dialog)
			toolbar_Full : 
			[
				['Source'],['ShowBlocks'],
				['Cut','Copy','Paste','PasteText','PasteFromWord','-'],		//removed 'SpellChecker'
				['Undo','Redo'],
				'/',
				['Format','-','Bold','Italic','Underline','Strike','Subscript','Superscript','TextColor','RemoveFormat'],
				'/',
				['NumberedList','BulletedList','-','Outdent','Indent'],
				['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
				'/',
				['Link','Unlink','Anchor'],
				['ckeditor_image','Flash','Table','HorizontalRule','SpecialChar'],	//'Image', 
				
			],
			sharedSpaces :  //detaches the toolbar(top) & status bar(bottom) into the specified div and allows multiple content to share the toolbar & status bar 
			{
//				bottom : 'statusBar',	//we don't use this
				top : 'ckeditorToolbar'
			},
			baseHref : base_url,	
			uiColor : 'transparent',
			contentsCss : stylesheets,
			resize_enabled : false,
			toolbarCanCollapse : false,
			tabIndex : 4,	//number of spaces to insert on tab key
			toolbarStartupExpanded : false,
			height : height,
			minHeight : 300,		//seems to be ignored
//			filebrowserBrowseUrl: base_url + 'kfmFileManager/index.php'		//filemanager plugin
		} );

		//get the new editor instance
		editorInstance = CKEDITOR.instances.replaceMe;
	

		//float the toolbar when the editor gets focus 
		editorInstance.on( 'instanceReady', function() {
			if (!initialized) {	//only do this once
				initialized = true;

				jQuery('.cke_contents > iframe').css('background', 'transparent none no-repeat');	//undo editor iframe's background color which defaults to white
				jQuery('.cke_wrapper').css('background', 'transparent none no-repeat');	//remove the kama skin background image

				//determine the position of the content
				var contentContainerHeight = $contentContainer.height();
				var contentContainerWidth = $contentContainer.width();
				var contentContainerTop = $contentContainer.offset().top - jQuery(window).scrollTop();
				var contentContainerLeft = $contentContainer.offset().left;
				var contentContainerRight = jQuery(document).width() - contentContainerWidth - contentContainerLeft;
				var contentContainerBottom = jQuery(document).height() - contentContainerTop - contentContainerHeight;
				var windowTop = jQuery(window).scrollTop();

				//determine the size of the toolbar(s)
				var toolbarHeight = 140;	//TODO compute these as the greater of the ckeditor & blogToolbar
				var toolbarWidth = 340;	//TODO compute this
				var toolbarMargin = 20;
				var numToolbars = ($blogToolbar.length) ? 2 : 1;
				
				var ckeditorToolbarTop;
				var ckeditorToolbarLeft;
				var blogToolbarTop;
				var blogToolbarLeft;
				
				//there are 4 possible positions for the toolbar(s): left margin, right margin, top centre, bottom centre (in order of desirability)
				
				//is there space on the left side of the content?
				if (contentContainerLeft > toolbarWidth) {
					ckeditorToolbarTop = jQuery(window).height() / (numToolbars + 2);
					ckeditorToolbarLeft = blogToolbarLeft = (contentContainerLeft - toolbarWidth) / 2;
					blogToolbarTop = ckeditorToolbarTop + toolbarHeight + toolbarMargin;
					
				//else on the right side of the content?	
				} else if (contentContainerRight > toolbarWidth) {
					ckeditorToolbarTop = jQuery(window).height() / (numToolbars + 2);
					ckeditorToolbarLeft = blogToolbarLeft = contentContainerLeft + contentContainerWidth + ((contentContainerRight - toolbarWidth) / 2);
					blogToolbarTop = ckeditorToolbarTop + toolbarHeight + toolbarMargin;
					
				//else above the content?
				} else if (contentContainerTop > toolbarHeight || contentContainerTop > contentContainerBottom) {
					ckeditorToolbarTop = blogToolbarTop = toolbarMargin;
					ckeditorToolbarLeft = contentContainerLeft;
					blogToolbarLeft = ckeditorToolbarLeft + toolbarWidth + toolbarMargin;

				//else below the content?
				} else {
					ckeditorToolbarTop = blogToolbarTop = jQuery(window).height() - toolbarHeight - toolbarMargin;
					ckeditorToolbarLeft = contentContainerLeft;
					blogToolbarLeft = ckeditorToolbarLeft + toolbarWidth + toolbarMargin;
				}

				
				//position the ckeditor toolbar				
				$ckeditorToolbar.animate({
					'top': ckeditorToolbarTop+'px',
					'left': ckeditorToolbarLeft+'px',
					'opacity': 1.0
				}, 2000).draggable();

				//determine where to locate the blog toolbar
				$blogToolbar.animate({
					'top': blogToolbarTop + 'px',
					'left': blogToolbarLeft + 'px',
					'opacity': 1.0
				}, 2000).draggable();
		

				//customize editors kama skin 
				$ckeditorToolbar.find('span.cke_skin_kama').css({
					'border-color': '#554',
				});

				
				//show the toolbox and add the close and save buttons, the save dialog, and server result box
				var toolbox = jQuery('.cke_toolbox');
				toolbox.css('display', '');
				toolbox.prepend('<img id="ckeditorCloseButton" class="jsHover" src="'+base_url+'img/closeButton.png" style="height:30px; margin:-25px; float:right; cursor:pointer" onclick="quitCKEditor();" title="Quit editor">');
				jsHover();	//setup close button rollover effect
				toolbox.append('<img id="ckeditorSaveButton" title="Save Your Edits" src="'+base_url+'img/saveButton.png" style="opacity:0.5; height:25px; margin:0 5px 0 20px; float:right; cursor:pointer" onclick="saveEditorContents();" onmouseover="onContentChange()">');
				var resultLeft = toolbox.width() + 15;
				toolbox.append('<div style="position:absolute; bottom:5px; left:'+resultLeft+'px"><span id="ckeditorResult"></span></div>');

				//capture changes to the content
				editorInstance.on( 'selectionChange', function() {onContentChange();});
				
				//setup the toggle section break button visibility
				sectionBreakExists();
				
			}
		});
	}
	



	function onContentChange() {
		if (!editorInstance.checkDirty()) {
			jQuery('#ckeditorSaveButton').css('opacity', '0.5');	//nothing to save
			return;
		}
		jQuery('#ckeditorSaveButton').css('opacity', '1.0');	//awaken save button



	//replace any marked thumbnail images (dragged from the image manager) with their high-quality counterpart
	//wrap marked mime images (representing downloadable files) with a download link  

		//TODO replace what follows with the direct jQuery manipulation of the editor area and have this 
		//handle mime thumbnails also
		
		ckeditorDocument = editorInstance.document.$;	//this must be gotten fresh because it can be lost when switching editor between source/edit modes 
			
		var images = ckeditorDocument.getElementsByTagName('img');
		if (!images.length) {return;}	//no images found
		
		var url;
		
		jQuery.each(images, function() {

			url = replaceThumbnail(jQuery(this).attr('src'));	//the original uncompressed image/file

			//convert .linkThumbnail into clickable download links
			jQuery(this).filter('.linkThumbnail').each(function(){
				convertImageToLink(jQuery(this), url);
				jQuery(this).css({
					'height': '60px',
					'vertical-align': 'text-bottom',
					'display': 'inline',
					'float': 'none'
				})
				.removeAttr('ondblclick')
				.removeAttr('_cke_pa_ondblclick')	//ckeditor renames ondblclick attribute while editing
				.removeClass('linkThumbnail');		//remove class to prevent this operation from repeating endlessly
			});

			//convert .replaceThumbnail into full-size images with default settings
			jQuery(this).filter('.replaceThumbnail').each(function() {
				jQuery(this).css({
					'width': '50%',
					'height': 'auto'
				})
				.attr('src', url)
				.attr('title', '')					//the thumbnail title is the filename, which is inapropriate for the fullsize image
				.removeAttr('_cke_saved_src')
				.removeAttr('ondblclick')
				.removeAttr('_cke_pa_ondblclick')	//ckeditor renames ondblclick attribute while editing
				.removeClass('replaceThumbnail');	//remove class to prevent this operation from repeating endlessly
			});
		});
		
		
		forceEncloseFloats();	//the ckeditor does autogrow to encompass floating images.  This function appends a final invisible <hr> element which fixes this
	}
	



	//the editor autogrow doesn't encompass floating images.  This function appends a final invisible <hr> element to fix this 
	function forceEncloseFloats() {
		//ensure that there's always an invisible "<hr />" at the end of the document to force the ckeditor to enclose floating images 
		var editorBody = editorInstance.document.$.body;
		var lastElement = editorBody.lastChild;
		if ((lastElement.tagName != 'HR') && (lastElement.innerHTML != '<br>')) {		//the <br> check is because innerHTML seems to erroneously return this - even when the last element is actually an <hr>
			//append a final invisible <hr/>
			var newElement = document.createElement('hr');
			newElement.style.visibility = 'hidden';
			newElement.style.margin = '0px';
			editorBody.appendChild(newElement);
log('added final hr', editorBody.lastChild.tagName)

			//remove all but the final hr element
			var hrElements = editorInstance.document.$.getElementsByTagName('hr');
			for (i = 0; i < (hrElements.length-1); i++) {
	   			if (hrElements[i].style.visibility.toLowerCase() == 'hidden') {
					jQuery(hrElements[i]).remove();
				}
			}
		}
	} 

	

	//insert the image (file) into the ckeditor cursor - otherwise send it to the server
	function ckeditorInsertImage(url) {
		var html;
		
		//if a ckeditor instance is open then insert the image/file at the cursor
		if (editorInstance) {
			var originalFile = replaceThumbnail(url);	//if the image url is a thumbnail then rename it to the original image
			var filename = originalFile.split('/');
			filename = filename[filename.length-1];

			//images get displayed in an <img> tag, files (mime thumbnails) are displayed as links
			if (url.indexOf('_mime.jpg') != -1) {
				//it's a mime image thumbnail of a real file - configure it for onclick downloading
				html = '<a href="'+originalFile+'" title="Download '+filename+'"><img src="' + url + '" style="height: 60px; vertical-align:text-bottom; display:inline"/></a>'
			} else {
				//if it's an image thumbnail then insert the full-size image with default settings (float:left width:50% etc)
				var extension = filename.split('.');
				extension = extension[extension.length - 1];

				switch (extension) {
					case 'jpg':
					case 'jpeg':
					case 'png':
					case 'gif':
					case 'tif':
					case 'bmp': 
						html = '<img src="' + originalFile + '" style="width: 50%; float: left;"/>';
						break;
					default:
						//it's a downloadable file - link it
						html = '<a href="'+originalFile+'" title="Download '+filename+'">'+filename+'</a>'
				}
			}

			editorInstance.insertHtml(html);
//			closePopupDialogs();		//close any open dialogs
			return true;
		} else {
			return false;
		}
	}
	
	
	
	
	
	function saveEditorContents() {
		if (editorInstance.checkDirty()) {
			savedContent = editorInstance.getData();
			var encodedContent = savedContent.myEncode();
			Post.Send('contentId=' + contentId + '&content=' + encodedContent, base_url + 'dataserver/ajaxSaveContent');
			editorInstance.resetDirty();
		}
		jQuery('#ckeditorSaveButton').css('opacity', '0.5');
	}






	//quit any open editor - prompt to save unsaved edits, show/hide the appropriate page elements 
	function quitCKEditor() {
		if (!editorInstance) {
			return;
		}

		//if the content is unsaved prompt to save (options: save, discard, cancel)
		if (editorInstance.checkDirty()) {
			//create the save dialog placeholder
			jQuery('.cke_toolbox').append('<div id="saveDialog" title="Save your Work?"><p>You have unsaved edits!</p></div>');
			
			jQuery("#saveDialog").dialog({
				resizable: false,
				modal: true,
				buttons: {
					'Save': function() {
						saveEditorContents();
						$(this).dialog('close');
						forceQuitCKEditor();
					},
					'Don\'t Save': function() {
						$(this).dialog('close');
						forceQuitCKEditor();
					}
				}
			});
			
		} else {
			forceQuitCKEditor();	//no edits to save - just quit editor
		}
		
		return 'wait';	//this is used to prevent fully ajax systems like the wiki from navigating to new content without prompting the user to confirm
	}


	//this will destroy the editor regardless if edits have been saved or not 
	function forceQuitCKEditor() {
		if (!editorInstance) {
			return;
		}
		
		// Destroy the editor.
		editorInstance.destroy();
		editorInstance = false;
		initialized = false;
		contentId = false;

		savedContent = (savedContent == 'Sample Content') ? '' : savedContent;	//remove default sample content

		$contentContainer.html(savedContent);	//restore the content to the original display element

		//close any open dialogs
		closePopupDialogs();

		//hide/reveal the appropriate page elements for edit mode
		jQuery('.hideForEdit').css('visibility', 'visible');
		jQuery('.showForEdit').css('visibility', 'hidden');
		$blogToolbar.css('opacity', 0);	//this prevents the ghosting that appears when the blogToolbar reappears
	}


	
	


	function sectionBreakExists() {
		var regex = new RegExp('<hr class="sectionBreak"[^>]*\/>', 'gi');
		var content = editorInstance.getData();

		//check for section breaks
		if (content.match(regex)) {
			jQuery('#removeSectionBreak').css('display', '');
			jQuery('#insertSectionBreak').css('display', 'none');
			return true;
		} else {
			jQuery('#removeSectionBreak').css('display', 'none');
			jQuery('#insertSectionBreak').css('display', '');
			return false;
		}

	}




	function insertSectionBreak() {
		removeSectionBreak();	//remove any existing section breaks
		
		editorInstance.insertHtml('<hr class="sectionBreak"/>');
		jQuery('#removeSectionBreak').css('display', '');
		jQuery('#insertSectionBreak').css('display', 'none');
	}

	//remove any section break elements
	function removeSectionBreak() {
		jQuery('#removeSectionBreak').css('display', 'none');	//hide remove section break button

		//remove any section break elements
		var classElements = editorInstance.document.$.getElementsByTagName('hr');
		for (i = 0; i < classElements.length; i++) {
   			if (classElements[i].className == 'sectionBreak') {
				jQuery(classElements[i]).remove();
			}
		}

		jQuery('#insertSectionBreak').css('display', '');	//show insert section break button
	}







	//prompt user to save changes on page unload
	function sc_ask()  {
	   if (editorInstance && editorInstance.checkDirty()){
			return false;	//browser will now ask for confirmation before navigating away 
	   }
	}
	window.onbeforeunload = sc_ask;
