
stylePath = "/skins/ace/";
_skin_path = "/skins/";
_script_path = "/";

baseHref = "http://infolit.viawiki.com";

_editor_url = "/editor/";
_editor_lang = "en"; 
_editor_skin = ""; 
_editor_styles_path = "/skins/ace/__editor.css";

/*
 * MindTouch Deki - a commercial grade open source wiki
 * Copyright (C) 2006 MindTouch, Inc.
 * http://www.mindtouch.com/  oss@mindtouch.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * http://www.gnu.org/copyleft/gpl.html
 */

/***
 * hooks an onclick to all links in the table of contents dropdown which closes the window
 */
function hookTOCLinks() {
	var elt = document.getElementById('menuPageContent');
	if (!elt) return;
	var a_ = elt.getElementsByTagName('a');	
	for (var i = 0; i < a_.length; i++)
		a_[i].onclick = function () { menuBodyClick() };
};

function breadcrumbLoad(z) {
	document.getElementById('breadcrumb').innerHTML = z;
};

function doClosePopupMessage(divid, clearInnerHtml) {
    parent.hidePopWin(false);
	return false;
};

function doHidePopupMessage() {
   return doClosePopupMessage();
};

/***
 * this function will take all external link icons from topic
 * and append a child span that contains the link icon
 * this is to correct IE's behaviour of handling links that break cross mult lines
 */
function fixLinkIcons() {
	if (clientBrowser.isIe) {
		var elt = document.getElementById('topic');
		var a = elt.getElementsByTagName('a');
		var j = a.length;
		for (var i = 0; i < j; i++) {
			var rel = a[i].getAttribute('rel');
			if (rel && typeof(rel) == 'string' && rel != '') {
				var icona = a[i].cloneNode(true);
				var texta = a[i].cloneNode(true);
				icona.innerHTML = '&nbsp;';
				icona.style.textDecoration = 'none';
				icona.removeAttribute('rel');
				texta.removeAttribute('rel');
				texta.removeAttribute('className');
				if (a[i].className == 'link-user') {
					icona.style.padding = '0 3px 0 6px';
				} else if (rel != 'internal') {
					icona.style.padding = a[i].className == 'link-mailto' ? '0 12px 0 0' : '0 9px 0 0';
					texta.style.paddingRight = '0';
					texta.style.background = '';
				} else {
					icona.style.padding = '0 0 0 14px';
				}
				var span = document.createElement('span');
				if (rel == 'internal') {
					span.appendChild(icona);
					span.appendChild(texta);	
				}
				else{
					span.appendChild(texta);
					span.appendChild(icona);	
				}
				var parent = a[i].parentNode;
				parent.replaceChild(span, a[i]);
			}
		}
	}
};

function createFullHtml(title, body, head, _lang) {
    var html = "<html>\n";
    html += "<head>\n";
    html += "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + (HTMLArea.is_gecko ? document.characterSet : document.charset) + "\">\n";
    html += "<title>" + title + "</title>\n";
    html += "<link rel=\"stylesheet\" type=\"text/css\" href=\"/editor/popups/popup.css\" />\n";
    html += "<link rel=\"stylesheet\" type=\"text/css\" href=\"/skins/ace/_icons.css\" />\n";
    html += "<link rel=\"stylesheet\" type=\"text/css\" href=\"/skins/ace/__icons.css\" />\n";
    html += "<link rel=\"stylesheet\" type=\"text/css\" href=\"/editor/popups/selectTopic.css\" />\n";
    html += "<script type=\"text/javascript\" src=\"/editor/popups/popup.js\"></script>\n";
    html += "<script type=\"text/javascript\">function Init() {};\n";
    for (var i in _lang)
    	html += "var "+i+" = '"+_lang[i]+"';\n";
    html += "</script>\n";
    if (head) html += head;
    html += "</head>\n";
    html += "<body onload='Init()'><div class=\"wrap\">\n";
    html += body;
    html += "</div></body>\n";
    html += "</html>";
    return html;
};

function doPopupAttach() {
    showPopWin('/editor/popups/loading.html', 650, 134);
    var lang = new Object();
    lang['_lang_removeattach'] = _lang_removeattach;
    lang['_lang_fileattach'] = _lang_fileattach;
    setPopWinHTML(createFullHtml('Attach File', 
    	'<div id="attachFileForm">'+document.getElementById('attachFileForm').innerHTML+'</div>',
        "<script src=\"/skins/ace/attach.js\"></script>\n" +
        "<script type=\"text/javascript\">function Init() { __dlg_sizeToContent(); };</script>\n", lang
    ));
    return false;
};

function doPopupAttachNotification() {
	gPopupDoc.getElementById('form').style.display = "none";
	gPopupDoc.getElementById('waiting').style.display = "inline";
};
function doPopupRename(titleID) {
	showPopWin('/skins/ace/popup-rename.php?titleID=' + titleID + '&userName=' + _userName, 570, 530);
	return false;
};
function doPopupMoveAttach(titleID, attachID) {
	showPopWin('/skins/ace/popup-move-attach.php?titleID=' + titleID +'&attachID=' +  attachID + '&userName=' + _userName, 570, 459);
	return false;
};
function doPopupEditAttach(attachID) {
	showPopWin('/skins/ace/popup-attach.php?attachID=' + attachID, 380, 206);
	return false;
};
function doPopupRestrict(titleID) {
	showPopWin('/skins/ace/popup-restrict.php?titleID=' + titleID + '&userName=' + _userName, 380, 315);
	return false;
};
function doPopupViewRestrict(titleID) {
	showPopWin('/skins/ace/popup-viewrestrict.php?titleID=' + titleID, 380, 320);
	return false;
};
function doPopupDelete(titleID) {
	showPopWin('/skins/ace/popup-delete.php?titleID=' + titleID + '&userName=' + _userName, 400, 224);
	return false;
};

function hookEditIcons() {	
	function showEditIcon() {
		if (this.childNodes[1]) 
			this.childNodes[1].style.visibility = 'visible';
	};	
	function hideEditIcon() {
		if (this.childNodes[1]) 
			this.childNodes[1].style.visibility = 'hidden';
	};
	var elt = document.getElementById('topic');
	for (var i = 2; i < 7; i++) {
		var headers = elt.getElementsByTagName('h'+i);
		for (var j = 0;j<headers.length;j++) {
			headers[j].onmouseover = showEditIcon;
			headers[j].onmouseout = hideEditIcon;
		}
	}
	var elt = document.getElementById('title');
	if (elt) {
		elt.onmouseover = showEditIcon;
		elt.onmouseout = hideEditIcon;
	}
};

var fps = 500;
function doFade(elt, duration, _fade) {
	if (elt.fadeTimer) 
		clearInterval(elt.fadeTimer);

	elt.fadeOps = new Array();

	elt.fadeFrames = Math.round(fps * duration / 1000);
	elt.fadeInterval = 1000 / fps;
	for (var i = 0; i < _fade.length; i++) {
		var op = {};
		op.param = _fade[i].param;
		op.from = _fade[i].from;
		op.to = _fade[i].to;
		elt.fadeOps[elt.fadeOps.length]= op;
	}
	
	elt.fadeFrame = 0;
	elt.fadeTimer = setInterval ("doStep ('" + elt.id + "')", elt.fadeInterval);
};
	
function doStep(divid) {
	var elt = document.getElementById (divid);

	var completed = elt.fadeFrame / elt.fadeFrames;
	var inverseCompleted = (elt.fadeFrames - elt.fadeFrame) / elt.fadeFrames;

	for (var i = 0; i < elt.fadeOps.length; i ++) {
		var op = elt.fadeOps[i];
		elt.style[op.param] = Number (op.from) * inverseCompleted + Number (op.to) * completed;
	}

	elt.fadeFrame++;

	if (elt.fadeFrame > elt.fadeFrames) {
		clearInterval (elt.fadeTimer);
		elt.fadeTimer = null;
	}
};

function displayInlineMsg(div) {
	var elt = document.getElementById(div);
	
	//page offset from top
	var yOffset = getPageYOffset();
	elt.style.display = 'block';
	var itemHeight = getItemHeight(elt);
	var itemWidth = getItemWidth(elt);
	var eltXOffset = (winX/2) - (itemWidth/2);
	var eltYOffset = (winY/2) - (itemHeight/2) + yOffset;
	
	//set the props of the elt
	elt.style.position = 'absolute';
	elt.style.left = Math.round(eltXOffset) + 'px';
	elt.style.top = Math.round(eltYOffset) + 'px';
	elt.zIndex = 9999;
	
	//hide the message after a few minutes
    window.setTimeout("hideInlineMsg('"+div+"')", 3000);
    
    //IE doesn't support opacity
    if (!ie6 && !ie5) {
		doFade (elt, 650, [{param: "opacity", from: 1.0, to: 0.0}]);
	}
};

function hideInlineMsg(div) {
	document.getElementById(div).style.display = 'none';
};

function fixTables() {
	if (!clientBrowser.isIe)
		return;
	var content = document.getElementById('topic');
	var _tables = content.getElementsByTagName('table');
	if (_tables.length == 0)
		return false;
		
	for (var i = 0; i < _tables.length; i++ ) {		
		var table = _tables[i].cloneNode(true);
		var divTag = document.createElement('div');
		divTag.className = 'wrap_tbl';
		divTag.appendChild(table);
		if (is_gecko) {
			var parentNode = _tables[i].parentNode;
			parentNode.replaceChild(divTag, _tables[i]);
		}
		else {
			_tables[i].replaceNode(divTag);
		}
	}
	
};
function doToggleLayer(elt, setClass, toggleClass) {
	if (!setClass)
		setClass = 'show-no';
		
	if (elt.className == setClass) {
		elt.className = toggleClass;
		return;
	}
	
	if (elt.className == toggleClass) {
		elt.className = setClass;
		return;
	}
		
	var cssClass = elt.className.split(' ');
	if (searchKey = array_search(setClass, cssClass)) 
		cssClass[searchKey] = toggleClass;
	
	else
		cssClass.push(setClass);
		
	elt.className = cssClass.join(' ');
};
function array_search(needle, haystack) {
	for (var i = 0; i < haystack.length; i++ ) {
		if (haystack[i] == needle)
			return i;	
	}	
	return false;
};

function doSectionEditRedirect() {
	var icon = this.getElementsByTagName('span');
	if (icon.length == 0)
		return false;
	for (var i = 0; i < icon.length; i++) {
		if (icon[i].className == 'editsection') {	
			var link = this.getElementsByTagName('a');
			top.location.href = link[0].getAttribute('href');
		}
	}
};

function setHiddenSubmit(divid) {
	document.getElementById(divid).value = '1';
};

// toggles between image description/image form
function fileDesc(divid, type) {
	if (type == 'hide') {
		setDisplayMode('fileDescForm_'+divid, 'hide');
		setDisplayMode('fileDescDisplay_'+divid, 'show');
	}
	else {
		setDisplayMode('fileDescForm_'+divid, 'show');
		setDisplayMode('fileDescDisplay_'+divid, 'hide');
		document.getElementById('fileDescElement_'+divid).focus();
	}	
	imageCellHeights.resize();
	return false;
};

var imageCellHeights = {
	x : null, //total width of the gallery
	cellWidth : 200, //width of each image cell
	cellMinHeight : 235, //minimum cell height
	resize : function ()  {
		var elt = document.getElementById('imageGallery');
		if (!elt) 
			return;
			
		this.x = getItemWidth(elt);
		var imagesPerRow = Math.floor(this.x / this.cellWidth);
		var i = 0; //current number of images in the row
		var curRowHeight = 0;
		var cellHeight = 0;
		var list = elt.getElementsByTagName('li');
		for (var j = 0; j < list.length; j++) {
			list[j].style.height = '';
			list[j].style.minHeight = '';
			cellHeight = getItemHeight(list[j]);
			if (cellHeight > curRowHeight) 
				curRowHeight = cellHeight;
			if (i < (imagesPerRow - 1))
				i++;
			else {
				i = 0;
				curRowHeight = curRowHeight < this.cellMinHeight ? this.cellMinHeight: curRowHeight;
				
				//reset all items in this row to the greatest height
				for (k = 0; k < imagesPerRow; k++) {
					if (ie6 == 1)
						list[j-k].style.height = curRowHeight+'px';
					else
						list[j-k].style.minHeight = curRowHeight+'px';
				}
				curRowHeight = 0;
			}
		}
	}
};

function setDisplayMode(divid, type) {
	if (divLayer = document.getElementById(divid)) {
		if (type == 'show')
			divLayer.style.display = 'block';
		if (type == 'hide')
			divLayer.style.display = 'none';
	}
};

function toggleVisi(divid) {
 	if (myselect = document.getElementById(divid)) {
	 	if (myselect.style.visibility != 'hidden')
		 	myselect.style.visibility = "hidden";
	 	else 
		 	myselect.style.visibility = "visible";
 	}
};

// Wikipedia JavaScript support functions
// if this is true, the toolbar will no longer overwrite the infobox when you move the mouse over individual items
var noOverwrite=false;
var alertText;
var clientPC = navigator.userAgent.toLowerCase(); // Get client info
var is_gecko = ((clientPC.indexOf('gecko')!=-1) && (clientPC.indexOf('spoofer')==-1)
                && (clientPC.indexOf('khtml') == -1) && (clientPC.indexOf('netscape/7.0')==-1));
var is_safari = ((clientPC.indexOf('AppleWebKit')!=-1) && (clientPC.indexOf('spoofer')==-1));
var is_khtml = (navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ));
if (clientPC.indexOf('opera')!=-1) {
    var is_opera = true;
    var is_opera_preseven = (window.opera && !document.childNodes);
    var is_opera_seven = (window.opera && document.childNodes);
}

// add any onload functions in this hook (please don't hard-code any events in the xhtml source)
function onloadhook () {
    // don't run anything below this for non-dom browsers
    if(!(document.getElementById && document.getElementsByTagName)) return;
    histrowinit();
    unhidetzbutton();
    akeytt();
};

if (window.addEventListener) window.addEventListener("load",onloadhook,false);
else if (window.attachEvent) window.attachEvent("onload",onloadhook);


// document.write special stylesheet links
if(typeof stylepath != 'undefined' && typeof skin != 'undefined') {
    if (is_opera_preseven) {
        document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera6Fixes.css" />');
    } else if (is_opera_seven) {
        document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera7Fixes.css" />');
    } else if (is_khtml) {
        document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/KHTMLFixes.css" />');
    }
}
// for enhanced RecentChanges
function toggleVisibility( _levelId, _otherId, _linkId) {
	var thisLevel = document.getElementById( _levelId );
	var otherLevel = document.getElementById( _otherId );
	var linkLevel = document.getElementById( _linkId );
	if ( thisLevel.style.display == 'none' ) {
		thisLevel.style.display = 'block';
		otherLevel.style.display = 'none';
		linkLevel.style.display = 'inline';
	} else {
		thisLevel.style.display = 'none';
		otherLevel.style.display = 'inline';
		linkLevel.style.display = 'none';
		}
};

// page history stuff
// attach event handlers to the input elements on history page
function histrowinit () {
    hf = document.getElementById('pagehistory');
    if(!hf) return;
    lis = hf.getElementsByTagName('td');
    for (i=0;i<lis.length;i++) {
        inputs=lis[i].getElementsByTagName('input');
        if(inputs[0] && inputs[1]) {
                inputs[0].onclick = diffcheck;
                inputs[1].onclick = diffcheck;
        }
    }
    diffcheck();
};

