/* sciDHTML-Library */


//
// first, determine what browser the client is using
//

var DHTML = false, DOM = false, MSIE4 = false, NS4 = false, OP = false;
var IE = document.all && !window.opera;
var FF = document.getElementById && !document.all;

if (document.getElementById) {
	DHTML = true;
	DOM = true;
}
else {
	if (document.all) {
		DHTML = true;
		MSIE4 = true;
	}
	else {
		if (document.layers) {
			DHTML = true;
			NS4 = true;
		}
	}
}

if (window.opera) {
	OP = true;
}



function getElement(mode, id, number) {
	/*******************************************************************************************************************
    function: getElement

    Description:
    	gets the element specifid by mode, id, number
		mode: "id", "name", or "tag"
		id: the id, name, or tagname
		number: in case of name or tagname, the number of the element in the list. "all" returns the array.
	*********************************************************************************************************************/
	
	var e = false, elist;
	
	if (DOM) {
		if ("id" == mode.toLowerCase()) {
			e = document.getElementById(id);
		}
		else if ("name" == mode.toLowerCase()) {
			elist = document.getElementsByName(id);
			e = (number == "all") ? elist : elist[number];
		}
		else if ("tag" == mode.toLowerCase()) {
			elist = document.getElementsByTagName(id);
			e = (number == "all") ? elist : elist[number];
		}
		return (!e) ? false : e;
	}
	else if (MSIE4) {
		if ("id" == mode.toLowerCase() || "name" == mode.toLowerCase()) {
			e = document.all(id);
		}
		if ("tag" == mode.toLowerCase()) {
			elist = document.all.tags(id);
			e = (number == "all") ? elist : elist[number];
		}
		return (!e) ? false : e;
	}
	else if (NS4) {
		if ("id" == mode.toLowerCase() || "name" == mode.toLowerCase()) {
			e = document[id];
			if (!e) {
				e = document.anchors[id];
			}
		}
		else if ("layerindex" == mode.toLowerCase()) {
			e = document.layers[id];
		}
		return (!e) ? false : e;
	}
	return false;

} // end function getElement


function getAttribute(mode, id, number, name) {
	/*******************************************************************************************************************
    function: getAttribute

    Description:
    	gets the attribute of the specified element
		mode, id, number: see getElement
	*********************************************************************************************************************/
	
	var attribute;
	var e = getElement(mode, id, number);
	
	if (!e) return false;
	
	if (DOM || MSIE4) {
		attribute = e.getAttribute(name);
		return attribute;
	}
	if (NS4) {
		attribute = e[name];
		if (!attribute) attribute = false;
	    return attribute;
	}
	return false;

} // end function getAttribute


function getContent(mode, id, number) {
	/*******************************************************************************************************************
    function: getContent

    Description:
    	gets the content of the specified element
		mode, id, number: see getElement
	*********************************************************************************************************************/
	
	var content;
	var e = getElement(mode, id, number);
	if (!e) return false;
	
	if (DOM && e.firstChild) {
		if (e.firstChild.nodeType == 3) {
			content = e.firstChild.nodeValue;
		}
		else {
			content = "";
		}
		return content;
	}
	else if (MSIE4) {
		return e.innerText;
	}
	return false;

} // end function getContent


function setContent(mode, id, number, content) {
	/*******************************************************************************************************************
    function: setContent

    Description:
    	sets the content of the specified element to "content"
		mode, id, number: see getElement
	*********************************************************************************************************************/
	
	var e = getElement(mode, id, number);
	if (!e) return false;
	
	if (DOM && e.firstChild) {
		e.firstChild.nodeValue = content;
		return true;
	}
	else if (MSIE4) {
		e.innerText = content;
		return true;
	}
	else if (NS4) {
		e.document.open();
		e.document.write(content);
		e.document.close();
		return true;
	}
	return false;

} // end function setContent


