// globals
var activeTab = '1';
var executable = 'indexplus';
var isIE = false;

function makeAJAXRequest(session, action, parameters) {
	// make the ajax call
	var url = executable + '?_IXSESSION_=' + session + '&_IXACTION_=file&_IXFILE_=templates/ajax/action.html&_IXAJAXID_=' + getRecordID() + '&_IXAJAXACTION_=' + action + '&_IXAJAXPARAMS_=' + parameters
	AJAX_request('POST', url, handleAJAXResponse);

}

function makeAJAXConfigEditRequest(session, configName, paramName, paramValue) {
	// make the ajax call
	var url = executable + '?_IXSESSION_=' + session + '&_IXACTION_=file&_IXFILE_=templates/ajax/action.html&_IXAJAXCONFIGNAME_=' + configName + '&_IXAJAXPARAMNAME_=' + paramName + '&_IXAJAXPARAMVALUE_=' + encodeURIComponent(paramValue)
	AJAX_request('POST', url, handleAJAXResponse);

}

function makeAJAXConfigEditAllRequest(session, configName, paramNames) {
	var paramNamesArgument = '';
	var paramValuesArgument = '';
 	for (var i = 0; i < paramNames.length; i++) {
 		var paramName = paramNames[i];
 		var inputNode = document.getElementById('cms_edit_' + paramName);
 		if (inputNode) {
 			var inputValue = inputNode.value;
 			if (paramNamesArgument) {
 				paramNamesArgument = paramNamesArgument + ','
 				paramValuesArgument = paramValuesArgument + ','
 			}
			paramNamesArgument = paramNamesArgument + paramName;
			paramValuesArgument = paramValuesArgument + inputValue;
 		}
 	}

	// make the ajax call
	var url = executable + '?_IXSESSION_=' + session + '&_IXACTION_=file&_IXFILE_=templates/ajax/action.html&_IXAJAXCONFIGNAME_=' + configName + '&_IXAJAXPARAMNAME_=' + paramNamesArgument + '&_IXAJAXPARAMVALUE_=' + encodeURIComponent(paramValuesArgument)
	AJAX_request('POST', url, handleAJAXResponse);

}

function makeAJAXHarvestEditRequest(session, harvest_name, harvest_field, harvest_value) {
	// make the ajax call
	var url = executable + '?_IXSESSION_=' + session + '&_IXACTION_=file&_IXFILE_=templates/ajax/action.html&_IXAJAXHARVESTNAME_=' + harvest_name + '&_IXAJAXHARVESTFIELD_=' + harvest_field + '&_IXAJAXHARVESTVALUE_=' + encodeURIComponent(harvest_value)
	AJAX_request('POST', url, handleAJAXResponse);

}

function makeAJAXTextEditRequest(session, action) {
	var textEditNode = document.getElementById('content_text_edit');
	var textEditValue = textEditNode.value;
	var escapedTextEditValue = encodeURIComponent(textEditValue);
	var url = executable + '?_IXSESSION_=' + session + '&_IXACTION_=file&_IXFILE_=templates/ajax/action.html&_IXAJAXID_=' + getRecordID() + '&_IXAJAXACTION_=' + action + '&_IXAJAXTEXTEDITVALUE_=' + escapedTextEditValue;
	
	// make the ajax call
	AJAX_request('POST', url, handleAJAXResponse);

	if (action == 'text_edit_cancel') {
		var originalNode = document.getElementById('content_text_edit_original');
		var originalValue = originalNode.value;
		textEditNode.value = originalValue;
	}
}