// check selection and tweak visibility/class onclick
function diffcheck() { 
    var dli = false; // the li where the diff radio is checked
    var oli = false; // the li where the oldid radio is checked
    hf = document.getElementById('pagehistory');
    if(!hf) return;
    lis = hf.getElementsByTagName('td');
    for (i=0;i<lis.length;i++) {
        inputs=lis[i].getElementsByTagName('input');
        if(inputs[1] && inputs[0]) {
            if(inputs[1].checked || inputs[0].checked) { // this row has a checked radio button
                if(inputs[1].checked && inputs[0].checked && inputs[0].value == inputs[1].value) return false;
                if(oli) { // it's the second checked radio
                    if(inputs[1].checked) {
                    oli.className = "selected";
                    return false 
                    }
                } else if (inputs[0].checked) {
                    return false;
                }
                if(inputs[0].checked) dli = lis[i];
                if(!oli) inputs[0].style.visibility = 'hidden';
                if(dli) inputs[1].style.visibility = 'hidden';
                lis[i].className = "selected";
                oli = lis[i];
            }  else { // no radio is checked in this row
                if(!oli) inputs[0].style.visibility = 'hidden';
                else inputs[0].style.visibility = 'visible';
                if(dli) inputs[1].style.visibility = 'hidden';
                else inputs[1].style.visibility = 'visible';
                lis[i].className = "";
            }
        }
    }
};


// Timezone stuff
// tz in format [+-]HHMM
function checkTimezone( tz, msg ) {
	var localclock = new Date();
	// returns negative offset from GMT in minutes
	var tzRaw = localclock.getTimezoneOffset();
	var tzHour = Math.floor( Math.abs(tzRaw) / 60);
	var tzMin = Math.abs(tzRaw) % 60;
	var tzString = ((tzRaw >= 0) ? "-" : "+") + ((tzHour < 10) ? "0" : "") + tzHour + ((tzMin < 10) ? "0" : "") + tzMin;
	if( tz != tzString ) {
		var junk = msg.split( '$1' );
		document.write( junk[0] + "UTC" + tzString + junk[1] );
	}
};
function unhidetzbutton() {
    tzb = document.getElementById('guesstimezonebutton')
    if(tzb) tzb.style.display = 'inline';
};

// in [-]HH:MM format...
// won't yet work with non-even tzs
function fetchTimezone() {
	// FIXME: work around Safari bug
	var localclock = new Date();
	// returns negative offset from GMT in minutes
	var tzRaw = localclock.getTimezoneOffset();
	return formatTimezone(tzRaw);
};

function formatTimezone(tzSecs) {
	var tzHour = Math.floor( Math.abs(tzSecs) / 60);
	var tzMin = Math.abs(tzSecs) % 60;
	return  ((tzSecs >= 0) ? "-" : "") + ((tzHour < 10) ? "0" : "") + tzHour +
		":" + ((tzMin < 10) ? "0" : "") + tzMin;
};

function checkTimezone() {
	var currentTZ = fetchTimezone();
	if (_cur_TZ != currentTZ) {
		x_doSetTimezone(currentTZ, cb_blank);
	}
};

function guessTimezone() {
    var wpHourDiff = document.getElementById('wpHourDiff');
	if (wpHourDiff) wpHourDiff.value = fetchTimezone();
};

function toggleItem(toggleid, contentid) {
	var toc = document.getElementById(toggleid);
	var content = document.getElementById(contentid);
	var spans = toc.getElementsByTagName('span');
	var showlink = spans[0];
	var hidelink = spans[1];
	
	//if we are showing the content
	if (content.style.display == 'none') {
		content.style.display = 'block';
		showlink.style.display = 'none';
		hidelink.style.display = 'block';
	}
	else {
		content.style.display = 'none';
		showlink.style.display = 'block';
		hidelink.style.display = 'none';
	}
};

function openWindow(href,menu) {
	window.open(href, 'popupwindow', 'width='+(winX - 100)+',height='+(winY - 100)+',scrollbars,resizable' + (menu ? ',menubar=yes' : ''));
	return false;
};

function addInfobox(infoText,text_alert) {
	alertText=text_alert;
	var clientPC = navigator.userAgent.toLowerCase(); // Get client info

	var re=new RegExp("\\\\n","g");
	alertText=alertText.replace(re,"\n");

	// if no support for changing selection, add a small copy & paste field
	// document.selection is an IE-only property. The full toolbar works in IE and
	// Gecko-based browsers.
	if(!document.selection && !is_gecko) {
 		infoText=escapeQuotesHTML(infoText);
	 	document.write("<form name='infoform' id='infoform'>"+
			"<input size=80 id='infobox' name='infobox' value=\""+
			infoText+"\" readonly='readonly'></form>");
 	}
};

function escapeQuotes(text) {
	var re=new RegExp("'","g");
	text=text.replace(re,"\\'");
	re=new RegExp('"',"g");
	text=text.replace(re,'&quot;');
	re=new RegExp("\\n","g");
	text=text.replace(re,"\\n");
	return text;
};

function escapeQuotesHTML(text) {
	var re=new RegExp('"',"g");
	text=text.replace(re,"&quot;");
	return text;
};

function akeytt() {
    if(typeof ta == "undefined" || !ta) return;
    pref = 'alt-';
    if(is_safari || navigator.userAgent.toLowerCase().indexOf( 'mac' ) + 1 ) pref = 'control-';
    if(is_opera) pref = 'shift-esc-';
    for(id in ta) {
        n = document.getElementById(id);
        if(n){
            a = n.childNodes[0];
            if(a){
                if(ta[id][0].length > 0) {
                    a.accessKey = ta[id][0];
                    ak = ' ['+pref+ta[id][0]+']';
                } else {
                    ak = '';
                }
                a.title = ta[id][1]+ak;
            } else {
                if(ta[id][0].length > 0) {
                    n.accessKey = ta[id][0];
                    ak = ' ['+pref+ta[id][0]+']';
                } else {
                    ak = '';
                }
                n.title = ta[id][1]+ak;
            }
        }
    }
};

function toggleTable(divid) {
	//change icon
 	var showlink = document.getElementById('showlink-'+divid);
 	var hidelink = document.getElementById('hidelink-'+divid);
 	
 	if( showlink.style.display == 'none') {
		hidelink.style.display='none';
		showlink.style.display='block';
	} else {
		hidelink.style.display='block';
		showlink.style.display='none';
	}	
	
	//loop through table	
	var cells = document.getElementsByTagName('tr');
	var numCells = cells.length;
	var i;
	
	for (i = 0; i < numCells; ++i) {
		// If cell should be changed (matching class)...
		if (divid+' show-no' == cells[i].className)
			cells[i].className = divid + ' display';
		else if (divid+' display' == cells[i].className)
			cells[i].className = divid + ' show-no';
	}
	return false;
};

/* blank function for sajax callback */
function cb_blank() {};

/* function for sajax; persistent addtl nav */
function do_context(z) {
	x_wfStoreContextStatus(z, cb_blank);
};

//MT: royk search toggling
function toggleSearchTabs() {
	var titleContent = document.getElementById('search-title');
	var pageContent = document.getElementById('search-page');
	var tabTitle = document.getElementById('search-title-tab');
	var tabPage = document.getElementById('search-page-tab');
	
	if (titleContent.style.display == 'none') {
		titleContent.style.display = 'block';
		pageContent.style.display = 'none';
		tabTitle.className = 'selected';
		tabPage.className = '';
		var page = 'title';
	}
	else {
		titleContent.style.display = 'none';
		pageContent.style.display = 'block';
		tabTitle.className = '';
		tabPage.className = 'selected';
		var page = 'page';
	}	
	x_wfStoreSearchStatus(page, cb_blank);
};

function createCookie(name,value,days) { 
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else {
		var expires = "";
	}
	document.cookie = name+"="+value+expires+"; path=/";
};

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') 
			c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) 
			return c.substring(nameEQ.length,c.length);
	}
	return null;
};

function eraseCookie(name) {
	createCookie(name,"",-1);
};
function doRestrictAccess(titleID, userName, protectType, userIds) {
	x_wfRestrictTopic(titleID, userName, protectType, userIds, function (data) { 
		hidePopWin (false); 
		window.location.reload(); 
	});
};

function doDeleteAction (titleID, includingChildren) {
	includingChildren = includingChildren == null ? false : includingChildren.checked;
	x_wfDeleteTopic(titleID, includingChildren, _userName, function (data) {
		var status = data.charAt(0);
		if (status == '<') {
			data = data.replace(/<br\s*\/?>/ig, "\n");
		}
		if (status == '+') {
			data = data.substring(1);
			hidePopWin (false);
			window.location = data;
		} else {
			if (status == '-')
				data = data.substring (1);
			alert (data);
			hidePopWin (false);
		}
	});
};

/*
 * MindTouch Deki - a commercial grade open source wiki
 * Copyright (C) 2006 MindTouch, Inc.
 * http://www.mindtouch.com/  oss@mindtouch.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * http://www.gnu.org/copyleft/gpl.html
 */

function hookAttachBackgrounds() {
    function fileBackground() {
    	var setClass = 'attach_bg_on';
    	var elt = this.parentNode.parentNode;
    	if (elt.tagName == 'TD')
    		doToggleLayer(elt, setClass, '');
    };

    var attachTable = document.getElementById('attachTable');
	if (!attachTable) {
		return;
	}
	var links = attachTable.getElementsByTagName('a');
	for (var i = 0; i < links.length; i++ ) {
		if (links[i].className == 'attachDesc') {
			links[i].onmouseover = fileBackground;
			links[i].onmouseout = fileBackground;
		}
	}
};

var row_count = 1;
function addRow() {
	var tbl = document.getElementById('attachFiles');
	var maxNum = document.getElementById('maxNum');
	
	var newRow = tbl.insertRow(tbl.rows.length);
	++row_count;
	newRow.insertCell(0).innerHTML = '<a href="#" onclick="return addRow()" title="'+_lang_fileattach+'"><span class="icon"><img src="/skins/ace/icon-trans.gif" class="attach-add" alt=""></span></a><a href="#" onclick="return delRow(this.parentNode.parentNode.rowIndex)" title="'+_lang_removeattach+'"><span class="icon"><img src="/skins/ace/icon-trans.gif" class="attach-remove"></span></a>';
	newRow.insertCell(1).innerHTML = '<input name="file_'+row_count+'" id="file_'+row_count+'" size="40" type="file" tabindex="'+(row_count+1)+'"/>';	
	newRow.insertCell(2).innerHTML = '<input type="text" name="filedesc_'+row_count+'" style="width:100%" tabindex="'+(row_count+2)+'"/>';
	if (row_count > maxNum.value)
		maxNum.value = row_count;
	__dlg_sizeToContent();
	return false;
};
function delRow(indexKey) {
	var tbl = document.getElementById('attachFiles');
	if (tbl.rows.length > 2) {
		tbl.deleteRow(indexKey);
		for (var j = indexKey + 1; j < tbl.rows.length; j++)
			if (tbl.rows[j] && typeof(tbl.moveRow) == 'function') 
				tbl.moveRow(j, j - 1);	
	} else
		parent.doClosePopupMessage();
	__dlg_sizeToContent();
	return false;
};

function doEditAttachDescription(attachID, attachDesc) {
	x_attachEdit(attachID, attachDesc, function(returnValue) {
		hidePopWin (false); 
		var elt = document.getElementById('fileDescDisplay_'+attachID);
    	var returnValues = returnValue.split('|');
    	var html = '';
    	if (returnValues.length > 3) {
    		for (var i=2;i<returnValues.length;i++)
    			html += returnValues[i];
    	}
    	else
    		html = returnValues[2];	

    	if (returnValues[0] == 'success')
    		elt.innerHTML = html == '' ? '<span class="nodescription">No description</span>' : html;
    		
        imageCellHeights.resize();
	});
};
/*
 * MindTouch Deki - a commercial grade open source wiki
 * Copyright (C) 2006 MindTouch, Inc.
 * http://www.mindtouch.com/  oss@mindtouch.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * http://www.gnu.org/copyleft/gpl.html
 */

var menuBubble = false;
var menuOpened = false;
var menuJustOpened = false;
var menuSelect = false;

menuLinkClick = function(divid) {
	if (menuOpened && menuOpened != divid)
		menuToggle(menuOpened);	
	menuToggle(divid);
};

menuToggle = function(navid) {
	var node = document.getElementById(navid);
	if (!node)
		return false;
	if (node.style.display == 'block') {
		node.style.display = 'none';	
		menuOpened = false;
	}
	else {
		node.style.display = 'block';	
		menuOpened = navid;
		menuJustOpened = true;
	}
};

menuOff = function(navid) {
	var node = document.getElementById(navid);
	if (!node)
		return false;
	if (node.style.display == 'block') {
		node.style.display = 'none';	
		menuOpened = false;
	}
};

menuBodyClick = function() {
	if (!menuJustOpened && !menuBubble && menuOpened) {
		if (menuSelect) {
			selectToggle(menuOpened);
		}
		else {
			menuToggle(menuOpened);
		}
	}
	if (menuBubble)
		menuBubble = false;	
	if (menuJustOpened)
		menuJustOpened = false;	
};

// select stuff
function selectClick(divid) {
	if (menuOpened && menuOpened != divid)
		selectToggle(menuOpened);	
	selectToggle(divid);
}

function selectToggle(divid) {
	var elt = document.getElementById(divid);
	if (!elt) {
		return false;
	}
	var ul_ = document.getElementsByTagName('ul');
	for ( var i = 0 ; i < ul_.length ; i++) {
		if (ul_[i].className == 'fauxOptions') {
	 		if (ul_[i].style.display == 'block') {
	 			ul_[i].style.display = 'none';
		 		doSetSelectClasses(divid, true);
				menuOpened = false;
				menuSelect = false;
	 		}
	 		else {
		 		ul_[i].style.display = 'block';
				menuOpened = divid;
				menuJustOpened = true;
				menuSelect = true;
	 		}
		}
	}		
}
 function selectBodyClick() {
  if (!menuJustOpened && !menuBubble && menuOpened)
    selectToggle(menuOpened);
  menuBubble = false;  
  menuJustOpened = false;  
};

function selectClick(node) {
  if (menuOpened && menuOpened != node)
    selectToggle(menuOpened);  
  selectToggle(node);
};

function selectToggle(node) {
  var fauxOptions = node.mt_select.fauxOptions;
  if (fauxOptions.style.display == 'block') {
    fauxOptions.style.display = 'none';
    node.mt_select.options[node.mt_select.selected].node.className = "selected";
    menuOpened = false;
    menuSelect = false;
  } else {
    fauxOptions.style.display = 'block';
    var selNode = node.mt_select.curSelectVal.parentNode;
    fauxOptions.style.left = MT.getOffsetLeft(selNode) + "px";
    fauxOptions.style.top = MT.getOffsetTop(selNode) + selNode.offsetHeight - 1 + "px";
    menuOpened = node;
    menuJustOpened = true;
	menuSelect = true;
  }
};

