//	Peda.net JS tweaks
//
//	- warn before leaving page after inputting data to form
//	- disable enter to submit from all text fields
//	- automatically focus first form control if it doesn't cause scrolling
//
//	Copyright (c) 2004,2005,2006, Mikko Rantalainen / Peda.net
//	All rights reserved.
//
//	Notes:
//	try-catch is supported in JavaScript 1.4
//	try-catch-finally is supported in JavaScript 1.5
//
//	MSIE 4.0 supports only JavaScript 1.3
//	NN 4.0 supports only Javascript 1.3
//	Netscape 6.0 supports JavaScript 1.5
//	MSIE 5.0 supports JavaScript 1.5
//

//window.onerror = function(msg,url,line)
//{
//	return true; // ignore error, we already "handled" it.
//}

// flag to keep track of changes
changed = false;

// flag to tell we're just trying to save changes so we don't want warnings about unsaved data
submitting = false;

// flag to tell we've already asked permission to lose data so be quiet!
quiet = false;

currentTextArea = null;
currentDocument = document;

/**
 * Language translation strings:
 * (regenerate with php doc/generate-js-tr.php)
 * * * * * * * * * * * * * * * * * * * * * * * *
 */

var _tr = Array();
// fi (Suomi)
_tr["fi"] = Array();
_tr["fi"]["/js/confirm before document unload"] = "Kaikki juuri sy\u00f6tt\u00e4m\u00e4si tiedot poistetaan, jos poistut sivulta l\u00e4hett\u00e4m\u00e4tt\u00e4 tietoja palvelimelle. Tallentaaksesi sy\u00f6tt\u00e4m\u00e4si tiedot, pysy nykyisell\u00e4 sivulla ja l\u00e4het\u00e4 lomake normaalisti.";
_tr["fi"]["/js/confirm before document unload, continue?"] = "Kaikki juuri sy\u00f6tt\u00e4m\u00e4si tiedot poistetaan, jos poistut sivulta l\u00e4hett\u00e4m\u00e4tt\u00e4 tietoja palvelimelle. Tallentaaksesi sy\u00f6tt\u00e4m\u00e4si tiedot, pysy nykyisell\u00e4 sivulla ja hyväksy lomake normaalisti.\n\nHaluatko varmasti jatkaa toiselle sivulle?";
// en (English)
_tr["en"] = Array();
_tr["en"]["/js/confirm before document unload"] = "Leaving the page without submitting the modifications will discard all the data you just entered. To keep the data, stay on current page and submit the form to save changes.";
_tr["en"]["/js/confirm before document unload, continue?"] = "Leaving the page without submitting the modifications will discard all the data you just entered. To keep the data, stay on current page and submit the form to save changes.\n\nAre you sure you want to continue to another page?";
// smi (Samegiella)
_tr["smi"] = Array();
_tr["smi"]["/js/confirm before document unload"] = "Kaikki juuri sy\u00f6tt\u00e4m\u00e4si tiedot poistetaan, jos poistut sivulta l\u00e4hett\u00e4m\u00e4tt\u00e4 tietoja palvelimelle. Tallentaaksesi sy\u00f6tt\u00e4m\u00e4si tiedot, pysy nykyisell\u00e4 sivulla ja l\u00e4het\u00e4 lomake normaalisti.";
_tr["smi"]["/js/confirm before document unload, continue?"] = "Kaikki juuri sy\u00f6tt\u00e4m\u00e4si tiedot poistetaan, jos poistut sivulta l\u00e4hett\u00e4m\u00e4tt\u00e4 tietoja palvelimelle. Tallentaaksesi sy\u00f6tt\u00e4m\u00e4si tiedot, pysy nykyisell\u00e4 sivulla ja l\u00e4het\u00e4 lomake normaalisti.\n\nHaluatko varmasti jatkaa toiselle sivulle?";

/* * * * * * * * * * * * * * * * * * * * * * * * *
 * end of language translation strings
 */