function makeAJAXSelectionRequest(session, action, parameters) {
	// get selection
	isIE = isIESelection();
	var selection = getSel();
	var selectionString = getSelText();
	var selectionLength = selectionString.length;
		
	// validate selection
	var selectionOK = 1;

	// have something selected
	if (selectionOK) {
		if (selectionLength == 0) {
			var gotAction = 0;
			if (action == 'prepare_media') {
				var atEnd = confirm('This will place your media file at the end of the page. If you would like it elsewhere, press Cancel and select the text in front of which you would like to place it.');
				if (atEnd) {
					makeAJAXRequest(session, action, parameters);
				}
				gotAction = 1;
			}
			if (action == 'prepare_link') {
				alert('Please select the text that you want to make into a link first.');
				gotAction = 1;
			}
			if (!gotAction) {
				alert('Please select some text first.');
			}
			selectionOK = 0;
		}
	}

	// but don't start with white space
	if (selectionOK) {
		if (selectionString.match(/^\r\n/)) {
			alert('Your selection should not include leading white space.');
			selectionOK = 0;
		}
	}
	
	// don't include any images
	if (selectionOK) {
		var selSource = getSelSource();
		var tmpSource = selSource.replace(/X/g, 'x');
		tmpSource = tmpSource.replace(/Y/g, 'y');
		tmpSource = tmpSource.replace(/<table[^>]*>/g, 'X');
		tmpSource = tmpSource.replace(/<\/table>/g, 'Y');
		if (tmpSource.match(/^.*X.*$/)) {
			alert('Your selection should not include any images.');
			selectionOK = 0;
		}
		if (tmpSource.match(/^<tr>.*<\/tr>$/)) {
			alert('Your selection should not be within an image.');
			selectionOK = 0;
		}
		if (tmpSource.match(/^<td>.*<\/td>$/)) {
			alert('Your selection should not be within an image.');
			selectionOK = 0;
		}
	}

	// if selection's fine, make the ajax call
	if (selectionOK) {

		// get nodes needed for calculating the offset
		var contentNode = document.getElementById('content_node');

		var offset = selectionOffset(contentNode);
		if (offset != -1) {
			// make the ajax call
			var url = executable + '?_IXSESSION_=' + session + '&_IXACTION_=file&_IXFILE_=templates/ajax/action.html&_IXAJAXID_=' + getRecordID() + '&_IXAJAXOFFSET_=' + offset.toString() + '&_IXAJAXLENGTH_=' + selectionLength.toString() + '&_IXAJAXACTION_=' + action + '&_IXAJAXPARAMS_=' + parameters
			if (isIE) {
				url = url + '&_IXIE_=yes'
			}
			AJAX_request('POST', url, handleAJAXResponse);
		}
	}
}


function reduceOffsetForImages(range, offset) {
	var error = 0;
	var tmp_div = document.createElement("div");
	tmp_div.appendChild(range.cloneContents());
	var offsetSource = tmp_div.innerHTML;
	var tmpSource = offsetSource.replace(/X/g, 'x');
	tmpSource = tmpSource.replace(/Y/g, 'y');
	tmpSource = tmpSource.replace(/Q/g, 'q');
	tmpSource = tmpSource.replace(/R/g, 'r');
	tmpSource = tmpSource.replace(/<table[^>]*>/g, 'X');
	tmpSource = tmpSource.replace(/<\/table>/g, 'Y');
	if (tmpSource.match(/^<div[^>]*>X[^Y]*Y<\/div>$/)) {
		alert('Your selection should not be within an image.');
		error = 1;
	} else {
		var offsetReduction = 0;
		var gotImages = 1;
		var loop = 0;
		while (gotImages) {
			loop = loop + 1;
			if (tmpSource.match(/^.*X.*$/)) {
				var initialSource = tmpSource;
				tmpSource = tmpSource.replace(/X[^Y]*<div[^>Y]*>([^Y]*)<a[^>Y]*>([^Y]*)<\/a><\/div>[^Y]*<div[^>Y]*>([^Y]*)<\/div>[^Y]*Y/, 'Q$1$2$3R');
				if (tmpSource == initialSource) {
					// regexp failed so try again without the link
					tmpSource = tmpSource.replace(/X[^Y]*<div[^>Y]*>([^Y]*)<\/div>[^Y]*<div[^>Y]*>([^Y]*)<\/div>[^Y]*Y/, 'Q$1$2R');
				}
				if (tmpSource == initialSource) {
					// regexp still failed so must be within an image
					alert('Your selection should not be within an image.');
					error = 1;
					gotImages = 0;
				}
				if (!error) {
					var reduction = tmpSource.replace(/^.*Q(.*)R.*$/, '$1');
					offsetReduction = offsetReduction + reduction.length;
					tmpSource = tmpSource.replace(/Q.*R/, '');
				}
			} else {
				gotImages = 0;
			}
			// stop if ludicrous
			if (loop > 100) {
				alert('Sorry, failed to offset for images.');
				error = 1;
				gotImages = 0;
			}
		}
	}
	if (error) {
		offset = -1;
	} else {
		offset = offset - offsetReduction;
	}
	return offset;
}