var NavMenu = { 
	lastOpened : null, //the last opened menu id
	isOpening : null,
	openMenu : false,
	justClosed : false,
	maxHeight: 132, //max height of the menu
	minHeight: 1, //min height of the menu; keep at least 1px for IE
	
	bodyClick : function() {
		if (this.isOpening) {
			this.isOpening = null;
			return;
		}
		if(this.lastOpened) {
			this.hide();
		}
		return false;
	},
	/*** 
	 * 
	 */
	show : function(contextNode, titleID, title, isWatching, isBookmarked, isLoggedIn,isValidMovePage) {
		this.menuBubble = true;
		this.isOpening = true;
		var divFiller = 'npdFiller_' + titleID;
		var divMenu = 'npdmenu_' + titleID;
		var divContainer = 'container_' + titleID;
		var eltContainer = document.getElementById(divContainer);
		addCSSClass(eltContainer, 'force');
		
		if (this.lastOpened && '_' + titleID != this.lastOpened) {
			this.hide();
		}
		else if (this.lastOpened) {
			this.hide();
			this.justClosed = true;
			return;
		}
		this.lastOpened = '_' + titleID;
		
		var eltFiller = document.getElementById(divFiller);
				
		var eltTriangle = document.getElementById('expANode_' + titleID);
		eltFiller.style.position = 'absolute';
		var offset = clientBrowser.isIe ? 12 : 6;
		eltFiller.style.left = (findPosX(eltTriangle) - offset)+'px';
		eltFiller.style.top = (findPosY(eltTriangle) - 1) + 'px';
		
		//for IE
		eltFiller.style.display = '';		
		//first, generate the new menu
		eltFiller.appendChild(this.generateMenu(contextNode, titleID, title, isWatching, isBookmarked, isLoggedIn,isValidMovePage));
		eltFiller.style.display = 'block';
		menuLinkClick(divMenu);
	},
	hide: function () {
		if (this.lastOpened) {
			var divContainer = 'container' +this.lastOpened;
			var eltContainer = document.getElementById(divContainer);
			removeCSSClass(eltContainer, 'force');
			removeCSSClass(eltContainer, 'container-hover');
			removeCSSClass(eltContainer, 'default');
			addCSSClass(eltContainer, 'container');
			var eltMenu = 'npdmenu' + this.lastOpened;	
			var trielt = document.getElementById('expNode'+this.lastOpened);
			if (trielt) trielt.style.visibility = 'hidden';
			var elt = document.getElementById(eltMenu);
			elt.parentNode.removeChild(elt);
			menuLinkClick(eltMenu);	
		}
		this.lastOpened = null;
	},
	
	generateMenu : function (contextNode, titleID, title, isWatching, isBookmarked, isLoggedIn, isValidMovePage) {
		function createColor(color, title, divid) {	
			var colorNode = document.createElement('a');
			colorNode.href = '#';
			if (color == 'cancel') {
				colorNode.className = 'block';
				colorNode.appendChild(iconify('cancel'));	
			}
			else {
				colorNode.className = 'block '+color;
			}
			colorNode.onclick = function() {
				setColor(title, color);
				return false;
			}
			return colorNode;
		};
		
		function addMenuItem(action, icon, text, onclick) {
    		var item = document.createElement('li');
    		var a = document.createElement('a');
    		
    		a.href = action && isLoggedIn ? url+action : "#";
    		a.className = 'mlink';
    		a.appendChild(iconify(icon));
    		    		
    		var span = document.createElement('span');
    		span.innerHTML = text;
    		span.className = 'text';    		
    		a.appendChild(span);
    		
    		if (onclick && isLoggedIn)
    		  a.onclick = onclick;
    		item.appendChild(a);
    		menuList.appendChild(item);
		};
		
		function addDisabledMenuItem(icon,text) {
    		var item = document.createElement('li');
    		var a = document.createElement('a');
    		a.className = 'mlink disabled';
    		a.href = "#";
    		a.onclick = function() { return false; }
    		a.appendChild(iconify(icon));
    		
    		var span = document.createElement('span');
    		span.innerHTML = text;
    		span.className = 'text'; 		
    		a.appendChild(span);
    		
    		item.appendChild(a);
    		menuList.appendChild(item);
		};

		var divid = 'npdmenu_' + titleID;
		var url = mt_gen.getUrlFromName(title);

		var divMain = document.createElement('div');
		divMain.onclick = function () {
			menuBubble = true;	
		};
		divMain.className = 'dmenu';

		var divWrap = document.createElement('div');
		divWrap.id = divid;
		divWrap.className = 'dmenu-wrap';

		var divTop = document.createElement('div');
		divTop.className = 'dmenu-top';

		var divBottom = document.createElement('div');
		divBottom.className = 'dmenu-bottom';

		var divBody = document.createElement('div');
		divBody.className = 'dmenu-body';

		var menuList = document.createElement('ul');
		
		if (isLoggedIn) {
			addMenuItem('&action=addsubpage','addSubpage', _lang_addSubpage);
		}
		else {
			addDisabledMenuItem('addSubpage-disabled', _lang_addSubpage);
		}
        
        if (isValidMovePage && isLoggedIn) {
	        addMenuItem(null,'move',_lang_move,function () {
				NavMenu.hide();
				doPopupRename(titleID, title);
				return false;
			});
		}
		else {
			addDisabledMenuItem('move-disabled', _lang_move);
		}
	
		if (isLoggedIn) {
	        addMenuItem(null,'delete',_lang_delete,function () {
				NavMenu.hide();
				doPopupDelete(titleID, title);
				return false;
			});
		}
		else {
			addDisabledMenuItem('delete-disabled', _lang_delete);
		}

		var separator = document.createElement('li');
		separator.className = 'separator';
		menuList.appendChild(separator);

		//highlighting
		var item = document.createElement('li');
		var span = document.createElement('div');
		span.className = 'option';
		var ispan = document.createElement('span');
		ispan.innerHTML = _lang_hilite;
		var breaker = document.createElement('div');
		breaker.className = 'br';

		var divColors = document.createElement('div');
		divColors.className = 'colors';
		divColors.appendChild(createColor('cancel', titleID, divid));
		divColors.appendChild(createColor('red', titleID, divid));
		divColors.appendChild(createColor('green', titleID, divid));
		divColors.appendChild(createColor('blue', titleID, divid));
		divColors.appendChild(createColor('yellow', titleID, divid));

		span.appendChild(divColors);
		span.appendChild(ispan);
		span.appendChild(breaker);

		item.appendChild(span);
		menuList.appendChild(item);

		divBody.appendChild(menuList);

		divWrap.appendChild(divTop);
		divWrap.appendChild(divBody);
		divWrap.appendChild(divBottom);

		divMain.appendChild(divWrap);
		
		return divMain;
	}
};

var FileMenu = { 
	lastOpened : null, //the last opened menu id
	isOpening : null,
	openMenu : false,
	justClosed : false,
	maxHeight: 132, //max height of the menu
	minHeight: 1, //min height of the menu; keep at least 1px for IE
	
	bodyClick : function() {
		if (this.isOpening) {
			this.isOpening = null;
			return;
		}
		if(this.lastOpened) {
			this.hide();
		}
		return false;
	},
	/*** 
	 * 
	 */
	show : function(node, titleID, attachID, title, isLoggedIn, alignLeft, showRevisions, areRevisions, reviseURL) {
		
		this.menuBubble = true;
		this.isOpening = true;
		var divFiller = 'menuFiller'; //filler div for filling the menu
		var divMenu = 'npdmenu_' + titleID; //menu generated by generateMenu()
		
		if (this.lastOpened && '_' + titleID != this.lastOpened) {
			this.hide();
		}
		else if (this.lastOpened) {
			this.hide();
			this.justClosed = true;
			return false;
		}
		this.lastOpened = '_' + titleID;
		
		var subtr = alignLeft ? -5: 155;
		var eltFiller = document.getElementById(divFiller);				
		eltFiller.style.position = 'absolute';
		eltFiller.style.left = (findPosX(node) - (clientBrowser.isIe ? 12 : 6) - subtr)+'px';
		eltFiller.style.top = (findPosY(node) + 16) + 'px';
		
		//for IE
		eltFiller.style.display = '';		
		//first, generate the new menu
		eltFiller.appendChild(this.generateMenu(titleID, attachID, title, isLoggedIn, showRevisions, areRevisions, reviseURL));
		eltFiller.style.display = 'block';
		menuLinkClick(divMenu);
		return false;
	},
	hide: function () {
		if (this.lastOpened) {
			var eltMenu = 'npdmenu' + this.lastOpened;	
			var elt = document.getElementById(eltMenu);
			elt.parentNode.removeChild(elt);
			menuLinkClick(eltMenu);	
		}
		this.lastOpened = null;
	},
	
	generateMenu : function (titleID, attachID, url, isLoggedIn, showRevisions, areRevisions, reviseURL) {
		function addMenuItem(icon, text, href, onclick, cssClass) {
    		var item = document.createElement('li');
    		var a = document.createElement('a');
    		
    		a.href = href;
    		a.className = 'mlink'+(cssClass && cssClass != '' ? ' '+cssClass: '');
    		a.appendChild(iconify(icon+(cssClass && cssClass != '' ? '-'+cssClass: '')));
    		    		
    		var span = document.createElement('span');
    		span.innerHTML = text;
    		span.className = 'text';    		
    		a.appendChild(span);
    		
    		if (onclick && isLoggedIn)
    		  a.onclick = onclick;
    		item.appendChild(a);
    		menuList.appendChild(item);
		};
		var divid = 'npdmenu_' + titleID;

		var divMain = document.createElement('div');
		divMain.onclick = function () {
			menuBubble = true;	
		};
		divMain.className = 'dmenu';

		var divWrap = document.createElement('div');
		divWrap.id = divid;
		divWrap.className = 'dmenu-wrap';

		var divTop = document.createElement('div');
		divTop.className = 'dmenu-top';

		var divBottom = document.createElement('div');
		divBottom.className = 'dmenu-bottom';

		var divBody = document.createElement('div');
		divBody.className = 'dmenu-body';

		var menuList = document.createElement('ul');
		
		if (isLoggedIn) {
			addMenuItem('attachedit', 'Edit description', '#', function () { 
				return doPopupEditAttach(attachID);
			});
			addMenuItem('attachmove', 'Move', '#', function () { 
				return doPopupMoveAttach(_page_ID, attachID);	
			});
			addMenuItem('attachdel', 'Delete', url+'&oldid='+attachID+'&action=remove', function() {
				return confirm(_lang_removeconfirm);
			});
		}
		else {
			addMenuItem('attachedit', 'Edit description', '#', function () { 
				return false;
			}, 'disabled');
			addMenuItem('attachmove', 'Move', '#', function () { 
				return false;
			}, 'disabled');
			addMenuItem('attachdel', 'Delete', '#', function() {
				return false;
			}, 'disabled');
		}
		if (showRevisions) {
			if (areRevisions) {
				addMenuItem('attachhist', _lang_galleryhist, reviseURL);
			}
			else {
				addMenuItem('attachhist', _lang_galleryhist, '#', function () { return false;}, 'disabled');
			}
		}
		divBody.appendChild(menuList);

		divWrap.appendChild(divTop);
		divWrap.appendChild(divBody);
		divWrap.appendChild(divBottom);

		divMain.appendChild(divWrap);
		
		return divMain;
	}
};

function setColor(titleID, color) {
	if (color == 'cancel') color = '';
	var elt = document.getElementById('container_' + titleID);
	if (elt) {
		if (!inCSSClass(elt, 'container-current')) {
			elt.className = 'container';
			addCSSClass(elt, color);
			elt.onmouseover = function () {
				NavPane.showBorder(this, color != '' ? ' '+color: '');
			}
			elt.onmouseout = function() {
				NavPane.hideBorder(this, color != '' ? ' '+color: '');
			}
		}
	}
	x_wfStoreHighlights(titleID, color, cb_blank);
};

var NavPane = { 
	lastOpened: null, 
	showBorder : function (elt, hilite) {
		if (inCSSClass(elt, 'force')) {
			return;
		}
		elt.className = hilite != '' ? 'container-hover'+hilite: 'container-hover default';
	}, 
	hideBorder : function (elt, hilite) {
		if (inCSSClass(elt, 'force')) {
			return;
		}
		elt.className = 'container'+hilite;
	},
	boxClick : function (elt) {
		if (NavMenu.menuBubble && (NavMenu.justClosed || NavMenu.lastOpened)) {
			NavMenu.justClosed = null;
			NavMenu.menuBubble = null;
			return;
		}
		var tags = elt.getElementsByTagName('div');
		for (var i = 0; i<tags.length;  i++) {
			if (tags[i].className == 'innerPadding') {
				document.location = tags[i].childNodes[0].href;
			}
		}
	},
	itemClick : function() {
		if (NavMenu.openMenu) return;
	},
	onHover : function (_titleID) {	
		var elt = document.getElementById('expNode' + _titleID);
		if (!elt) return;
		elt.style.visibility = 'visible';
		if (this.lastOpened && this.lastOpened != _titleID) {
			this.onUnhover(this.lastOpened);
			this.lastOpened = null;	
		}
		this.lastOpened = _titleID;
		return true;
	}, 
	
	onUnhover : function (_titleID) {
		if (NavMenu.lastOpened && NavMenu.lastOpened == _titleID) {
			return;
		}
		var elt = document.getElementById('expNode'+_titleID);
		if (!elt) return;
		elt.style.visibility = 'hidden';
		return true;
	}
};

/*
 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
 * Digest Algorithm, as defined in RFC 1321.
 * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for more info.
 */

/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }

/*
 * Calculate the MD5 of an array of little-endian words, and a bit length
 */
function core_md5(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << ((len) % 32);
  x[(((len + 64) >>> 9) << 4) + 14] = len;

  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;

    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);

    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);

    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);

    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
  }
  return Array(a, b, c, d);

}

/*
 * These functions implement the four basic operations the algorithm uses.
 */
function md5_cmn(q, a, b, x, s, t)
{
  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
}
function md5_ff(a, b, c, d, x, s, t)
{
  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t)
{
  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t)
{
  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t)
{
  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}

/*
 * Calculate the HMAC-MD5, of a key and some data
 */
function core_hmac_md5(key, data)
{
  var bkey = str2binl(key);
  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
  return core_md5(opad.concat(hash), 512 + 128);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function bit_rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert a string to an array of little-endian words
 * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
 */
function str2binl(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
  return bin;
}

/*
 * Convert an array of little-endian words to a string
 */
function binl2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
  return str;
}

/*
 * Convert an array of little-endian words to a hex string.
 */
function binl2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of little-endian words to a base-64 string
 */
function binl2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}

/*
 * MindTouch Deki - a commercial grade open source wiki
 * Copyright (C) 2006 MindTouch, Inc.
 * http://www.mindtouch.com/  oss@mindtouch.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * http://www.gnu.org/copyleft/gpl.html
 */

