/**
 * Netizens RTE jQuery plugin
 * Wersja 0.1.200810201401
 *
 * Prosty edytor wizualny dla pól TEXTAREA
 *
 * Sposób podłączania:
 * $(pole).netiRte({allowedTags: "<b>,<i>,<strong>,<em>", inheritStyles: false, bodyStyles: {"background-color": "#171717"}, "toolbarSelector": ".rich-text-edit" });
 *
 * Opcje:
 * allowedTags - lista dozwolonych tagów (pozostałe będą filtrowane) dołączana do domyślnej listy (nie zastępuje domyślnej!)
 * inheritStyles - określa, czy iframe ma dziedziczyć style podmienianego textarea
 *                 (w obecnej wersji cząstkowo oprogramowane, najlepiej ustawiać na false )
 * bodyStyles - style CSS dla BODY iframe'a edytora
 * toolbarSelector - selector jQuery toolbara edytora (przyciski bold, italic, itd.);
 *                   Gdy uda się zainicjalizować RTE, to skrypt wyświetla element(y) o tym selektorze.
 *                   Gdy nie uda się zainicjalizować RTE, to skrypt ukrywa element(y) o tym selektorze.
 *
 * Pobieranie zawartości pola:
 * $(pole).netiRteVal();
 *
 * Przypisywanie treści do pola:
 * $(pole).netiRteVal(tresc);
 *
 * Autor: jm
 *
 */

jQuery.fn.netiRte = function(opcje) {
	return this.each(function(){
		// jeśli pole nie jest typu TEXTAREA, to przerywamy wykonywanie funkcji
		if (this.tagName != "TEXTAREA") {
			return;
		}
		
		// jeśli textarea nie ma przypisanego id, to dajemy automatyczne
		if ( !jQuery(this).attr("id") ) {
			jQuery(this).attr("id", "netiRte_"+(jQuery.netiRte.auto_id_index++));
		}
		
		// inicjalizacja edytora
		jQuery.netiRte.init(
			jQuery(this),
			opcje
		);
	});
};

jQuery.fn.netiRteVal = function(tresc) {
	if ( !this[0] ) {
		return null;
	}
	
	var pole = this[0];
	
	// jeśli pole nie jest typu TEXTAREA, to przerywamy wykonywanie funkcji
	if (pole.tagName != "TEXTAREA" || !jQuery(pole).attr("id")) {
		return null;
	}
	
	
	// zwrócenie treści
	if ( typeof(tresc) == "undefined" ) {
		return jQuery.netiRte.pobierz_tresc(pole.id);
	}
	// zmiana treści
	else {
		return jQuery.netiRte.zmien_tresc(pole.id, tresc);
	}
};

