// ----- methods shared by text editor in various locations - pop-ups, in-lines etc -----
function SetFileManagerModalInRetro(p_oWin){
	// adjust modal so it's above any popped up iframes
	var oFrames = document.getElementsByTagName('iframe');
	for(var i = 0; i < oFrames.length; i++){
		if(oFrames[i].style.zIndex > ncModal.CoverIndex){
			ncModal.CoverIndex = oFrames[i].style.zIndex + 10;
		}
	}
	
	// retrofit the window as modal target
	var oArgs = {SiteId: g_oNcEditorOptions.SiteId, FeatureId: g_oNcEditorOptions.FeatureId, TextId: g_oNcEditorOptions.TextId, 
				RecordId: g_oNcEditorOptions.RecordId, FileFolderType: g_oNcEditorOptions.FileFolderType, 
				ElementId: g_oNcEditorOptions.ElementId, TempFileFolderId: g_oNcEditorOptions.TempFileFolderId, 
				ReturnSecurePath: g_oNcEditorOptions.ReturnSecurePath, EmailId: g_oNcEditorOptions.EmailId, 
				EmailEventId: g_oNcEditorOptions.EmailEventId};
	top.ncModal.Retrofit(p_oWin, oArgs, null, null, true);
	return true;
}
function SetEditorGlobals(p_oTextOptionsEl){
	window.g_oNcEditorOptions = {};
	// wire to top if in a frame (e.g. settings editor)
	if(window != top){
		top.g_oNcEditorOptions = g_oNcEditorOptions;
		top.SetFileManagerModalInRetro = SetFileManagerModalInRetro;
	}
	eval('g_oNcEditorOptions.NcEditorBtns = ' + p_oTextOptionsEl.getAttribute('NcEditorBtns'));
	
	g_oNcEditorOptions.OtherOptionArr = CreateOtherOptionArr(p_oTextOptionsEl);
	g_oNcEditorOptions.QueryFeatureId = parseInt(p_oTextOptionsEl.getAttribute("QueryFeatureId"), 10);
	
	// create as global array as well as adding to object - used by ncEmbedCls
	window.g_oQueryFieldArr = g_oNcEditorOptions.QueryFieldArr = CreateQueryFieldArr(p_oTextOptionsEl);
	window.g_oFormFieldArr = g_oNcEditorOptions.FormFieldArr = CreateFormFieldArr(p_oTextOptionsEl);

	g_oNcEditorOptions.SiteId = typeof g_lSiteId != 'undefined' ? g_lSiteId : ncSiteId;
	g_oNcEditorOptions.FeatureId = typeof g_lFeatureId != 'undefined' ? g_lFeatureId : ncFeatureId;
	g_oNcEditorOptions.TextType = p_oTextOptionsEl.getAttribute("TextType");
	g_oNcEditorOptions.TextId = typeof g_lTextId != 'undefined' ? g_lTextId : 0;
	g_oNcEditorOptions.RecordId = typeof g_lRecordId != 'undefined' ? g_lRecordId : 0;
	g_oNcEditorOptions.ElementId = typeof g_lElementId != 'undefined' ? g_lElementId : 0;
	g_oNcEditorOptions.EmailId = typeof g_lEmailId != 'undefined' ? g_lEmailId: 0;
	g_oNcEditorOptions.EmailEventId = typeof g_lEmailEventId != 'undefined' ? g_lEmailEventId: 0;
	g_oNcEditorOptions.FileFolderType = typeof g_lFileFolderType != 'undefined'  ? g_lFileFolderType : -1;
	g_oNcEditorOptions.TempFileFolderId = 0;
	g_oNcEditorOptions.TempFileFolderHash = '';
	
	// always return secure path if secure files - so they render in editor and preview ok
	g_oNcEditorOptions.ReturnSecurePath = true;	
	
	var sSiteUrl = window.location.href.replace(window.location.search, '');	
	if(sSiteUrl.indexOf('/v/') != -1){
		sSiteUrl = sSiteUrl.substr(0, sSiteUrl.lastIndexOf("/v/"));
	}else{
		sSiteUrl = sSiteUrl.substr(0, sSiteUrl.lastIndexOf('/'));
		sSiteUrl = sSiteUrl.substr(0, sSiteUrl.lastIndexOf('/'));
	}
	g_oNcEditorOptions.SiteUrl = sSiteUrl;
}
function CreateEditor(p_oTextOptionsEl, p_sInstanceName, p_vWidth, p_vHeight, p_sToolbarSet, p_sValue){
	//(instanceName, width, height, toolbarSet, value)
	var oEditor = new FCKeditor(p_sInstanceName, p_vWidth, p_vHeight, p_sToolbarSet, p_sValue);
	oEditor.BasePath = g_oNcEditorOptions.SiteUrl + '/v/editor/';
	oEditor.Config.CustomConfigurationsPath = g_oNcEditorOptions.SiteUrl + '/v/nceditor/config.js';
	oEditor.Config.PluginsPath = g_oNcEditorOptions.SiteUrl + '/v/nceditor/plugins/';
	oEditor.Config.BaseHref = g_oNcEditorOptions.SiteUrl + '/v/';
	oEditor.Config.ImageBrowserURL = oEditor.Config.FlashBrowserURL = g_oNcEditorOptions.SiteUrl + '/v/htm/FileManager.htm';
	oEditor.Config.EditorAreaCSS = GetEditorCss(p_oTextOptionsEl.getAttribute("StyleSheets"));
	
	// start as blank string otherwise you get 'undefined' when using +=
	oEditor.Config.EditorAreaStyles = '';
	
	// prevent embed resizing for IE (behavior file needs fully qualifying)
	if(typeof document.body.style.behavior != 'undefined'){
		oEditor.Config.EditorAreaStyles += 'div.ncEmbed, img.ncEmbed{behavior: url(' + g_oNcEditorOptions.SiteUrl + '/v/nceditor/css/behaviors/disablehandles.htc);}';
	}
	oEditor.Config.BodyClass = p_oTextOptionsEl.getAttribute("BodyClass");
	
	if(p_oTextOptionsEl.getAttribute("BodyStyle")){
		oEditor.Config.EditorAreaStyles += 'body{' + p_oTextOptionsEl.getAttribute("BodyStyle") + '}';
	}
	return oEditor;
}
function CreateOtherOptionArr(p_oTextOptonsEl){
	var oTempArr = [];
	var oEmbedEls = ncXml.selectNodes(p_oTextOptonsEl, "EmbedOptions/EmbedOptionGroup/EmbedOption");
	for(var i = 0; i < oEmbedEls.length; i++){ 
		oTempArr[i] = {Text: ncXml.getNodeText(oEmbedEls[i]), Value: oEmbedEls[i].getAttribute("Value")};
	}
	return oTempArr;
}
function CreateQueryFieldArr(p_oTextOptionsEl){
	// use object - otherwise we'd create an array the size of the largest fieldid
	var oTempArr = {};
	var oQueryFieldEls = ncXml.selectNodes(p_oTextOptionsEl, "QueryFields/QueryField");
	for(var i = 0; i < oQueryFieldEls.length; i++){
		oTempArr[oQueryFieldEls[i].getAttribute("FieldId")] = oQueryFieldEls[i].getAttribute("Type");
	}
	return oTempArr;				
}
function CreateFormFieldArr(p_oTextOptionsEl){
	// use object - otherwise we'd create an array the size of the largest fieldid
	var oTempArr = {};
	var oFormFieldEls = ncXml.selectNodes(p_oTextOptionsEl, "FormFields/FormField");
	for(var i = 0; i < oFormFieldEls.length; i++){
		oTempArr[oFormFieldEls[i].getAttribute("FieldId")] = oFormFieldEls[i].getAttribute("Type");
	}
	return oTempArr;				
}
function GetEditorCss(p_sStyleSheets){
	var oStyleSheetArr = p_sStyleSheets ? p_sStyleSheets.split(',') : [];
	oStyleSheetArr[oStyleSheetArr.length] = g_oNcEditorOptions.SiteUrl + '/v/nceditor/css/EditFrame.css';
	return oStyleSheetArr;
}
function FCKeditor_OnComplete(p_oEditor){
	// prevent embed tag resizing (moz) n.b. do now and after html setting
	FCKEDitor_AfterSetHTML(p_oEditor);
	p_oEditor.Events.AttachEvent('OnAfterSetHTML', FCKEDitor_AfterSetHTML);
	
	
	//p_oEditor.Events.AttachEvent( 'OnSelectionChange', DoSomething );
	
	if(typeof ncExtraFCKeditor_OnComplete != 'undefined'){
		ncExtraFCKeditor_OnComplete(p_oEditor);
	}
}
function FCKEDitor_AfterSetHTML(p_oEditor){
	// stop embed tags being resized if object resizing not disabled (moz) 
	if(PreventObjectResizeOk(p_oEditor)){
		if(!p_oEditor.Config.DisableObjectResizing){
			var sMethod = new Function('PreventEmbedTagResize(arguments[0], "' + p_oEditor.Name + '");');
			ncBwHlpr.AttachEvent(p_oEditor.EditorDocument.body, 'mousedown', sMethod);
		}
	}
}
function PreventObjectResizeOk(p_oEditor){
	try{
		if(p_oEditor.EditorDocument.queryCommandEnabled('enableObjectResizing')){
			return true;
		}
	}catch(e){}
	return false;
}