var Print = { 
	open : function(href, menu) {
		window.open(href, 'popupwindow', 'width='+(winX - 100)+',height='+winY+',scrollbars,resizable' + (menu ? ',menubar=yes' : ''));
		return false;
	}, 
	doPrint : function () {
		parent.topic.focus();
		parent.topic.print();
		// the first time you print in firefox (or mozilla), immediately executing parent.close() will 
		// result in the page just closing with no print; oddly, if you open the print dialogue again, 
		// the document will print then close the window correctly
		// setting a timeout on the close allows the browser to popup the "print" dialogue before parent.close()
		window.setTimeout("Print.doClose()", 2000);
	},
	doClose : function () {
		parent.close();	
	},
	createEndnotes : function () {
		var elt = document.getElementById('topic');
		var endnotes = '';
		var j = 0;
		var links = elt.getElementsByTagName('a');
		for (i = 0; i < links.length; i++ ) {
			if (links[i].getAttribute('href')) {
				j++;
				var sup = document.createElement('sup');
				sup.className = 'endnotes';
				sup.innerHTML = j;
				links[i].appendChild(sup);
				endnotes += '<sup>'+(j)+'</sup> '+links[i].getAttribute('href')+'<br/>';
			}
		}	
		var div = document.createElement('div');
		div.setAttribute('id', 'endnotes');
		div.setAttribute('class', 'print-toc');
		elt.appendChild(div);
		div.innerHTML = '<h5>Endnotes</h5><div><small>'+endnotes+'</small></div>';
	},
	showEndnotes : function (displayType) {
		var endnotes = parent.topic.document.getElementsByTagName('sup');
		for (i = 0; i < endnotes.length; i++ ) {
			if (endnotes[i].className == 'endnotes') {
				endnotes[i].style.display = displayType == 'show' ? 'inline': 'none';
			}	
		}
		var endnotesBody = parent.topic.document.getElementById('endnotes');
		if (endnotesBody) {
			endnotesBody.style.display = displayType == 'show' ? 'block' : 'none';
		}
	}, 
	onBodyLoad : function () {		
	    Print.createEndnotes();	    
	    if (readCookie('printlinks') == 0) {
	   	 	Print.showEndnotes('none');
		}
	    if (readCookie('printtoc') == 0) {
		   document.getElementById('content-toc').style.display = 'none';
	    }
	    if (readCookie('printfooter') == 0) {
		    document.getElementById('printfooter').style.display = 'none';
	    }	
	}, 
	options : function () {	
		var frameset = parent.topic;
		var printtoc = document.getElementById('print-toc');
		var toc = frameset.document.getElementById('content-toc');
		var printfooter = document.getElementById('print-footer');
		var footer = frameset.document.getElementById('printfooter');
		var printlinks = document.getElementById('print-links');
		
		createCookie('printtoc', (printtoc.checked) ? 1: 0, 365);
		createCookie('printfooter', (printfooter.checked) ? 1: 0, 365);
		createCookie('printlinks', (printlinks.checked) ? 1: 0, 365);
		
		if (printtoc && toc)
			toc.style.display = (printtoc.checked) ? 'block': 'none';
		if (printfooter && footer)
			footer.style.display = (printfooter.checked) ? 'block': 'none';
		if (printlinks) {
			if (printlinks.checked) {
				Print.showEndnotes('show');
			}	
			else {
				Print.showEndnotes('hide');
			}
		}	
	}
};

function saveToPDF (page) {
	var tm = document.getElementById ('tmargin');
	var rm = document.getElementById ('rmargin');
	var bm = document.getElementById ('bmargin');
	var lm = document.getElementById ('lmargin');
	var ls = document.getElementById ('landscape');

	var args = "&action=export&type=pdf";
	
	if (ls.checked) 
		args += "&landscape=true"; 
	
	if (tm.value != null && tm.value != "")
		args += "&tm=" + tm.value; 
	if (rm.value != null && rm.value != "")
		args += "&rm=" + rm.value; 
	if (bm.value != null && bm.value != "")
		args += "&bm=" + bm.value; 
	if (lm.value != null && lm.value != "")
		args += "&lm=" + lm.value; 

	parent.topic.location = page + '&action=export&type=pdf' + args;
}

prefsShow = function (divid) {
	var arrow = document.getElementById('prefs-'+divid+'_button');
	var content = document.getElementById('prefs-'+divid+'_content');
	
	if (content.style.display == 'none') {
		content.style.display = 'block';
		var atype = 'show';
	}
	else {
		content.style.display = 'none';
		var atype = 'hide';	
	}
	arrow.className = (arrow.className == 'buttonify show') ? 'buttonify hide': 'buttonify show';
	x_wfStorePrefsStatus(divid, atype, cb_blank);
};

prefsInfo = function (divid, subdivid, type) {
	if (subdiv = document.getElementById(divid+'-'+subdivid)) {
		var div = document.getElementById(divid+'-msg');
		if (type == 'show') {
			div.style.display = 'block';
			subdiv.style.display = 'block';	
		}
		else {
			div.style.display = 'none';
			subdiv.style.display = 'none';	
		}
	}
};
/*
 * MindTouch Deki - a commercial grade open source wiki
 * Copyright (C) 2006 MindTouch, Inc.
 * http://www.mindtouch.com/  oss@mindtouch.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * http://www.gnu.org/copyleft/gpl.html
 */

var ttTimeout = null;
var _ttwidth = 302; //width of the topic tip (set in CSS)
var curTT = null;

ttOn = function(obj, lyr) {
	if (ttTimeout)
		clearTimeout(ttTimeout);
	ttTimeout = window.setTimeout("ttDisplay('"+lyr+"', "+findPosY(obj)+", "+findPosX(obj)+")", 400);
};

ttDisplay = function(lyr, topOffset, leftOffset) {
	var tt = document.getElementById(lyr);
	var extraClasses = '';
	if (!tt) 
		return false;	
	
	if (ttTimeout != null)
		window.clearTimeout(ttTimeout);
	
	if (typeof(winX) != 'object' && (leftOffset + _ttwidth) > winX) {
		leftOffset = leftOffset - _ttwidth;
		extraClasses += 'r';
	} 
	ttTimeout = null;
	curTT = tt;
	if (clientBrowser.isMoz) {
		tt.style.visibility = 'hidden';
	}
	tt.style.display = 'block';
	var itemHeight = tt.offsetHeight;
	
	var pageOffset = 0;
	pageOffset = getPageYOffset();
	if ((topOffset + tt.offsetHeight) > (pageOffset + winY)) {
		var to = topOffset - tt.offsetHeight; //hardcode hack to move tt up since CSS is being weird
		extraClasses += 'u';
	}
	else {
		var to = topOffset + 20; //hardcode hack to move tt down since CSS is being weird
	}
	if (extraClasses != '') {
		tt.className += ' flip'+extraClasses;	
	}
	tt.style.position = 'absolute';
	tt.style.top = to + 'px';
	tt.style.left = leftOffset + 'px';
	if (clientBrowser.isMoz) {
		tt.style.visibility = 'visible';
	}
};

function clearTT() {
    if (ttTimeout)
        clearTimeout(ttTimeout);
    ttTimeout = null;
    if (curTT)
        curTT.style.display = 'none';
    curTT = null;
};

ttOff = function(lyr) {
	if (ttTimeout)
		clearTimeout(ttTimeout);
	ttTimeout = null;
	if (tt = document.getElementById(lyr)) {
	    if (curTT == tt)
	       curTT = null;
		tt.style.display = 'none';
		tt.style.position = '';
		tt.className = '';
	}
};

var imageTT = null;
var imageTTDont = false;

function imageOptions_cb(content) {
    if (content == "")
        return;
    imageOption_hide();
    if (imageTTDont)
        return;
    // $at_id."\n".$timestamp."\n".$file->at_user_text."\n".$file->at_name.".".$file->at_extension."\n".$file->at_filesize
    var fields = content.split("\n");
    var at_id = fields[0];
    var at_timestamp = fields[1];
    var at_user_text = fields[2];
    var at_name = fields[3];
    var at_filesize = fields[4];
    var imageEl = document.getElementById("imgSrc" + at_id);

    imageTT = document.createElement('div');
	imageTT.style.display = 'block';
	imageTT.style.position = 'absolute';
	var top = findPosY(imageEl) + imageEl.offsetHeight;
	var left = findPosX(imageEl) - 27;
	imageTT.style.top = top + 'px';
	imageTT.style.zIndex = 999;
	imageTT.style.left = left + 'px';
	imageTT.innerHTML = "<div class='ttshadow'><div class='tt_top'></div><div class='tt_content'><div><table><tbody>"+
	   "<tr><td><strong>Name:</strong></td><td>"+at_name+"</td></tr>"+
	   "<tr><td><strong>Size:</strong></td><td>"+at_filesize+"</td></tr>"+
	   "<tr><td><strong>Date:</strong></td><td>"+at_timestamp+"</td></tr>"+
	   "<tr><td><strong>Added by:</strong></td><td>"+at_user_text+"</td></tr>"+
	   "</tbody></table></div></div><div class='tt_bottom'></div></div>";
    imageEl.parentNode.appendChild(imageTT);
}

function imageOption_hide() {
    if (imageTT != null) {
        imageTT.parentNode.removeChild(imageTT);
        imageTT = null;
    }
}

function imageOptions(action, at_id) {
    if (action == 'show') {
        imageTTDont = false;
        x_wfGetImageDescription(at_id, imageOptions_cb)
    } else {
        imageTTDont = true;
        imageOption_hide();
    }
}

// Browser detection
var nav = navigator.userAgent.toLowerCase();
var ie6=0; ie5=0; moz5=0; moz0=0; opera=0; needConfirm=0; confirmFlag = 1;
if (nav.indexOf("win") != -1) {
	var pos = nav.indexOf("msie");
	var v = nav.charAt(pos + 5);
	if (pos != -1) {
		if (v >= 6) {
			ie6 = 1;
			ie5 = 1;

		}

		else if (v >= 5)
			ie5 = 1;
	}
}
if (nav.indexOf("compatible") == -1) {
	if (nav.charAt(8) >= 5 && nav.indexOf("7.02") == -1) {
		moz5 = 1;
		moz0 = 1;
	}
}
if (nav.indexOf("opera") != -1) opera=1;
/**
 * COMMON DHTML FUNCTIONS
 * These are handy functions I use all the time.
 *
 * By Seth Banks (webmaster at subimage dot com)
 * http://www.subimage.com/
 *
 * Up to date code can be found at http://www.subimage.com/dhtml/
 *
 * This code is free for you to use anywhere, just keep this comment block.
 */

/**
 * X-browser event handler attachment and detachment
 *
 * @argument obj - the object to attach event to
 * @argument evType - name of the event - DONT ADD "on", pass only "mouseover", etc
 * @argument fn - function to call
 */
function addEvent(obj, evType, fn){
 if (obj.addEventListener){
    obj.addEventListener(evType, fn, true);
    return true;
 } else if (obj.attachEvent){
    var r = obj.attachEvent("on"+evType, fn);
    return r;
 } else {
    return false;
 }
}
function removeEvent(obj, evType, fn, useCapture){
  if (obj.removeEventListener){
    obj.removeEventListener(evType, fn, useCapture);
    return true;
  } else if (obj.detachEvent){
    var r = obj.detachEvent("on"+evType, fn);
    return r;
  } else {
    alert("Handler could not be removed");
  }
}

/**
 * Code below taken from - http://www.evolt.org/article/document_body_doctype_switching_and_more/17/30655/
 *
 * Modified 4/22/04 to work with Opera/Moz (by webmaster at subimage dot com)
 *
 * Gets the full width/height because it's different for most browsers.
 */
function getViewportHeight() {
	if (window.innerHeight!=window.undefined) return window.innerHeight;
	if (document.compatMode=='CSS1Compat') return document.documentElement.clientHeight;
	if (document.body) return document.body.clientHeight; 
	return window.undefined; 
}
function getViewportWidth() {
	if (window.innerWidth!=window.undefined) return window.innerWidth; 
	if (document.compatMode=='CSS1Compat') return document.documentElement.clientWidth; 
	if (document.body) return document.body.clientWidth; 
	return window.undefined; 
}
/**
 * POPUP WINDOW CODE v1.1
 * Used for displaying DHTML only popups instead of using buggy modal windows.
 *
 * By Seth Banks (webmaster at subimage dot com)
 * http://www.subimage.com/
 *
 * Contributions by Eric Angel (tab index code) and Scott (hiding/showing selects for IE users)
 *
 * Copyright (C) 2006 MindTouch, Inc.
 *
 * Up to date code can be found at http://www.subimage.com/dhtml/subModal
 *
 * This code is free for you to use anywhere, just keep this comment block.
 */

// Popup code
var gPopupMask = null;
var gPopupContainer = null;
var gPopFrame = null;
var gPopupDoc = null;
var gReturnFunc;
var gPopupIsShown = false;

var gHideSelects = false;


var gTabIndexes = new Array();
// Pre-defined list of tags we want to disable/enable tabbing into
var gTabbableTags = new Array("A","BUTTON","TEXTAREA","INPUT","IFRAME");	

// If using Mozilla or Firefox, use Tab-key trap.
if (!document.all) {
	document.onkeypress = keyDownHandler;
}

/**
 * Initializes popup code on load.	
 */
function initPopUp() {
	gPopupMask = document.getElementById("popupMask");
	gPopupContainer = document.getElementById("popupContainer");
	gPopFrame = document.getElementById("popupFrame");
	
	// check to see if this is IE version 6 or lower. hide select boxes if so
	// maybe they'll fix this in version 7?
	var brsVersion = parseInt(window.navigator.appVersion.charAt(0), 10);
	if (brsVersion <= 6 && window.navigator.userAgent.indexOf("MSIE") > -1) {
		gHideSelects = true;
	}
};
//addEvent(window, "load", initPopUp);

 /**
	* @argument width - int in pixels
	* @argument height - int in pixels
	* @argument url - url to display
	* @argument returnFunc - function to call when returning true from the window.
	*/

function showPopWin(url, width, height, returnFunc) {
	if (!gPopupMask) initPopUp();
	if (!gPopupMask) {
debugger;
		return;
	}
	gPopupIsShown = true;
	disableTabIndexes();
	gPopupMask.style.display = "block";
	gPopupContainer.style.display = "block";
	// calculate where to place the window on screen
	centerPopWin(width, height);

	var titleBarHeight = parseInt(document.getElementById("popupTitleBar").offsetHeight, 10);
	
	gPopupContainer.style.width = width + "px";
	gPopupContainer.style.height = (height+titleBarHeight) + "px";
	// need to set the width of the iframe to the title bar width because of the dropshadow
	// some oddness was occuring and causing the frame to poke outside the border in IE6
	gPopFrame.style.width = parseInt(document.getElementById("popupTitleBar").offsetWidth, 10) + "px";
	gPopFrame.style.height = (height) + "px";
	
	// set the url
	gPopFrame.src = url;

	gReturnFunc = returnFunc;
	// for IE
	if (gHideSelects)
		hideSelectBoxes();
	
  document.getElementById("popupTitle").innerHTML = "";
	window.setTimeout(function () { setPopTitle(); }, 600);
};

function setPopWinHTML(html) {
    try {
        gPopupDoc = gPopFrame.contentDocument ? gPopFrame.contentDocument : gPopFrame.contentWindow.document;
        if (!gPopupDoc) { // try later
            if (HTMLArea.is_gecko) {
                setTimeout(function() { setPopWinHTML(html) }, 50);
                return false;
            } else
                alert("ERROR: IFRAME can't be initialized.");
        }
    } catch(e) {
        setTimeout(function() { setPopWinHTML(html) }, 50);
        return false;
    }

    gPopupDoc.write(html);
    gPopupDoc.close();
    return true;
};

