var common_enableDebug = false;
var overlay_enableDebug = false;
var mouse_enableDebug = false;
var opacity_enableDebug = false;
var common_kb_enableDebug = false;

// CHECK seuraavasta hässäkästä pitää päästä eroon,
// siirrytään käyttämään 'textContent' -propertyä aina kun mahdollista ja
// ainoastaan vanhemmilla selaimilla innerText

//emulate legacy getter/setter API using ES5 APIs
try {
	if (!Object.prototype.__defineGetter__ && Object.defineProperty({},"x",{get: function(){return true}}).x) {
		Object.defineProperty(Object.prototype, "__defineGetter__", {enumerable: false, configurable: true, value: function(name,func) {Object.defineProperty(this,name, {get:func,enumerable: true,configurable: true}); }});
		Object.defineProperty(Object.prototype, "__defineSetter__", {enumerable: false, configurable: true, value: function(name,func) {Object.defineProperty(this,name, {set:func,enumerable: true,configurable: true}); }});
	}
} catch(defPropException) {/*Do nothing if an exception occurs*/};

if((typeof HTMLElement != 'undefined') && HTMLElement.prototype.__defineGetter__ != 'undefined') {
	HTMLElement.prototype.__defineGetter__("innerText", function () {
		var r = this.ownerDocument.createRange();
		r.selectNodeContents(this);
		return r.toString();
	});
}

if(typeof Node == 'undefined') {
	Node = {};
	Node.ELEMENT_NODE = 1;
	Node.TEXT_NODE = 3;
}

Object.size = function(obj) {
	var size = 0, key;
	for (key in obj) {
		if (obj.hasOwnProperty(key)) size++;
	}
	return size;
};

function common_isArray(mixed_var) {
	var getFuncName = function (fn) {
		var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn);
		if (!name) {
			return '(Anonymous)';
		}
		return name[1];
	};

	if (typeof mixed_var === 'object') {
		return mixed_var.hasOwnProperty('length') &&
		!mixed_var.propertyIsEnumerable('length') &&
		getFuncName(mixed_var.constructor) !== 'String';
	}
}

function common_function_exists(function_name) {
	if (typeof function_name == 'string') {
		return (typeof this.window[function_name] == 'function');
	} else {
		return (function_name instanceof Function);
	}
}

// kts. http://www.alistapart.com/articles/getoutbindingsituations
function common_createBoundedWrapper(object, method) {
  return function() {
    return method.apply(object, arguments);
  };
}

function common_setClass(element, pClass) {
	element.className = pClass;
//	element.setAttribute("className", pClass);
//	var test = element.getAttribute("class");
//	debugPrint(test);
}

function common_trim(txt) {
	return txt.replace(/^\s+|\s+$/g, '');
}


// abstract mouse button codes between browsers
// returns a 3-bit integer where the bits correspond to buttons like this:
// bit 1:	left button
// bit 2: midde button
// bit 3: right button
function common_resolveButton(aEvent) {
	var mouseButton = 0;
	var myEvent = aEvent ? aEvent : window.event;
	var eWhich = 0;
	var eButton = 0;
	if(myEvent.which) {
		eWhich = myEvent.which;
		// mozilla which-property doesn't support multiple buttons at once, but we don't care, since we don't need to detect those situations
		if(myEvent.which == 1) mouseButton = mouseButton | 1;
		if(myEvent.which == 2) mouseButton = mouseButton | 2;
		if(myEvent.which == 3) mouseButton = mouseButton | 4;
		// should be noted here that firefox seems to return always 1 for mousemove, regardles of the actual button
	} else {
		eButton = myEvent.button;
		if(myEvent.type == "contextmenu") {
			// IE doesnt't set the button property on this one, so we just assume it's right
			mouseButton = mouseButton | 4;
		} else if(myEvent.type == "click") {
			// IE doesnt't set the button property on this one, so we just assume it's left
			mouseButton = mouseButton | 1;
		} else if(myEvent.button) {
			if(myEvent.button & 1) mouseButton = mouseButton | 1;
			if(myEvent.button & 2) mouseButton = mouseButton | 4;
			if(myEvent.button & 4) mouseButton = mouseButton | 2;
		}
	}

	debugPrint("common_resolveButton: type="+myEvent.type+" which="+eWhich+" button="+eButton+" resolved="+mouseButton, "mouse");

	return mouseButton;
}

// abstract modifier keys between platforms (mac/win)
// returns an integer where the bits correspond to buttons like this:
// bit 1:	ctrl/cmd key (multiselect)
// bit 2: shift key (multiselect)
function common_resolveModifierKeys(aEvent) {
	var keys = 0;

	var platform = navigator.platform.toLowerCase();

	if(platform.indexOf('mac') != -1) {
		// mac
		if(aEvent.metaKey) keys = keys | 1;
	} else {
		// other os
		if(aEvent.ctrlKey) keys = keys | 1;
	}

	if(aEvent.shiftKey) keys = keys | 2;

	debugPrint('common_resolveModifierKeys: ctrlKey='+aEvent.ctrlKey+' shiftKey='+aEvent.shiftKey+' metaKey='+aEvent.metaKey+' keys='+keys , 'common_kb');

	return keys;
}

/*
	Tekee uniikin ID:n jota ei löydy koko sivun DOM:sta + se on isompi kuin aikaisemmin tehdyt.
*/

function common_generate_uid() {
	var thisDate = new Date();
	var uid = thisDate.getTime();
	var failSafe = 100;
	var exists = document.getElementById("uniq"+uid);
	while(!exists && failSafe) {
		uid++;
		failSafe--;
		exists = document.getElementById("uniq"+uid);
	}

	if(!exists) {
		return "uniq"+uid;
	} else {
		alert("common_generate_uid() failed.");
		return 0;
	}
}

function toggle_display(imageElement, toggleElementId) {
	toggleElement = document.getElementById(toggleElementId);
	if(toggleElement) {
		if(toggleElement.style.display == "none") {
			toggleElement.style.display = "";
			if(imageElement) imageElement.src = imageElement.src.replace(/closed/i,"open");
		} else {
			toggleElement.style.display = "none";
			if(imageElement) imageElement.src = imageElement.src.replace(/open/i,"closed");
		}
	}
}