function handleAJAXResponse() {
/*  httpRequest.readyState
    * 0 (uninitialized)
    * 1 (loading)
    * 2 (loaded)
    * 3 (interactive)
    * 4 (complete) 

    httpRequest.status is the HTTP status 

*/
	window.status = window.status+" "+httpRequest.readyState;
	try { 
		if(httpRequest.readyState == 4) {
			if(httpRequest.status == 200) {
				window.status = "TRUE";
				// THIS IS WHERE IT HAPPENS
				updateDisplay(httpRequest.responseText);				
			} else {
				//FAILED: webserver/web gateway error
				window.status = "FALSE";
				alert("Server Response: "+httpRequest.status);		
			}			
	 	}
	} catch(e) {
		alert("Server Response: "+httpRequest.status);	
		//FAILED: webserver/webgateway/client request error	
		//httpRequest = null;
		alert('failed AJAX call: '+e.description);
		window.status = "NULL : "+e.description;
	}

}


function updateDisplay(response) {
	var status = response.substr(0,3);
	var data = response.replace(/^.../, '');
	data = data.replace(/\n\r\n$/, '');
	var got_status = 0;
	// K_CMS_AJAX_status_message
	if (status == '000') {
		got_status = 1;
		alert(data);
	}
	// K_CMS_AJAX_status_html
	if (status == '001') {
		got_status = 1;
		var contentNode = document.getElementById('content_node');
		contentNode.innerHTML = data;
		// and if on text edit tab, also need to update the textarea holding the original text
		if (activeTab == '2') {
			makeAJAXRequest(getSessionID(), 'update_text_edit_from_current', '');			
		}		
	}
	// K_CMS_AJAX_status_save
	if (status == '002') {
		got_status = 1;
		var contentNode = document.getElementById('content_node');
		contentNode.innerHTML = data;
		var recordNode = document.getElementById('content_node_record');
		if (recordNode) {
			recordNode.innerHTML = data;
			// if on text edit tab, also need to reset textarea holding original text
			if (activeTab == '2') {
				var originalNode = document.getElementById('content_text_edit_original');
				var textEditNode = document.getElementById('content_text_edit');
				var textEditValue = textEditNode.value;
				originalNode.value = textEditValue;
			}
			// if on style tab, also need to reset both textareas on the edit tab
			// this requires an ajax call to get the new data in the field
			makeAJAXRequest(getSessionID(), 'update_text_edit', '');
			alert('Your changes have been saved.');
		} else {
			alert('Sorry, failed to find "content_node_record". Your changes have not been saved.');
		}
	}
	// K_CMS_AJAX_status_cancel
	if (status == '003') {
		got_status = 1;
		alert('Sorry, an unexpected status has been returned.');
	}
	// K_CMS_AJAX_status_update_text_edit
	if (status == '004') {
		got_status = 1;
		// data is the raw data and we need to update the text edit controls with it
		var originalNode = document.getElementById('content_text_edit_original');
		originalNode.value = data;
		var textEditNode = document.getElementById('content_text_edit');
		textEditNode.value = data;

		// and need to reload tinyMCE
		tinyMCE.activeEditor.load();
	}
	// K_CMS_AJAX_status_no_action
	if (status == '005') {
		got_status = 1;
	}
	// K_CMS_AJAX_status_link_prepare
	if (status == '006') {
		got_status = 1;
		// data is the html controls we need to show
		var paletteNode = document.getElementById('cms_edit_palette');
		paletteNode.innerHTML = data;
		hideItem('cms_edit_toolbar_tab3');
		showItem('cms_edit_palette');
		if (document.getElementById('url_input')) {
			document.getElementById('url_input').focus();
		}
	}
	// K_CMS_AJAX_status_media_prepare
	if (status == '007') {
		got_status = 1;
		// data is the html controls we need to show
		var paletteNode = document.getElementById('cms_edit_palette');
		paletteNode.innerHTML = data;
		hideItem('cms_edit_toolbar_tab3');
		showItem('cms_edit_palette');
	}
	// K_CMS_AJAX_status_update_title
	if (status == '008') {
		got_status = 1;
		// data is the new title
		var oldTitle = document.getElementById('pagetitle').innerHTML;
		var titleRegExp = new RegExp (oldTitle + '$')
		var newSiteTitle = document.title.replace(titleRegExp, data)
		document.title = newSiteTitle
		document.getElementById('pagetitle').innerHTML = data;
	}
	// K_CMS_AJAX_status_update_config
	if (status == '009') {
		got_status = 1;
		// data is the config name that's been updated
		if (data == 'contact_email') {
			// just update the hidden form input (if it's there)
			var emailInputs = document.getElementsByName('TO_EMAIL');
			if (emailInputs.length == 1) {
				emailInputs[0].value = document.getElementById('cms_edit_' + data).value;
			}
		} else {
			confirmCloseEditWindow = false;
			location.reload(true);
		}
		alert('Your settings have been updated.');
	}
	// K_CMS_AJAX_status_update_pub_date
	if (status == '010') {
		got_status = 1;
		// data is the new date
		var dateElement = document.getElementById('pub_date');
		if (dateElement) {
			dateElement.innerHTML = data;
		}
	}
	if (got_status == 0) {
		alert(response);
	}
}