//
var gi = 0;
function centerPopWin(width, height) {
	if (gPopupIsShown) {
		if (width == null || isNaN(width)) {
			width = gPopupContainer.offsetWidth;
		}
		if (height == null) {
			height = gPopupContainer.offsetHeight;
		}
		
		var fullHeight = getViewportHeight();
		var fullWidth = getViewportWidth();
		
		var theBody = document.documentElement;
		if (!theBody.scrollTop && document.body)
			theBody = document.body;
		
		var scTop = parseInt(theBody.scrollTop,10);
		var scLeft = parseInt(theBody.scrollLeft,10);
		
		gPopupMask.style.height = fullHeight + "px";
		gPopupMask.style.width = fullWidth + "px";
		gPopupMask.style.top = scTop + "px";
		gPopupMask.style.left = scLeft + "px";
		
		window.status = gPopupMask.style.top + " " + gPopupMask.style.left + " " + gi++;
		
		var titleBarHeight = parseInt(document.getElementById("popupTitleBar").offsetHeight, 10);
		
		gPopupContainer.style.top = (scTop + ((fullHeight - (height+titleBarHeight)) / 2)) + "px";
		gPopupContainer.style.left =  (scLeft + ((fullWidth - width) / 2)) + "px";
		//alert(fullWidth + " " + width + " " + gPopupContainer.style.left);
	}
}
addEvent(window, "resize", centerPopWin);
//addEvent(window, "scroll", centerPopWin);
window.onscroll = centerPopWin;

/**
 * @argument callReturnFunc - bool - determines if we call the return function specified
 * @argument returnVal - anything - return value 
 */
function hidePopWin(callReturnFunc) {
	gPopupIsShown = false;
	restoreTabIndexes();
	if (!gPopupMask)
		return;
    gPopupMask.style.display = "none";
	gPopupContainer.style.display = "none";
	document.getElementById("popupTitle").innerHTML = "";
	if (callReturnFunc && gReturnFunc != null)
		gReturnFunc(gPopFrame.returnVal);
	gPopFrame.src = '/editor/popups/loading.html';
	// display all select boxes
	if (gHideSelects)
		displaySelectBoxes();
};

/**
 * Sets the popup title based on the title of the html document it contains.
 * Uses a timeout to keep checking until the title is valid.
 */
function setPopTitle() {
    try {
        gPopupDoc = gPopFrame.contentDocument ? gPopFrame.contentDocument : gPopFrame.contentWindow.document;
        if (gPopupDoc && gPopupDoc.title)
            document.getElementById("popupTitle").innerHTML = gPopupDoc.title;
        else
            window.setTimeout(function() { setPopTitle(); }, 100);
    } catch (e) {
        window.setTimeout(function() { setPopTitle(); }, 100);
    }
};

// Tab key trap. iff popup is shown and key was [TAB], suppress it.
// @argument e - event - keyboard event that caused this function to be called.
function keyDownHandler(e) {
    if (gPopupIsShown && e.keyCode == 9)  return false;
};

// For IE.  Go through predefined tags and disable tabbing into them.
function disableTabIndexes() {
	if (document.all) {
		var i = 0;
		for (var j = 0; j < gTabbableTags.length; j++) {
			var tagElements = document.getElementsByTagName(gTabbableTags[j]);
			for (var k = 0 ; k < tagElements.length; k++) {
				gTabIndexes[i] = tagElements[k].tabIndex;
				tagElements[k].tabIndex="-1";
				i++;
			}
		}
	}
};

// For IE. Restore tab-indexes.
function restoreTabIndexes() {
	if (document.all) {
		var i = 0;
		for (var j = 0; j < gTabbableTags.length; j++) {
			var tagElements = document.getElementsByTagName(gTabbableTags[j]);
			for (var k = 0 ; k < tagElements.length; k++) {
				tagElements[k].tabIndex = gTabIndexes[i];
				tagElements[k].tabEnabled = true;
				i++;
			}
		}
	}
};

/**
* Hides all drop down form select boxes on the screen so they do not appear above the mask layer.
* IE has a problem with wanted select form tags to always be the topmost z-index or layer
*
* Thanks for the code Scott!
*/
function hideSelectBoxes() {
	for(var i = 0; i < document.forms.length; i++) {
		for(var e = 0; e < document.forms[i].length; e++){
			if(document.forms[i].elements[e].tagName == "SELECT") {
				document.forms[i].elements[e].style.visibility="hidden";
			}
		}
	}
};

/**
* Makes all drop down form select boxes on the screen visible so they do not reappear after the dialog is closed.
* IE has a problem with wanted select form tags to always be the topmost z-index or layer
*/
function displaySelectBoxes() {
	for(var i = 0; i < document.forms.length; i++) {
		for(var e = 0; e < document.forms[i].length; e++){
			if(document.forms[i].elements[e].tagName == "SELECT") {
			document.forms[i].elements[e].style.visibility="visible";
			}
		}
	}
};

/*
 * MindTouch Deki - a commercial grade open source wiki
 * Copyright (C) 2006 MindTouch, Inc.
 * http://www.mindtouch.com/  oss@mindtouch.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * http://www.gnu.org/copyleft/gpl.html
 */

if (typeof _script_path == "undefined") _script_path = "/";
if (typeof _page_titleName == "undefined") _page_titleName = "Sandbox";
if (typeof _page_titlePath == "undefined") _page_titlePath = "/";
if (typeof _path_skin == "undefined") _path_skin = "/skin/ace";

xinha_editors = null;
xinha_init = null;
xinha_init_adv = null;
xinha_init_simple = null;
xinha_config = null;
xinha_plugins = null;
start_editor  = false;
content_editors = null;
title = null;
sectiontoedit = null;
oldcontent = null;
cur_section = null;
cur_editor = null;
did_quicksave = false;

var width = null;
var height = '';
var prevHTML = '';
var saveFlag = false;

var useMTDialogs = true;

function getWindowSize() {
  if (parseInt(navigator.appVersion)>3) {
    // Can't use HTMLArea.is_ie, not defined yet for some reason
    if (navigator.appName=="Netscape") {
      width = window.innerWidth;
      height = window.innerHeight;
    }
    if (navigator.appName.indexOf("Microsoft")!=-1) {
      width = document.documentElement.offsetWidth;
      height = document.documentElement.offsetHeight;
    }
  }
};
getWindowSize();

xinha_init = xinha_init ? xinha_init : function() {
  //hide the box
  wait = document.getElementById('formLoading');

  if (xinha_config == null) {
    xinha_config = new HTMLArea.Config();
    
    xinha_config.URIs = {
      "blank":        "popups/blank.html",
      "link":         "link.html",
      "insert_image": "insert_image.html",
      "insert_table": "insert_table.html",
      "select_color": "select_color.html",
      "forecolor":    "select_color.php?type=fg",
      "hilitecolor":  "select_color.php?type=bg",
      "mkstemplates": "select_template.php",
      "about":        "about.html"
    };
  }

  xinha_config.mozParaHandler = 'built-in'; // set to 'built-in', 'dirty' or 'best'
  xinha_config.stripBaseHref = false;
  xinha_config.baseHref = baseHref;
  xinha_config.formatblock = {
    "&mdash; format &mdash;"  : "",
    "Title":      "h1",
    "Heading 1":  "h2",
    "Heading 2":  "h3",
    "Heading 3":  "h4",
    "Heading 4":  "h5",
    "Heading 5":  "h6",
    "Normal":     "p",
    "Blockquote": "blockquote",
    "Formatted":  "pre"
  };

  xinha_config.fontsize = {
    "&mdash; size &mdash;"  : "mixed",
    "Small":  "-2",
    "Normal": "0",
    "Big":    "+2",
    "Huge":   "+3"
  };

  xinha_config.fontname = {
    "&mdash; font &mdash;": '',
    "Courier New":      'courier new,courier,monospace',
    "Garamond":         'garamond|small-caps',
    "Impact":           'impact',
    "Times New Roman":  'times new roman,georgia,times,serif',
    "Verdana":          'verdana,arial,helvetica,sans-serif'
  };
  
  xinha_config.fontstyles = {
    "&mdash; styles &mdash;": "mixed",
    "Normal":     "normal",
    "Important":  "edimportant",
    "Highlight":  "edhighlight",
    "Subtle":     "edsubtle", 
    "Code":       "edcode",
    "Plain (No Special Tags)": "plain"
  };
  
  xinha_config.registerButton(
    "simple", "Simple", _script_path+"editor/images/ed_toggle.gif", false,
    function(editor) { switchToSimple(editor); }
  );

  xinha_config.registerButton(
    "advanced", "Advanced", _script_path+"editor/images/ed_toggle.gif", false,
    function(editor) { switchToAdvanced(editor); }
  );

  xinha_config.registerButton(
    "mkstemplates", "Templates", _script_path+"editor/images/ed_template.gif", false,
    function(editor) { popupTemplates(400, 110, editor); }
  );
  
  xinha_config.registerButton(
    "mksSave", _lang_tooltip_save, _path_skin+"/save_18.gif", false,
    function(editor) {
      okToLeave();
      doSave();
      document.editform.submit();
    }
  );
  
  xinha_config.registerButton(
    "mksCancel", _lang_tooltip_cancel, _path_skin+"/back_18.gif", false,
    function(editor) {
      if (!doCancelEdit(true))
        return;
      if (typeof _cancel_url != 'undefined')
        window.location = _cancel_url;
      else if (typeof _staticEditor != 'undefined' && _staticEditor)
        window.location = mt_gen.getUrlFromName(document.getElementById('wpOldTitle').value);
	  else if (document.editform)
	    document.editform.submit();
    }
  );
  
  xinha_config.registerButton(
    "mksQuicksave", _lang_tooltip_saveminor, _path_skin+"/save_18.gif", false,
    function(editor) {
      okToLeave();
      doSaveMinor();
    }
  );
  
  xinha_config.registerButton(
    "mksPreview", _lang_tooltip_preview, _path_skin+"/srch_18.gif", false,
    function(editor) {
      okToLeave();
      setHiddenSubmit('wpPreviewH');
      var html = cur_editor.getHTML();
      html = stripTitle(html);
      cur_editor.setHTML(html);
      document.getElementById('editarea').value = html;
      document.editform.submit();
    }
  );
  
  xinha_config.registerButton("mksLink", "Insert/modify link", _path_skin+"/ed_link.png", false,
    function(editor) { cur_editor._createLinkMT(); }
  );
  
  xinha_config.registerButton("mksInsertImage", "Insert image", _path_skin+"/ed_ins_img.png", false,
    function(editor) { cur_editor._insertImageMT(); }
  );
  
  if (typeof(_editor_styles_path) != 'undefined')
    xinha_config.pageStyleSheets = [_editor_styles_path];

  createConfigToolBar(xinha_config,advancedEditor);

  xinha_config.width = clientBrowser.isIe ? '99%': '100%'; //IE will push the whole editor down otherwise
  xinha_config.height = getEditorHeight(null) + "px";
  function doneLoading() {
    startContentEditor();
    if (wait)
      wait.className = 'show-no';
  };

  if (!createPlugins(advancedEditor, doneLoading))
    return;
  doneLoading();
};

function createPlugins(advancedEditor, callbackIfNotReady) {
  xinha_plugins = xinha_plugins ? xinha_plugins : true ? [
    'MindTouch',
    'ContextMenu',
    'FullScreen',
    'SpellChecker',
    'Stylist',
    'TableOperations'
  ] : [
    'MindTouch',
    'FullScreen',
    'SpellChecker',
    'Stylist'
  ];

  return HTMLArea.loadPlugins(xinha_plugins, callbackIfNotReady);
};

function getOffsetTop(item) {
  return getRecursiveProperty(item,"offsetTop");
};

function getRecursiveProperty(item,prop) {
  var ret = 0;
  while(item) {
    ret += item[prop];
    try {
      item = item.offsetParent;
    } catch (e) { item = null; }
  }
  return ret;
};

function getEditorHeight(editor) {
  getWindowSize();
  if (!editor || document.getElementById('isConflict') || cur_section != null)
    return 400;
  var offsetTop = getOffsetTop(editor._htmlArea);
  var newHeight = height - offsetTop - (HTMLArea.is_ie ? 5 : 12);
  if (newHeight < 400)
    newHeight = 400;
  return newHeight;
};

function switchToSimple(editor) {
  advancedEditor = false;
  if (typeof x_wfSaveEditor != 'undefined') x_wfSaveEditor('0', function() {});
  recreatedToolbar(editor);
};

function switchToAdvanced(editor) {
  advancedEditor = true;
  if (typeof x_wfSaveEditor != 'undefined') x_wfSaveEditor('1', function() {});
  recreatedToolbar(editor);
};

function recreatedToolbar(editor) {
  xinha_plugins = null;
  if (!createPlugins(advancedEditor, function() {recreatedToolbar(editor);}))
    return;
  editor.disableToolbar();
  var tb_cell = editor._framework.tb_cell;
  HTMLArea.removeFromParent(editor._toolBar);
  createConfigToolBar(editor.config,advancedEditor);
  editor.registerPlugins(xinha_plugins);
  for (var i in editor.plugins) {
    var plugin = editor.plugins[i].instance;
    HTMLArea.refreshPlugin(plugin);
  }
  var toolbar = editor._createToolbar();
  editor._framework.tb_cell.appendChild(toolbar);
  editor.enableToolbar();
};

function createConfigToolBar(config,adv) {
  config.toolbar = adv ?
  [
    ["mksSave","label:mksSave|"+_lang_label_save,"linebreak","mksCancel","label:mksCancel|"+_lang_label_cancel,"linebreak"],
    ["separator","formatblock","fontstyles","linebreak","fontname","fontsize"],
    ["separator","bold","italic","underline","linebreak","strikethrough","forecolor","hilitecolor"],
    ["separator","justifyleft","justifycenter","justifyright","justifyfull","linebreak","insertorderedlist","insertunorderedlist","outdent","indent"],
    ["separator","inserttable","mksLink","mksInsertImage","linebreak","inserthorizontalrule","mkstemplates"],
    ["separator","undo","redo","mksQuicksave","removeformat","linebreak","htmlmode","simple","mksPreview"]
  ] : [
    ["mksSave","label:mksSave|"+_lang_label_save,"linebreak","mksCancel","label:mksCancel|"+_lang_label_cancel,"linebreak"],
    ["separator","formatblock"],
    ["separator","bold","italic","underline","linebreak","strikethrough"],
    ["separator","createlink","linebreak"],
    ["separator","undo","redo","mksQuicksave","removeformat","linebreak","htmlmode","advanced","mksPreview"]
  ];
};

function cleanStyles(el,fn) {
  if (fn(el)) {
    HTMLArea.removeTag(el);
    return true;
  }
  var c = el.firstChild;
  while (c != null) {
    var next = c.nextSibling;
    if (c.nodeType == 1 && cleanStyles(c,fn))
      next = el.firstChild;
    c = next;
  }
  return false;
};

var convertStyleToSizeID = {
  normal      : "0",
  edimportant : 2,
  edhighlight : 3,
  edsubtle    : 4,
  edcode      : 5,
  plain       : 6
};

var convertSizeIDToStyle = [
  /*0*/ 'normal',
  /*1*/ 'xxx',
  /*2*/ 'edimportant',
  /*3*/ 'edhighlight',
  /*4*/ 'edsubtle',
  /*5*/ 'edcode',
  /*6*/ 'plain'
];

function doApplyFontStyles(editor, txt, value,isArray, tag, text) {
  if (value == "0") {
    if ((!isArray && editor.getHTMLText(HTMLArea.getOuterHTML(tag)) == editor.getHTMLText(text)) || HTMLArea.is_gecko) 
      editor.execCommand(txt, false, HTMLArea.is_ie ? "<>" : "+0");
    else if (isArray) {
      applyFontSize(editor, txt, value);
      editor.execCommand(txt, false, HTMLArea.is_ie ? "<>" : "+0");
    } else
      editor.splitOutRange(tag, editor._createRange(editor._getSelection()));
  } else
    applyFontSize(editor, txt, value);
};