function IE_PNG_Fix() {
	elementsToFix = new Array();
	elementsToFix[0] = document.getElementById("IE_bugfix1");
	elementsToFix[1] = document.getElementById("IE_bugfix2");
	elementsToFix[2] = document.getElementById("IE_bugfix3");
	elementsToFix[3] = document.getElementById("IE_bugfix4");
	elementsToFix[4] = document.getElementById("IE_bugfix5");
	elementsToFix[5] = document.getElementById("IE_bugfix6");
	elementsToFix[6] = document.getElementById("IE_bugfix7");
	elementsToFix[7] = document.getElementById("IE_bugfix8");

	for(i in elementsToFix) {
		el = elementsToFix[i];
		if(el) {
			// jos elementistä löytyy filter-style, niin ollaan (todennäköisesti) IE:ssä.
			if(el.style.filter) {
				el.style.backgroundImage = "";	// otetaan IE:llä background pois, jotta filter toimii.
			}
		}
	}

}


var activeDoc = null;
var selectionMemory;
var rangeMemory;
var storedSelection = null;

function restoreSelection() {
	debugPrint("restoreSelection()","common");

	if(activeDoc) {
		if(storedSelection) {
			if(storedSelection.select) {
				debugPrint("Selecting storedSelection","common");
				storedSelection.select();
			}
		} else {
			debugPrint("Setting activeDoc active","common");
//			var sel = activeDoc.document.selection;
//			activeRange = sel.createRange();
//			activeRange.select();
			activeDoc.setActive();
		}
	}
}

function storeSelection() {
	debugPrint("storeSelection","common");
	if(activeDoc) {
		var sel = activeDoc.document.selection;
		debugPrint("storeSelection: seltype "+sel.type,"common");
		if(sel.type == "Text") {
			storedSelection = sel.createRange();
			debugPrint("storeSelection: textrange "+storedSelection,"common");
		} else if(sel.type=="Control") {
			storedSelection = sel.createRange();
			debugPrint("storeSelection: controlrange "+storedSelection,"common");
		} else if(sel.type=="None") {
			storedSelection = null;
//			storedSelection = sel.createRange();
			debugPrint("storeSelection: none "+storedSelection,"common");
		}
	}
}


/*
// 13.1.2011 should not be used anymore, not firefox compatible
// funktio poistaa editFocuksen.
function loseEditFocus() {
	debugPrint("loseEditFocus()","common");
	if(activeDoc) {
		var sel = activeDoc.document.selection;
		if(sel) {
			if(sel.type == "Control") {
				debugPrint("Control selection emptied","common");
				sel.empty();
			}
		}
	}
}
*/

// kätevä debug-funktio. Näyttää olion kaikki propertyt (tai arrayn keyt/valuet)
function showProps(element, printMethod) {
	var info = "";
	var line;
	var cnt = 0;
	// jos on olemassa showProps-elementti
	// sijoitetaan output siihen, muuten alert
	var el = document.getElementById('showProps');
	if(el) el.innerHTML = "<pre>";

	for(var i in element) {
		cnt++;

		info += i + " = ";
		if(el) el.innerHTML += i + " = ";

		// jotkut täytyy skipata, muuten tulee errori
		line = "";
		if(i != "selectionStart" && i != "selectionEnd")
			line = element[i];

		if(el) {
			el.innerHTML += line + "<br>\n";
		} else {
			info += line + "\n";
		}

		if(cnt==20) {
			// paloitellaan pitkä data useaan alerttiin
			alert(info);
			info = "";
			cnt = 0;
		}
	}

	if(cnt>0) {
		if(el) {
			el.innerHTML += '</pre>';
		} else {
			alert(info);
		}
	}
}

function showPropsInAWindow(element) {
	var info = "";
	var cnt = 0;
	var line = "";

	for(var i in element) {
		cnt++;
		info += i + " = ";

		// jotkut täytyy skipata, muuten tulee errori
		line = "";
		if(i != "selectionStart" && i != "selectionEnd") line = element[i];

		info += line + "\n";
	}
	showTextInAWindow(info);
}

function objectToString(element) {
	var info = "";
	var cnt = 0;
	var line = "";
	for(var i in element) {
		cnt++;
		info += i + " = ";
		// jotkut täytyy skipata, muuten tulee errori
		line = "";
		if(i != "selectionStart" && i != "selectionEnd") line = element[i];
		info += line + "\n";
	}
	return info;
}

/**
 *	Tällä funktiolla voi printata debug-viestejä.
 *
 *	@param txt Viesti
 *	@param group optionaalinen group, joka viestin printtasi.
 *								Tämän perusteella viesti joko näytetään tai ei näytetä, riippuen siitä onko groupin debuggaus käytössä.
 *								(esim. treeview, treeview_action.. Tämä voi siis olla mitä vaan kooderi on päättänyt tietyn debug-groupin nimeksi)
 *
 *								Eli siis kun teet jotain skriptiä johonkin mokkulaan ja haluat vain siitä mokkulasta debug-viestit näkyviin,
 *								keksi mokkulalle joku nimi, laita skriptin alkuun "var mokkulanNimi_enableDebug = true;",
 *								ja kaikkiin debugPrint() kutsuihin toiseksi parametriksi "mokkulanNimi".
 *								debugPrint näyttää vain ne debug-viestit jotka ovat enabloitu.
 */
function debugPrint(txt, group) {
	var doc = document;
	// tarkistetaan onko debug-viestien kohde-elementti olemassa (eli js_debug-moodi on päällä)
	var dbg = doc.getElementById("js_debug");
	if(!dbg) {
		var parentFrame = null;
		if(window && window.frameElement) {
			parentFrame = window.frameElement;
			if(parentFrame) {
				if(parentFrame.document) {
					doc = parentFrame.document;
				} else {
					if(window.parent) {
						doc = window.parent.document;
					}
				}
				if(doc) dbg = doc.getElementById("js_debug");
			}
		}
	}

	if(!dbg) return;	// jos ei löydy, pois..

	// tarkistetaan onko kyseisen groupin debuggaus päällä?
	var debugging = false;
	if(!group) {
		debugging = true;
	} else {
		// koitetaan onko "group" itse määritellyt debugin päälle?
		try {
			eval("debugging = "+group+"_enableDebug;");
		} catch(err) {
			debugging = false;
		}
	}

	// groupin debug ei ole päällä
	if(!debugging) {
//		alert("Debug ei ole päällä.\n"+txt);
//		if(group == "CWerttiUpload") {
//			alert("skipping: "+txt);
//		}
		return;
	}

	if(dbg.style.display != "block") dbg.style.display = "block";

	var oTextNode = doc.createTextNode(txt+"\n");
	var inserted = dbg.appendChild(oTextNode);
	if(IE7) {
		var newLine = doc.createElement('br');
		inserted = dbg.appendChild(newLine);
	}

	dbg.scrollTop = dbg.scrollHeight;
}

