/*
**  cb_scripts.js
**      2008-10-04  initial release, extracted from ee_scripts
**		2009-05-06	removed warnings
**		2009-06-06	setTheFocus() takes BUTTONs as well
**		2009-07-02	centerElement()
**		2009-07-14	doNothing() calls cancelBubble()
**		2010-01-24	getScrollX/Y()
**		2010-06-02	isValidDate() moved to here and refined
**		2010-06-02	toggleAll() moved to here
**		2010-12-04	toggleAll() improved / findTableForElement() invented / String functions moved to here
**		2011-01-22	respect noFocus on ancestor elements
**		2011-07-25	nl2br() 
*/


//
// 	General Purpose Event Handlers.
//

/**
 * Make sure an event is completely ignored.
 */
function doNothing(evt)
{
    if (evt && evt.cancelBubble)
        evt.cancelBubble() ;
    if (evt && evt.preventDefault)
        evt.preventDefault() ;
    if (evt && evt.returnValue)
        evt.returnValue = false ;
    return false ;
}


//
// 	Helper Functions for Event Handlers.
//

/**
 * Browser safe function to get the element for an event. 
 */
function getElementForEvent(evt)
{
	var local = evt ? evt : (window.event ? window.event : "");
	var elem = local.target ? local.target : local.srcElement ;
    return elem ;
}

/**
 * Browser safe function to get the key code for an event such as onKeyUp.
 */
function getKeyCode(evt)
{
	var local = evt ? evt : (window.event ? window.event : "");
    var code = 0 ;
	if (local.keyCode) 
        code = local.keyCode;
	else if (local.which) 
        code = local.which;
    return code ;
}


//
// 	Helper Functions to find Elements, Attributes etc.
//

/**
 * Find the Attribute attr for Element elem or any of the Element's ancestors. 
 */
function findParentAttribute(elem, attr)
{
    if (elem.getAttribute && elem.getAttribute(attr))
        return elem.getAttribute(attr) ;
    else if (elem.parentNode)
        return findParentAttribute(elem.parentNode, attr) ;
    else
        return null ;
}

/**
 * Find the 1st Tag with a given Attribute. 
 */
function findTagWithAttr(elem, tag, attr)
{
    var a = elem.getElementsByTagName(tag) ;
    
    for(var i=0 ; i<a.length ; i++)
	    if (a[i].getAttribute(attr))
            return a[i] ;
    return null ;
}

/**
 * Find all Tags with a given Attribute. 
 */
function findAllTagsWithAttr(elem, attr)
{
    var a = elem.getElementsByTagName("*") ;
    var b = new Array() ;

    // the elem itself may have the attribute
    if (elem.getAttribute(attr))
        b.push(elem) ;

    for(var i=0 ; i<a.length ; i++)
	    if (a[i].getAttribute(attr))
            b.push(a[i]) ;
    return b ;
}

/**
 * Find the 1st or only Element with a given Tag Name 
 */
function findTagByName(elem, name)
{
    var a = elem.getElementsByTagName("*") ;
    for(var i=0 ; i<a.length ; i++)
	    if (a[i].name == name)
            return a[i] ;
    return null ;
}

/**
 * Find the the Value of the 1st or only Element with a given Name 
 */
function findValueByName(elem, name)
{
    var tag = findTagByName(elem, name) ;
    if (tag)
        return tag.value ;
    else
        return "" ;
}

/**
 * Find the INPUT elements that are checked from an array of checkboxes.
 */
function findCheckedElements(a)
{
	var c = new Array() ;

	for (var i=0; i<a.length ; i++)
		if (a[i].checked)
		    c.push(a[i]) ;
	return c ;
}


//
//	Helper Functions to handle Fields and Forms.
//

/**
 * Find the FORM an Element belongs to 
 */
function findFormForElement(elem)
{
    var form = elem ;
    while (form != null && form.tagName != 'FORM')
        form = form.parentNode ;
    return form ;
}

/**
 * Find the TABLE an Element belongs to 
 */
function findTableForElement(elem)
{
    var table = elem ;
    while (table != null && table.tagName != 'TABLE')
        table = table.parentNode ;
    return table ;
}

/**
 * Find a specific Field in the FORM 
 */
function findFormElementByName(elem, name)
{
    var form = findFormForElement(elem) ;

    if (form != null)
        return form.elements[name] ;
    else
        return null ;
}


//
//	GUI functions
//

/**
 * Set the focus to the 1st input field that makes sense to receive the focus. 
 */
