/*
	EzPz WYSIWYG Editor
	Copyright 2009 John Josef
	Depends on  * Color picker, Author: Stefan Petre www.eyecon.ro * for color pickers
	
	History
	-------
	v1.0 - Initial release
*/

;(function($){

	var bookmarkRange = null;
	
	$.ezpz = {
		original: {},
		editor: null,
		toolbar: null,
		iframe: null,
		content: '',
		defaults: {
			saveUrl: '',
			bold: true,
			italic: true,
			underline: true,
			fontSize: true,
			fontFamily: true,
			headings: true,
			image: true,
			video: true,
			link: true,
			unlink: true,
			ordlist: true,
			unordlist: true,
			color: true,
			background: true,
			html: false,
			width: 'auto',
			height: 'auto',
			mySizes: { '1': 'Very Small', '2': 'Small', '3': 'Normal', '4': 'Big', '5': 'Very Big' },
			myFonts: ['Arial', 'Courier', 'Georgia', 'Helvetica', 'Impact', 'sans-serif', 'serif', 'Tahoma', 'Times New Roman', 'Trebuchet MS', 'Verdana' ],
			myHeadings: { '<p>': 'Paragraph', '<h1>': 'Heading 1', '<h2>': 'Heading 2', '<h3>': 'Heading 3', '<h4>': 'Heading 4', '<h5>': 'Heading 5', 'clear': 'Clear' },
			allowUploads: true,
			uploadUrl: '',
			uploadDir: '',
			uploadRelativeDir: ''
		}
	};
	
	$.fn.extend({
		ezpz: function(settings){
			settings = $.extend({}, $.ezpz.defaults, settings);
			$.getScript('_assets/js/ajaxfileupload.js');
			$.getScript('_assets/js/colorpicker.js');
			var head = document.getElementsByTagName('head')[0];
			$(document.createElement('link'))
			    .attr({type: 'text/css', href: '_assets/css/colorpicker.css', rel: 'stylesheet', media: 'screen'})
    			.appendTo(head); 
			return this.each(function(){
				$.ezpz.original.copy = this;
				$.ezpz.original.element = this.tagName;
				$.ezpz.original.name = this.name;
				$.ezpz.original.id = this.id;
				$.ezpz.original.className = $(this).attr('class');
				
				content = $(this).html();
				$(this).before('<div class="ezpzEditor"></div>');
				$.ezpz.editor = $(this).prev('.ezpzEditor');
				editor = $.ezpz.editor;
				if(settings.width == 'auto')
					editor.width($(this).outerWidth());
				else
					editor.width(settings.width);
				if(settings.height != 'auto')
					editor.height(settings.height);
				editor.prepend('<div class="ezpzToolbar"></div>');
				$.ezpz.toolbar = editor.children().eq(0);
				toolbar = $.ezpz.toolbar;
				
				var width = editor.innerWidth();
				$.ezpz.iframe = document.createElement("iframe");
				iframe = $.ezpz.iframe;
        		iframe.frameBorder=0;
        		iframe.frameMargin=0;
        		iframe.framePadding=0;
        		iframe.height=200;
        		iframe.width=width;
				iframe.id = 'ezpz_'+$(this).attr('id');
				iframe.title = 'EzPz Editor';
				//editor.append('<br clear="all" />');
				
				editor.append(iframe);
				
				loadFrameBase(content);
				buildToolbar(settings);
				$(this).hide();
				
		        var iframeDoc = $(iframe.contentWindow.document);
		        
		        iframeDoc.mouseup(function(){ 
		        	
		            bookmarkRange = saveSelection();
		            return true;
		        });
		        iframeDoc.keyup(function(){ 
		            var body = $('body', iframeDoc);
		            if(body.scrollTop()>0)
		                iframe.height = Math.min(350, parseInt(iframe.height)+body.scrollTop());
		            return true;
		        });
				iframeDoc.bind('keypress', function(e) {
				        if(e.keyCode==13){

				        }
				});
			});
		},
		returnVal: function() {
		
		}
	});
	
	function getSelection(){
		var d = iframe.contentWindow.document;
		if(d.selection)
			return d.selection.type == "Text" ? d.selection : null;
		return null;
	}
	
	function saveSelection(){
		var sel = getSelection();
		if(sel)
		{
			if(sel.createRange) return sel.createRange();
			if(sel.rangeCount && sel.getRangeAt) return sel.getRangeAt(0);
		}
		return null;
	}
	
	function restoreSelection(rng){
		if(rng.select)
		{
			rng.select();
		}
		else 
		{
			var s = getSelection();
			if(s.removeAllRanges && s.addRange){
				s.removeAllRanges();
				s.addRange(rng);
			}
		}
	}
	
	function setCaretPosition(elemId, caretPos){
		var elem = iframe.contentWindow.document.getElementById(elemId);
		if(elem != null) {
			if(elem.createTextRange) {
				var range = elem.createTextRange();
				range.move('character', caretPos);
				range.select();
			}
			else {
				if(elem.selectionStart) {
					elem.focus();
					elem.setSelectionRange(caretPos, caretPos);
				}
				else
					elem.focus();
			}
		}
	}
	
	function loadFrameBase(frameContent){
		try {
            iframe.contentWindow.document.open();
            iframe.contentWindow.document.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html><head></head><body>'+frameContent+'</body></html>');
            iframe.contentWindow.document.close();
        } catch(error) {
            console.log(error)
        }
        if (document.contentEditable) {
            iframe.contentWindow.document.designMode = "On";
            return true;
        }
        else if (document.designMode != null) {
            try {
                iframe.contentWindow.document.designMode = "on";
                return true;
            } catch (error) {
            }
        }
        setTimeout(function(){loadFrameBase(frameContent)}, 100);
        return false;
	
	}
	
	function destroyEditor(){
		var check = confirm('Are you sure you wish to close the editor?');
		if(check)
		{
			$.ezpz.editor.remove();
			$($.ezpz.original.copy).show();
		}
	}
	
	function buildToolbar(settings){
		if(settings.fontSize){
			toolbar.append('<select class="fontSizeSelect"><option value="">Font Size</option></select>');
			$.each(settings.mySizes, function(i, val){
				$('.fontSizeSelect', toolbar).append('<option value="'+i+'">'+val+'</option>');
			});
			$('.fontSizeSelect', toolbar).change(function(){
				if($(this).children(':selected').eq(0).val() != '')
				{
					formatText('fontsize', $(this).children(':selected').eq(0).val());
				}
			});
		}
		if(settings.fontFamily){
			toolbar.append('<select class="fontFamilySelect"><option value="">Font Family</option></select>');
			$.each(settings.myFonts, function(){
				$('.fontFamilySelect', toolbar).append('<option value="'+this+'">'+this+'</option>');
			});
			$('.fontFamilySelect', toolbar).change(function(){
				if($(this).children(':selected').eq(0).val() != '')
				{
					formatText('fontname', $(this).children(':selected').eq(0).val());
				}
			});
		}
		if(settings.headings){
			toolbar.append('<select class="headingsSelect"><option value="">Format</option></select>');
			$.each(settings.myHeadings, function(i, val){
				$('.headingsSelect', toolbar).append('<option value="'+i+'">'+val+'</option>');
			});
			$('.headingsSelect', toolbar).change(function(){
				if($(this).children(':selected').eq(0).val() != '')
				{
					if($(this).children(':selected').eq(0).val() == 'clear')
					{
						formatText('removeformat');
						formatText('formatblock', '<p>');
						$(this).children().removeAttr('selected');
					}
					else
					{
						formatText('formatblock', $(this).children(':selected').eq(0).val());
					}
				}
			});
		}
		if(settings.bold){
			toolbar.append('<a href="javascript:;" class="boldTextButton" title="Bold Text">bold</a>');
			toolbar.children('.boldTextButton').click(function(){
				formatText('bold');
			});
		}
		if(settings.italic){
			toolbar.append('<a href="javascript:;" class="italicTextButton" title="Italicize Text">italic</a>');
			toolbar.children('.italicTextButton').click(function(){
				formatText('italic');
			});
		}
		if(settings.underline){
			toolbar.append('<a href="javascript:;" class="underlineTextButton" title="Underline Text">underline</a>');
			toolbar.children('.underlineTextButton').click(function(){
				formatText('underline');
			});
		}
		if(settings.image){
			toolbar.append('<a href="javascript:;" class="imageButton" title="Add Image">image</a>');
			toolbar.children('.imageButton').click(function(){
				if(!$('#imageSelect_'+$.ezpz.original.id, editor).html())
				{
					$(toolbar).after('<div class="imageSelect" id="imageSelect_'+$.ezpz.original.id+'">Image Upload </div>');
					var imageUpload = $('#imageSelect_'+$.ezpz.original.id);
					imageUpload.css('display', 'none');
					if(settings.uploadUrl == '')
					{
						imageUpload.html('Image Upload is misconfigured.');
					}
					else
					{
						imageUpload.html('<form action="'+settings.uploadUrl+'" method="post" id="ezpzImageForm"><label>Image Upload</label> <input type="file" name="imageFile" id="imageFile" /> <input type="submit" name="action" value="Upload" /> <input type="button" class="cancel" onclick="$(this).parent().parent().remove();" value="Cancel" /> <img id="uploadLoading" src="_assets/images/loading.gif" alt="Loading..." /></form>');
						$('#uploadLoading').hide();
					}
					
					$('#ezpzImageForm').submit(function(){
						$('#uploadLoading').ajaxStart(function(){
							$(this).show();
						}).ajaxComplete(function(){
							$(this).hide();
						});

						$.ajaxFileUpload({
							url: settings.uploadUrl, 
							secureuri: false,
							fileElementId: 'imageFile',
							fileDir: settings.uploadDir,
							relativeDir: settings.uploadRelativeDir,
							dataType: 'json',
							success: function (data, status){
								if(typeof(data.error) != 'undefined')
								{
									if(data.error != '')
									{
										alert(data.error);
									}else
									{
										alert(data.fileName+' was uploaded.');
										insertAtCarat('<img style="float: left;" src="'+data.filePath+'" alt="" />');
										//formatText('insertimage', data.filePath);
										
										$('#imageSelect_'+$.ezpz.original.id).remove();
									}
								}
							},
							error: function (data, status, e){
								alert(e);
							}
						});

						return false;
					});
					imageUpload.slideDown();
				}
			});
		}
		if(settings.video){
			toolbar.append('<a href="javascript:;" class="videoButton" title="Embed Content">video</a>');
			toolbar.children('.videoButton').click(function(){
				if(!$('#imageSelect_'+$.ezpz.original.id, editor).html())
				{
					$(toolbar).after('<div class="imageSelect" id="embedContent_'+$.ezpz.original.id+'">Embed Content </div>');
					var embedContent = $('#embedContent_'+$.ezpz.original.id);
					embedContent.css('display', 'none');
					embedContent.html('<form action="" method="post" id="ezpzEmbedForm"><label>Embed Content</label> <input type="text" name="embedHtml" /> <input type="submit" name="action" value="Insert Html" /> <input type="button" class="cancel" onclick="$(this).parent().parent().remove();" value="Cancel" /></form>');
					
					$('#ezpzEmbedForm').submit(function(){
						//$(iframe.contentWindow.document.body).append($('#ezpzEmbedForm input[name="embedHtml"]').val());
						insertAtCarat($('#ezpzEmbedForm input[name="embedHtml"]').val());
						$('#embedContent_'+$.ezpz.original.id).remove();
						return false;
					});
					embedContent.slideDown();
				}			
			});
		}
		if(settings.link){
			toolbar.append('<a href="javascript:;" class="linkButton" title="Add Link">link</a>');
			toolbar.children('.linkButton').click(function(){
				var link = prompt('Enter a URL', 'http://');
				if($.trim(link) != '')
					formatText('createlink', $.trim(link));
			});
		}
		if(settings.unlink){
			toolbar.append('<a href="javascript:;" class="unlinkButton" title="Unlink">list</a>');
			toolbar.children('.unlinkButton').click(function(){
				formatText('unlink');			
			});
		}
		if(settings.ordlist){
			toolbar.append('<a href="javascript:;" class="ordListButton" title="Ordered List">ordered list</a>');
			toolbar.children('.ordListButton').click(function(){
				formatText('insertorderedlist');			
			});
		}
		if(settings.unordlist){
			toolbar.append('<a href="javascript:;" class="unordListButton" title="Unordered List">unordered list</a>');
			toolbar.children('.unordListButton').click(function(){
				formatText('insertunorderedlist');			
			});
		}
		if(settings.color){
			toolbar.append('<a href="javascript:;" class="colorButton" title="Text Color">color</a>');
			toolbar.children('.colorButton').ColorPicker({
				onChange: function(hsb, hex, rgb, el) {
					if(bookmarkRange)
						restoreSelection(bookmarkRange);
					formatText('forecolor', '#'+hex);
				},
				onHide: function(colpkr) {
					if(bookmarkRange)
						restoreSelection(bookmarkRange);
				}
			});
		}
		if(settings.background){
			toolbar.append('<a href="javascript:;" class="backgroundButton" title="Highlight Color">highlight</a>');
			toolbar.children('.backgroundButton').ColorPicker({
				onChange: function(hsb, hex, rgb, el) {
					if(bookmarkRange)
						restoreSelection(bookmarkRange);
					if($.browser.msie || $.browser.safari)
						formatText('backcolor', hex);
					else
						formatText('hilitecolor', '#'+hex);
				},
				onHide: function(colpkr) {
					if(bookmarkRange)
						restoreSelection(bookmarkRange);
				}
			});
		}
		if(settings.html){
			toolbar.append('<a href="javascript:;" class="htmlButton" title="Source/Html">html</a>');
			toolbar.children('.htmlButton').click(function(){
				
			});
		}
		
		toolbar.append('<a href="javascript:;" class="saveButton" title="Save">save</a>');
		toolbar.children('.saveButton').click(function(){
			
		});
		toolbar.append('<a href="javascript:;" class="closeButton" title="Close">close</a>');
		toolbar.children('.closeButton').click(function(){
			destroyEditor();
		});
		toolbar.append('<br clear="all" />');
		toolbar.children('a').hover(function(){ $(this).addClass('active'); }, function(){ $(this).removeClass('active'); });
	}
	
	function formatText(command, option){
		iframe.contentWindow.focus();
        try
        {
			iframe.contentWindow.document.execCommand(command, false, option);
        }
        catch(e)
        {
        
        }
        iframe.contentWindow.focus();
	}
	
	function insertAtCarat(html){
		iframe.contentWindow.focus();
		if(bookmarkRange)
			restoreSelection(bookmarkRange);
		if($.browser.msie)
		{
		    var range = iframe.contentWindow.document.selection.createRange();
		
		    if (jQuery(range.parentElement()).parents('.wym_iframe').is('*')) {
		        try {
		            range.pasteHTML(html);
		        } catch (e) { }
		    } else {
		        this.paste(html);
		    }	
		}
		else
		{
		    if (iframe.contentWindow.getSelection().focusNode != null) {
		        formatText('inserthtml', html);
		    } else {
		    	paste(html);
		    }
		}
	}
	
	function paste(data){
		var sTmp;
		var container = selected();

		var aP = sData.split("\n");
		var rExp = new RegExp("\n", "g");
		
		//add a P for each item
		if(container && container.tagName.toLowerCase() != 'body') {
		for(x = aP.length - 1; x >= 0; x--) {
		    sTmp = aP[x];
		    //simple newlines are replaced by a break
		    sTmp = sTmp.replace(rExp, "<br />");
		    jQuery(container).after("<p>" + sTmp + "</p>");
		}
		} else {
		for(x = 0; x < aP.length; x++) {
		    sTmp = aP[x];
		    //simple newlines are replaced by a break
		    sTmp = sTmp.replace(rExp, "<br />");
		    jQuery(this._doc.body).append("<p>" + sTmp + "</p>");
		}
		
		}
	}
	
	function selected(){
		if($.browser.msie)
		{
		    var caretPos = iframe.contentWindow.document.caretPos;
        	if(caretPos!=null) {
            	if(caretPos.parentElement!=undefined)
              		return(caretPos.parentElement());
       		}
		}
		else
		{
		    var sel = iframe.contentWindow.getSelection();
		    var node = sel.focusNode;
		    if(node) {
		        if(node.nodeName == "#text") return(node.parentNode);
		        else return(node);
		    } else return(null);
		}
	}
	
})(jQuery);