function updateFontStyles(editor, value) {
  var text = editor.getSelectedHTML();
  var tags = getFontStyleTags(editor);
  if (text == "" && value == "normal") {
    editor.selectWord();
    text = editor.getSelectedHTML();
    tags = getFontSizeTags(editor);
  }
  var r = editor.getRange();
  var isArray = typeof tags.tags != "undefined";
  var root = isArray ? tags.root : tags.tag.parentNode;

  // replace font size into span tags (move away tags to make room)
  HTMLArea.replaceTagsF(root,function (el) {
    if (!/^font$/i.test(el.tagName) || el.size == "")
      return null;
    var ret = editor._doc.createElement("span");
    ret.className = '_font_size|' + el.size;
    if (tags.tag == el)
      tags.tag = ret;
    return HTMLArea.cloneNode(el,ret);
  });
  // replace font styles into font size tags (prepare for native use)
  HTMLArea.replaceTagsF(root,function (el) {
    if (!/^span$/i.test(el.tagName) || !/(edimportant|edhighlight|edsubtle|edcode|plain)/i.test(el.className))
      return null;
    
    var ret = editor._doc.createElement("font");
    ret.size = convertStyleToSizeID[el.className];
    if (tags.tag == el)
      tags.tag = ret;
    return HTMLArea.cloneNode(el,ret);
  });

  editor.setRange(r);
  doApplyFontStyles(editor,"fontsize",convertStyleToSizeID[value],isArray,tags.tag,text);
  
  // replace font size into font style tags (store result of native use into wished tags)
  HTMLArea.replaceTagsF(root,function (el) {
    if (!/^font$/i.test(el.tagName) || el.size == "")
      return null;
    var ret = editor._doc.createElement("span");
    ret.className = convertSizeIDToStyle[el.size];
    return HTMLArea.cloneNode(el,ret);
  });
  // replace span into font size tags (move back from hiding)
  HTMLArea.replaceTagsF(root,function (el) {
    if (!/^span$/i.test(el.tagName) || !/_font_size.+/i.test(el.className))
      return null;
    
    var ret = editor._doc.createElement("font");
    ret.size = el.className.substr('_font_size|'.length);
    return HTMLArea.cloneNode(el,ret);
  });
  editor.setRange(r);
  editor.updateToolbar();
};

function getFontSizeTags(editor) {
  return editor.getSelectionTagsF("font",function(el) { return el.size != ""; });
};

function getFontStyleTags(editor) {
  return editor.getSelectionTagsF("span",function(el) { return el.className != ""; });
};

function fontSizes(editor) {
  var tags = getFontSizeTags(editor);
  if (typeof tags.tags != "undefined") // 'mixed' has a false positive if the same size is applied across multiple blocks
    return tags.tags.length > 0 ? "mixed" : "0";
  return tags.tag.size;
};

function fontStyles(editor) {
  var tags = getFontStyleTags(editor);
  if (typeof tags.tags != "undefined") // 'mixed' has a false positive if the same style is applied across multiple blocks
    return tags.tags.length > 0 ? "mixed" : "normal";
  return tags.tag.className;
};

function applyFontSize(editor, txt, value) {
  editor._doc.execCommand(txt, false, HTMLArea.is_ie ? "1" : value);
  if (HTMLArea.is_ie) {
    var sel = editor._getSelection();
    var range = editor._createRange(sel);
    var rangeEl = editor.getParentElement(sel,range);
    var els = rangeEl.getElementsByTagName('font');
    if (els.length == 0)
      els = [rangeEl];
    for (var i = 0; i < els.length; ++i) {
      var el = els[i];
      if (el.size == 1)
        el.size = value;
    }
  }
};

function updateFontSizes(editor, txt, value) {
  var text = editor.getSelectedHTML();
  var tags = getFontSizeTags(editor);
  if (text == "" && value == "0") {
    editor.selectWord();
    text = editor.getSelectedHTML();
    tags = getFontSizeTags(editor);
  }
  doApplyFontStyles(editor, txt, value, typeof tags.tags != "undefined", tags.tag, text);
  editor.updateToolbar();
};

function popupTemplates(width, height, editor) {
  var sel = editor._getSelection();
  var range = editor._createRange(sel);
  editor._popupDialog(width, height, editor.config.URIs["mkstemplates"], function(param) {
    if (!param || (!param.f_template && !param.f_site)) {	// user must have pressed Cancel
      return false;
    }
    editor.focusEditor();
    var doc = editor._doc;
    var template = param.f_template;
    if (!template) {
      var siteTemplate = param.f_site;
      var siteName = siteTemplate.siteName;
      var tree = siteTemplate.tree;
      function createLink(topic,name) {
        return '<a class="site" href="#" title="'+topic+'" template="Template:'+topic+'">'+name+'</a>';
      }
      function createHtml(node) {
        var itemsHtml = '<ul>';
        for (var itemKey in node) {
          if (itemKey == "__value" || itemKey == "__path") continue;
          var item = node[itemKey];
          itemsHtml += '<li>' + createLink(siteName+'/'+item.__path,item.__value) + createHtml(item) + '</li>';
        }
        return itemsHtml == '<ul>' ? "" : itemsHtml + '</ul>';
      };
      template = '<ul><li>' + createLink(siteName,siteName);
      template += createHtml(tree);
      template += '</li></ul>';
    }
    editor.insertHTML(template);
    if (!HTMLArea.is_ie) {
      // Toggle in and out of htmlmode after inserting a template
      // This works around the FF insert unable to backspace bug
      editor.execCommand("htmlmode");
      editor.execCommand("htmlmode");
    }
    return true;
  }, null);
};

function removeFormat(editor) {
  function checkEmpty(el) {
    if (/^(a|span|b|strong|i|em|font|div)$/i.test(el.tagName) &&
        !el.firstChild)
      HTMLArea.removeFromParent(el);
  };
  function parseTree(root) {
    var tag = root.tagName.toLowerCase(), i, next;
    if (/^(a|span|b|strong|i|em|font|small|big|strike|del)$/i.test(root.tagName)) {
      HTMLArea.removeTag(root);
      return false;
    } else {
      for (i = root.firstChild; i; i = next) {
        next = i.nextSibling;
        if (i.nodeType == 1 && parseTree(i))
          checkEmpty(i);
      }
    }
    return true;
  };

  var html = editor.getSelectedHTML();
  var div = editor._doc.createElement("div");
  div.innerHTML = html;
  parseTree(div);
  if (div.innerHTML == html)
    return;
  html = div.innerHTML;
  var r = editor.getRange();
  HTMLArea.is_ie ? document.execCommand("Delete") : editor._createRange().deleteContents();
  editor.insertHTML(html);
  editor.setRange(r);
  editor.updateToolbar();
};

function getAttachmentUrl(id, aref) {
  if (typeof x_wfGetAttachmentUrl == 'undefined') return;
  x_wfGetAttachmentUrl(id, function(data) {
    if (data == '-' || data == '')
      return;
    MindTouch.setLink(aref, data);
  });
}

function startContentEditor() {
  if (!start_editor)
    return;
  
  content_editors = content_editors ? content_editors :
  [
    'editarea'
  ];
  if (document.getElementById('wpTextbox2'))
    content_editors.push('wpTextbox2');
  for (var i = 0; i < content_editors.length; ++i)
    if (!document.getElementById(content_editors[i]))
      return;
  xinha_config = xinha_config ? xinha_config : new HTMLArea.Config();
  content_editors = HTMLArea.makeEditors(content_editors, xinha_config, xinha_plugins);

  for(var i in content_editors) {
    var e = content_editors[i];
    if (i == 'editarea') cur_editor = e;
    if (typeof contextTopic != 'undefined') {
      e.contextTopic = contextTopic;
      e.contextTopicID = _page_ID;
    }
    if(document.compatMode && document.compatMode != 'BackCompat') {
      HTMLArea._addEvent(window, 'resize', function() {
        e.sizeEditor();
      });
    }
  }

  HTMLArea.startEditors(content_editors);
};

var editorStarting = false;
var wpEditTimeValue = null;
var wpSectionValue = null;

function doCheckChanges(editor) {
  if (editorStarting) {
    if (typeof clearTT == 'function') clearTT();

    if (cur_editor != editor)
      return;
    var wpEditTime = document.getElementById('wpEditTime');
    if (wpEditTime) wpEditTime.value = wpEditTimeValue;
    var wpSection = document.getElementById('wpSection');
    if (wpSection) wpSection.value = wpSectionValue;
    wpEditTimeValue = null;
    wpSectionValue = null;
    editorStarting = false;
  }
  if (!editor) 
    return false;
  if (typeof hex_md5 != 'function')
    return false;
  var cur = hex_md5(editor.getHTML());
  if (!saveFlag) {
    saveFlag = true;
    prevHTML = cur;
  }
  else if (prevHTML == cur)
    return true;
  return false;
};

function handleEdit_cb(responseContent) {
  oldcontent = sectiontoedit.innerHTML;
  var r = responseContent.indexOf('|');
  sectiontoedit.innerHTML = responseContent.substring(r+1);

  editorStarting = true;
  wpEditTimeValue = responseContent.substring(0,r);
  wpSectionValue = cur_section != null ? cur_section : '';

  cur_editor = null; content_editors = null; xinha_config = null; xinha_plugins = null;
  start_editor = true;
  new xinha_init;
};

function doSectionEdit_cb(responseContent) {
  if (typeof (sectiontoedit) != 'undefined') {
    handleEdit_cb(responseContent);
  }
};

function doLoadEditor_cb(responseContent) {
  sectiontoedit = document.getElementById("topic");
    
  handleEdit_cb(responseContent);
};

function doCancelEdit(check) {
  if (check) {
    var display = checkForChanges();
    if (display != null) {
      if (!confirm("Are you sure you want to navigate away from the editor?\n\n" + display + "\n\nPress OK to continue, or Cancel to stay on the current editor."))
        return false;
    }
  } else {
    x_wfStatistics('', 'edit-cancel', function(data) {});
  }
  if (sectiontoedit != null) {
    sectiontoedit.innerHTML = oldcontent;
    hookEditIcons();
    sectiontoedit = null;
  }
  saveFlag = false;
  
  if (did_quicksave)
    window.location.reload();
  return true;
};

// Public entry point
function doLoadEditor() {
  cur_section = null;
  if (sectiontoedit != null)
    if (!doCancelEdit(true))
      return;
  title = contextTopic;
  x_loadInplaceEditor(contextTopic,doLoadEditor_cb);
};

// Public entry point
function doEditSection (page, section, sectionDivID, sectionAnchor) {
  cur_section = section;
  var newSection = document.getElementById(sectionDivID);
  if (sectiontoedit == newSection)
    return;
  if (sectiontoedit != null)
    if (!doCancelEdit(true))
      return;
  oldcontent = document.getElementById("topic").innerHTML;
  title = page;
  sectiontoedit = newSection;
  x_doSectionEdit(section, page, doSectionEdit_cb);
};

function isNameChanged() {
  var html = HTMLArea.getHTML(cur_editor._doc.getElementsByTagName('body')[0], false, cur_editor);
  html = stripTitle(html);  // sets wpNewTitle based on page content

  var wpNewTitleName = document.getElementById('wpNewTitle').value;
  var wpOldTitleName = _page_titleName;
  return wpNewTitleName != wpOldTitleName;
};

function saveEntryInline() {
  if (doCheckChanges(cur_editor))
    return;
  var html = HTMLArea.getHTML(cur_editor._doc.getElementsByTagName('body')[0], false, cur_editor);
  html = stripTitle(html);
  var title = contextTopic;
  var time = document.getElementById('wpEditTime').value;
  var section = document.getElementById('wpSection').value;
  html = escape(html);
  var r = new RegExp("\\+","g");
  html = html.replace(r,'%2B');
  x_wfSaveEdit(title, html, time, section, cb_saveEntryInline);
};

function cb_saveEntryInline(responseContent) {
  if (responseContent == '') {
    document.getElementById('quicksavewait').style.display = 'none';
    alert('An unknown error has occured, quick save failed.');
    return;
  }
  var r = responseContent.split('|');
  var wpEditTime = document.getElementById('wpEditTime');
  if (wpEditTime) wpEditTime.value = r[0];
  document.getElementById('quicksavewait').style.display = 'none';
  if (r[1] != '1') {
    // Only show the fading text at bottom of editor, if the action succeeded, otherwise show the alert
    alert(r[2]);
  } else {
    displayInlineMsg('saveMsgSuccess');
    saveFlag = false;
    did_quicksave = true;
    doCheckChanges(cur_editor);
  }
};

function stripTitle(html) {
  if (cur_section != null)
    return html;
  var titleStart = html.indexOf('<h1>');
  var firstTag = html.indexOf('<');
  if (titleStart != firstTag)
    return html;
  var titleStop = html.indexOf('</h1>');
  if (titleStart == -1 || titleStop == -1 || titleStop - titleStart <= 0)
    return html;
  var title = html.substring(titleStart + 4, titleStop);
  var node = document.createElement('div');
  node.innerHTML = title;
  title = HTMLArea.getInnerText(node);
  document.getElementById('wpNewTitle').value = title;
  html = html.substring(titleStop + 5);
  return html;
};

function doSave() {
  setHiddenSubmit('wpSaveH');
  doShowSaveMessage();
  var html = cur_editor.getHTML();
  html = stripTitle(html);
  cur_editor.setHTML(html);
  document.getElementById('editarea').value = html;
};

function doSaveMinor() {
  if (isNameChanged()) {
      alert('Unable to quicksave because you have renamed the page.  You must Save.');
      return;
  }
  setHiddenSubmit('wpSaveMinorH');
  doShowSaveMessage();
  saveEntryInline();
  return false;
};

function okToLeave() {
  saveFlag = false;
};

function doShowSaveMessage() {
  document.getElementById('quicksavewait').style.display = 'block';
};

function doHideSaveMessage() {
  document.getElementById('quicksavedone').style.display = 'none';
};

function prependHTMLToToolbar(editor) {
  if (cur_editor != editor)
    return null;
  
  var sectionAndEditTime;
  if (document.getElementById('wpEditTime') == null)
    sectionAndEditTime = '<input type="hidden" name="wpSection" value="" id="wpSection" />'+
      '<input type="hidden" name="wpEdittime" value="" id="wpEditTime" />';
  else
    sectionAndEditTime = '';
  
  return _prependHTMLToToolbar() + sectionAndEditTime;
};

function addClick(a,type) {
  HTMLArea.addDom0Event(a, 'click', function() {
    x_wfStatistics(a.href, type, function(data) {
//      debugger;
        window.location = a.href;
    });
    return false;
  });
};