function Position(element) {
	/*******************************************************************************************************************
    function: Position

    Description:
    	An object with fields X, Y, W, and H reprsenting the position of the given page element
	*********************************************************************************************************************/

    this.X = -1;
    this.Y = -1;
    this.W = 0;
    this.H = 0;

	if (element == document) {
		if (typeof(window.pageYOffset) == "number") {
			this.X = window.pageYOffset;
			this.Y = window.pageXOffset;
			this.W = window.innerWidth;
			this.H = window.innerHeight;
		}
		else {
			var b = (document.compatMode && document.compatMode != "BackCompat") ? 
				document.documentElement : document.body

			this.X = b.scrollTop;
			this.Y = b.scrollLeft;
			this.W = b.clientWidth;
			this.H = b.clientHeight;
		}
	}
	else if (element != null) {
		var left = 0;
		var top = 0;
		var e = element;
		
		while (e != null) {
			left += e.offsetLeft;
			top += e.offsetTop;
			e = e.offsetParent;
		}
	
		this.X = left;
		this.Y = top;
		this.W = element.offsetWidth;
		this.H = element.offsetHeight;
	}

} // end function Position


function ScrollPosition() {
	/*******************************************************************************************************************
    function: ScrollPosition

    Description:
    	An object with fields X and Y reprsenting the scroll position of the page    
	*********************************************************************************************************************/

	this.X = -1;
	this.Y = -1;
	
	if (window.pageYOffset) // all except Explorer
	{
		this.X = window.pageXOffset;
		this.Y = window.pageYOffset;
	}
	else
	{
		var b = (document.compatMode && document.compatMode != "BackCompat") ? 
			document.documentElement : document.body
		this.X = b.scrollLeft;
		this.Y = b.scrollTop;
	}

} // end function ScrollPosition




/* **********************************************************************************************************************
   ++
   ++	V I S I B I L I T Y   O F   D I V S   A N D   O T H E R   E L E M E N T S
   ++ 
   **********************************************************************************************************************/


function ShowDivById(id) {
    /*******************************************************************************************************************
    function: ShowDivById

    Description:
        shows the div with id="id"
	*********************************************************************************************************************/

	var x = getElement("id", id);
	if (x) x.style.display = "block";

} // end function ShowDivById
	

function HideDivById(id) {
    /*******************************************************************************************************************
    function: HideDivById

    Description:
        hides the div with id="id"
	*********************************************************************************************************************/

	var x = getElement("id", id);
	if (x) x.style.display = "none";

} // end function HideDivById
	

function HideDivsByClass(classname) {
    /*******************************************************************************************************************
    function: HideDivsByClass

    Description:
        hides all divs with class="class"
	*********************************************************************************************************************/

	var x = document.getElementsByTagName("div");
	for (var i = 0; i < x.length; i++) {
		if (x[i].className == classname) {
			x[i].style.display = "none";
		}
	}

} // end function HideDivsByClass
	

function ShowDivsByClass(classname) {
    /*******************************************************************************************************************
    function: ShowDivsByClass

    Description:
        shows all divs with class="class"
	*********************************************************************************************************************/

	var x = document.getElementsByTagName("div");
	for (var i = 0; i < x.length; i++) {
		if (x[i].className == classname) {
			x[i].style.display = "block";
		}
	}

} // end function ShowDivsByClass


function SetDisplay(id, show) {
    /*******************************************************************************************************************
    function: SetDisplay

    Description:
        toggles visiblity of the element with id="id" by setting stlye.display to "block" or "none" depending on
		the boolean "show" (true = visible)
	*********************************************************************************************************************/
	
	try {
		getElement("id", id).style.display = show ? "block" : "none";
	}
	catch (ex) { }

} // end function SetDisplay

function ToggleDisplay(id) {
    /*******************************************************************************************************************
    function: ToggleDisplay

    Description:
        toggles visiblity of the element with id="id" by setting stlye.display to "block" or "none" depending on
        the current setting.
    *********************************************************************************************************************/
    
    try {
        var e = getElement("id", id);
        e.style.display = (e.style.display == "none") ? "block" : "none";
    }
    catch (ex) { }

} // end function SetDisplay