function tr(str)
{
	lang = getDocumentLanguage(); // unknown browser language, try document's language instead
	if (!lang)
		lang = "fi";
	if (_tr[lang][str])
		return _tr[lang][str];
	else
		return "[[tr("+str+")]]";
}

// Tätä kutsutaan sivulta poistumisen yhteydessä (window.onbeforeunload) ...
function getOnBeforeUnloadString()
{
	return tr("/js/confirm before document unload");
}

// Tätä käyttää addLinkHandlers:n kautta onLinkClickWhenChanged ...
function getOnLinkClickWhenChangedString()
{
	return tr("/js/confirm before document unload, continue?");
}

// Tätä kutsutaan sivun lataamisen yhteydessä (window.onload) ...
function focusFirstInput()
{
	if (! document.getElementsByTagName)
		return;

	var minoffset = 1e6;  // a big number for offset we wouldn't focus anyway
	var firstElement = null; // the element to focus automatically

	// find out first textarea or input in the layout and focus it
	// if it doesn't cause viewport to scroll

	// first, we need to find topmost control
	// search textareas first
	var textareas = document.getElementsByTagName("textarea");
	for (var i = 0; i < textareas.length; i++)
	{
		var e = textareas[i];
		var offset = getGlobalOffsetTop(e);
		if (offset && offset < minoffset)
		{
			minoffset = offset;
			firstElement = e;
		}
	}
	// search inputs, too
	var inputs = document.getElementsByTagName("input");
	for (var i = 0; i < inputs.length; i++)
	{
		var e = inputs[i];
		var offset = getGlobalOffsetTop(e);
		if (!(e.disabled || e.type == "submit" || e.type=="hidden" || e.type=="file")) // don't focus disabled controls or buttons
		{
			if (offset && offset < minoffset)
			{
				minoffset = offset;
				firstElement = e;
			}
		}
	}

	//alert("minoffset="+minoffset+" firstElement="+firstElement+" firstElement.name="+(firstElement ? firstElement.name : null));

	// if we have found an element to focus and none of the elements
	// have been modified, focus the element if it doesn't cause scroll
	if (firstElement && !changed)
	{
		e = firstElement;
		
		// TODO: use e.scrollIntoView() if it exists // http://developer.mozilla.org/en/docs/DOM:element.scrollIntoView

		// focus only if top edge of the focusable element is less than
		// 'margin' pixels away from the bottom of the viewport

		// offsetHeight, scrollHeight and clientHeight are poorly documented
		// but here's a short description:
		// offsetHeight: space the element requires to not overlap anything on layout (content window + scrollbars + borders)
		// scrollHeight: total height of the element (scroll content)
		// clientHeight: visible content (scroll window size)

		if (e.offsetHeight)
			margin = 4 + e.offsetHeight; // px, element height plus some for borders and margin
		else
			margin = 32; // px

		// e.offsetTop is length to top of the parent position box (parent?), not length to the top of the viewport
		// compute length to the top of the viewport

		offsetTop = getGlobalOffsetTop(e);

		//alert("e.offsetTop="+e.offsetTop+" e.offsetHeight="+e.offsetHeight+" window.innerHeight="+window.innerHeight+" document.documentElement.clientHeight="+document.documentElement.clientHeight+" margin="+margin);
		//alert("offset="+offsetTop+" offsetTop+margin="+(offsetTop+margin)+" window.innerHeight="+window.innerHeight+" document.documentElement.clientHeight="+document.documentElement.clientHeight);

		/*
			window scrolling info:
			window.scrollY = window.scrollYOffset: amount of pixels scrolled from top
			window.scrollMaxY = maximum amount of pixels the UA is able to scroll with current content
		*/

		//alert("window.scrollTop="+window.scrollTop+" window.scrollY="+window.scrollY+" window.pageYOffset="+window.pageYOffset+" window.scrollMaxY="+window.scrollMaxY);
		//alert("document.documentElement.scrollTop="+document.documentElement.scrollTop);

		scrollTop = window.pageYOffset ?
			window.pageYOffset : (document.documentElement && document.documentElement.scrollTop) ?
			document.documentElement.scrollTop : window.scrollY ?
			window.scrollY : 0;

 		// test for all standards compliant browser (Mozilla, Firefox, Opera, Safari etc)
		if (offsetTop>0 && window && window.innerHeight && e.focus) // standard way
		{
			if (offsetTop+margin < window.innerHeight && scrollTop < offsetTop)
			{
				try { e.focus(); } catch (error) { /* do nothing if focus() fails */ }
				return; // we're done
			}
		}
		else if (offsetTop>0 && document && document.documentElement && document.documentElement.clientHeight && e.focus) // MSIE6
		{
			if (offsetTop+margin < document.documentElement.clientHeight && scrollTop < offsetTop)
			{
				try { e.focus(); } catch (error) { /* do nothing if focus() fails */ }
				return; // we're done
			}
		}
		else if (offsetTop>0 && document && document.body && document.body.clientHeight && e.focus) // MSIE5
		{
			if (offsetTop+margin < document.body.clientHeight && scrollTop < offsetTop)
			{
				try { e.focus(); } catch (error) { /* do nothing if focus() fails */ }
				return; // we're done
			}
		}
		else // no success
		{
			//alert("element doesn't fit screen - will not focus!");
		}
	}

	// no element to focus
}