function getType(el) {
  if (el.nodeType != 1) {
    return null;
  }
  var tagName = el.tagName.toLowerCase();
  var className = el.className;
  switch (tagName) {
  case 'div':
    switch (className) {
    case 'breadcrumb': return 'breadcrumb';
    case 'wrap_vtop': return 'vtop-custom';
    case 'wrap_bottom': return 'vbottom-custom';
    case 'prevChild': return 'nav-bar-prev';
    case 'nextChild': return 'nav-bar-next';
    case 'item sibling': return 'nav-bar-sibling';
    case 'item child': return 'nav-bar-child';
    case 'item currentnode': return 'nav-bar-current';
    case 'topic-expand': return 'content';
    case 'editsection-big': return 'edit-icon';
    case 'headerlink': return 'edit-text';
    case 'print-toc': return 'toc';
    case 'printfooter': return 'footer';
    case 'user-dmenu-ff': return 'user-menu';
    case 'addNode': return 'add-node';
    case 'image':
    case 'filelink': return 'file-download';
    }
    switch (el.id) {
    case 'attachments': return 'file';
    case 'menuBacklink': return 'backlink';
    }
    break;
  case 'a':
    var optPos = className.indexOf('opt-');
    if (optPos >= 0) {
        switch (className.substring(optPos)) {
        case 'opt-watchlist': return 'menu-watchlist';
        case 'opt-delete': return 'menu-delete';
        case 'opt-print': return 'menu-print';
        case 'opt-recentchanges': return 'menu-recentchanges';
        case 'opt-controlpanellink': return 'menu-controlpanel';
        case 'opt-listusers': return 'menu-listusers';
        case 'opt-allpages': return 'menu-allpages';
        case 'opt-popularpages': return 'menu-popularpages';
        case 'opt-wantedpages': return 'menu-wantedpages';
        case 'opt-lonelypages': return 'menu-lonelypages';
        case 'opt-doubleredirects': return 'menu-doubleredirects';
        case 'opt-preferences': return 'menu-preferences';
        case 'opt-mycontris': return 'menu-mycontris';
        }
    }
    switch (className) {
    case 'buttonify icon-delattach': return 'file-delete';
    case 'attachDesc': return null;
    }
    break;
  case 'p':
    if (className == 'modified') return 'history';
    break;
  case 'h5':
    if (className == 'nav-parent') return 'nav-bar-parent';
    break;
  case 'li':
    switch (el.id) {
    case 'myhomepage': return 'nav-mypage';
    case 'n-mainpage': return 'nav-home';
    case 'n-portal': return 'nav-community';
    case 'n-currentevents': return 'nav-events';
    case 'n-help': return 'nav-help';
    }
    break;
  }
  if (el.parentNode != null)
    return getType(el.parentNode);
  return null;
};

function hookClicks() {
  var as = document.getElementsByTagName("a");
  for (var i = as.length; i > 0; ) {
    var a = as[--i];
    if (a.href == "") continue;
    var type = getType(a);
    if (type) addClick(a,type)
  }
};


/*--------------------------------------:noTabs=true:tabSize=2:indentSize=2:--
--  Xinha (is not htmlArea) - http://xinha.gogo.co.nz/
--
--  Use of Xinha is granted by the terms of the htmlArea License (based on
--  BSD license)  please read license.txt in this package for details.
--
--  Xinha was originally based on work by Mihai Bazon which is:
--      Copyright (c) 2003-2004 dynarch.com.
--      Copyright (c) 2002-2003 interactivetools.com, inc.
--      This copyright notice MUST stay intact for use.
--
--  Copyright (C) 2006 MindTouch, Inc.
--
--  Developers - Coding Style:
--   For the sake of not committing needlessly conflicting changes,
--
--   * New code to be indented with 2 spaces ("soft tab").
--   * New code preferably uses BSD-Style Bracing
--      if(foo)
--      {
--        bar();
--      }
--   * Don't change brace styles unless you're working on the non BSD-Style
--     area (so we don't get spurious changes in line numbering).
--   * Don't change indentation unless you're working on the badly indented
--     area (so we don't get spurious changes of large blocks of code).
--   * Jedit is the recommended editor, a comment of this format should be
--     included in the top 10 lines of the file (see the embedded edit mode)
--
--  $HeadURL: http://svn.xinha.python-hosting.com/trunk/htmlarea.js $
--  $LastChangedDate: 2005-10-02 04:58:27 -0600 (Sun, 02 Oct 2005) $
--  $LastChangedRevision: 377 $
--  $LastChangedBy: kimss $
--------------------------------------------------------------------------*/

HTMLArea.version =
{
'Release'   : 'Trunk',
'Head'      : '$HeadURL: http://svn.xinha.python-hosting.com/trunk/htmlarea.js $'.replace(/^[^:]*: (.*) \$$/, '$1'),
'Date'      : '$LastChangedDate: 2005-10-02 04:58:27 -0600 (Sun, 02 Oct 2005) $'.replace(/^[^:]*: ([0-9-]*) ([0-9:]*) ([+0-9]*) \((.*)\) \$/, '$4 $2 $3'),
'Revision'  : '$LastChangedRevision: 377 $'.replace(/^[^:]*: (.*) \$$/, '$1'),
'RevisionBy': '$LastChangedBy: kimss $'.replace(/^[^:]*: (.*) \$$/, '$1')
};

if (typeof _editor_url == "string") {
    // Leave exactly one backslash at the end of _editor_url
    _editor_url = _editor_url.replace(/\x2f*$/, '/');
} else {
    alert("WARNING: _editor_url is not set!  You should set this variable to the editor files path; it should preferably be an absolute path, like in '/htmlarea/', but it can be relative if you prefer.  Further we will try to load the editor files correctly but we'll probably fail.");
    _editor_url = '';
}

// make sure we have a language
if (typeof _editor_lang == "string") {
    _editor_lang = _editor_lang.toLowerCase();
} else {
    _editor_lang = "en";
}

// skin stylesheet to load
if (!(typeof _editor_skin == "string")) {
    _editor_skin = "";
}

var __htmlareas = [ ];

// browser identification
HTMLArea.agt = navigator.userAgent.toLowerCase();
HTMLArea.is_ie     = ((HTMLArea.agt.indexOf("msie") != -1) && (HTMLArea.agt.indexOf("opera") == -1));
HTMLArea.is_opera  = (HTMLArea.agt.indexOf("opera") != -1);
HTMLArea.is_mac    = (HTMLArea.agt.indexOf("mac") != -1);
HTMLArea.is_mac_ie = (HTMLArea.is_ie && HTMLArea.is_mac);
HTMLArea.is_win_ie = (HTMLArea.is_ie && !HTMLArea.is_mac);
HTMLArea.is_gecko  = (navigator.product == "Gecko");

// Creates a new HTMLArea object.  Tries to replace the textarea with the given
// ID with it.
function HTMLArea(textarea, config)
{
    if(!textarea) throw("Tried to create HTMLArea without textarea specified.");

    if (HTMLArea.checkSupportedBrowser()) {
        if (typeof config == "undefined") {
            this.config = new HTMLArea.Config();
        } else {
            this.config = config;
        }
        this._htmlArea = null;

        if(typeof textarea != 'object')
        {
            textarea = HTMLArea.getElementById('textarea', textarea);
        }
        this._textArea = textarea;

        // Before we modify anything, get the initial textarea size
        this._initial_ta_size =
        {
            w: textarea.style.width ? textarea.style.width   : (textarea.offsetWidth + 'px'),
            h: textarea.style.height ? textarea.style.height : (textarea.offsetHeight + 'px')
        };

        this._editMode = "wysiwyg";
        this.plugins = {};
        this._timerToolbar = null;
        this._timerUndo = null;
        this._undoQueue = new Array(this.config.undoSteps);
        this._undoPos = -1;
        this._customUndo = true;
        this._mdoc = document; // cache the document, we need it in plugins
        this.doctype = '';
        this.__htmlarea_id_num = __htmlareas.length;
        __htmlareas[this.__htmlarea_id_num] = this;

        this._notifyListeners = { };

        // Panels
        var panels = this._panels =
        {
            right:
            {
                on: true,
                container:    document.createElement('td'),
                panels: [ ]
            },
            left:
            {
                on: true,
                container:    document.createElement('td'),
                panels: [ ]
            },
            top:
            {
                on: true,
                container:    document.createElement('td'),
                panels: [ ]
            },
            bottom:
            {
                on: true,
                container:    document.createElement('td'),
                panels: [ ]
            }
        };

        for(var i in panels)
        {
            panels[i].div = panels[i].container; // legacy
            panels[i].container.className = 'panels ' + i;
            HTMLArea.freeLater(panels[i], 'container');
            HTMLArea.freeLater(panels[i], 'div');
        }
        HTMLArea.freeLater(this, '_textArea');
    }
};

HTMLArea.onload = function(){};
HTMLArea.init = function() {
    HTMLArea.onload();
};


// cache some regexps
HTMLArea.RE_tagName = /(<\/|<)\s*([^ \t\n>]+)/ig;
HTMLArea.RE_doctype = /(<!doctype((.|\n)*?)>)\n?/i;
HTMLArea.RE_head    = /<head>((.|\n)*?)<\/head>/i;
HTMLArea.RE_body    = /<body[^>]*>((.|\n|\r|\t)*?)<\/body>/i;
HTMLArea.RE_Specials = /([\/\^$*+?.()|{}[\]])/g;
HTMLArea.RE_email    = /[a-z0-9_]{3,}@[a-z0-9_-]{2,}(\.[a-z0-9_-]{2,})+/i;
HTMLArea.RE_url      = /(https?:\/\/)?(([a-z0-9_]+:[a-z0-9_]+@)?[a-z0-9_-]{2,}(\.[a-z0-9_-]{2,}){2,}(:[0-9]+)?(\/\S+)*)/i;