/*
var counter = 0 ;
function DoSomething( editorInstance )
{
    // This is a sample function that shows in the title bar the number of times
    // the "OnSelectionChange" event is called.
    window.document.title = editorInstance.Name + ' : ' + ( ++counter ) ;
}
*/



// turns off object resizing if the source is an nc embed object (FF / WebKit - IE done using behaviours)
function PreventEmbedTagResize(e, p_sEditorName){
	var bAllowResize = true;
	var oEditor = FCKeditorAPI.GetInstance(p_sEditorName);
	var oImg = e.target;
	if(oImg && oImg.tagName == 'IMG'){
		if(oImg.getAttribute('src').toString().indexOf('/v/nc/GetEmbedImage.nc') != -1){
			bAllowResize = false;
		}
	}
	oEditor.EditorDocument.execCommand('enableObjectResizing', false, bAllowResize);
}

/* ----- convert / revert embed tags ----- */
// converts tag codes to html buttons for rendering in html editor
function ConvertEmbedTags(p_sValue){
	// tidy legacy html before opening in editor - it's cleaning can upset the html
	var sValue = TidyLegacyHtml(p_sValue);

	// <P></P> checks in case a block embed was added in a <P> tag - editor will convert this to a div surrounded by 2 <p>'s
	// convert tags between elements to images / blocks
	var oExp = new RegExp("(<p>)?&lt;#((?:E-)?Embed\\.\\d+\\.\\d+(?:/[^:]+)?):?((?:[^#]|(?:&#35;))*)#&gt;((?:&nbsp;)?</p>)?", "gi");
	sValue = sValue.replace(oExp, ReplaceEmbedTag);
	
	// convert tags within elements - used in relative links etc
	// n.b. we move trailing text for legacy compatibility - no longer used
	oExp = new RegExp("<#(Embed\\.\\d+\\.\\d+)/?((?:[^#]|(&#35;))*)?#>", "g");
	//sValue = sValue.replace(oExp, "_#$1#_$2");
	sValue = sValue.replace(oExp, "_#$1#_");
	
	return sValue;
}
// removes unwanted <p> tags from old editor - otherwise they get expanded and add extra spacing in new editor
function TidyLegacyHtml(p_sHtml){
	var sHtml = p_sHtml;
	
	// remove multiple empty <p> tags - editor will insert &nbsp; into each one and when empty 
	// html only inserts space for first one with content 
	var oExp = new RegExp('(<p></p>\n?)+<p>', 'gi');
	sHtml = sHtml.replace(oExp, '<p>');
	
	// remove open <p> followed by <p> or tags that will wrap <p> tags
	oExp = new RegExp('<p>\n?(<(?:p|blockquote|div|table))', 'gi');
	sHtml = sHtml.replace(oExp, '$1');
		
	return sHtml;
}
function ReplaceEmbedTag(p_sEmbed, p_sOpenP, p_sData, p_sText, p_sCloseP){
	var sData = p_sData;
	
	// replace html entities in data with : and #
	sData = sData.replace(/&#35;/g, '#');
	sData = sData.replace(/&#58;/g, ':');
	
	// remove new line chars that some browsers pass here
	var sText = p_sText.replace(new RegExp('\n', 'gi'), '');
	var sImgSrc = '../v/nc/GetEmbedImage.nc?t=' + UrlEncode(sText);
	
	var sTemp;
	var oEmbed = new ncEmbed(sData, p_sText);
	if(oEmbed.DisplayType() == ncTextEmbedBlock){
		// block embed - n.b. add "[e]" inside it otherwise editor strips out the empty div (&nbsp; no good either)
		// n.b. ignore surrounding open & close <p>'s if we have any 
		sTemp = '<div class="ncEmbed" data="' + sData + '" style="background-image: url(\'' + sImgSrc + '\');">[e]</div>';
	}else{
		// inline embed
		sTemp = (p_sOpenP ? p_sOpenP : '') + '<img class="ncEmbed" data="' + sData + '" src="' + sImgSrc + '" alt="" />' + 
				(p_sCloseP ? p_sCloseP : '');
	}
	
	return sTemp;
}
function RevertEmbedTags(p_sValue, p_bConvertHtmlEmbeds){
	var sValue = p_sValue;
	
	sValue = RevertInlineEmbedTags(sValue, p_bConvertHtmlEmbeds);
	sValue = RevertBlockEmbedTags(sValue, p_bConvertHtmlEmbeds);
	
	return sValue;
}

function RevertInlineEmbedTags(p_sValue, p_bConvertHtmlEmbeds){
	var sValue = p_sValue; 
	
	// revert embeds between tags n.b. allow data and src in either order
	var sSrcPattern = 'src="\\.\\./v/nc/GetEmbedImage\\.nc\\?t=([^\\"]*)"';
	var sDataPattern = 'data="([^\\"]+)"';
	var sEmbedPattern = '(?:' + '<img[^>]*' + sDataPattern + '[^>]*' + sSrcPattern + '[^>]*/>' + '|' + 
								'<img[^>]*' + sSrcPattern + '[^>]*' + sDataPattern + '[^>]*/>' + ')';
	
	var oEmbedExp = new RegExp(sEmbedPattern, "gi");
	if(p_bConvertHtmlEmbeds){
		sValue = sValue.replace(oEmbedExp, RevertEmbedTags__EmbedReplaceIncludingHtml);
	}else{
		sValue = sValue.replace(oEmbedExp, RevertEmbedTags__EmbedReplaceExcludingHtml);
	}
	
	if(p_bConvertHtmlEmbeds){
		// no longer place external text back inside embed - we don't use it and it upsets relative links with anchors / querystrings
		// revert embeds within tags
		//oEmbedExp = new RegExp('_#(Embed\\.\\d+\\.\\d+)#_([^"]*)?', 'g');
		//sValue = sValue.replace(oEmbedExp, RevertEmbedTags_EmbedReplaceWithinTag);
		oEmbedExp = new RegExp('_#(Embed\\.\\d+\\.\\d+)#_', 'g');
		sValue = sValue.replace(oEmbedExp, '<#$1#>');
	}
	return sValue;
}
//function RevertEmbedTags_EmbedReplaceWithinTag(p_sEmbed, p_sData, p_sText){
//	return '<#' + p_sData + '/' + p_sText.replace(/#/g, '&#35') + '#>';
//}
function RevertBlockEmbedTags(p_sInText, p_bConvertHtmlEmbeds){
	// ----- strip out content that may have snuck in between the opening and closing part of the block tag -----
	var oExp = GetRevertBlockEmbedExp(false, "i");
	
	var sText = p_sInText;
	var sOutText = '';
	var lStartPos = sText.search(oExp);
	var lChildDivDepth = 0;
	
	while(lStartPos != -1){
		var bEmbedOpen = true;
		
		// add text preceding the embed to output
		sOutText += sText.substr(0, lStartPos);
		sText = sText.substr(lStartPos);
		
		// add opening part of teh embed tag to output
		var lFinishPos = sText.indexOf('>');
		sOutText += sText.substr(0, lFinishPos + 1);
		sText = sText.substr(lFinishPos + 1);
		
		// strip out content inside the div tag - should not be any, but a browser or user may sneak it in
		while(bEmbedOpen){
			// look for div close - watch out for child divs!!!
			var lCloseDivPos = sText.search(/<\/div>/i);
			var lOpenDivPos = sText.search(/<div[^>]*>/i);
			
			if(lChildDivDepth == 0 && (lOpenDivPos == -1 || lOpenDivPos > lCloseDivPos)){
				// closing div tag - add it to the out text
				sOutText += sText.substr(lCloseDivPos, 6);
				sText = sText.substr(lCloseDivPos + 6);
				bEmbedOpen = false;
			}else{
				if(lOpenDivPos != -1 && lOpenDivPos < lCloseDivPos){
					// <div> before </div>
					lChildDivDepth++;
					sText = sText.substr(lOpenDivPos + 1);
				}else{
					// </div>
					lChildDivDepth--;
					sText = sText.substr(lCloseDivPos + 1);
				}
			}
		}
		// look for the next embed
		lStartPos = sText.search(oExp);
	}
	sOutText += sText;
	
	// ----- replace the tags now we've tidied them up -----
	var oEmbedExp = GetRevertBlockEmbedExp(true, "gi");
	if(p_bConvertHtmlEmbeds){
		sOutText = sOutText.replace(oEmbedExp, RevertEmbedTags__EmbedReplaceIncludingHtml);
	}else{
		sOutText = sOutText.replace(oEmbedExp, RevertEmbedTags__EmbedReplaceExcludingHtml);
	}
	
	return sOutText;
}
function GetRevertBlockEmbedExp(p_bIncludeClosingTag, p_sFlags){
	var sClosingTag = p_bIncludeClosingTag ? '</div>' : '';

	// allow for full or relative urls - some browsers expand 
	var sUrlBase = '(?:' + g_oNcEditorOptions.SiteUrl + '|\\.\\.)';
	//var sSrcPattern = 'background-image: url\\(\'?' + sUrlBase + '/v/nc/GetEmbedImage\\.nc\\?t=([^\\(\']*)\'?\\)';
	// some browsers insert ', some &quot;
	var sQuot = '(?:\'|&quot;)';
	var sSrcPattern = 'background-image: url\\(' + sQuot + '?' + sUrlBase + '/v/nc/GetEmbedImage\\.nc\\?t=([^\\)\';]*)' + sQuot + '?\\)';
	
	// n.b. allow data and src in either order
	var sDataPattern = 'data="([^\\"]+)"';
	var sEmbedPattern = '(?:' + '<div[^>]*' + sDataPattern + '[^>]*' + sSrcPattern + '[^>]*>' + sClosingTag + '|' + 
								'<div[^>]*' + sSrcPattern + '[^>]*' + sDataPattern + '[^>]*>' + sClosingTag + ')';							
	return new RegExp(sEmbedPattern, p_sFlags);
}
function RevertEmbedTags__EmbedReplaceIncludingHtml(p_sEmbed, p_sData1, p_sText1, p_sText2, p_sData2){
	return RevertEmbedTags__EmbedReplaceBase(p_sEmbed, p_sData1, p_sText1, p_sText2, p_sData2, true);
}
function RevertEmbedTags__EmbedReplaceExcludingHtml(p_sEmbed, p_sData1, p_sText1, p_sText2, p_sData2){
	return RevertEmbedTags__EmbedReplaceBase(p_sEmbed, p_sData1, p_sText1, p_sText2, p_sData2, false);
}
function RevertEmbedTags__EmbedReplaceBase(p_sEmbed, p_sData1, p_sText1, p_sText2, p_sData2, p_bConvertHtmlEmbeds){
	var sText = p_sText1 ? p_sText1 : p_sText2;
	var sData = p_sData1 ? p_sData1 : p_sData2; 
	
	// only convert email embeds, not html embeds if changing from html to text email
	if(p_bConvertHtmlEmbeds || sData.indexOf("E-") == 0){
		// convert html new lines to new lines (before removing hashes)
		sData = sData.replace(/&#13;&#10;/gi, "\r\n");
		
		if(sData.substr("E-") == 0){			
			// email embed remove hashes and colons (text embeds allow these as entities - emails don't as may be plain text)
			sData = sData.replace(/[#\:]/gi, "");
		}else{
			// replace any : / # chars with html entities
			sData = sData.replace(/\:/g, '&#58;');
			sData = sData.replace(/#/g, '&#35;');
		}
		
		// remove tags and hashes from text value (text embeds hashes as entities - emails don't as may be plain text)
		if(sText){
			sText = sText.replace(/<[^>]*>/gi, "");
			sText = sText.replace(/#/gi, "");
		}else{
			sText = "embed"
		}
		
		return "&lt;#" + sData + ":" + UrlDecode(sText) + "#&gt;"  
	}else{
		// html embed tag - remove it
		return '';
	}
}
/* ----- / convert / revert embed tags ----- */