function openInWindow(href,target) {
	var dummy = window.open(href,target);
}


function showTextInAWindow(txt) {
	var swin = window.open();
	swin.document.write("<html><head><title>info</title></head><body style='overflow: hidden; padding: 0px; margin: 0px;'><textarea style='width: 100%; height: 100%; padding: 0px; margin: 0px; border: 0px;'>");
	swin.document.write(txt);
	swin.document.write("</textarea></body></html>");
}

function sendErrorReport(txt) {
	txt = "Virheraportti osoitteesta "+document.location.href+":\n--- Virheraportti: ---\n"+txt;
	var errorReportXml = createXMLHttpRequest();
	errorReportXml.open("POST", "index.php",false);
	// vältetään cachetus
	errorReportXml.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
	errorReportXml.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
	errorReportXml.onreadystatechange=function() {
		if(errorReportXml.readyState == 4) {
			if(errorReportXml.status == "200") {
				alert(errorReportXml.responseText);
			}
		}
	}
	var postData = "action=errorReport&errorReport-report="+encodeURIComponent(txt);
	if(confirm("Haluatko nähdä lähetettävän raportin ennen lähetystä?")) {
		alert("Seuraavanlainen raportti lähetetään kun painat ok:\n\n"+txt);
	}
	errorReportXml.send(postData);
}


// geneerinen eventin cancel-handler
function cancelEvent(e) {
	if(!e) e = window.event;
	if(e) {
		e.returnValue = false;
		e.cancelBubble = true;
//		e.bubbles = false;
		if(e.preventDefault) e.preventDefault();
//		debugPrint(e.type +" cancelled.", "common");
	}
	return false;
}

// pari yleiskäyttöistä funktiota joilla voi chekata jonkun elementin paikan.

// palauttaa elementin y-koordinaatin koko dokumentin ylälaitaan nähden.
function getOffsetTop(elm) {
	var mOffsetTop = elm.offsetTop;
	var mOffsetParent = elm.offsetParent;
	while(mOffsetParent){
		mOffsetTop += mOffsetParent.offsetTop;
		if(mOffsetParent.scrollTop > 0) {
			mOffsetTop -= mOffsetParent.scrollTop;
		}
		mOffsetParent = mOffsetParent.offsetParent;
	}
	mOffsetTop += document.body.scrollTop;
	return mOffsetTop;
}

// palauttaa elementin x-koordinaatin koko dokumentin vasempaan laitaan nähden.
function getOffsetLeft(elm) {
	var mOffsetLeft = elm.offsetLeft;
	var mOffsetParent = elm.offsetParent;
	while(mOffsetParent) {
		mOffsetLeft += mOffsetParent.offsetLeft;
		if(mOffsetParent.scrollLeft > 0) {
			mOffsetLeft -= mOffsetParent.scrollLeft;
		}
		mOffsetParent = mOffsetParent.offsetParent;
	}
	mOffsetLeft += document.body.scrollLeft;
	return mOffsetLeft;
}

function getContentHeight(el) {
	var hgt = 0;
	var childs = el.children;
	for(i in childs) {
		if(childs[i].style) {
				if(childs[i].style.pixelHeight) hgt = hgt + Math.floor(childs[i].style.pixelHeight);
		}
	}
	return Math.floor(hgt);
}

function getContentWidth(el) {
	var hgt = 0;
	var childs = el.children;
	for(i in childs) {
		if(childs[i].style) {
				if(childs[i].style.pixelWidth) hgt = hgt + Math.floor(childs[i].style.pixelWidth);
		}
	}
	return Math.floor(hgt);
}


// etsii annetun elementin sellaisen parentin, jolla on id
function findElementParentWithId(src) {
	var failsafe = 0;
	while(src && failsafe < 20) {
		//debugPrint("findElemId: searching " + failsafe + " id " + src.id,"common");
		if(src.id) return src; // löytyi
		//muuten etsitään ylöspäin
		src = src.parentElement;
		failsafe = failsafe + 1;
	}
	if(failsafe == 20) {
		alert("findElementParentWithId: failsafe 20");
	}
	//ei löytynyt
	return null;
}

// etsii annetun elementin sellaisen parentin, jolla on annettun niminen parametri
function findElementParentWithParam(src, paramName) {
	var failsafe = 0;
	while(src && (failsafe < 20) ) {
//		debugPrint("findElemP: searching ("+src.tagName+") " +src.id+" " + failsafe,"common");
		params = getElementParams(src);
		if(params[paramName]) return src; //löytyi

//		showProps(src);

		src = src.parentNode;
		failsafe = failsafe + 1;
	}
	if(failsafe == 20) {
		alert("findElementParentWithId: failsafe 20");
	}

	//ei löytynyt
	return null;
}

// tällä pääsee eroon ylimääräisistä tagi-parametreistä (expandot)
// eli name parametriin vain samalla lailla kuin esim stylessä "key:value;key:value"
// timo 250408: sallittu välilyönnit, oliko jokin syy miksei saa olla välilyöntejä?
function getElementParams(el) {
	var hash = {};
	if(el.id) {
		var elParams = document.getElementById(el.id + '_params');
		if(elParams) {
			// jos elementillä on parametrejä
			var allParams = elParams.innerHTML.replace(/[\n\r]+/, "");
			var params = allParams.split(';');
//			showProps(params);
			for(var i = 0; i < params.length; i++) {
				if(params[i]) {
					var keyvalue = params[i].split(':');
					arvo = keyvalue[1];
					if(!arvo) arvo = "true";
					hash[keyvalue[0]] = arvo;
					//debugPrint("param1: " + keyvalue[0] + " = " + arvo,"common");
				}
			}
		} else {
			// ei löytynyt params-diviä
			var expandoList = ['context'];
			var value;
			for(var i = 0; i < expandoList.length; i++) {
				value = el.getAttribute(expandoList[i]);
				hash[expandoList[i]] = value;
			}
		}
	} else {
		// ei ole id:tä
		//alert("debug: getElementParams: elementillä ei ole id:tä");
		var expandoList = ['context'];
		var value;
		for(var i = 0; i < expandoList.length; i++) {
			value = el.getAttribute(expandoList[i]);
			hash[expandoList[i]] = value;
		}
	}
	return hash;
}