function showCMSEditTab1() {
	// check whether ok to leave tab
	if (okToLeave()) {
		// drop any sitting changes
		var recordNode = document.getElementById('content_node_record');
		var contentNode = document.getElementById('content_node');
		contentNode.innerHTML = recordNode.innerHTML;
		var originalNode = document.getElementById('content_text_edit_original');
		var textEditNode = document.getElementById('content_text_edit');
		textEditNode.value = originalNode.value;
		if (activeTab == '3') {
			makeAJAXRequest(getSessionID(), 'cancel', '');
		}
		// switch tabs
		hideItem('cms_edit_tab2');
		hideItem('cms_edit_tab3');
		showItem('cms_edit_tab1');
		activeTab = '1';
	}
}

function showCMSEditTab2() {
	// check whether ok to leave tab
	if (okToLeave()) {
		// drop any sitting changes
		if (activeTab == '3') {
			var recordNode = document.getElementById('content_node_record');
			var contentNode = document.getElementById('content_node');
			contentNode.innerHTML = recordNode.innerHTML;
			var originalNode = document.getElementById('content_text_edit_original');
			var textEditNode = document.getElementById('content_text_edit');
			textEditNode.value = originalNode.value;
			makeAJAXRequest(getSessionID(), 'cancel', '');
		}
		// switch tabs
		hideItem('cms_edit_tab1');
		hideItem('cms_edit_tab3');
		showItem('cms_edit_tab2');
		activeTab = '2';
	}
}

function showCMSEditTab3() {
	// check whether ok to leave tab
	if (okToLeave()) {
		// drop any sitting changes
		if (activeTab == '2') {
			var recordNode = document.getElementById('content_node_record');
			var contentNode = document.getElementById('content_node');
			contentNode.innerHTML = recordNode.innerHTML;
			var originalNode = document.getElementById('content_text_edit_original');
			var textEditNode = document.getElementById('content_text_edit');
			textEditNode.value = originalNode.value;
		}
		// switch tabs
		hideItem('cms_edit_tab1');
		hideItem('cms_edit_tab2');
		showItem('cms_edit_tab3');
		activeTab = '3';
	}
}

function okToLeave() {
	ok_to_leave = 1;
	if (activeTab == '2') {
		var originalNode = document.getElementById('content_text_edit_original');
		var textEditNode = document.getElementById('content_text_edit');
		if (textEditNode.value != originalNode.value) {
			ok_to_leave = confirm('OK to discard your changes on this tab?');
		}
	}
	if (activeTab == '3') {
		var recordNode = document.getElementById('content_node_record');
		var contentNode = document.getElementById('content_node');
		if (contentNode.innerHTML != recordNode.innerHTML) {
			ok_to_leave = confirm('OK to discard your changes on this tab?');
		}
	}
	return ok_to_leave;
}

function linkCancel() {
	hideItem('cms_edit_palette');
	showItem('cms_edit_toolbar_tab3');
	var paletteNode = document.getElementById('cms_edit_palette');
	paletteNode.innerHTML = '';
}

function linkOK(linkType) {
	var urlValue = document.getElementById('url_input').value;
	var targetValue = document.getElementById('target_input').value;
	makeAJAXRequest(getSessionID(), 'make_link', encodeURIComponent(urlValue) + ',' + encodeURIComponent(targetValue));
	hideItem('cms_edit_palette');
	showItem('cms_edit_toolbar_tab3');
	var paletteNode = document.getElementById('cms_edit_palette');
	paletteNode.innerHTML = '';
}

function mediaCancel() {
	hideItem('cms_edit_palette');
	showItem('cms_edit_toolbar_tab3');
	var paletteNode = document.getElementById('cms_edit_palette');
	paletteNode.innerHTML = '';
}

function imageSelect(imageID) {
	makeAJAXRequest(getSessionID(), 'insert_image', imageID);
	hideItem('cms_edit_palette');
	showItem('cms_edit_toolbar_tab3');
	var paletteNode = document.getElementById('cms_edit_palette');
	paletteNode.innerHTML = '';
}

function docSelect(docID) {
	makeAJAXRequest(getSessionID(), 'insert_document', docID);
	hideItem('cms_edit_palette');
	showItem('cms_edit_toolbar_tab3');
	var paletteNode = document.getElementById('cms_edit_palette');
	paletteNode.innerHTML = '';
}