// Tätä käyttää focusFirstInput funktio
function getGlobalOffsetTop(e)
{
	var offsetTop = 0;
	for (var p = e, depth = 0; p && depth < 100; p = p.offsetParent, depth++) // 'depth' is infinite loop blocker
	{
		if (p.offsetTop)
			offsetTop += p.offsetTop;
	}
	return offsetTop;
}

// Tätä kutsutaan sivun lataamisen yhteydessä (window.onload) ...
function addSubmitHandlers()
{
	if (! (document.getElementsByTagName))
		return;
	
	var b = document.getElementsByTagName("body")[0];
	if (!b)
		return;
	if (b.className.match(/jsbrowser/))
	{
		/* add code that deals with submit buttons with javascript */
		var fs = document.getElementsByTagName("form");
		for (var i = 0; i < fs.length; i++)
		{
			var f = fs.item(i);
			f.onsubmit = submitReferenceBrowser;
		}
	}
	else // normal behavior
	{
		/* add code to set submitting to true to all submit inputs */
		var fs = document.getElementsByTagName("form");
		for (var i = 0; i < fs.length; i++)
		{
			var f = fs.item(i);
			f.onsubmit = setSubmitting;
		}
	}
}

// Tätä kutsutaan sivun lataamisen yhteydessä (window.onload) ...
function addInputHandlers()
{
	if (! (document.getElementsByTagName))
		return;

	/* add code to set changed to true to all inputs but submit buttons */
	var inputs = document.getElementsByTagName("input");
	for (var i = 0; i < inputs.length; i++)
	{
		var input = inputs.item(i);
		if (input.type == "checkbox" || input.type == "radio")
		{
			input.onchange = setChangedCheckbox;
			// add handler to ignore enter key so that users don't send partially filled forms by mistake
			input.onkeypress = handleEnter;
		}
		else if (input.type == "reset")
		{
			input.onclick = handleFormReset;
		}
		else if (input.type != "submit")
		{
			input.onchange = setChanged;
			// add handler to ignore enter key so that users don't send partially filled forms by mistake
			input.onkeypress = handleEnter;
		}
	}

	/* add code to set changed to true to all textareas */
	var textareas = document.getElementsByTagName("textarea");
	for (var i = 0; i < textareas.length; i++)
	{
		var textarea = textareas.item(i);
		textarea.onchange = setChanged;
		textarea.onkeypress = handleKeyPress;
	}
}