// asettaa annetun params-hashin annetun elementin parametreiksi
function setElementParams(el, params) {
	if(! el.id) {
		alert("debug: setElementParams: element has no id");
		// ehkä tässä voisi luoda myös id:n?
		return;
	}
	var elParams = document.getElementById(el.id + '_params');
	if(! elParams) {
		// jos parametri-diviä ei löydy
		// luodaan tyhjä params-elementti
		//<div id="' + el.id + '_params" style="display: none;"></div>
		elParams = document.createElement('DIV');
		elParams.id = el.id + '_params';
		elParams.style.display = 'none';

		// tarvitseeko välttämättä edes liittää bodyyn?
		document.body.appendChild(elParams);
	}
	// debug
	if(! elParams) {
		alert("debug: elParams couldn't be created");
		return;
	}
	// käydään annettu hash läpi ja luodaan uusi params-string
	var allParams = '';
	for (var i in params) {
		if(allParams) {
			allParams = allParams + ';' + i + ':' + params[i];
		} else {
			allParams = i + ':' + params[i];
		}
	}
	elParams.innerHTML = allParams;
}

function setElementParam(el, param, value) {
	var currentParams = getElementParams(el);
	currentParams[param] = value;
	setElementParams(el, currentParams);
}

// pari kätevää konversiofunktiota.

function hexToDec(what) {
	// Hex To Dec
	// parametrissa voi olla alussa "#" tai sitten ei.

	if (what.charAt(0)=="#") what = what.substr(1);
	len = what.length;
	dec = 0;
	base = 16;
	mult = 1;
	for(i=len-1; i>=0; i--) {
		ch = what.charAt(i);
		if(ch == "0") ch = 0;
		if(ch == "1") ch = 1;
		if(ch == "2") ch = 2;
		if(ch == "3") ch = 3;
		if(ch == "4") ch = 4;
		if(ch == "5") ch = 5;
		if(ch == "6") ch = 6;
		if(ch == "7") ch = 7;
		if(ch == "8") ch = 8;
		if(ch == "9") ch = 9;
		if(ch == "a") ch = 10;
		if(ch == "b") ch = 11;
		if(ch == "c") ch = 12;
		if(ch == "d") ch = 13;
		if(ch == "e") ch = 14;
		if(ch == "f") ch = 15;

		dec = dec + ch*(mult);
		mult = mult * base;
	}

	return dec;
}

function decToHex(what,digits) {
	// Dec To Hex
	// palauttaa luvun heksana käyttäen digits-määrän merkkejä. luku palautetaan ilman "#" merkkia tai muita etuliitteitä.
	var ret = "";
	while(what>0) {
		nybble = what & 15;
		if(nybble > 9) {
			if(nybble == "10") nybble = "a";
			if(nybble == "11") nybble = "b";
			if(nybble == "12") nybble = "c";
			if(nybble == "13") nybble = "d";
			if(nybble == "14") nybble = "e";
			if(nybble == "15") nybble = "f";
		}
		ret = nybble + ret;
		what = what >> 4;
	}

	if(digits && ret.length<digits) {
		for(i=ret.length; i<digits; i++) ret = "0" + ret;
	}

	return ret;
}

function sqlNow() {
	stamp = new Date();

//	showProps(stamp);

	var sqldate = stamp.getYear();

	var temp;

	temp = (stamp.getMonth()+1).toString();
	while(temp.length<2) temp = "0"+temp;
	sqldate += "-" + temp;

	temp = stamp.getDate().toString();
	while(temp.length<2) temp = "0"+temp;
	sqldate += "-" + temp;

	temp = stamp.getHours().toString();
	while(temp.length<2) temp = "0"+temp;
	sqldate += " " + temp;
	temp = stamp.getMinutes().toString();
	while(temp.length<2) temp = "0"+temp;
	sqldate += ":" + temp;
	temp = stamp.getSeconds().toString();
	while(temp.length<2) temp = "0"+temp;
	sqldate += ":" + temp;

	return sqldate;
}

function common_decodeEmail(data) {
	data = decodeURIComponent(data);
	var decoded = "";
	var keyIndex = 0;
	for(var i = 0; i < data.length; i++) {
		decoded += String.fromCharCode(data.charCodeAt(i) ^ common_email_unscramble_key.charCodeAt(keyIndex));
		keyIndex++;
		if(keyIndex >= common_email_unscramble_key.length) keyIndex = 0;
	}
	return decoded;
}

// skrollin määrä
function common_getScroll() {
	var scr = {x:0, t:0};
	if(window.pageXOffset !== undefined) {
		scr.x = window.pageXOffset;
		scr.y = window.pageYOffset;
	} else {
		var docEl = document.documentElement, bodyEl = document.body;
		scr.x = (docEl && docEl.scrollLeft || bodyEl && bodyEl.scrollLeft);
		scr.y = (docEl && docEl.scrollTop || bodyEl && bodyEl.scrollTop);
	}
	return scr;
}

// elementin position
function common_getPosition(el) {
	var curleft = curtop = 0;
	if(el.offsetParent) {
		do {
			curleft += el.offsetLeft;
			curtop += el.offsetTop;
		} while (el = el.offsetParent);
	}
	return {'x':curleft, 'y':curtop};
}

function common_getOffset(el) {
	return {'x':el.offsetLeft, 'y':el.offsetTop};
}

function common_cssToStyle(propertyName) {
	var ret = "";
	var nextToUpper = false;
	for(var i = 0; i < propertyName.length; i++) {
		if(propertyName.charAt(i) == '-') {
			nextToUpper = true;
			continue;
		}
		if(nextToUpper) {
			ret += propertyName.charAt(i).toUpperCase();
		} else {
			ret += propertyName.charAt(i);
		}
		nextToUpper = false;
	}
	debugPrint("cssToStyle: "+propertyName+" = "+ret, "common");
	return ret;
}