function ToggleDisable(ids, state) {
    /*******************************************************************************************************************
    function: ToggleDisable

    Description:
        sets the disabled state of object(s) 
    *********************************************************************************************************************/
	
	ids = ids.split(",");
	for (var i = 0; i < ids.length; i++)
		getElement("id", ids[i]).disabled = state;
	
} // end function ToggleDisable



function GetCheckedItems(name) {
    /*******************************************************************************************************************
    function: GetCheckedItems

    Description:
        returns a comma-delimited list of items selected in the checkbox-group with name="name"
    *********************************************************************************************************************/
	
	var boxes = getElement("name", name, "all");
	// get checked ids
	var checked = new Array();
	for (var i = 0; i < boxes.length; i++)
		if (boxes[i].checked)
			checked.push(boxes[i].value);
	// build answer string
	var ids = "";
	for (var i = 0; i < checked.length; i++)
		ids = ids + checked[i] + ",";
	ids = ids.substr(0, ids.length - 1);
	
	return ids;

} // end function GetCheckedItems


function GetSelectedItems(name) {
    /*******************************************************************************************************************
    function: GetSelectedItems

    Description:
        returns a comma-delimited list of items selected in the checkbox-group with name="name"
    *********************************************************************************************************************/
	
	var opts = getElement("id", name).options;
	// get checked ids
	var checked = new Array();
	for (var i = 0; i < opts.length; i++)
		if (opts[i].selected)
			checked.push(opts[i].value);
	// build answer string
	var ids = "";
	for (var i = 0; i < checked.length; i++)
		ids = ids + checked[i] + ",";
	ids = ids.substr(0, ids.length - 1);
	
	return ids;

} // end function GetSelectedItems






/* **********************************************************************************************************************
   ++
   ++	T E X T   M A N I P U L A T I O N
   ++ 
   **********************************************************************************************************************/


function ClearElements(ids, text, ask) {
    /*******************************************************************************************************************
    function: ClearElements

    Description:
        clears the elements in ids (comma-delimited) by setting their value properties to "".
		asks for confirmation with message "text" unless "ask" = false
	*********************************************************************************************************************/

	if (!ask || confirm(text)) {
		ids = ids.split(',');
		for (var i = 0; i < ids.length; i++) {
			try {
				getElement("id", ids[i]).value = "";
			}
			catch (e) { }
		}
	}

} // end function ClearElements


function strpos(needle, haystack) {
	/*******************************************************************************************************************
    function: strpos

    Description:
        returns position of first needle in haystack, or -1
	*********************************************************************************************************************/

	var nl = needle.length;
	for (var i = 0; i < haystack.length; i++)
		if (haystack.substring(i, i + nl) == needle)
			return i;
	return -1;

} // end function strpos


function strcpos(c, s) { 
	/*******************************************************************************************************************
    function: strcpos

    Description:
        returns position of first occurence of character c in string s, or -1
	*********************************************************************************************************************/

	for (var i = 0; i < s.length; i++) 
		if (s.substring(i, i+1) == c) 
			return i; 
	return -1; 

} // end function strcpos


function Flank(id, sTag, eTag) {
    /*******************************************************************************************************************
    function: Flank

    Description:
        flanks the selected text in container with id="id" with sTag (start) and eTag (end)
	*********************************************************************************************************************/

	var e = getElement("id", id);
	var scrollPos = e.scrollTop;
	
	e.focus();
	if (IE) { // IE
		var range = document.selection.createRange();
		var fText = range.text;
		range.text = sTag + fText + eTag;
		range = document.selection.createRange();
		if (fText.length == 0) { // set cursor position
			range.move('character', -eTag.length);
		}
		else {
			range.moveStart('character', sTag.length + fText.length + eTag.length);
		}
		range.select();
	}
	else if (FF || OP) { // Gecko, Opera
		var start = e.selectionStart;
		var end = e.selectionEnd;
		var fText = e.value.substring(start, end);
		e.value = e.value.substr(0, start) + sTag + fText + eTag + e.value.substr(end);
		var pos;
		if (fText.length == 0) { // set cursor position
			pos = start + sTag.length;
		}
		else {
			pos = start + sTag.length + fText.length + eTag.length;
		}
		e.selectionStart = pos;
		e.selectionEnd = pos;
	}
	else { // others
		alert("Not supported by browser!");
	}
	
	e.scrollTop = scrollPos;

} // end function Flank