function makeThisSiteLink(articleID) {
	var targetValue = document.getElementById('target_input').value;
	makeAJAXRequest(getSessionID(), 'make_this_site_link', articleID + ',' + targetValue);
	hideItem('cms_edit_palette');
	showItem('cms_edit_toolbar_tab3');
	var paletteNode = document.getElementById('cms_edit_palette');
	paletteNode.innerHTML = '';
}

function initTinyMCE(cgi_document_base) {
	var css = cgi_document_base + "stylesheets/ajax.css"
	//theme_advanced_buttons1 : "ssl_bold,ssl_italic,separator,ssl_align_left,ssl_align_centre,ssl_align_right,ssl_align_justify,separator,ssl_heading1,ssl_heading2,ssl_heading3,undo,redo,separator,code,separator,save,cancel",
	tinyMCE.init({
		mode : "textareas",
		editor_selector : "mceEditor",
		theme : "advanced",
		plugins : "save,ssl_c24ssn",
		add_unload_trigger : false,
		theme_advanced_toolbar_location : "top",
		theme_advanced_toolbar_align : "left",
		theme_advanced_buttons1 : "undo,redo,separator,save,cancel,separator,code",
		theme_advanced_buttons2 : "",
		theme_advanced_buttons3 : "",
		save_onsavecallback : "cmsSave",
		valid_elements: "@[id|class|style],span,div,br,link[handle|template|address|newwindow],-image[handle|showcaption],-asset[handle|caption]",
		custom_elements : "~link,image,~asset",
		apply_source_formatting : false,
		forced_root_block : false,
		force_br_newlines : true,
   	force_p_newlines : false,
		content_css : css,
		width : "420",
		height: "300"
});
}


// returns the offset of the current browser selection relative to the
// given container

function selectionOffset (contentNode) {
	var selection = getSel();

	var offset = -1;

	if (selection.anchorNode !== undefined) {
		var anchorNode = selection.anchorNode;
		var anchorOffset = selection.anchorOffset;
		var focusNode = selection.focusNode;
		var focusOffset = selection.focusOffset;

		// get length to selection anchor
		var rangeToAnchor = document.createRange();
		rangeToAnchor.setStartBefore(contentNode);
		rangeToAnchor.setEnd(anchorNode, anchorOffset);
		var stringToAnchor = rangeToAnchor.toString();
		var lengthToAnchor = stringToAnchor.length;

		// get length to selection focus
		var rangeToFocus = document.createRange();
		rangeToFocus.setStartBefore(contentNode);
		rangeToFocus.setEnd(focusNode, focusOffset);
		var stringToFocus = rangeToFocus.toString();
		var lengthToFocus = stringToFocus.length;

		// use the shortest length for the offset
		// reduceOffsetForImages sets offset to -1 if there's a problem
		var offset = 0;
		if (lengthToAnchor < lengthToFocus) {
			offset = lengthToAnchor;
			offset = reduceOffsetForImages(rangeToAnchor, offset);
		} else {
			offset = lengthToFocus;
			offset = reduceOffsetForImages(rangeToFocus, offset);
		}
	} else { // IE; adapted from TinyMCE's getBookmark()
		var marker = '<SPAN id=userselection></SPAN>'
		var oldhtml = contentNode.innerHTML;
		selection.pasteHTML(marker + selection.htmlText);
		var html = contentNode.innerHTML;
		offset = html.indexOf(marker);
		// strip out HTML
		if (offset >= 0) {
			var sub = html.substr(0,offset);
			// nullify the forthcoming magic offset for headings
			// if they're right at the beginning - see olly again
			if (sub.match(/^<DIV/)) {
				offset+=2;
			}
			var intag = false;
			var intable = false;
			var i = 0;
			for (var i=0; i<sub.length; i++) {
				var c = sub.charAt(i);
				if (c == '<') {
					intag = true;
					// images are in tables, with captions
					// etc outside HTML - ignore the table
					if (sub.indexOf('<TABLE',i)==i) {
						intable = true;
					} else if(sub.indexOf('</TABLE>',i)==i){
						intable = false;
					}
					// magic offset for headings - ask olly
					if (!intable && (sub.indexOf('<DIV',i)==i)) {
						offset-=2;
					}
				}
				if (intag || intable)
					offset--;
				if (c == '>')
					intag = false;
			}
		}
		contentNode.innerHTML = oldhtml;
	}

	return offset;
}

