function standardCleanup(type, value) {
//	alert(type);
		switch (type) {
		case "insert_to_editor":
			//alert("insert_to_editor: Value HTML string: " + value);
			value = JS_CleanMSWordString(value);
			break;

		case "get_from_editor_dom":
			// alert("get_from_editor_dom: Value DOM Element: " + value);
			// cleanup disabled
			// value = JS_CleanMSWord(value); //.innerHTML
			break;
	}
	return value;
}

function removeParasInLI(mceDOM) {
    var nestedParas = tinyMCE.activeEditor.selection.select(tinyMCE.activeEditor.dom.select('li p'));
	for (var i=(nestedParas.length-1); nestedParas[i]; i--) {
		tinyMCE.activeEditor.dom.remove(nestedParas[i],true);
	}
}

function JS_CleanMSWord(mceDOM) {
	// disable this entire cleanup routine
	return mceDOM;
	// remove all style and script tags
    tinyMCE.activeEditor.dom.remove(tinyMCE.activeEditor.dom.select('script'), false);
    tinyMCE.activeEditor.dom.remove(tinyMCE.activeEditor.dom.select('style'), false);

	//removeParasInLI(mceDOM);

	/* Eliminate useless MS Word section dividers */
	var msDivTags = new Array();
	for (var i=1; i<200; i++) {
	    var divSection = tinyMCE.activeEditor.dom.select('div.Section' + i, mceDOM);
		if (divSection[0])
			msDivTags[msDivTags.length] = divSection[0];
	}
	if (msDivTags.length)
		tinyMCE.activeEditor.dom.remove(msDivTags,true);

	tinyMCE.activeEditor.dom.setAttrib(tinyMCE.activeEditor.dom.select('div', mceDOM), 'style', null);


	var editorLang = tinyMCE.activeEditor.id.replace(/.*_/,"");
	var currLang = new RegExp("(\\s*|"+editorLang+"(-[az]+|))","i");
	// remove span tags that are empty of class or lang attributes
//	for (var repeat=0; repeat<10; repeat++) {
	    var spanTags = tinyMCE.activeEditor.dom.select('span', mceDOM);
		for (var i=0; i<spanTags.length; i++) {
			if ((!tinyMCE.activeEditor.dom.getAttrib(spanTags[i],"class")) && 
				(!tinyMCE.activeEditor.dom.getAttrib(spanTags[i],"mce_name")) && 
				(!tinyMCE.activeEditor.dom.getAttrib(spanTags[i],"lang") || 
					tinyMCE.activeEditor.dom.getAttrib(spanTags[i],"lang").test(currLang))) {
				tinyMCE.activeEditor.dom.remove(spanTags[i],true);
			}
		}
//	}

	/* remove nesting of tables inside block elements */
	var nestingTags = Array("h2", "h3", "h4", "h5", "p");
	for (var j=0; nestingTags[j]; j++) {
	    var nestedTables = tinyMCE.activeEditor.dom.select(nestingTags[j] + ' table', mceDOM);
		for (var i=(nestedTables.length-1); nestedTables[i]; i--) {
			tinyMCE.activeEditor.dom.remove(nestedTables[i].parentNode,true);
		}
	}

	/* remove nesting of blockquotes inside block elements */
	var nestingTags = Array("h2", "h3", "h4", "h5", "p");
	for (var j=0; nestingTags[j]; j++) {
	    var nestedBQuotes = tinyMCE.activeEditor.dom.select(nestingTags[j] + ' blockquote', mceDOM);
		for (var i=(nestedBQuotes.length-1); nestedBQuotes[i]; i--) {
			tinyMCE.activeEditor.dom.remove(nestedBQuotes[i].parentNode,true);
		}
	}

	return mceDOM;//.innerHTML;

	// remove empty div tags that are empty of class or lang attributes
    var divTags = tinyMCE.activeEditor.dom.select('div', mceDOM);
	for (var i=0; i<divTags.length; i++) {
		if ((!tinyMCE.activeEditor.dom.getAttrib(divTags[i],"class")) && 
			(!tinyMCE.activeEditor.dom.getAttrib(divTags[i],"mce_name"))) 
		{
//			if (divTags[i].parentNode.tagName == "BODY") {
//				alert(divTags[i].innerHTML);
//				var el = tinyMCE.activeEditor.dom.create('p',{}, divTags[i].innerHTML);
//				tinyMCE.activeEditor.dom.replace(el, divTags[i]);
//			} else if (divTags[i]) {
//				alert(divTags[i].parentNode.tagName);
				tinyMCE.activeEditor.dom.remove(divTags[i],true);
//			}
		}
	}
	var uTags = tinyMCE.activeEditor.dom.select('u', mceDOM);
	for (var i=0; uTags[i]; i++) {
		var el = tinyMCE.activeEditor.dom.create('span',{}, uTags[i].innerHTML);
		tinyMCE.activeEditor.dom.addClass(el, "underline");
		tinyMCE.activeEditor.dom.replace(el, uTags[i]);
	}

	//alert("Body : "+mceDOM.innerHTML);
	/* remove nesting of block elements inside block elements */
	var nestingTags = Array("h2", "h3", "h4", "h5", "p");
	for (var j=0; nestingTags[j]; j++) {
		for (var k=0; nestingTags[k]; k++) {
			for (var repeat=0; repeat<10; repeat++) {
			    var nestedTags = tinyMCE.activeEditor.dom.select(nestingTags[j] + ' ' + nestingTags[k], mceDOM);
				for (var i=(nestedTags.length-1); nestedTags[i]; i--) {
					tinyMCE.activeEditor.dom.remove(nestedTags[i].parentNode,true);
				}
			}
		}
	}
}