function common_getSize(el) {
	var sz = {'width':el.offsetWidth, 'height':el.offsetHeight};
	if(el.currentStyle) {
		sz.borderLeft = Number(el.currentStyle.borderLeftWidth.replace(/[^0-9]/g,""));
		sz.borderTop = Number(el.currentStyle.borderTopWidth.replace(/[^0-9]/g,""));
		sz.borderRight = Number(el.currentStyle.borderRightWidth.replace(/[^0-9]/g,""));
		sz.borderBottom = Number(el.currentStyle.borderBottomWidth.replace(/[^0-9]/g,""));
		if(sz.borderLeft && sz.borderTop && sz.borderRight && sz.borderBottom == sz.borderLeft) sz.border = sz.borderLeft;

		sz.paddingLeft = Number(el.currentStyle.paddingLeft.replace(/[^0-9]/g,""));
		sz.paddingTop = Number(el.currentStyle.paddingTop.replace(/[^0-9]/g,""));
		sz.paddingRight = Number(el.currentStyle.paddingRight.replace(/[^0-9]/g,""));
		sz.paddingBottom = Number(el.currentStyle.paddingBottom.replace(/[^0-9]/g,""));
		if(sz.paddingLeft && sz.paddingTop && sz.paddingRight && sz.paddingBottom == sz.paddingLeft) sz.padding = sz.paddingLeft;
	}

	if(sz.borderLeft) sz.width += sz.borderLeft;
	if(sz.borderRight) sz.width += sz.borderLeft;
	if(sz.borderTop) sz.height += sz.borderLeft;
	if(sz.borderBottom) sz.height += sz.borderRight;
	if(sz.paddingLeft) sz.width += sz.paddingLeft;
	if(sz.paddingRight) sz.width += sz.paddingRight;
	if(sz.paddingTop) sz.height += sz.paddingTop;
	if(sz.paddingBottom) sz.height += sz.paddingBottom;

	return sz;
}

function common_getMousePosition(event) {
	if (event.pageX == null && event.clientX != null ) {
		var scroll = {x:0, t:0};
		var docEl = document.documentElement, bodyEl = document.body;
		event.pageX = event.clientX + (docEl && docEl.scrollLeft || bodyEl && bodyEl.scrollLeft);
		event.pageY = event.clientY + (docEl && docEl.scrollTop || bodyEl && bodyEl.scrollTop);
	}
	return {'x':event.pageX, 'y':event.pageY};
}

/**
 *	Seuraavat funktiot tekevät parhaansa selvittääkseen selaimen käytettävissä olevan pikselikoon.
 *	Tämä siis on näkyvä alue, eli selaimen ikkunan koko - käyttöliittymän elementit
 */
function common_getClientArea() {
//	debugPrint("common_getClientArea", "common");
	var area = {"width":0, "height":0};

	if(document.documentElement && document.documentElement.clientWidth) {
		area.width = document.documentElement.clientWidth;
		area.height = document.documentElement.clientHeight;
	} else if(typeof( window.innerWidth ) == 'number') {
		area.width = window.innerWidth;
		area.height = window.innerHeight;
	} else {
		var docEl = document.documentElement, bodyEl = document.body;
		area.width =  (docEl && docEl.clientWidth || bodyEl && bodyEl.clientWidth);
		area.height = (docEl && docEl.clientHeight || bodyEl && bodyEl.clientHeight);
	}
	return area;
}

function common_getInnerWidth() {
	var innerSize = common_getClientArea();
	return innerSize.width;
}

function common_getInnerHeight() {
	var innerSize = common_getClientArea();
	return innerSize.height;
}

function json_handleEvalError(request, err) {
	var txt = "eval() ei onnistunut.\n";

	for(var e in err) {
		txt + e + ": " + err[e] + "\n";
	}

	var sHeaders = request.getAllResponseHeaders();
	for(var h in sHeaders) {
		txt + h + ": " + sHeaders[h] + "\n";
	}

	// kerätään mahdolliset reportit talteen
	var regString = '<!-- <reports> -->([^\000]*?)<!-- </reports> -->';
	var rx = new RegExp(regString, "mig");
	var reports = rx.exec(request.responseText);
	if(reports) {
		txt += reports[0]+"\n";
	}

	txt += "\nPaina ok nähdäksesi koko responseTextin.";
	if(confirm(txt)) {
		showTextInAWindow(request.responseText);
	}
	return true;
}

function common_addOnLoadFunction(func) {
	if(typeof window.addEventListener != "undefined") {
		window.addEventListener("load", func, false);
	} else if(typeof document.addEventListener != "undefined") {
		document.addEventListener("load", func, false);
	} else if(typeof window.attachEvent != "undefined") {
		window.attachEvent("onload", func);
	} else if(typeof window.onload == "function") {
		var fnOld = window.onload;
		window.onload = function() {
			fnOld();
			this.init();
		};
	} else {
		// fail, cannot attach onload
		return false;
	}
	return true;
}

function common_addEventListener(element, eventName, func) {
	if(typeof element.addEventListener != "undefined") {
		element.addEventListener(eventName, func, false);
	} else if(typeof element.attachEvent != "undefined") {
		element.attachEvent("on"+eventName, func);
	} else {
		// fail, cannot attach event
		return false;
	}
	return true;
}


/**
 *	perform unit-test
 *
 *	funcStr:		function name to test (string)
 *	testParams:	array of array of mixed to feed to the function to be tested
 *		eg. [[null],['someString'],[123],['someString',123]]	// note: the last test will get 2 parameters, 'someString' and 123
 *
 *
 */
function common_unitTest(funcStr, testParams) {
	debugPrint("unitTest for "+funcStr, "common");
	var errors = "";
	var temp;
	for(var i=0; i < testParams.length; i++) {
		var js = funcStr+"(";
		for(var p=0; p < testParams[i].length; p++) {
			if(typeof testParams[i][p] == 'string') {
				js += "'"+testParams[i][p]+"',";
			} else {
				js += testParams[i][p]+",";
			}
		}
		js = js.replace(/,$/gi, '') + ")";
		var ok = true;
		try {
			eval('temp = '+js);
		} catch(e) {
			ok = false;
			var eText = e;
			if(typeof e != 'string') {
				eText = objectToString(e);
			}
			errors += "--- "+js+":\n"+eText+"\n\n";
		}
		var rep = temp;
		if(temp) {
			rep = temp.toString();
		}
		if(ok) {
			debugPrint(js+": "+rep, "common");
		} else {
			debugPrint(js+": "+rep+" FAIL", "common");
		}
	}
	if(errors) {
		alert(errors);
	}
}