function CursorPos(objText) {
    /*******************************************************************************************************************
    function: CursorPos

    Description:
        gets the position of the cursor in a text object
	*********************************************************************************************************************/

	this.pos = -1;
	this.lenght = 0;
	
	var sText = objText.value;
	var oRange = document.selection.createRange();
	var sRange = oRange.text;
	this.length = sRange.length;
	var sMarker = '§^§';
	
	oRange.text = sRange + sMarker;
	oRange.moveStart('character', -(sRange.length + sMarker.length));
	var sNew = objText.value;
	oRange.text = sRange;
	this.pos = strpos(sMarker, sNew) - this.length;
	if (sRange.length > 0) {
		oRange = document.selection.createRange();
		oRange.select();
	}

} // end function CursorPos
	

function SaveCursor(objText, storage_id) {
    /*******************************************************************************************************************
    function: SaveCursor

    Description:
        saves the position of the cursor in objText to an object with id="storage_id"
	*********************************************************************************************************************/

return; // buggy!
	if (!IE) return;
	var cp = new CursorPos(objText);
	var e = getElement('id', storage_id);
	if (e) e.value = cp.pos + ',' + cp.length;

} // end function SaveCursor


function Insert(id, text) {
    /*******************************************************************************************************************
    function: Insert

    Description:
        inserts text into a container with id="id" at the current cursor position
	*********************************************************************************************************************/

	var e = getElement("id", id);
	e.focus();
	if (IE) { // IE
		// get cursor position
		var cp = getElement('id', id + '_cursor');
		cp = cp ? cp.value : '0,0';
		cp = cp.split(',');
		
		var t = e.value;
		var range_start = parseInt(cp[0]);
		var range_end = range_start + parseInt(cp[1]);
		var t1 = t.substr(0, range_start);
		var t2 = t.substr(range_end, t.length);
		e.value = t1 + text + t2;
		// adjust cursor
		e.select();
		t = e.value;
		range = document.selection.createRange();
		range.moveStart('character', range_start + text.length);
		range.moveEnd('character', - t.length + range_end + text.length);
		range.select();
	}
	else if (FF || OP) { // Gecko, Opera
		var start = e.selectionStart;
		var end = e.selectionEnd;
		var fText = e.value.substring(start, end);
		e.value = e.value.substr(0, start) + text + e.value.substr(end);
		e.selectionStart = e.selectionEnd = start + text.length;
	}
	else { // others
		alert("Not supported by browser!");
	}
	
} // end function Insert


function EscapeSpecialChars(text) {
    /*******************************************************************************************************************
    function: EscapeSpecialChars

    Description:
        The characters less-than, greater-than, and ampersands are illegal in XML syntax. This function 
		escapes these characters: 

		< --> &lt;
        > --> &gt;
        & --> &amp;
    *********************************************************************************************************************/

    // replace matrix
	var toSearch = new Array( "&", "<", ">" );
	var replaceWith = new Array( "&amp;", "&lt;", "&gt;" );
	
	for (var i = 0; i < toSearch.length; i++) {
		var p = -1; var np;
		var s = toSearch[i];
		var r = replaceWith[i];
		while ((np = text.indexOf(s, p + 1)) > -1) {
       		p = np;
        	text = text.substr(0, p) + r + text.substr(p + 1, text.length);
		}
	}

    return text;
	
} // end function EscapeSpecialChars










function Pause(milliseconds) {
	var now = new Date();
	var endTime = now.getTime() + milliseconds;
	while (true) {
		setTimeout("now = new Date();", 50);
		if (now.getTime() > endTime)
		return;
	}
}