/*
	This method should work with at least NS, MSIE and Mozilla
	It makes ENTER key to behave better so that it just moves to next
	element instead of sending the form.
	Call this like onkeypress="return handleEnter(this,event)"
*/
// Tätä käyttää addInputHandlers ...
function handleEnter(event)
{
	/* figure out which event and which element (mostly for MSIE) */
	if (typeof(event) == 'undefined' && window.event)
		event = window.event;
	if (typeof(this) != 'undefined')
		input = this;
	else if (event.srcElement)
		input = event.srcElement;
	else if (event.target)
		input = event.target;

	if (!event || !input) return true; // default

	// every UA manufacturer has their own "standard" for keypresses, try each one:
	//alert("Trying to redefine the ENTER key!");
	var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
	var hasModifiers = event.modifiers ? true : event.ctrlKey ? true : event.shiftKey ? true : event.altKey ? true : false;

	if (keyCode == 13)
	{
		if (!input || !input.form || !input.form.elements)
			return true; // don't know how to deal with this UA, allow default behavior

		var i;
		// find out current form element index
		for (i = 0; i < input.form.elements.length; i++)
			if (input == input.form.elements[i])
				break;

		do
		{
			// compute next form element index, or go to first if we're in the last element
			i = (i + 1) % input.form.elements.length;
		}			
		while (input.form.elements[i].type == "hidden");

		try
		{
		// focus next element
		input.form.elements[i].focus();
		// if next form element is submit button, press it!
		if (input.form.elements[i].type == "submit" || input.form.elements[i].type == "button")
			input.form.elements[i].click();
		}
		catch (e)
		{
			/* ignore errors with focus() and emulated click() */
		}

		//alert("about to return false. This should cause the form NOT TO SEND!");
		return false;
	}
	else
	{
		if (!hasModifiers && keyCode > 46)
		{
			setChanged();
		}
		// allow default behavior
		return true;
	}
}

// Tätä käyttää addInputHandlers ...
function handleKeyPress(event)
{
	/* figure out which event and which element (mostly for MSIE) */
	if (typeof(event) == 'undefined' && window.event)
		event = window.event;
	if (typeof(this) != 'undefined')
		input = this;
	else if (event.srcElement)
		input = event.srcElement;
	else if (event.target)
		input = event.target;

	if (!event || !input) return true; // default

	// every UA manufacturer has their own "standard" for keypresses, try each one:
	var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
	var hasModifiers = event.modifiers ? true : event.ctrlKey ? true : event.shiftKey ? true : event.altKey ? true : false;

	if (!hasModifiers && keyCode > 46)
	{
		setChanged();
	}
	return true;
}

// Tätä kutsutaan sivun lataamisen yhteydessä (window.onload) ...
function addLinkHandlers()
{
	if (! (document.getElementsByTagName))
		return;

	/* add code to check changed status to all links */
	var links = document.getElementsByTagName("a");
	for (var i = 0; i < links.length; i++)
	{
		var link = links.item(i);
		if (link.href && ! link.onclick) // don't remove any custom click handlers!
			link.onclick = onLinkClickWhenChanged;
	}
}