function setTheFocus(elem)
{
	if (!elem)
		elem = document ;
	var a = elem.getElementsByTagName('*') ;

    for (var i=0; i<a.length ; i++)
    {
        var e = a[i] ;

        if (e.tagName == 'INPUT' || e.tagName == 'SELECT' || e.tagName == 'BUTTON')
        {     
            if (e.type != 'hidden' && 
                !e.getAttribute('readonly') && 
                !e.disabled && 
                !findParentAttribute(e,'noFocus'))
            {
                // make sure we don't scroll
                if (getX(e) > getScrollX() && getX(e) < getScrollX()+getWindowWidth() 
                 && getY(e) > getScrollY() && getY(e) < getScrollY()+getWindowHeight())
                {
                	try
                	{
                    	e.focus() ;
	                    if (e.tagName == 'INPUT')       
	                        e.select() ;            // because IE can't do this with a SELECT item
	                    break ;
	                }
	                catch (e)
	                {
	                	// ignore, e.g. field is not visible
	                } 
                }
            }
        }
    }
}

/**
 * Find a radio button by its value, check it and return the radio element.
 */
function checkRadioByValue(elem, value)
{
    for (var ix=0 ; ix<elem.length ; ix++)
        if (elem[ix].value == value)
        {
            elem[ix].checked = true ;
            return elem[ix] ;
        }
    return null ;
}

/**
 * Get the (checked) value for a set of radio buttons.
 */
function getRadioValue(elem)
{
    for (var i=0; i<elem.length; i++) 
        if (elem[i].checked) 
            return elem[i].value;
    return false;
}

/**
 * Toggle all checkboxes in the form or table where the clicked element lives in.
 */
function toggleAll(evt)
{
    var elem = getElementForEvent(evt) ;
    var formOrTable = findFormForElement(elem) ;
    if (formOrTable == null)
    	formOrTable = findTableForElement(elem) ;
    
    if (formOrTable)
    {
	    var a = formOrTable.getElementsByTagName('INPUT') ;
	
	    for(var i=0 ; i<a.length ; i++)
	    {
	    	if (a[i].type == 'checkbox')
	    		a[i].checked = ! a[i].checked ;
	    }
    }
	return false ;    
}


//
//  Helper functions for element and screen coordinates
//

/**
 * Get the absolute x-position for an element. 
 */
function getX(oElement)
{
    var iReturnValue = 0;
    while( oElement != null ) 
    {
        iReturnValue += oElement.offsetLeft;
        oElement = oElement.offsetParent;
    }
    return iReturnValue;
}

/**
 * Get the absolute y-position for an element.
 */
function getY(oElement)
{
    var iReturnValue = 0;
    while( oElement != null ) 
    {
        iReturnValue += oElement.offsetTop;
        oElement = oElement.offsetParent;
    }
    return iReturnValue;
}

/**
 * Get the width of the browser window.
 */
function getWindowWidth()
{
    var x;
    if (self.innerWidth)        // all except Explorer
        x = self.innerWidth;
                                // Explorer 6 Strict Mode
    else if (document.documentElement && document.documentElement.clientWidth)  
        x = document.documentElement.clientWidth;
    else if (document.body)     // other Explorers
        x = document.body.clientWidth;

    return x ;
}

/**
 * Get the height of the browser window.
 */
function getWindowHeight()
{
    var y;
    if (self.innerHeight)       // all except Explorer
    	y = self.innerHeight;
	                            // Explorer 6 Strict Mode
    else if (document.documentElement && document.documentElement.clientHeight)
    	y = document.documentElement.clientHeight;
    else if (document.body) // other Explorers
    	y = document.body.clientHeight;
    return y ;
}

/**
 * Center an element on the screen.
 */
function centerElement(e)
{
	var x = (getWindowWidth() - e.offsetWidth) / 2 ;
	var y = (getWindowHeight() - e.offsetHeight) / 2 ;
	e.style.left = '' + x + 'px' ;
	e.style.top = '' + y + 'px' ;
}

/**
 * Get horizontal (X) scroll position
 */
function getScrollX()
{
  	if (window.pageXOffset)							// FF
  		return window.pageXOffset ;		
	if (document.documentElement.scrollLeft)		// IE
		return document.documentElement.scrollLeft ;
	return 0 ;
}

/**
 * Get verticalal (Y) scroll position
 */
function getScrollY()
{
  	if (window.pageYOffset)							// FF
  		return window.pageYOffset ;		
	if (document.documentElement.scrollTop)		// IE
		return document.documentElement.scrollTop ;
	return 0 ;
}


//
//	Date and Time stuff
//

/**
 * Check a date for the correct (European) format DD.MM.YYYY
 * or for just a year YYYY. 
 */