HTMLArea.Config = function () {
    var cfg = this;
    this.version = HTMLArea.version.Revision;

    // Width and Height
    //  you may set these as follows
    //  width = 'auto'      -- the width of the original textarea will be used
    //  width = 'toolbar'   -- the width of the toolbar will be used
    //  width = '<css measure>' -- use any css measurement, eg width = '75%'
    //
    //  height = 'auto'     -- the height of the original textarea
    //  height = '<css measure>' -- any css measurement, eg height = '480px'
    this.width  = "auto";
    this.height = "auto";

    // the next parameter specifies whether the toolbar should be included
    // in the size above, or are extra to it.  If false then it's recommended
    // to have explicit pixel sizes above (or on your textarea and have auto above)
    this.sizeIncludesBars = true;

    // the next parameter specifies whether the panels should be included
    // in the size above, or are extra to it.  If false then it's recommended
    // to have explicit pixel sizes above (or on your textarea and have auto above)
    this.sizeIncludesPanels = true;

    // each of the panels has a dimension, for the left/right it's the width
    // for the top/bottom it's the height.
    //
    // WARNING: PANEL DIMENSIONS MUST BE SPECIFIED AS PIXEL WIDTHS
    this.panel_dimensions =
    {
        left:   '200px', // Width
        right:  '200px',
        top:    '100px', // Height
        bottom: '100px'
    };

    // enable creation of a status bar?
    this.statusBar = true;

    // intercept ^V and use the HTMLArea paste command
    // If false, then passes ^V through to browser editor widget
    this.htmlareaPaste = false;

    this.mozParaHandler = 'best'; // set to 'built-in', 'dirty' or 'best'
    // built-in: will (may) use 'br' instead of 'p' tags
    // dirty   : will use p and work good enough for the majority of cases,
    // best    : works the best, but it's about 12kb worth of javascript
    //   and will probably be slower than 'dirty'.  This is the "EnterParagraphs"
    //   plugin from "hipikat", rolled in to be part of the core code

    // maximum size of the undo queue
    this.undoSteps = 20;

    // the time interval at which undo samples are taken
    this.undoTimeout = 500; // 1/2 sec.

    // if true then HTMLArea will retrieve the full HTML, starting with the
    // <HTML> tag.
    this.fullPage = false;

    // style included in the iframe document
    this.pageStyle = "";

    // external stylesheets to load (REFERENCE THESE ABSOLUTELY)
    this.pageStyleSheets = [ ];

    // specify a base href for relative links
    this.baseHref  = null;

    // we can strip the base href out of relative links to leave them relative, reason for this
    //   especially if you don't specify a baseHref is that mozilla at least (& IE ?) will prefix
    //   the baseHref to any relative links to make them absolute, which isn't what you want most the time.
    this.stripBaseHref = true;

    // and we can strip the url of the editor page from named links (eg <a href="#top">...</a>)
    //  reason for this is that mozilla at least (and IE ?) prefixes location.href to any
    //  that don't have a url prefixing them
    this.stripSelfNamedAnchors = true;

    // sometimes high-ascii in links can cause problems for servers (basically they don't recognise them)
    //  so you can use this flag to ensure that all characters other than the normal ascii set (actually
    //  only ! through ~) are escaped in URLs to % codes
    this.only7BitPrintablesInURLs = true;

    // if you are putting the HTML written in Xinha into an email you might want it to be 7-bit
    //  characters only.  This config option (off by default) will convert all characters consuming
    //  more than 7bits into UNICODE decimal entity references (actually it will convert anything
    //  below <space> (chr 20) except cr, lf and tab and above <tilde> (~, chr 7E))
    this.sevenBitClean  = false;

    // sometimes we want to be able to replace some string in the html comng in and going out
    //  so that in the editor we use the "internal" string, and outside and in the source view
    //  we use the "external" string  this is useful for say making special codes for
    //  your absolute links, your external string might be some special code, say "{server_url}"
    //  an you say that the internal represenattion of that should be http://your.server/
    this.specialReplacements = { }; // { 'external_string' : 'internal_string' }

    // set to true if you want Word code to be cleaned upon Paste
    this.killWordOnPaste = true;

    // enable the 'Target' field in the Make Link dialog
    this.makeLinkShowsTarget = true;

    // CharSet of the iframe, default is the charset of the document
    this.charSet = HTMLArea.is_gecko ? document.characterSet : document.charset;

    // URL-s
    this.imgURL = "images/";
    this.popupURL = "popups/";

    // remove tags (these have to be a regexp, or null if this functionality is not desired)
    this.htmlRemoveTags = null;

    // Turning this on will turn all "linebreak" and "separator" items in your toolbar into soft-breaks,
    // this means that if the items between that item and the next linebreak/separator can
    // fit on the same line as that which came before then they will, otherwise they will
    // float down to the next line.

    // If you put a linebreak and separator next to each other, only the separator will
    // take effect, this allows you to have one toolbar that works for both flowToolbars = true and false
    // infact the toolbar below has been designed in this way, if flowToolbars is false then it will
    // create explictly two lines (plus any others made by plugins) breaking at justifyleft, however if
    // flowToolbars is false and your window is narrow enough then it will create more than one line
    // even neater, if you resize the window the toolbars will reflow.  Niiiice.

    this.flowToolbars = true;

    /** CUSTOMIZING THE TOOLBAR
    * -------------------------
    *
    * It is recommended that you customize the toolbar contents in an
    * external file (i.e. the one calling HTMLArea) and leave this one
    * unchanged.  That's because when we (InteractiveTools.com) release a
    * new official version, it's less likely that you will have problems
    * upgrading HTMLArea.
    */
    this.toolbar =
    [
    ["popupeditor"],
    ["separator","formatblock","fontname","fontsize","bold","italic","underline","strikethrough"],
    ["separator","forecolor","hilitecolor","textindicator"],
    ["separator","subscript","superscript"],
    ["linebreak","separator","justifyleft","justifycenter","justifyright","justifyfull"],
    ["separator","insertorderedlist","insertunorderedlist","outdent","indent"],
    ["separator","inserthorizontalrule","createlink","insertimage","inserttable"],
    ["separator","undo","redo","selectall","print"], (HTMLArea.is_gecko ? [] : ["cut","copy","paste","overwrite","saveas"]),
    ["separator","killword","clearfonts","removeformat","toggleborders","splitblock","lefttoright", "righttoleft"],
    ["separator","htmlmode","showhelp","about"]
    ];


    this.fontname = {
    "&mdash; font &mdash;":         '',
    "Arial":            'arial,helvetica,sans-serif',
    "Courier New":      'courier new,courier,monospace',
    "Georgia":          'georgia,times new roman,times,serif',
    "Tahoma":           'tahoma,arial,helvetica,sans-serif',
    "Times New Roman":  'times new roman,times,serif',
    "Verdana":          'verdana,arial,helvetica,sans-serif',
    "impact":           'impact',
    "WingDings":        'wingdings'
    };

    this.fontsize = {
    "&mdash; size &mdash;"  : "",
    "1 (8 pt)" : "1",
    "2 (10 pt)": "2",
    "3 (12 pt)": "3",
    "4 (14 pt)": "4",
    "5 (18 pt)": "5",
    "6 (24 pt)": "6",
    "7 (36 pt)": "7"
    };

    this.formatblock = {
    "&mdash; format &mdash;"  : "",
    "Heading 1": "h1",
    "Heading 2": "h2",
    "Heading 3": "h3",
    "Heading 4": "h4",
    "Heading 5": "h5",
    "Heading 6": "h6",
    "Normal"   : "p",
    "Address"  : "address",
    "Formatted": "pre"
    };

    this.customSelects = {};

    function cut_copy_paste(e, cmd, obj) {
        e.execCommand(cmd);
    };

    this.debug = true;

    this.URIs = {
    "blank": "popups/blank.html",
    "link": "link.html",
    "insert_image": "insert_image.html",
    "insert_table": "insert_table.html",
    "select_color": "select_color.html",
    // <MT
	"forecolor":    "select_color.php?type=fg",
	"hilitecolor":  "select_color.php?type=bg",
	// MT> 
    "about": "about.html",
    "help": "editor_help.html"
    };


    // ADDING CUSTOM BUTTONS: please read below!
    // format of the btnList elements is "ID: [ ToolTip, Icon, Enabled in text mode?, ACTION ]"
    //    - ID: unique ID for the button.  If the button calls document.execCommand
    //      it's wise to give it the same name as the called command.
    //    - ACTION: function that gets called when the button is clicked.
    //              it has the following prototype:
    //                 function(editor, buttonName)
    //              - editor is the HTMLArea object that triggered the call
    //              - buttonName is the ID of the clicked button
    //              These 2 parameters makes it possible for you to use the same
    //              handler for more HTMLArea objects or for more different buttons.
    //    - ToolTip: tooltip, will be translated below
    //    - Icon: path to an icon image file for the button
    //            OR; you can use an 18x18 block of a larger image by supllying an array
    //            that has three elemtents, the first is the larger image, the second is the column
    //            the third is the row.  The ros and columns numbering starts at 0 but there is
    //            a header row and header column which have numbering to make life easier.
    //            See images/buttons_main.gif to see how it's done.
    //    - Enabled in text mode: if false the button gets disabled for text-only mode; otherwise enabled all the time.
    this.btnList = {
        bold:          [ "Bold",   HTMLArea._lc({key: 'button_bold', string: ["ed_buttons_main.gif",3,2]}, 'HTMLArea'), false, function(e) {e.execCommand("bold");} ],
        italic:        [ "Italic", HTMLArea._lc({key: 'button_italic', string: ["ed_buttons_main.gif",2,2]}, 'HTMLArea'), false, function(e) {e.execCommand("italic");} ],
        underline:     [ "Underline", HTMLArea._lc({key: 'button_underline', string: ["ed_buttons_main.gif",2,0]}, 'HTMLArea'), false, function(e) {e.execCommand("underline");} ],
        strikethrough: [ "Strikethrough", HTMLArea._lc({key: 'button_strikethrough', string: ["ed_buttons_main.gif",3,0]}, 'HTMLArea'), false, function(e) {e.execCommand("strikethrough");} ],
        subscript:     [ "Subscript", HTMLArea._lc({key: 'button_subscript', string: ["ed_buttons_main.gif",3,1]}, 'HTMLArea'), false, function(e) {e.execCommand("subscript");} ],
        superscript:   [ "Superscript", HTMLArea._lc({key: 'button_superscript', string: ["ed_buttons_main.gif",2,1]}, 'HTMLArea'), false, function(e) {e.execCommand("superscript");} ],

        justifyleft:   [ "Justify left", ["ed_buttons_main.gif",0,0], false, function(e) {e.execCommand("justifyleft");} ],
        justifycenter: [ "Justify center", ["ed_buttons_main.gif",1,1], false, function(e){e.execCommand("justifycenter");}],
        justifyright:  [ "Justify right", ["ed_buttons_main.gif",1,0], false, function(e) {e.execCommand("justifyright");} ],
        justifyfull:   [ "Justify full", ["ed_buttons_main.gif",0,1], false, function(e) {e.execCommand("justifyfull");} ],

        orderedlist:         [ "Ordered list", ["ed_buttons_main.gif",0,3], false, function(e) {e.execCommand("insertorderedlist");} ],
        unorderedlist:       [ "Bulleted list", ["ed_buttons_main.gif",1,3], false, function(e) {e.execCommand("insertunorderedlist");} ],
        insertorderedlist:   [ "Ordered list", ["ed_buttons_main.gif",0,3], false, function(e) {e.execCommand("insertorderedlist");} ],
        insertunorderedlist: [ "Bulleted list", ["ed_buttons_main.gif",1,3], false, function(e) {e.execCommand("insertunorderedlist");} ],

        outdent:     [ "Decrease indent", ["ed_buttons_main.gif",1,2], false, function(e) {e.execCommand("outdent");} ],
        indent:      [ "Increase indent",["ed_buttons_main.gif",0,2], false, function(e) {e.execCommand("indent");} ],
        // >MT: Change "Font color" to "Text color"
        forecolor:   [ "Text color", ["ed_buttons_main.gif",3,3], false, function(e) {e.execCommand("forecolor");} ],
        // <MT
        hilitecolor: [ "Background color", ["ed_buttons_main.gif",2,3], false, function(e) {e.execCommand("hilitecolor");} ],

        // >MT: Clean up the wordsmithing of "Undo", "Redo", "Cut", "Copy", and "Paste"
        undo: [ "Undo last action", ["ed_buttons_main.gif",4,2], false, function(e) {e.execCommand("undo");} ],
        redo: [ "Redo last action", ["ed_buttons_main.gif",5,2], false, function(e) {e.execCommand("redo");} ],
        cut:       [ "Cut", ["ed_buttons_main.gif",5,0], false, cut_copy_paste ],
        copy:      [ "Copy", ["ed_buttons_main.gif",4,0], false, cut_copy_paste ],
        paste:     [ "Paste", ["ed_buttons_main.gif",4,1], false, cut_copy_paste ],
        // <MT
        selectall: [ "Select all", "ed_selectall.gif", false, function(e) {e.execCommand("selectall");} ],

        inserthorizontalrule: [ "Horizontal rule", ["ed_buttons_main.gif",6,0], false, function(e) {e.execCommand("inserthorizontalrule");} ],
        // >MT: use standard createlink, so that param is passed, also change "Insert web link" to "Insert/modify link"
        createlink:           [ "Insert/modify link", ["ed_buttons_main.gif",6,1], false, function(e) {e.execCommand("createlink");} ],
        // <MT
        insertimage:          [ "Insert/modify image", ["ed_buttons_main.gif",6,3], false, function(e) {e.execCommand("insertimage");} ],
        inserttable:          [ "Insert table", ["ed_buttons_main.gif",6,2], false, function(e) {e.execCommand("inserttable");} ],

        htmlmode:      [ "Toggle HTML source", ["ed_buttons_main.gif",7,0], true, function(e) {e.execCommand("htmlmode");} ],
        toggleborders: [ "Toggle borders", ["ed_buttons_main.gif",7,2], false, function(e) { e._toggleBorders() } ],
        print:         [ "Print document", ["ed_buttons_main.gif",8,1], false, function(e) {e._iframe.contentWindow.print();} ],
        saveas:        [ "Save as", "ed_saveas.gif", false, function(e) {e.execCommand("saveas",false,"noname.htm");} ],
        about:         [ "About this editor", ["ed_buttons_main.gif",8,2], true, function(e) {e.execCommand("about");} ],
        showhelp:      [ "Help using editor", ["ed_buttons_main.gif",9,2], true, function(e) {e.execCommand("showhelp");} ],

        splitblock:   [ "Split block", "ed_splitblock.gif", false, function(e) {e._splitBlock();} ],
        lefttoright:  [ "Direction left to right", ["ed_buttons_main.gif",0,4], false, function(e) {e.execCommand("lefttoright");} ],
        righttoleft:  [ "Direction right to left", ["ed_buttons_main.gif",1,4], false, function(e) {e.execCommand("righttoleft");} ],
        overwrite:    [ "Insert/overwrite", "ed_overwrite.gif", false, function(e) {e.execCommand("overwrite");} ],

        // >MT: Clean up the capitalization of "MS word cleaner"
        wordclean:     [ "MS Word cleaner", ["ed_buttons_main.gif",5,3], false, function(e) {e._wordClean();} ],
        // <MT
        clearfonts:    [ "Clear inline font specifications", ["ed_buttons_main.gif",5,4], true, function(e) {e._clearFonts();} ],
        // >MT: "Clear" is being used instead of "Remove"
        removeformat:  [ "Clear formatting", ["ed_buttons_main.gif",4,4], false, function(e) {e.execCommand("removeformat");} ],
        // <MT
        killword:      [ "Clear MS Office tags", ["ed_buttons_main.gif",4,3], false, function(e) {e.execCommand("killword");} ]

    };
    /* ADDING CUSTOM BUTTONS
    * ---------------------
    *
    * It is recommended that you add the custom buttons in an external
    * file and leave this one unchanged.  That's because when we
    * (InteractiveTools.com) release a new official version, it's less
    * likely that you will have problems upgrading HTMLArea.
    *
    * Example on how to add a custom button when you construct the HTMLArea:
    *
    *   var editor = new HTMLArea("your_text_area_id");
    *   var cfg = editor.config; // this is the default configuration
    *   cfg.btnList["my-hilite"] =
    *  [ function(editor) { editor.surroundHTML('<span style="background:yellow">', '</span>'); }, // action
    *    "Highlight selection", // tooltip
    *    "my_hilite.gif", // image
    *    false // disabled in text mode
    *  ];
    *   cfg.toolbar.push(["linebreak", "my-hilite"]); // add the new button to the toolbar
    *
    * An alternate (also more convenient and recommended) way to
    * accomplish this is to use the registerButton function below.
    */
    // initialize tooltips from the I18N module and generate correct image path
    for (var i in this.btnList) {
        var btn = this.btnList[i];
        if(typeof btn[1] != 'string')
        {
            btn[1][0] = _editor_url + this.imgURL + btn[1][0];
        }
        else
        {
            btn[1] = _editor_url + this.imgURL + btn[1];
        }
        btn[0] = HTMLArea._lc(btn[0]); //initialize tooltip
    }

};

/** Helper function: register a new button with the configuration.  It can be
* called with all 5 arguments, or with only one (first one).  When called with
* only one argument it must be an object with the following properties: id,
* tooltip, image, textMode, action.  Examples:
*
* 1. config.registerButton("my-hilite", "Hilite text", "my-hilite.gif", false, function(editor) {...});
* 2. config.registerButton({
*      id       : "my-hilite",      // the ID of your button
*      tooltip  : "Hilite text",    // the tooltip
*      image    : "my-hilite.gif",  // image to be displayed in the toolbar
*      textMode : false,            // disabled in text mode
*      action   : function(editor) { // called when the button is clicked
*                   editor.surroundHTML('<span class="hilite">', '</span>');
*                 },
*      context  : "p"               // will be disabled if outside a <p> element
*    });
*/
HTMLArea.Config.prototype.registerButton = function(id, tooltip, image, textMode, action, context) {
    var the_id;
    if (typeof id == "string") {
        the_id = id;
    } else if (typeof id == "object") {
        the_id = id.id;
    } else {
        alert("ERROR [HTMLArea.Config::registerButton]:\ninvalid arguments");
        return false;
    }
    // check for existing id
    if (typeof this.customSelects[the_id] != "undefined") {
        // alert("WARNING [HTMLArea.Config::registerDropdown]:\nA dropdown with the same ID already exists.");
    }
    if (typeof this.btnList[the_id] != "undefined") {
        // alert("WARNING [HTMLArea.Config::registerDropdown]:\nA button with the same ID already exists.");
    }
    switch (typeof id) {
        case "string": this.btnList[id] = [ tooltip, image, textMode, action, context ]; break;
        case "object": this.btnList[id.id] = [ id.tooltip, id.image, id.textMode, id.action, id.context ]; break;
    }
};

HTMLArea.prototype.registerPanel = function(side, object)
{
    if(!side) side = 'right';
    var panel = this.addPanel(side);
    if(object)
    {
        object.drawPanelIn(panel);
    }
};

/** The following helper function registers a dropdown box with the editor
* configuration.  You still have to add it to the toolbar, same as with the
* buttons.  Call it like this:
*
* FIXME: add example
*/
HTMLArea.Config.prototype.registerDropdown = function(object) {
    // check for existing id
    if (typeof this.customSelects[object.id] != "undefined") {
        // alert("WARNING [HTMLArea.Config::registerDropdown]:\nA dropdown with the same ID already exists.");
    }
    if (typeof this.btnList[object.id] != "undefined") {
        // alert("WARNING [HTMLArea.Config::registerDropdown]:\nA button with the same ID already exists.");
    }
    this.customSelects[object.id] = object;
};

/** Call this function to remove some buttons/drop-down boxes from the toolbar.
* Pass as the only parameter a string containing button/drop-down names
* delimited by spaces.  Note that the string should also begin with a space
* and end with a space.  Example:
*
*   config.hideSomeButtons(" fontname fontsize textindicator ");
*
* It's useful because it's easier to remove stuff from the defaul toolbar than
* create a brand new toolbar ;-)
*/
HTMLArea.Config.prototype.hideSomeButtons = function(remove) {
    var toolbar = this.toolbar;
    for (var i = toolbar.length; --i >= 0;) {
        var line = toolbar[i];
        for (var j = line.length; --j >= 0; ) {
            if (remove.indexOf(" " + line[j] + " ") >= 0) {
                var len = 1;
                if (/separator|space/.test(line[j + 1])) {
                    len = 2;
                }
                line.splice(j, len);
            }
        }
    }
};

/** Helper Function: add buttons/drop-downs boxes with title or separator to the toolbar
* if the buttons/drop-downs boxes doesn't allready exists.
* id: button or selectbox (as array with separator or title)
* where: button or selectbox (as array if the first is not found take the second and so on)
* position:
* -1 = insert button (id) one position before the button (where)
* 0 = replace button (where) by button (id)
* +1 = insert button (id) one position after button (where)
*
* cfg.addToolbarElement(["T[title]", "button_id", "separator"] , ["first_id","second_id"], -1);
*/

HTMLArea.Config.prototype.addToolbarElement = function(id, where, position) {
    var toolbar = this.toolbar;
    var a, i, j, o, sid;
    var idIsArray = false;