function HTMLTidyCleanup(newData) {
	tinymce.util.XHR.send({
       url : "/admin/ajax_handler.php",
       content_type : "application/x-www-form-urlencoded",
       type : "POST",
       data : "AJAX_Action=cleanupHTML&content="+escape(newData),
       async : false,
       
       success : function( data, req, o ) {
           newData = data;
       },
       
       error : function( type, req, o ){
           alert( type ); // Should display "TIMED_OUT" or "GENERAL"
           alert( req.status ); // Should display anything but 200
           alert( o.url ); // Should display "service.php"
       }
   });
   return newData;

}

var cleanupRunCount = 0; // On startup the cleanup runs a couple times automatically
function JS_CleanMSWordString(newData) {
	if (typeof(tinyMCE_RULING_FILTERS) != 'undefined' && tinyMCE_RULING_FILTERS)
		newData = tinyMCE_fixRulingIssues(newData);
	// Quote All Attributes
	//var findPattern = new RegExp("(<[^>]+)\\s([a-zA-Z0-9]+)=([^\"> ]+)", "ig");
	//while (findPattern.test(newData))
	//	newData = newData.replace(findPattern, '$1 $2="$3"');

	// MS OFFICE CLEANUP
	newData = newData.replace(/<o:p>(&nbsp;|\s)*<\/o:p>/g, ""); // Remove all instances of <o:p>
	newData = newData.replace(/<\/?o\:[^>]*>/g, "");
	newData = newData.replace(/<st1:[^>]*>/g, ""); // remove all SmartTags (from MS Word)
	newData = newData.replace(/<\?xml:[^>]*>/g, ""); // remove all XML(from MS Word)
	newData = newData.replace(/<\/?(?:st1|font|V:|o:p)[^>]*>/ig, "");
	newData = newData.replace(/<!\[if !mso\]>.*?<!\[endif\]>/ig, "");
	newData = newData.replace(/<!\[if !supportEmptyParas\]>.*?<!\[endif\]>/ig, "");
	newData = newData.replace(/<!--\[if supportFields\]>.*?<!\[endif\]-->/ig, "");
	newData = newData.replace(/<!\[if !supportLists\]>.*?<!\[endif\]>/ig, "<li>");
	newData = newData.replace(/<!\[if !supportMisalignedRows+\]>.*?<!\[endif\]>/ig, "");
	newData = newData.replace(/<v:shapetype .*?<\/v:shapetype>/ig, "");
	newData = newData.replace(/<v:shape .*?<\/v:shape>/ig, "");
	newData = newData.replace(/ v:shapes="[^"]+"/ig, "");
	// apply any unaccepted tracked changes in documents
	newData = newData.replace(/<del [^>]+>.*?<\/del>/ig, "");
	newData = newData.replace(/<ins [^>]+>(.*?)<\/ins>/ig, "$1");

	newData = newData.replace(/<!--\[if[^>]+-->/ig, "");
	newData = newData.replace(/<!\[endif\]-->/ig, "");
	newData = newData.replace(/\s+class="mso[^"]+"/ig, "");
	newData = newData.replace(/margin:\s+[^;]+(\s+[^;]+)\s+[^;]+(\s+[^;]+);/ig, "margin: auto $1 auto $2;");
	newData = newData.replace(/%1e/g, "-");
	newData = newData.replace(/(<li(?:>|\s[^>]*>))(?:&nbsp;|\s)*(?:&middot;|o|&sect;|&bull;)(?:&nbsp;|\s)+/ig, "$1");
	newData = newData.replace(/<(p|h[1-6])(?:>|\s[^>]*>)(?:&nbsp;|\s|<br \/>|<\/?(?:em|strong|b|i)(?:>|\s[^>]*>))*<\/\1>/ig, "");
	newData = newData.replace(/(<td[^>]*>)\s*(<\/td>)/ig, "$1&nbsp;$2");
	newData = newData.replace(/(<(?:em|strong|b|i)>)\s*(<(?:p|h[1-6])[^>]*>)/ig, "$2$1");
	newData = newData.replace(/(<\/(?:p|h[1-6])>)\s*(<\/(?:em|strong|b|i)>)/ig, "$2$1");
	newData = newData.replace(/(<(?:p|h[1-6])[^>]*)\s+align="left"/ig, "$1");
	newData = newData.replace(/(<(?:p|h[1-6])(?:>|\s[^>]*>))(&nbsp;|\s|<br[^>]*>)+/ig, "$1");
	newData = newData.replace(/(?:<(p|h[1-6])(?:>|\s[^>]*>))(&nbsp;|\s|<br[^>]*>)*<\/\1>/ig, "");
	newData = newData.replace(/&nbsp;(&nbsp;)+\s/ig, " ");
	newData = newData.replace(/<(?:b|strong)>\s*(<p(?:>|\s[^>]*>))(.*?)(<\/p>)\s*<\/(?:b|strong)>/ig, "$1<strong>$2</strong></p>");
	newData = newData.replace(/<(strong|em)>(\s*)<\/\1>/ig, "$2");
	return fixStyles(newData);

	// newData = newData.replace(/\n/g,"\uffff").replace(/<\/?span[^>]*>/ig, "").replace(/\uffff/g,"\n");

	// general layout corrections
	newData = newData.replace(/(<img[^>]*)\s+hspace="(\d+)"/ig, "$1 style=\"margin-left: $2px;margin-right: $2px;\"");
	newData = newData.replace(/(<img[^>]*)\s+vspace="(\d+)"/ig, "$1 style=\"margin-top: $2px;margin-bottom: $2px;\"");
	newData = newData.replace(/(<\/?)h1/ig, "$1h1");
//	newData = newData.replace(/<u>(.*?)<\/u>/ig, "<span style=\"text-decoration: underline\">$1</span>");
	newData = newData.replace(/<\/dir>/ig, "</blockquote>");
	newData = newData.replace(/<dir(?:>|\s[^>]*>)/ig, "<blockquote>");
	newData = newData.replace(/<\/li>\s*<li>\s*(<[ou]l[^>]*>)/ig, "$1");
	newData = newData.replace(/<li(?:>|\s[^>]*>)/ig, "<li>");
	newData = newData.replace(/(<li(?:>|\s[^>]*>))\s*<div(?:>|\s[^>]*>)(.{5,800}?)<\/div>\s*(<\/li>)/ig, "$1$2$3");
	newData = newData.replace(/&rsquo;/g, "'");
	newData = newData.replace(/(?:&nbsp;|\s)+(<\/(?:p|h[1-6])>)/ig, "$1");
	newData = newData.replace(/(?:&nbsp;|\s|<br\s*\/?>)+(<\/(?:p|h[1-6]|li)>)/ig, "$1");
	newData = newData.replace(/<table[^>]*>\s*<\/table>/ig, "");
}

var styleExclusions = Array(
	'img|object', Array("width","height","text-align"),
	'h\\d|p|a', Array("margin*","width","height"),
	'h\\d|p|a', Array("background*","color"),
	'table', Array("mso-border*","margin*"),
	'th|td|tr', Array("mso-border*","padding*","width*","height","page-break*"),
	'[a-z][a-z\\d]*', Array("tab-*","line*","mso-*","text-indent","text-justify")
);
var styleExclusionsExact = Array(
	'[a-z][a-z\\d]*', Array("background-color:\\s*transparent","line-height:\\s*0px","text-indent:\\s*-[^;]+","text-justify:\\s*full")
);
function fixStyles(txt) {	// remove particular style definitions in tags
	// remove undesireable attributes from style definitions
	for (var i = 0; styleExclusions[i]; i+=2) {
		var tags = styleExclusions[i];
		var styles = styleExclusions[i+1];
		for (var j = 0; styles[j]; j++) {
			var styleDef = styles[j].replace("*","[^:]*");
			var findPattern = new RegExp("(<(?:"+tags+")\\s[^>]*style=\")\\s*"+styleDef+"\\s*:[^;\"]+;?", "ig");
			for (var z=0; z<10; z++) {
				while (findPattern.test(txt))
					txt = txt.replace(findPattern, "$1");
			}
			var findPattern = new RegExp("(<(?:"+tags+")\\s[^>]*style=\"[^\"]+;)\\s*"+styleDef+"\\s*:[^;\"]+;?", "ig");
			for (var z=0; z<10; z++) {
				while (findPattern.test(txt))
					txt = txt.replace(findPattern, "$1");
			}
		}
	}
	for (var i = 0; styleExclusionsExact[i]; i+=2) {
		var tags = styleExclusionsExact[i];
		var styles = styleExclusionsExact[i+1];
		for (var j = 0; styles[j]; j++) {
			var styleDef = styles[j].replace("*","[^:]*");
			var findPattern = new RegExp("(<(?:"+tags+")\\s[^>]*style=\")\\s*"+styleDef+"\\s*;?", "ig");
			for (var z=0; z<10; z++) {
				while (findPattern.test(txt))
					txt = txt.replace(findPattern, "$1");
			}
			var findPattern = new RegExp("(<(?:"+tags+")\\s[^>]*style=\"[^\"]+;)\\s*"+styleDef+"\\s*;?", "ig");
			for (var z=0; z<10; z++) {
				while (findPattern.test(txt))
					txt = txt.replace(findPattern, "$1");
			}
		}
	}
	txt = txt.replace(/(<[^>]*\s+style=")\s+/ig, "$1");
	return txt;
}

/*
use the following code to call this function (assuming PHP processing):
	tinyMCE.triggerSave();
	return validateContent(Array("<?=join('","', $SITE_LANGUAGES) ?>"));
*/
function validateContent() {
	var thisForm=validateContent.arguments[0], langs = validateContent.arguments[1];
	var field_prefix = validateContent.arguments[2] ? validateContent.arguments[2] : "content_";
	/* content validations */
	var contentErrors = "";
	var errorInfo = "";
	var hasEmptyAltTags = /<img[^>]*src="([^"]+)"[^>]*alt=""[^>]*>/i;
	var hasTable = /<table[^>]*>/i;
	var hasTableNoTh = /<table[^>]*>[^<]*(?:<(?:tbody|thead)[^>]*>[^<]*)?<tr[^>]*>[^<]*(<td[^>]*>(?:[^<]|<\/?(?:p|strong|em|sup|sub|span|br|a)[^>]*>)*<\/td>[^<]*)+<\/tr>/i;
	for (i=0; langs[i]; i++) {
		var content = thisForm[field_prefix+langs[i]].value;
		if (hasTable.test(content) && hasTableNoTh.test(content)) {
			contentErrors += "\n - Tables without header rows exist in "+(langs[i]=="en"?"English":"French")+"!\n";
			errorInfo += "\nTable headers found to be missing. Source code snippet:"+content.match(hasTableNoTh)[0].replace(/<\/?(?:table|thead|tbody)[^>]*>/ig,"");
		}
		if (hasEmptyAltTags.test(content)) {
			contentErrors += "\n - Images without alt tags exist in "+(langs[i]=="en"?"English":"French")+"!\n";
			errorInfo += "\nImages without alt tags found. Source code snippet:\n"+content.match(hasEmptyAltTags)[0];
		}
	}
	if (contentErrors) {
		var confVal = confirm("Content Errors Exist - please fix the following (Click OK to ignore these errors):\n"+contentErrors);
		disableSubmitButtons(thisForm, confVal);
		if (!confVal)
			alert("Use the information below to fix the errors.\n"+errorInfo);
		return confVal;
	}
	return true;
}

var extendedCharArray = new Array('&lsquo;', 'lsquo', '&rsquo;', 'rsquo', '&ldquo;', 'ldquo', '&rdquo;', 'rdquo', 'À', 'Agrave', 'Á', 'Aacute', 'Â', 'Acirc', 'Ã', 'Atilde', 'Ä', 'Auml', 'Å', 'Aring', 'Ç', 'Ccedil', 'È', 'Egrave', 'É', 'Eacute', 'Ê', 'Ecirc', 'Ë', 'Euml', 'Ì', 'Igrave', 'Í', 'Iacute', 'Î', 'Icirc', 'Ï', 'Iuml', 'Ò', 'Ograve', 'Ó', 'Oacute', 'Ô', 'Ocirc', 'Õ', 'Otilde', 'Ö', 'Ouml', 'Ù', 'Ugrave', 'Ú', 'Uacute', 'Û', 'Ucirc', 'Ü', 'Uuml', 'Ý', 'Yacute', 'à', 'agrave', 'á', 'aacute', 'â', 'acirc', 'ã', 'atilde', 'ä', 'auml', 'å', 'aring', 'ç', 'ccedil', 'è', 'egrave', 'é', 'eacute', 'ê', 'ecirc', 'ë', 'euml', 'ì', 'igrave', 'í', 'iacute', 'î', 'icirc', 'ï', 'iuml', 'ð', 'eth', 'ñ', 'ntilde', 'ò', 'ograve', 'ó', 'oacute', 'ô', 'ocirc', 'õ', 'otilde', 'ö', 'ouml', 'ù', 'ugrave', 'ú', 'uacute', 'û', 'ucirc', 'ü', 'uuml', 'ý', 'yacute', 'ÿ', 'yuml', '&mdash;', 'mdash', '&ndash;', 'ndash', '\'', 'rsquo', '»', 'raquo', '«', 'laquo', '&#339;', '#339', '&#338;', '#338');
function tinyMCE_fixRulingIssues(newData) {
	var count=1;
	while (newData != newData.replace(/(<P[^>]*>)\[\] /i, "$1["+(count)+"] ") && count < 500) {
		newData = newData.replace(/(<P[^>]*>)\[\] /i, "$1["+count+"] ");
		count = count + 1;
	}
	for (var i=0; i < extendedCharArray.length; i+=2) {
		newData = newData.replace(new RegExp("&amp;"+extendedCharArray[i+1]+";","g"),extendedCharArray[i]);
	}
	return newData;
}