// Tätä käyttää addLinkHandlers ...
function onLinkClickWhenChanged(event)
{
	/* figure out which event and which element (mostly for MSIE) */
	if (typeof(event) == 'undefined' && window.event)
		event = window.event;
	if (typeof(this) != 'undefined')
		link = this;
	else if (event.srcElement)
		link = event.srcElement;
	else if (event.target)
		link = event.target;

	try
	{
	// if we have an anchor to current page, use default handler
	if (link.href && link.href.indexOf && link.href.match
	    && link.href.indexOf(document.location) != -1 || link.href.match(/^#/))
		return true;
	}
	catch (e)
	{
		// this has ever happened only with broken MSIE installations, fallback to default behavior
		return true;
	}

	if (typeof(changed) == 'undefined' || typeof(submitting) == 'undefined')
		return true; // something smells fishy, just drop back to default behavior...
	if (changed && ! submitting)
	{
		// check if it's okay to lose changes, return true if so
		if (confirm(getOnLinkClickWhenChangedString()))
		{
			quiet = true;
			return true;
		}
		else
		{
			return false;
		}
	}
	else
	{
		// nothing has been changed, we can safely leave
		return true;
	}
}

function addImgHandlers()
{
	if (!(navigator.userAgent && navigator.userAgent.match("MSIE")))
		return; // nothing to be done here
	if (! (document.getElementsByTagName))
		return;

	/* add onclick handler to all img elements to activate parent label if one exists */
	var images = document.getElementsByTagName("img");
	for (var i = 0; i < images.length; i++)
	{
		var img = images.item(i);
		if (! img.onclick) // don't remove any custom click handlers!
			img.onclick = clickParentLabel;
	}
}

function clickParentLabel(event)
{
	if (!event && window.event)
		event = window.event;
	var img;
	if (typeof(this) != 'undefined')
		img = this;
	else if (event.srcElement)
		img = event.srcElement;
	else if (event.target)
		img = event.target;
	if (!img)
		return; // we can do nothing
	
	if (img.parentNode && img.parentNode.nodeName.toLowerCase() == "label" && img.parentNode.click)
	{
		// activate direct parent
		img.parentNode.click();
	}
	else if (img.parentNode.parentNode && img.parentNode.parentNode.nodeName.toLowerCase() == "label" && img.parentNode.parentNode.click)
	{
		// activate parent's parent
		img.parentNode.parentNode.click();
	}
	return true; // do the normal action in addition
}

// Tätä käytää addInputHandlers, handleKeyPress ja handleEnter ...
function setChanged()
{
	changed = true;
	return changed;
}

// Tätä käyttää addInputHandlers ...
setChangedCheckbox.counter = 2; // checkboxes or radio buttons must be used at least this many times until changed flag is raised
function setChangedCheckbox()
{
	setChangedCheckbox.counter--;
	if (setChangedCheckbox.counter <= 0)
		changed = true;
	return changed;
}

// Tätä käyttää addSubmitHandlers ...
function setSubmitting()
{
	submitting = true;
	return submitting;
}

// Tätä käyttää tr funktio ...
function getDocumentLanguage()
{
	var lang = 0;
	if (document.getElementsByTagName)
	{
		//alert("Using document's language...");
		var html = document.getElementsByTagName("html").item(0);
		if (html)
		{
			if (!lang && html.getAttributeNS) // try to get real xml:lang attribute
				lang = html.getAttributeNS("xml","lang");
			if (!lang && html.getAttribute) // try to get lang from html without namespace
				lang = html.getAttribute("lang");
			if (!lang && html.getAttribute) // try to get lang from html with invalid attribute name
				lang = html.getAttribute("xml:lang");
			if (!lang && html && html["lang"]) // try to get lang from html via properties
				lang = html["lang"];
		}
	}
	return lang;
}

window.onbeforeunload = function onbeforeunloadhandler()
{
	if (changed && ! submitting && ! quiet)
		return getOnBeforeUnloadString();
	/* don't return anything and we're cool -- all browsers take this as we're ok to go */
}

window.onload = function ()
{
//	hideJsMissingWarning();

	// Hook event handlers:
	addSubmitHandlers();
	addInputHandlers();
	addLinkHandlers();
//	addImgHandlers();

//	resizeHandler(); // call handler to deal with the initial window size
	focusFirstInput(); // must be called last

//	preCacheThrobber();
}

window.onresize = function()
{
	resizeHandler();
}

// Tätä kutsutaan sivun lataamisen yhteydessä (window.onload) ...
function hideJsMissingWarning()
{
	if (document.getElementById)
	{
		e = document.getElementById("jsmissingwarning");
		if (e)
			e.style.display = "none";
	}
}

// Tätä kutsutaan sivun lataamisen yhteydessä (window.onload) ...
function resizeHandler()
{
	// force reflow if UA is MSIE/win32
	// if somebody fakes his UA to look like MSIE, it should better behave like MSIE...
	if (navigator.userAgent.match(/MSIE/))
		forceReflow();
}

// Tätä käyttää resizeHandler ...
function forceReflow()
{
	//alert("forcing reflow");
	// generic reflow for W3C DOM compliant UAs
	if (document && document.body && document.body.style)
	{
		//document.body.style.display = "none";	// causes problems with MSIE 5.0 (but works with MSIE 5.5, MSIE 6.0 and MSIE 7.0)
		//document.body.style.display = "";
		document.body.style.backgroundImage = "none";
		document.body.style.backgroundImage = "";
	}

	/* MSIE sometimes has problems with reflowing floating elements
	   we cannot easily target those but lets reflow all headers because
	   it seems to work for me (I could reflow DIVs but it hits the CPU hard)
	   Note that we don't want full reflow here because that's exactly where
	   MSIE gets it wrong. */
	if (document.all && window.external && navigator.userAgent && navigator.userAgent.match
		&& navigator.userAgent.match(/MSIE/))
	{
		var items = document.getElementsByTagName("h1");
		for (var i = 0; i < items.length; i++)
		{
			var item = items[i];
			//if (item.style && item.style.backgroundImage)
			if (item.style)
			{
				item.style.backgroundImage = "none";
				item.style.backgroundImage = "";
				// could try item.style.border = item.style.border instead
			}
		}
	}
	if (navigator.userAgent && navigator.userAgent.match
		&& navigator.userAgent.match(/MSIE [78]/))
	{
		/* just another workaround - it's important that the style reset is done via setTimeout(), just calling the reset directly does not seem to work */
		document.body.style.backgroundImage = "none";
		window.setTimeout(resetBodyStyleReflowHack,0);
	}
}

// Tätä käyttää forceReflow ...
function resetBodyStyleReflowHack()
{
	if (document && document.body && document.body.style)
	{
		document.body.style.backgroundImage = "";
	}
}


// from http://mysite.verizon.net/negatron/custom_alert.htm
// Tätä käyttää addSubmitHaldlers ...
function submitReferenceBrowser(event)
{
	if (!event && window.event)
		event = window.event;
	
	var id = 0;
	
	// go through all the inputs looking for target id 
	var inputs = document.getElementsByTagName("input");
	for (var i = 0; i < inputs.length; i++)
	{
		var input = inputs.item(i);
		if (input.type != "radio")
			continue; // skip this input
		
		if (input.name && input.name.match(/p[0-9]+xtarget_id/) && input.checked)
		{
			id = parseInt(input.value);
		}
	}

	var win = window;
	if (win && !win.currentTextArea) // we do not know the current textarea yet
	{
		if (win.parent)
		{
			win = win.parent;
		}
	}
	if (id && win.currentTextArea && win.currentDocument && win.insertIntoTextArea)
	{
		// check if we have a stored selection (MSIE bug workaround)
		if (win.currentTextArea.selectionEndOffset && win.currentTextArea.createTextRange)
		{
			// the textarea must have focus or the selection will not be correctly set
			win.currentTextArea.focus();
			var r = win.currentTextArea.createTextRange();
			r.collapse(true); // the selection must be collapsed at least once or setting it will fail
			r.moveStart('character',win.currentTextArea.selectionStartOffset);
			r.moveEnd('character',win.currentTextArea.selectionEndOffset - win.currentTextArea.selectionStartOffset);
			r.select(); // activate selection
			
			// clear stored selection
			win.currentTextArea.selectionStartOffset = null;
			win.currentTextArea.selectionEndOffset = null;
		}
		win.insertIntoTextArea(win.currentTextArea,"[[",id.toString(),"]]",true);
		closeReferenceBrowser(win.currentDocument,win.currentTextArea);
	}
	else
	{
		alert("Valitse jokin viite ensin!");
	}

	// prevent normal submit behavior
	return false;
}

// Tätä käyttää addInputHandlers ...
function handleFormReset(event)
{
	var d = document;
	var b = d.getElementsByTagName("body")[0]
	if (b.className.match(/jsbrowser/))
	{
		// user has hit the reset button in jsbrowser; we have to close the jsbrowser and focus the textarea user had active before starting the browser
		var win = window;
		if (win && !win.currentTextArea) // we do not know the current textarea yet
		{
			if (win.parent)
			{
				win = win.parent;
			}
		}
		if (win.currentTextArea && win.currentDocument && win.insertIntoTextArea)
		{
			win.closeReferenceBrowser(win.currentDocument,win.currentTextArea);
		}
		return false;
	}
	return true;
}

// Tätä käyttää handleFormReset ...
//	Close reference browser in document doc and
//	focus textarea if not null
function closeReferenceBrowser(doc,textarea)
{
	textarea.forceKeepTextAreaEditorOpen = false;
	doc.getElementsByTagName("body")[0].removeChild(doc.getElementById("referencebrowsercontainer"));
	if (textarea && textarea.focus)
		textarea.focus();
}

// Syöttökenttien sanalaskuri
function WordCount(obj) {

	var maxlength = obj.getAttribute("maxlength");
	var maxwords = obj.getAttribute("maxwords");
	var wc_ename = "wc_"+obj.name;
	var text = obj.value;
	var text_length = text.length;

	// Katkaistaan syöttäminen maksimimerkkimäärän tullessa täyteen.
	if (maxlength > 0 && text.length > maxlength)
	{
		obj.value=obj.value.substring(0,maxlength);
		return false;
	}

	// Poistetaan tekstin lopusta välilyönnit ja lasketaan sanojen määrä.
	text = text.replace(/\s+$/,"");
	var words = text.split(/\s+/);

	// Asetetaan sanalaskuri nollaksi, mikäli kenttä on tyhjä.
	var wc = 0;
	if (text.length) wc = words.length;

	// Katkaistaan syöttäminen maksimisanamäärän tullessa täyteen.
	if (maxwords > 0 && wc > maxwords)
	{
		obj.value=obj.value.substring(0,text.length - 1);
		return false;
	}

	// Tulostetaan sanojen lukumäärä ja tarvittaessa myös maksimimäärä.
	if (maxwords) document.getElementById(wc_ename).innerHTML = wc+"/"+maxwords;
	else document.getElementById(wc_ename).innerHTML = wc;

	return true;
}

// Valintaruutujen muutosfunktio.
function changeCheckboxState(group) {

        var group_checked = group.checked;
        var group_name = group.name;

        // Muutetaan kyseiseen ryhmään kuuluvien checkboxien arvot Valitse kaikki -valinnan mukaisiksi.
        var emens = document.getElementsByClassName(group_name);
        for (var i=0;i<emens.length;i++) emens[i].checked=group_checked;

        // Muutetaan Valitse kaikki -valintojen tilat.
        emens = document.getElementsByName(group_name);
        for (i=0;i<emens.length;i++) emens[i].checked=group_checked;

	return true;
}

function openNewWindow(url, width, height) {
  
    var wleft = (screen.width - width) / 2;
    var wtop  = (screen.height - height) / 2;
    var attribs  = 'width='+ width;
        attribs += ',height='+ height;
        attribs += ',left='+ wleft;
        attribs += ',top='+ wtop;
        attribs += ',resizeable=no';
        attribs += ',scrollbars=yes';
        attribs += ',location=no';
        attribs += ',menubar=no';

    var newWin = window.open(url, 'newWindow', attribs);
    newWin.focus();

}