function isValidDateOrYear(s)
{
    var a = s.split(".") ;
    var ultimo ;

    switch (a.length)
    {
    case 1:
        if (isNaN(a[0]) || a[0] < 1000 || a[0] > 9999)
            return false ;
        else
            return true ;

    case 3:
        if (isNaN(a[1]) || a[1] < 1 || a[1] > 12)
            return false ;
        if (isNaN(a[2]) || a[2] < 0)
            return false ;
        if (a[2] < 10)          // 2 digit 2000-2009
            a[2] += 2000 ;
        if (a[2] < 100)         // 2 digit 1910-1999
            a[2] += 1900 ;
        if (a[2] < 1000)        // should be 4 digit now
            return false ;

        switch(parseInt(a[1],10))
        {
        case 2:
            if (a[2] % 4 == 0)
                ultimo = 29 ;
            else
                ultimo = 28 ;
            break ;
        case 4:
        case 6:
        case 9:
        case 11:
            ultimo = 30 ;
            break ;
        default:
            ultimo = 31 ;
            break ;
        }

        if (a[0] < 1 || a[0] > ultimo)
            return false ;
        return true ;

    default:
        return false ;
    }
}

/**
 * Return today's date as YYYY-MM-DD
 */
function getTodayAsISO()
{
    var d = new Date() ;
    return String(d.getFullYear()) + "-" + String(d.getMonth()+1) + "-" + String(d.getDate())  ;
}

/**
 * Convert a German date (TT.MM.JJJJ or TT.MM.JJ) as YYYY-MM-DD.
 * 
 * 2-digit-years are considered to lie in the past or in the current year
 * which should always be ok for birth dates.
 * 
 * Empty string stays what it is.
 */
function convertDateToISO(s)
{
    if (s == "")
        return s ;

    var a = s.split(".") ;
    var j = parseInt(a[2],10) ;
    
    if (j < 100)
    {
        d = new Date() ;
        yearNow = d.getFullYear() ;
        if (j + 2000 > yearNow)
            j += 1900 ;
        else
            j += 2000 ; 
    }
    return String(j) + "-" + String(a[1]) + "-" + String(a[0]) ;
}


//
//String functions
//

/**
 * Returns true if one of the strings starts with the other one.
 */
function cmpStart(a, b)
{
	if (a == null || b == null)
		return false ;
	return a == b.substr(0,a.length) || b == a.substr(b.length) ;
}

/**
 * Return the part of a string up to the 1st tab character, 
 * not including the tab itself, whole string if no tab found. 
 */
function substrTab(s)
{
	var ix = s.indexOf('\t') ; 
	if (ix >= 0)
		s = s.substr(0,ix) ;
	return s ;
}

/**
 * Return the part of a string behind the 1st tab character,
 * empty string if no tab found. 
 */
function substrTabRest(s)
{
	var ix = s.indexOf('\t') ;
	if (ix < 0)
		return "" ;
	else
		return s.substr(ix+1) ;
}

/**
 * Replace every newline in a string with a <br/> tag.
 */
function nl2br(s)
{
    var ix = s.indexOf("\n") ;
    while (ix >= 0)
    {
        s = s.substr(0,ix) + "<br/>" + s.substr(ix+1) ;
        ix = s.indexOf("\n") ;
    }
    return s ;
}

/**
 * Convert a text with HTML entities to a Unicode string.
 */
function toUnicode(ent)
{
	// dirty trick, creating an invisible field for the conversion 
	var oDiv = document.createElement("DIV");

	if (navigator.appName == 'Microsoft Internet Explorer')
	{
		oDiv.innerHTML = nl2br(ent) ;
		return oDiv.innerText ;
	}
	else
	{
		oDiv.innerHTML = ent ;
		return oDiv.firstChild.nodeValue ;
	}
}

function encodeUTF8(rohtext) 
{
	var utftext = "";
    for(var n=0; n<rohtext.length; n++)
	{
 		// ermitteln des Unicodes des  aktuellen Zeichens
        var c=rohtext.charCodeAt(n);

        if (c < 128)
        {
	        // alle Zeichen von 0-127 => 1byte
            utftext += String.fromCharCode(c);
        }
        else if(c < 2048) 
        {
	        // alle Zeichen von 127 bis 2047 => 2byte
            utftext += String.fromCharCode((c>>6)|192);
            utftext += String.fromCharCode((c&63)|128);
        }
        else 
        {
            // alle Zeichen von 2048 bis 66536 => 3byte
            utftext += String.fromCharCode((c>>12)|224);
            utftext += String.fromCharCode(((c>>6)&63)|128);
            utftext += String.fromCharCode((c&63)|128);
        }
    }
    return utftext;
}