jQuery.netiRte =
{
	// nie modyfikować!
	auto_id_index: 1,

	// lista tagów, które zawsze są dozwolone
	zawsze_dozwolone_tagi: "<span>,<br>,<p>",
	
	// dozwolone tagi dla konkretnego elementu
	dozwolone_tagi: {},

	init: function(textarea, opcje) {
		var textarea_id = textarea.attr("id");
		
		if ( typeof(opcje) != "undefined" ) {
			var dozwolone_tagi = opcje.allowedTags;
			var style_body = opcje.bodyStyles;
			var toolbar_selector = opcje.toolbarSelector;
			if ( opcje.inheritStyles || opcje.inheritStyles == undefined ) {
				var dziedziczyc_style = true;
			}
			else {
				var dziedziczyc_style = false;
			}
		}
		
		// stworzenie iframe'a dla textarea (jeśli nie ma iframe'a w DOM-ie)
		if ( !jQuery("iframe[name='rte_"+textarea_id+"']").get(0) ) {
			var iframe = document.createElement("iframe");
			j_iframe = jQuery(iframe);
			j_iframe.attr("id", "rte_"+textarea_id);
			if ( dziedziczyc_style ) {
				j_iframe.css("width", textarea.css("width"));
				j_iframe.css("height", textarea.css("height"));
				if ( textarea.css("background-color") && textarea.css("background-color") != "transparent" ) {
					j_iframe.css("background-color", textarea.css("background-color"));
				}
				else {
					j_iframe.css("background-color", "#fff");
				}
			}
			
			// operacje wykonywane po załadowaniu iframe'a - te operacje będą wykonywane po wyświetleniu iframe'a
			j_iframe.load(function(e) {
				jQuery.netiRte.iframe_onload(iframe, textarea_id, dozwolone_tagi, style_body, toolbar_selector);
			});
			
			// ukrycie textarea
			textarea.hide();
			
			// wyświetlenie iframe'a
			j_iframe.insertAfter(textarea);
		}
		// jeśli iframe istnieje w DOM-ie, to jego wyświetlenie
		else {
			var j_iframe = jQuery("iframe[name='rte_"+textarea_id+"']");
			var iframe = j_iframe.get(0);
			
			j_iframe.show();
			// ukrycie textarea
			textarea.hide();
			// operacje wykonywane po załadowaniu iframe'a - te operacje będą wykonywane po przeładowaniu iframe'a
			j_iframe.load(function() { jQuery.netiRte.iframe_onload(iframe, textarea_id, dozwolone_tagi, style_body, toolbar_selector);});
			//iframe.src = "about:blank";
			iframe.contentWindow.location.reload();
		}
		
	},
	
	iframe_onload: function(iframe, textarea_id, dozwolone_tagi, style_body, toolbar_selector) {
		var textarea = $("textarea#"+textarea_id);
		
		// zabezpieczenie przed dwukrotnym wykonaniem poniższego kodu w IE
		if ( textarea.hasClass("rte_loaded") ) {
			return;
		}
		textarea.addClass("rte_loaded");
		
		// próba włączenia designMode
		try {
			iframe.contentWindow.document.designMode = "on";
			iframe.contentWindow.document.execCommand("undo", false, null);
			if ( toolbar_selector ) {
				jQuery(toolbar_selector).show();
			}
		} catch (e) {
			// jeśli przeglądarka nie obsługuje designMode - to usuwamy iframe'a i zostawiamy standardowe textarea
			j_iframe.remove();
			textarea.show();
			if ( toolbar_selector ) {
				jQuery(toolbar_selector).hide();
			}
			return false;
		}
		
		// inicjalizacja iframe'a			
		jQuery.netiRte.iframe_init(iframe, textarea_id, dozwolone_tagi, style_body);
	},
	
	// "onload" dla przypadku, gdy iframe jest w DOM-ie od początku
	iframe_onload_old: function(iframe, textarea_id, dozwolone_tagi, style_body) {
		// czy iframe został zainicjalizowany przez przeglądarkę?
		try {
			if ( iframe.contentWindow.document.body.innerHTML != '|' ) {
				window.setTimeout(function() {jQuery.netiRte.iframe_onload(iframe, textarea_id, dozwolone_tagi, style_body);}, 20 );
				return;
			}
		} catch (e) {
			// jeśli iframe nie został całkowicie zainicjalizowany przez przeglądarkę, to ponawiamy próbę
			window.setTimeout(function() {jQuery.netiRte.iframe_onload(iframe, textarea_id, dozwolone_tagi, style_body);}, 20 );
			return;
		}
		
		// próba włączenia designMode
		try {
			iframe.contentWindow.document.designMode = "on";
			iframe.contentWindow.document.execCommand("undo", false, null);
			
			// inicjalizacja iframe'a			
			jQuery.netiRte.iframe_init(iframe, textarea_id, dozwolone_tagi, style_body);
			
			// ukrycie textarea
			var textarea = jQuery("textarea#"+textarea_id);
			textarea.hide();
			
		} catch (e) {
			// jeśli przeglądarka nie obsługuje designMode - to zostawiamy standardowe textarea
			var j_iframe = jQuery(iframe);
			j_iframe.hide();
			return false;
		}
		
	},
	
	// inicjalizacja iframe'a
	iframe_init: function(iframe, textarea_id, dozwolone_tagi, style_body) {
		var textarea = $("textarea#"+textarea_id);
		
		// próba przekopiowania do iframe'a zawartości textarea
		try {
			iframe.contentWindow.document.body.innerHTML = textarea.val();
		} catch (e) {
			// jeśli iframe nie został całkowicie zainicjalizowany przez przeglądarkę, to ponawiamy próbę
			window.setTimeout(function() {jQuery.netiRte.iframe_init(iframe, textarea_id, dozwolone_tagi, style_body);}, 20 );
			return;
		}
		
		// jeśli zawartość iframe'a jest pusta, to umieszczamy w nim spację,
		// ponieważ w niektórych przypadkach nie był widoczny kursor
		if ( iframe.contentWindow.document.body.innerHTML == "" ) {
			iframe.contentWindow.document.body.innerHTML = " ";
		}
		
		// dodanie atrybutu frameborder
		jQuery(iframe).attr("frameborder", 0);
		
		// przeniesienie atrybutu "color" ze stylu IFRAME-a do BODY IFRAME-a
		if ( jQuery(iframe).css("color") ) {
			jQuery(iframe.contentWindow.document.body).css("color", jQuery(iframe).css("color"));
		}
		if ( jQuery(iframe).css("background-color") ) {
			jQuery(iframe.contentWindow.document.body).css("background-color", jQuery(iframe).css("background-color"));
		}
		// bodyStyles
		for(i in style_body) {
			jQuery(iframe.contentWindow.document.body).css(i, style_body[i]);
		}
		
		// oprogramowanie przycisków edytora (bold, italic, itd.)
		jQuery("a[rel='rte["+textarea_id+"]']").click(function(e) {
			var cmd = this.href.match(/#(.+)/)[1];
			iframe.contentWindow.document.execCommand(cmd, false, null);
			iframe.contentWindow.focus();
			return false;
		});
		
		// przygotowanie listy dozwolonych tagow
		if ( typeof(dozwolone_tagi) != "undefined" ) {
			dozwolone_tagi += ","+jQuery.netiRte.zawsze_dozwolone_tagi;
		}
		else {
			var dozwolone_tagi = jQuery.netiRte.zawsze_dozwolone_tagi;
		}
		// ta "dziwna" kopia zmiennej musi być ze względu na zachowanie Opery
		var dozwolone_tagi_kopia = dozwolone_tagi;
		
		jQuery.netiRte.dozwolone_tagi[textarea_id] = dozwolone_tagi;
		// przechwycenie submita formularza
		jQuery(textarea.get(0).form).bind("submit", function(e) {
			// przekopiowanie zawartości iframe'a do textarea			
			var tresc = iframe.contentWindow.document.body.innerHTML;
			tresc = jQuery.netiRte.filtruj(tresc, dozwolone_tagi_kopia);
			textarea.val(tresc);
			return true;
		});
		
		// śledzenie zmian tekstu - wykrywanie wklejania
		jQuery.netiRte.dlugosc_tekstu[textarea_id] = iframe.contentWindow.document.body.innerHTML.length;
		window.setTimeout( function() { jQuery.netiRte.sprawdz_zmiany(iframe, textarea_id, dozwolone_tagi); }, 100 );
	},
	
	// funkcja wykrywająca zmiany w tekście takie jak wklejanie, wycinanie bloków
	dlugosc_tekstu: {},
	sprawdz_zmiany: function(iframe, textarea_id, dozwolone_tagi) {
		var iframe_html = iframe.contentWindow.document.body.innerHTML;
		dlugosc_tekstu = iframe_html.length;
		// jeśli długość aktualnego tekstu mocno różni się od poprzednio sprawdzanej -> prawdopodobnie wklejenie tekstu
		if (Math.abs(this.dlugosc_tekstu[textarea_id]-dlugosc_tekstu) > 90) {
			// przefiltrowanie tekstu
			iframe_html = this.filtruj(iframe_html, dozwolone_tagi);
			iframe.contentWindow.document.body.innerHTML = iframe_html;
		}
		
		this.dlugosc_tekstu[textarea_id] = dlugosc_tekstu;
		
		window.setTimeout( function() { jQuery.netiRte.sprawdz_zmiany(iframe, textarea_id, dozwolone_tagi); }, 100 );
	},
	
	// funkcja zwraca treść iframe'a
	pobierz_tresc: function(textarea_id) {
		var iframe = jQuery("iframe[name='rte_"+textarea_id+"']").get(0);
		if ( !iframe ) {
			return null;
		}
		
		var tresc = iframe.contentWindow.document.body.innerHTML;
		tresc = jQuery.netiRte.filtruj(tresc, this.dozwolone_tagi[textarea_id]);
		return tresc;
	},
	
	// funkcja podmienia treść iframe'a
	zmien_tresc: function(textarea_id, tresc) {
		tresc = jQuery.netiRte.filtruj(tresc, this.dozwolone_tagi[textarea_id]);
		var iframe = jQuery("iframe[name='rte_"+textarea_id+"']").get(0);
		iframe.contentWindow.document.body.innerHTML = tresc;
		return true;
	},
	
	// funkcja filtruje tekst
	filtruj: function(tresc, dozwolone_tagi) {
		// Safari
		tresc = tresc.replace(' class="apple-style-span"', "");
	
		// komentarze
		tresc = tresc.replace(/<(!--)([\s\S]*)(--)>/gi, "");
		// formatowanie worda
		tresc = this.filtruj_word(tresc);
		// tagi html
		tresc = this.filtruj_tagi(tresc, dozwolone_tagi);
		
		return tresc;
	},
	
	// filtrowanie formatowania MS Word - na podstawie funkcji TinyMCE
	filtruj_word: function(tresc) {
		var bull = String.fromCharCode(8226);
		var middot = String.fromCharCode(183);

		tresc = tresc.replace(new RegExp('<p class=MsoHeading.*?>(.*?)<\/p>', 'gi'), '<p><b>$1</b></p>');
		tresc = tresc.replace(new RegExp('tab-stops: list [0-9]+.0pt">', 'gi'), '">' + "--list--");
		tresc = tresc.replace(new RegExp(bull + "(.*?)<BR>", "gi"), "<p>" + middot + "$1</p>");
		tresc = tresc.replace(new RegExp('<SPAN style="mso-list: Ignore">', 'gi'), "<span>" + bull); // Covert to bull list
		tresc = tresc.replace(/<o:p><\/o:p>/gi, "");
		tresc = tresc.replace(new RegExp('<br style="page-break-before: always;.*>', 'gi'), '-- page break --'); // Replace pagebreaks
		tresc = tresc.replace(new RegExp('<(!--)([^>]*)(--)>', 'g'), "");  // Word comments
		tresc = tresc.replace(/<\/?font[^>]*>/gi, "");
		tresc = tresc.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3");
		//tresc = tresc.replace(new RegExp('href="?' + this._reEscape("" + document.location) + '', 'gi'), 'href="' + this.editor.documentBaseURI.getURI());
		tresc = tresc.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3");
		tresc = tresc.replace(/<\\?\?xml[^>]*>/gi, "");
		tresc = tresc.replace(/<\/?\w+:[^>]*>/gi, "");
		tresc = tresc.replace(/-- page break --\s*<p>&nbsp;<\/p>/gi, ""); // Remove pagebreaks
		tresc = tresc.replace(/-- page break --/gi, ""); // Remove pagebreaks

//		tresc = tresc.replace(/\/?&nbsp;*/gi, ""); &nbsp;
//		tresc = tresc.replace(/<p>&nbsp;<\/p>/gi, '');

		//tresc = tresc.replace(/<\/?div[^>]*>/gi, "");
		
		// Replace all headers with strong and fix some other issues
		tresc = tresc.replace(/<h[1-6]>&nbsp;<\/h[1-6]>/gi, '<p>&nbsp;&nbsp;</p>');
		tresc = tresc.replace(/<h[1-6]>/gi, '<p><b>');
		tresc = tresc.replace(/<\/h[1-6]>/gi, '</b></p>');
		tresc = tresc.replace(/<b>&nbsp;<\/b>/gi, '<b>&nbsp;&nbsp;</b>');
		tresc = tresc.replace(/^(&nbsp;)*/gi, '');

		tresc = tresc.replace(/--list--/gi, ""); // Remove --list--
		
		return tresc;
	},
	
	
	// filtrowanie tagów HTML - przeróbka funkcji strip_tags (szczegóły wewnątrz funkcji)
	filtruj_tagi: function(str, allowed_tags) {
		
		/* 
		 * More info at: http://kevin.vanzonneveld.net/techblog/category/php2js
		 * 
		 * php.js is copyright 2008 Kevin van Zonneveld.
		 * 
		 * Portions copyright Ates Goral (http://magnetiq.com), Legaev Andrey,
		 * _argos, Jonas Raoni Soares Silva (http://www.jsfromhell.com),
		 * Webtoolkit.info (http://www.webtoolkit.info/), Carlos R. L. Rodrigues, Ash
		 * Searle (http://hexmen.com/blog/), Tyler Akins (http://rumkin.com), mdsjack
		 * (http://www.mdsjack.bo.it), Alexander Ermolaev
		 * (http://snippets.dzone.com/user/AlexanderErmolaev), Andrea Giammarchi
		 * (http://webreflection.blogspot.com), Bayron Guevara, Cord, David, Karol
		 * Kowalski, Leslie Hoare, Lincoln Ramsay, Mick@el, Nick Callen, Peter-Paul
		 * Koch (http://www.quirksmode.org/js/beat.html), Philippe Baumann, Steve
		 * Clay, booeyOH
		 * 
		 * Licensed under the MIT (MIT-LICENSE.txt) license.
		 * 
		 * Permission is hereby granted, free of charge, to any person obtaining a
		 * copy of this software and associated documentation files (the
		 * "Software"), to deal in the Software without restriction, including
		 * without limitation the rights to use, copy, modify, merge, publish,
		 * distribute, sublicense, and/or sell copies of the Software, and to
		 * permit persons to whom the Software is furnished to do so, subject to
		 * the following conditions:
		 * 
		 * The above copyright notice and this permission notice shall be included
		 * in all copies or substantial portions of the Software.
		 * 
		 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
		 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
		 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
		 * IN NO EVENT SHALL KEVIN VAN ZONNEVELD BE LIABLE FOR ANY CLAIM, DAMAGES 
		 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
		 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
		 * OTHER DEALINGS IN THE SOFTWARE.
		 */
	
		// http://kevin.vanzonneveld.net
		// +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
		// +   improved by: Luke Godfrey
		// +      input by: Pul
		// +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
		// +   bugfixed by: Onno Marsman
		// *     example 1: strip_tags('<p>Kevin</p> <br /><b>van</b> <i>Zonneveld</i>', '<i>,<b>');
		// *     returns 1: 'Kevin <b>van</b> <i>Zonneveld</i>'
		// *     example 2: strip_tags('<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>', '<p>');
		// *     returns 2: '<p>Kevin van Zonneveld</p>'
		// *     example 3: strip_tags("<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>", "<a>");
		// *     returns 3: '<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>'
	 
		var key = '', tag = '', allowed = false;
		var matches = allowed_array = [];
		var allowed_keys = {};
	 
		var replacer = function(search, replace, str) {
			var tmp_arr = [];
			tmp_arr = str.split(search);
			return tmp_arr.join(replace);
		};
		
		// Build allowes tags associative array
		if (allowed_tags) {
			allowed_tags  = allowed_tags.replace(/[^a-zA-Z,]+/g, '');;
			allowed_array = allowed_tags.split(',');
		}
	 
		str += '';
		
		// Match tags
		matches = str.match(/(<\/?[^>]+>)/gi);
	 
		// Go through all HTML tags
		for (key in matches) {
			if (isNaN(key)) {
				// IE7 Hack
				continue;
			}
	 
			// Save HTML tag
			html = matches[key].toString();
	 
			// Is tag not in allowed list? Remove from str!
			allowed = false;
	 
			// Go through all allowed tags
			for (k in allowed_array) {
				// Init
				allowed_tag = allowed_array[k];
				i = -1;
				
				// poniższe linijki są konieczne - to jest formatowanie tekstu pod różnymi przeglądarkami
				// FF
				if (i != 0) { i = html.toLowerCase().indexOf('<span style="font-weight:');}
				if (i != 0) { i = html.toLowerCase().indexOf('<span style="font-style:');}
				if (i != 0) { i = html.toLowerCase().indexOf('<br style="');}
				// Safari
				if (i != 0) { i = html.toLowerCase().indexOf('<div>');}
				if (i != 0) { i = html.toLowerCase().indexOf('</div>');}
				// IE i Opera
				if (i != 0) { i = html.toLowerCase().indexOf('<p>');}
				if (i != 0) { i = html.toLowerCase().indexOf('</p>');}
				
				// sprawdzanie czy tag jest dozwolony
				if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+'>');}
				// nie pozwalamy na tagi z atrybutami, bo mogą pozostać formatowania po wklejeniu z edytorów tekstu
				/*if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+' ');}*/
				if (i != 0) { i = html.toLowerCase().indexOf('</'+allowed_tag)   ;}
	 
				// Determine
				if (i == 0) {
					allowed = true;
					break;
				}
			}
	 
			if (!allowed) {
				str = replacer(html, "", str); // Custom replace. No regexing
			}
		}
		
		return str;
	}
}