/*
// parsii css-väriarvon objektiksi jossa värin komponentit on eroteltu.
// paluuobjektissa arvo myös hex-muotona valmiina laitettavaksi esim. styleen
// parametrina annettu css-väri voi olla muodossa #xxx (12 bit hex), #xxxxxx (24bit hex), rgb(x,x,x), rgba(x,x,x,x)
// hex-arvojen #-prefix ei ole pakollinen
// palauttaa tyhjän objektin jos arvoa ei saada parsittua
function common_parseCssColor(cssColor) {
	var ret = {};
	if(!cssColor) return ret;
	cssColor = cssColor.toString().toLowerCase();
	cssColor = cssColor.replace('#', '');
	if(cssColor.length < 3) return ret;
	if(cssColor.match(/[^0-9a-f]/gi)) {
		// non-hex value
		if(cssColor.substr(0,3) == 'rgb') {	// alku on rgb, eli saadaan kiinni sekä rgb että rgba -alkuiset.
			cssColor = cssColor.replace(/[^\d%,.]/gi, '');
			cssColor = cssColor.split(',');
			for(var i in cssColor) {
				var component = common_trim(cssColor[i]);
				if(component && component.length) {
					if(component[component.length-1] == '%') {
						component = Math.round(Number(component.replace(/%/gi, ''))*255/100);
					} else {
						component = Number(component);
					}
				} else {
					cssColor = null;
					break;
				}
				cssColor[i] = component;
			}
			if(cssColor && cssColor.length) {
				ret.red = cssColor[0];
				ret.green = cssColor[1];
				ret.blue = cssColor[2];
				if(cssColor.length == 4) ret.alpha = cssColor[3];
			}
		}
	} else {
		// hex-value
		if(cssColor.length == 3) {	// 12bit
			ret.red = hexToDec(cssColor.substr(0, 1)+cssColor.substr(0, 1));
			ret.green = hexToDec(cssColor.substr(1, 1)+cssColor.substr(1, 1));
			ret.blue = hexToDec(cssColor.substr(2, 1)+cssColor.substr(2, 1));
		} else if(cssColor.length == 6) {	// 24bit
			ret.red = hexToDec(cssColor.substr(0, 2));
			ret.green = hexToDec(cssColor.substr(2, 2));
			ret.blue = hexToDec(cssColor.substr(4, 2));
		}	// 32bit support for hex?
	}

	if(ret) {
		ret.htmlColor = decToHex(ret.red,2) + decToHex(ret.green,2) + decToHex(ret.blue,2);	// there is no alpha support for hex-format colors
		ret.rgbColor = "rgb("+ret.red+","+ret.green+","+ret.blue+")";
		if(ret.alpha) ret.rgbaColor = "rgba("+ret.red+","+ret.green+","+ret.blue+","+ret.alpha+")";
	}

	return ret;
}
*/

/**
 *	cssColor -luokka abstraktoi selaimien erilaista tapaa tallentaa värejä elementtien styleissä ja css:ssä
 *
 *	constructorille annetaan stringinä suoraan stylestä tullut värimääritys, josta koitetaan muodostaa cssColor-objekti.
 *	tämä väri voidaan sitten hakea eri muodoissa metodeilla:
 *	cssColor.htmlColor()	: palauttaa värin html-koodina #xxxxxx
 *	cssColor.rgbColor()		: palauttaa värin mozillan käyttämässä muodossa rgb(x,x,x)
 *	cssColor.rgbaColor()	: palauttaa värin mozillan käyttämässä muodossa rgba(x,x,x,x)
 *
 */
function cssColor(cssColorString) {
	this.set(cssColorString);
}
function cssColor_set(cssColorString) {
	this.red = null;
	this.green = null;
	this.blue = null;
	this.alpha = null;
	if(!cssColorString) return;
	cssColorString = cssColorString.toString().toLowerCase();
	cssColorString = cssColorString.replace('#', '');
	if(cssColorString.length < 3) return;
	if(cssColorString.match(/[^0-9a-f]/gi)) {
		// non-hex value
		if(cssColorString.substr(0,3) == 'rgb') {	// alku on rgb, eli saadaan kiinni sekä rgb että rgba -alkuiset.
			cssColorString = cssColorString.replace(/[^\d%,.]/gi, '');
			cssColorComponents = cssColorString.split(',');
			for(var i in cssColorComponents) {
				var component = common_trim(cssColorComponents[i]);
				if(component && component.length) {
					if(component[component.length-1] == '%') {
						component = Math.round(Number(component.replace(/%/gi, ''))*255/100);
					} else {
						component = Number(component);
					}
				} else {
					cssColorComponents = null;
					break;
				}
				cssColorComponents[i] = component;
			}
			if(cssColorComponents && cssColorComponents.length) {
				this.red = cssColorComponents[0];
				this.green = cssColorComponents[1];
				this.blue = cssColorComponents[2];
				if(cssColorComponents.length == 4) this.alpha = cssColorComponents[3];
			}
		}
	} else {
		// hex-value
		if(cssColorString.length == 3) {	// 12bit
			this.red = hexToDec(cssColorString.substr(0, 1)+cssColorString.substr(0, 1));
			this.green = hexToDec(cssColorString.substr(1, 1)+cssColorString.substr(1, 1));
			this.blue = hexToDec(cssColorString.substr(2, 1)+cssColorString.substr(2, 1));
		} else if(cssColorString.length == 6) {	// 24bit
			this.red = hexToDec(cssColorString.substr(0, 2));
			this.green = hexToDec(cssColorString.substr(2, 2));
			this.blue = hexToDec(cssColorString.substr(4, 2));
		}	// 32bit support for hex?
	}
}
function cssColor_htmlColor() {
	if(this.red != null && this.green != null && this.blue != null) {
		return '#'+decToHex(this.red,2) + decToHex(this.green,2) + decToHex(this.blue,2);	// there is no alpha support for hex-format colors
	}
	return '';
}
function cssColor_rgbColor() {
	if(this.red != null && this.green != null && this.blue != null) {
		return "rgb("+this.red+","+this.green+","+this.blue+")";
	}
	return '';
}
function cssColor_rgbaColor() {
	if(this.red != null && this.green != null && this.blue != null && this.alpha != null) {
		return "rgba("+this.red+","+this.green+","+this.blue+","+this.alpha+")";
	}
	return '';
}
function cssColor_hilite() {
	var avg = (this.red + this.green + this.blue) / 3;
	var amount = 32;
	if(avg<128) {	// make it brighter
		if(avg<32) amount+=16;
		this.red += amount;
		this.green += amount;
		this.blue += amount;
		if(this.red>255) this.red=255;
		if(this.green>255) this.green=255;
		if(this.blue>255) this.blue=255;
	} else {	// make it darker
		if(avg>255-32) amount+=16;
		this.red -= amount;
		this.green -= amount;
		this.blue -= amount;
		if(this.red<0) this.red=0;
		if(this.green<0) this.green=0;
		if(this.blue<0) this.blue=0;
	}
}
cssColor.prototype.set = cssColor_set;
cssColor.prototype.htmlColor = cssColor_htmlColor;
cssColor.prototype.rgbColor = cssColor_rgbColor;
cssColor.prototype.rgbaColor = cssColor_rgbaColor;
cssColor.prototype.toString = cssColor_htmlColor;
cssColor.prototype.hilite = cssColor_hilite;



