var common_enableDebug = false;

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

function common_decode_html_entities(text) {
	var ret = "";
	var temp = document.createElement("TEXTAREA");
	var lines = text.split('\n');
	for(i in lines) {
		temp.innerHTML = lines[i];
		ret += temp.innerText+'\n';
	}
	temp = null;

	return ret;
}


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");
		}
	}
}

// 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) {
	var info = "";
	var cnt = 0;
	for(i in element) {
		info = info + i +" = " + element[i] + "\n";
//		if(typeof element[i] == "object") showProps(element[i]);
		cnt++;
		if(cnt==20) {
			alert(info);
			info = "";
			cnt = 0;
		}
	}
	if(cnt>0) alert(info);
}

/*
// printtaa debug-frameen, jos sellainen on olemassa.
function debugPrint(txt) {
	var dbg = document.getElementById("js_debug");
	if(! dbg) {
		dbg = parent.document.getElementById("js_debug");
	}
	if(! dbg) return;

	dbg.innerHTML = dbg.innerHTML + "<div>"+txt+"</div>";
	dbg.scrollTop = dbg.scrollTop + 100;
}
*/

/**
 *	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) {
	// tarkistetaan onko debug-viestien kohde-elementti olemassa (eli js_debug-moodi on päällä)
	var dbg = document.getElementById("js_debug");
	if(! dbg) {
		dbg = parent.document.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) return;

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

	var oDiv=document.createElement("div");
	var oTextNode = document.createTextNode(txt);
	oDiv.appendChild(oTextNode);

	dbg.appendChild(oDiv);
	dbg.scrollTop = dbg.scrollTop + 100;
}


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

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="+escape(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;
		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].tagName == "TABLE") {
				if(childs[i].style.pixelHeight) hgt = hgt + Math.floor(childs[i].style.pixelHeight);
//			}
		}
//		if(childs[i].children) hgt = hgt + getContentHeight(childs[i]);
	}
	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].tagName == "TABLE") {
				if(childs[i].style.pixelWidth) hgt = hgt + Math.floor(childs[i].style.pixelWidth);
//			}
		}
//		if(childs[i].children) hgt = hgt + getContentHeight(childs[i]);
	}
	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"
// huom: EI välilyöntejä!
function getElementParams(el) {
	var hash = new Array();
	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(';');
			for (var i in params) {
				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 = new Array('context');
			var value;
			for(var exp in expandoList) {
				eval("value = el." + expandoList[exp] + ";");
				hash[expandoList[exp]] = value;
				//debugPrint("param2: " + expandoList[exp] + " = " + value,"common");
			}
		}
	} else {
		// ei ole id:tä
		//alert("debug: getElementParams: elementillä ei ole id:tä");
		var expandoList = new Array('context');
		var value;
		for(var exp in expandoList) {
			eval("value = el." + expandoList[exp] + ";");
			hash[expandoList[exp]] = value;
			//debugPrint("param2: " + expandoList[exp] + " = " + value,"common");
		}
	}
	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;
}

// 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ä.
	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(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;
}