/*
// palauttaa css-väriarvon 24bit hex-muodossa (xxxxxx), varustettuna prefixillä jos sellainen annetaan parametrina
// palauttaa tyhjän stringin jos väriä ei pystytä parsimaan heksamuotoon
// eli koitetaan siis muokata firefoxin ja ie:n eritavalla stylessä olevat rgb-arvot yhteen yhteiseen formaattiin
// ie palauttaa #xxxxxx -arvoja ja firefox taas palauttaa rgb(x,x,x) -arvoja (tai rgba(x,x,x,x)...)
// formaatteja saattaa olla muitakin
function common_hexColor(cssColor, prefix) {
	if(!cssColor) return '';
	var ret = '';
	var orig = cssColor;
	cssColor = cssColor.toString().toLowerCase();
	if(cssColor.charAt(0)!="#") {
		if(cssColor.substr(0,3)=='rgb') {	// alku on rgb, eli saadaan kiinni sekä rgb että rgba -alkuiset. mahdollinen alpha tiputetaan vain pois, koska sitä ei tueta hex-muodossa.
			cssColor = cssColor.replace(/[^\d%,\.]/gi, '');
			cssColor = cssColor.split(',');
			for(var i in cssColor) {
				var component = common_trim(cssColor[i]);
				if(component && component.length) {
					if(component[component.length-1] == '%') {
						component = Math.round(Math.floor(component.replace(/%/gi, ''))*255/100);
					} else {
						if(component.match(/\./gi)) {
							component = Math.round(component*255);
						} else {
							component = Math.floor(component);
						}
					}
				} else {
					cssColor = null;
					break;
				}
				cssColor[i] = component;
			}
			cssColor = decToHex(cssColor[0],2)+decToHex(cssColor[1],2)+decToHex(cssColor[2],2);
		} else {
			cssColor = null;
		}
	} else {
		cssColor = cssColor.substr(1);
	}

	if(cssColor && cssColor.length) {
		if(cssColor.length == 3) cssColor = cssColor.charAt(0) + cssColor.charAt(0) + cssColor.charAt(1) + cssColor.charAt(1) + cssColor.charAt(2) + cssColor.charAt(2);
		if(prefix) {
			ret = prefix+cssColor;
		} else {
			ret = cssColor;
		}
	}
	debugPrint("common_hexColor: "+orig+" -> "+ret, "common");
	return ret;
}
*/
/*
// Muokkaa väristä hiukan erilaisen hilite-käyttöön.
function common_makeHiliteColor(rgb) {
	if(typeof rgb == 'string') rgb = common_parseCssColor(rgb);

	var avg = (rgb.red + rgb.green + rgb.blue) / 3;
	var amount = 32;
	if(avg<128) {	// make it brighter
		if(avg<32) amount+=16;
		rgb.red += amount;
		rgb.green += amount;
		rgb.blue += amount;
		if(rgb.red>255) rgb.red=255;
		if(rgb.green>255) rgb.green=255;
		if(rgb.blue>255) rgb.blue=255;
	} else {	// make it darker
		if(avg>255-32) amount+=16;
		rgb.red -= amount;
		rgb.green -= amount;
		rgb.blue -= amount;
		if(rgb.red<0) rgb.red=0;
		if(rgb.green<0) rgb.green=0;
		if(rgb.blue<0) rgb.blue=0;
	}

	return rgb;
}
*/

function common_humanReadable(bytes) {
	var kb = bytes / 1024;
	var mb = kb / 1024;
	var gb = mb / 1024;
	var string = "";
	var hr = "";
	var unit = "";
	if(gb >= 1) {
		hr = String(Math.round(gb*10)/10);
		unit = "GB";
	} else if(mb >= 1) {
		hr = String(Math.round(mb*10)/10);
		unit = "MB";
	} else if(kb >= 1) {
		hr = String(Math.round(kb*10)/10);
		unit = "KB";
	} else {
		hr = String(bytes);
		unit = "B";
	}

	if(hr) {
		if(unit != "B" && hr.indexOf(".") == -1) hr += ".0";
		string = hr + " " + unit;
	}

	return string;
}

/*
// palauttaa true/false riippuen siitä onko parametrina annetulla nimellä olemassa funktiota
function common_function_exists(funcNameString) {
	var ret = null;
	var test = 'ret = typeof '+funcNameString;
	eval(test);
//	debugPrint("common_function_exists: "+ret, "common");
	if(ret == 'function') {
		return true;
	}
	return false;
}
*/

function common_getIFrameById(id) {
	var iframe = null;
	if(window.frames[id]) iframe = window.frames[id];
	if(!iframe) {
		var temp = document.getElementById(id);
		if(temp && temp.contentWindow) iframe = temp.contentWindow;
	}
	return iframe;
}

// IE proprietary alpha-filter opacity support removed. Old IEs now only support 100% and 0%
function common_getOpacity(el) {
	var gotOpacity = false;
	var opacity = 100;

	if(el.style.visibility == 'hidden') {
		opacity =  0;
		gotOpacity = true;
	}

	if(!gotOpacity) {
		if(el.style.opacity) {
			// check the standard first
			opacity =  Number(Math.round(el.style.opacity*100));
			gotOpacity = true;
		}
	}
	debugPrint("common_getOpacity opacity="+opacity, "opacity");
	return opacity;
}

function common_setOpacity(el, opacity) {
	debugPrint("common_setOpacity opacity="+opacity, "opacity");
	var newOpacity = opacity / 100;
	if(opacity == 0) {
		el.style.visibility = 'hidden';
		el.style.opacity =  newOpacity;
	} else {
		if(el.style.visibility == 'hidden') el.style.visibility = 'visible';
		el.style.opacity =  newOpacity;
	}
}

function common_fadeElement(el, destinationOpacity, duration) {
	var fadeSpeed = 30;
	debugPrint("common_fadeElement el="+el+" destinationOpacity="+destinationOpacity+" duration="+duration, "common");
	var fadeTimerId = el.getAttribute('fadeTimerId');
	if(fadeTimerId) common_stopFade(el);
	var currentOpacity = common_getOpacity(el);
	if(currentOpacity == destinationOpacity) return;	// already there, no need to fade
	el.setAttribute('destinationOpacity', destinationOpacity);
	el.setAttribute('duration', duration);
	el.setAttribute('fadeSpeed', fadeSpeed);
	fadeTimerId = window.setTimeout(common_createBoundedWrapper(el,common_fadeEngine), fadeSpeed);
	el.setAttribute('fadeTimerId', fadeTimerId);
}

function common_stopFade(el) {
	var fadeTimerId = el.getAttribute('fadeTimerId');
	debugPrint("common_stopFade el="+el+" fadeTimerId="+fadeTimerId, "common");
	if(fadeTimerId) {
		window.clearTimeout(fadeTimerId);
		el.removeAttribute('fadeTimerId');
		el.removeAttribute('destinationOpacity');
		el.removeAttribute('duration');
		el.removeAttribute('fadeSpeed');
	}
}

function common_fadeEngine() {
	var fadeTimerId = this.getAttribute('fadeTimerId');
	if(fadeTimerId) {
		// ...
		var currentOpacity = common_getOpacity(this);
		var destinationOpacity = this.getAttribute('destinationOpacity');
		var fadeDirection = (currentOpacity < destinationOpacity) ? 1 : -1;
		var duration = this.getAttribute('duration');
		var fadeSpeed = this.getAttribute('fadeSpeed');
		var newOpacity = currentOpacity + fadeDirection*20;
		var endFade = false;
		if(fadeDirection > 0) {
			if(this.style.visibility == 'hidden') this.style.visibility = '';
			if(this.style.display == 'none') this.style.display = '';
			if(newOpacity >= destinationOpacity) {
				endFade = true;
				newOpacity = destinationOpacity;
			}
		} else {
			if(newOpacity <= destinationOpacity) {
				endFade = true;
				newOpacity = destinationOpacity;
			}
		}
		common_setOpacity(this, newOpacity);
		debugPrint("common_fadeEngine this="+this+" fadeTimerId="+fadeTimerId+" duration="+duration+" currentOpacity="+currentOpacity+" destinationOpacity="+destinationOpacity+" fadeDirection="+fadeDirection+" newOpacity="+newOpacity, "common");
		if(endFade) {
			common_stopFade(this);
		} else {
			fadeTimerId = window.setTimeout(common_createBoundedWrapper(this,common_fadeEngine), fadeSpeed);
			this.setAttribute('fadeTimerId', fadeTimerId);
		}
	}
}

function common_getElementsByName(rootElement, nameAttribute) {
//	debugPrint('common_getElementsByName ' + rootElement, 'common');
	var ret = [];

	if(rootElement.hasChildNodes()) {
		for(var i = 0; i < rootElement.childNodes.length; i++) {
			if(rootElement.childNodes[i].nodeType == Node.ELEMENT_NODE) {
				var nodeName = rootElement.childNodes[i].getAttribute('name');
//				if(nodeName) debugPrint('checking node '+ rootElement.childNodes[i] + " " + nodeName + " == " + nameAttribute, 'common');
				if(nodeName == nameAttribute) {
					ret.push(rootElement.childNodes[i]);
				}
				if(rootElement.childNodes[i].hasChildNodes()) ret = ret.concat(common_getElementsByName(rootElement.childNodes[i], nameAttribute));
			}
		}
	}

	return ret;
}

// testaa onko elementti el jonkun elementin descendant (tai onko elementti itsessään testattava elementti)
function common_isDescendant(el, ancestor) {
	while(el){
		if(el === ancestor) {
			return true;
		}
		el = el.parentNode;
	}
	return false;
}

function common_isChild(child, parent) {
	return common_isDescendant(child, parent);
}


function common_createOverlay(el, txt, maxWidth) {
	debugPrint("common_createOverlay el="+el, "overlay");

	var overlay = {};

	if(maxWidth == 'undefined') maxWidth = 0;

	overlay.element = el;

	overlay.txtDiv = document.createElement("div");
	overlay.txtDiv.onselectstart = cancelEvent;

	var targetPos = common_getPosition(el);
	var targetSize = common_getSize(el);
	css_addClass(overlay.txtDiv, 'common_overlay');
	overlay.txtDiv.style.left = (targetPos.x + targetSize.width) + "px";
	overlay.txtDiv.style.top = targetPos.y + "px";
	document.body.appendChild(overlay.txtDiv);
	overlay.txtDiv.innerHTML = decodeURIComponent(txt).replace(/\n/gi, '<br>');

	var overlaySize = common_getSize(overlay.txtDiv);

	if(maxWidth) {
		if(overlaySize.width > maxWidth) {
			overlay.txtDiv.style.width = maxWidth + "px";
		}
	}
//	overlay.txtDiv.style.left = targetPos.x - overlaySize.width + "px";

	overlay.element.onmouseout = common_createBoundedWrapper(overlay, common_overlay_mouseOut);
	overlay.txtDiv.onmouseout = common_createBoundedWrapper(overlay, common_overlay_mouseOut);
	overlay.element.setAttribute("overlay", overlay);
	return overlay;
}

function common_overlay_mouseOut(myEvent) {
	if(!myEvent) myEvent = window.event;
//	showProps(e);
	var target = myEvent.toElement ? myEvent.toElement : myEvent.relatedTarget;
//	debugPrint("editor_overlay_mouseOut target="+target.tagName+" this.txtDiv.tagName="+this.txtDiv.tagName+" this.element.tagName="+this.element.tagName, "article_edit_image");
	if(target != this.txtDiv && target != this.element && !common_isDescendant(target, this.txtDiv) && !common_isDescendant(target, this.element)) {
		this.element.removeAttribute("overlay");
		this.txtDiv.onmouseout = null;
		this.element.onmouseout = null;
		document.body.removeChild(this.txtDiv);
		this.txtDiv = null;
	}
	return;
}
/*
function editor_image_mouseOver(e) {
	if(!e) e = window.event;
//	showProps(e);
	var target = e.srcElement ? e.srcElement : e.target;
	if(!target) return;
//	debugPrint("editor_image_mouseOver "+target.tagName, "article_edit_image");
	if(target.tagName != "IMG") return;
	var overlayText = target.getAttribute("mouseOverText");
	if(overlayText) {
		var overlay = editor_createOverlay(target, overlayText);
	}
	return;
}
*/
