function util_getElementDimensions(obj)
{
    var w = 0; 
    var h = 0;

  if(document.layers)
  {
    w = parseInt(obj.clip.width || 0);
    h = parseInt(obj.clip.height || 0);
  }
  else
  {
      if (obj.offsetWidth) {
          w = parseInt(obj.offsetWidth || 0);
          h = parseInt(obj.offsetHeight || 0);
      }
      else if (obj.style.pixelWidth) {
          w = parseInt(obj.style.pixelWidth || 0);
          h = parseInt(obj.style.pixelHeight || 0);
      }
      else if (obj.style.width) {
          w = parseInt(obj.style.width || 0);
          h = parseInt(obj.style.height || 0);
      }

      /* Borders */
      if (obj.style.borderLeftWidth) {
          var val = parseInt(obj.style.borderLeftWidth || 0);
          if (!isNaN(val)) {
              w += val;
          }
      }
      if (obj.style.borderRightWidth) {
          var val = parseInt(obj.style.borderRightWidth || 0);
          if (!isNaN(val)) {
              w += val;
          }
      }
      if (obj.style.borderTopWidth) {
          var val = parseInt(obj.style.borderTopWidth || 0);
          if (!isNaN(val)) {
              h += val;
          }
      }
      if (obj.style.borderBottomWidth) {
          var val = parseInt(obj.style.borderBottomWidth || 0);
          if (!isNaN(val)) {
              h += val;
          }
      }
  }

  return [w,h];
}

/**
* Überprüft das Event-Objekt und "repariert" es, wenn möglich
*/
function util_fixEventObj(e)
{
  if(!e) {
    e = (typeof event != "undefined") ? event : null;
  }
  return e;
}

/**
* gets keycode from the last occurred key event
*/
function util_getKeyCode(e) {

  if(window.event) {
    return window.event.keyCode;
  } else if (e) {
    return e.which;
  } else {
    return 0;
  }
}

function util_getButtonCode(e)
{
  if(window.event) {
    return window.event.button;
  } else if(e) {
    return e.which;
  } else {
    return 0;
  }
}

function util_getEventSrc(e)
{
  if(window.event)
  {
    return window.event.srcElement;
  } else if(e) {
    return e.target;
  } else {
    return 0;
  }
}

function util_getMousePosition(e, screen)
{
  var x,y

  if(window.event)
  {
    x = window.event.clientX;
    y = window.event.clientY;
    if(!screen) {
      x += document.body.scrollLeft;
      y += document.body.scrollTop;
    }
  }
  else if(e)
  {
    if(screen) {
      x = e.screenX;
      y = e.screenY;
    } else {
      x = e.pageX;
      y = e.pageY;
    }
  }

  return [x,y];
}

function util_parseInteger(a, b) {
  return isNaN(b = parseInt(a))? 0 : b;
}

function util_inArray(aSearch, val)
{
  for(var i = 0; i < aSearch.length; i++)
  {
    if(aSearch[i] == val) {
      return i;
    }
  }

  return false;
}

function util_getElementPosition(obj)
{
  var x,y;

  if(document.layers)
  {
    x = obj.pageX || 0;
    y = obj.pageY || 0;
  }
  else
  {
    x = 0;
    y = 0;

    var nodeList = [];

    while(obj)
    {
    	if(util_inArray(nodeList, obj) === false)
    	{
	    	nodeList[nodeList.length] = obj;
	      x += util_parseInteger(obj.offsetLeft);
	      y += util_parseInteger(obj.offsetTop);
	    }
      obj = obj.offsetParent || null;
    }
  }

  return [x,y];
}

function util_setElementPosition(obj, intX, intY) {
  if(document.layers) {
    if(intX != UNDEFINED) {
      obj.left = intX;
    }
    if(intY != UNDEFINED) {
      obj.top = intY;
    }
  } else {
    if(intX != UNDEFINED) {
      obj.style.left = intX + "px";
    }
    if(intY != UNDEFINED) {
      obj.style.top = intY + "px";
    }
  }
}

function util_setElementTransparency(obj, alpha)
{
  if(document.all) {
    if(alpha == 100) {
      obj.style.filter = "";
    } else {
      obj.style.filter = "Alpha(opacity=" + alpha + ")";
    }
  } else {
    obj.style.MozOpacity = alpha/100;
  }
}

function util_getPageDimensions(w)
{
  if(document.all) {
    return [w.document.body.clientWidth, w.document.body.clientHeight];
  } else {
    return [w.innerWidth, w.innerHeight];
  }
}

function util_addEventHandler(el, type, fn)
{
  if(el.addEventListener)
  {
      /* W3C-Modell */
    el.addEventListener(type, fn, false);
  }
  else if (el.attachEvent)
  {
      /* Microsoft-Modell */
    el["e"+type+fn] = fn;
    el[type+fn] = function() { el["e"+type+fn](window.event); }
    el.attachEvent("on"+type, el[type+fn]);
  }
  else
  {
      /* Inline-Modell */
    if(el["on"+type] == null)
    {
      el["on"+type] = util_inlineEventHandler;
      el[type+"_inlinefunc"] = [fn];
    }
    else
    {
      var idx = el[type+"_inlinefunc"].length;
      el[type+"_inlinefunc"][idx] = fn;
    }
  }
}

/**
* Entfernt den angegebenen Event-Handler vom Element
*/
function util_removeEventHandler(el, type, fn)
{
  if(el.removeEventListener)
  {
      /* W3C-Modell */
    el.removeEventListener(type, fn, false);
  }
  else if(el.attachEvent)
  {
      /* Microsoft-Modell */
    el.detachEvent("on"+type, el[type+fn]);
  }
  else
  {
      /* Inline-Modell */
    if(el[type+"_inlinefunc"])
    {
      var idx = util_inArray(el[type+"_inlinefunc"], fn);
      if(idx !== false) {
        util_removeFromArray(el[type+"_inlinefunc"], idx);
      }
      if(el[type+"_inlinefunc"].length == 0) {
        el[type+"_inlinefunc"] = null;
      }
      el["on"+type] = null;
    }
  }
}

/**
* FÃ¼hrt die zu einem Element hinzugefÃ¼gten Event-Handler beim Inline-Modell aus.
*/
function util_inlineEventHandler(e)
{
  e = util_fixEventObj(e);
  var aFunc = this[e.type + "_inlinefunc"];
  for(var i = 0; i < aFunc.length; i++) {
    aFunc[i](e);
  }
}

/**
* Entfernt den eingegebenen Eintrag (Index) vom Ã¼bergebenen Array
*/
function util_removeFromArray(aOrig, idx)
{
  var len = aOrig.length-1;
  for(var i = idx; i < len; i++)
  {
    aOrig[i] = aOrig[i+1];
  }
    
  aOrig.length--;
  return aOrig;
}

function util_getWindowScroll(w)
{
    var ret = {top: 0, left: 0};
    
    if(document.all)
    {
        ret.top = w.document.body.scrollTop;
        ret.left = w.document.body.scrollLeft;
    }
    else
    {
        ret.top = w.pageYOffset;
        ret.left = w.pageXOffset
    }
    
    return ret;   
}

/**
* Gets width of scrollbar
*/
function util_getScrollBarWidth ()
{
    var inner = document.createElement("p");
    inner.style.width = "100%";
    inner.style.height = "200px";

    var outer = document.createElement("div");
    outer.style.position = "absolute";
    outer.style.top = "0px";
    outer.style.left = "0px";
    outer.style.visibility = "hidden";
    outer.style.width = "200px";
    outer.style.height = "150px";
    outer.style.overflow = "hidden";
    outer.appendChild (inner);

    document.body.appendChild (outer);
    var w1 = inner.offsetWidth;
    outer.style.overflow = "scroll";
    var w2 = inner.offsetWidth;
    if (w1 == w2) w2 = outer.clientWidth;

    document.body.removeChild(outer);
    
    return (w1 - w2);
}

/**
* Sets input information text
*/
function util_setInputInfoMessage(inputId, infoText, focusType, blurType)
{
    var inputEl = document.getElementById(inputId);
    if (inputEl.value == "") {
        if (focusType != blurType) {
            var parentNode = inputEl.parentNode;

            var newInputEl = document.createElement("input");
            newInputEl.type = blurType;
            newInputEl.value = infoText;
            newInputEl.id = inputEl.id;
            newInputEl.name = inputEl.name;

            parentNode.replaceChild(newInputEl, inputEl);

            newInputEl.onfocus = function() { util_clearInputInfoMessage(inputId, infoText, focusType, blurType); };
            newInputEl.onblur = function() { util_setInputInfoMessage(inputId, infoText, focusType, blurType); };

            if (inputEl.onkeyup != null) {
                newInputEl.onkeyup = inputEl.onkeyup;
            }
        }
        else {
            inputEl.value = infoText;
        }
    }
}

/**
* Clears input information text
*/
function util_clearInputInfoMessage(inputId, infoText, focusType, blurType)
{
    var inputEl = document.getElementById(inputId);
    if (inputEl.value == infoText) {
        if (focusType != blurType) {
            var parentNode = inputEl.parentNode;

            var newInputEl = document.createElement("input");
            newInputEl.type = focusType;
            newInputEl.value = "";
            newInputEl.id = inputEl.id;
            newInputEl.name = inputEl.name;

            parentNode.replaceChild(newInputEl, inputEl);

            newInputEl.onfocus = function() { util_clearInputInfoMessage(inputId, infoText, focusType, blurType); };
            newInputEl.onblur = function() { util_setInputInfoMessage(inputId, infoText, focusType, blurType); };

            if (inputEl.onkeyup != null) {
                newInputEl.onkeyup = inputEl.onkeyup;
            }

            window.setTimeout(function() { document.getElementById(inputId).focus(); }, 0);
        } else {
            inputEl.value = "";
        }
    }
}

function util_getEventSrc(e) {
    if (window.event) {
        return window.event.srcElement;
    } else if (e) {
        return e.target;
    } else {
        return 0;
    }
}

function util_trim(s) {
    var o = s.charCodeAt(0);
    while (o == 32 || 0 == 9 || o == 160) {
        s = s.substring(1, s.length);
        o = s.charCodeAt(0);
    }
    var o = s.substring(s.length - 1);
    while (o == 32 || 0 == 9 || o == 160) {
        s = s.substring(0, s.length - 1);
        o = s.charCodeAt(s.length - 1);
    }
    return s;
}

/**
* Validates an email address
*/
/**
* Überprüft eine E-Mail-Adresse auf Gültigkeit
*/
function util_validateString(s, validChars)
{
    for(var i = 0; i < s.length; i++)
    {
        var c = s.substr(i, 1);
        if(validChars.indexOf(c) == -1) {
            return false;
        }
    }
    
    return true;
}

function util_validateEmail(s)
{
    var dot = ".";
	var at = "@";
	var validLocalPartChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-!#$%&'*+-/=?^_`{|}~";
	var validDomainPartChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-";
	var validTLDs = "AC,AD,AE,AERO,AF,AG,AI,AL,AM,AN,AO,AQ,AR,ARPA,AS,ASIA,AT,AU,AW,AX,AZ,BA,BB,BD,BE,BF,BG,BH,BI,BIZ,BJ,BM,BN,BO,BR,BS,BT,BV,BW,BY,BZ,CA,CAT,CC,CD,CF,CG,CH,CI,CK,CL,CM,CN,CO,COM,COOP,CR,CU,CV,CX,CY,CZ,DE,DJ,DK,DM,DO,DZ,EC,EDU,EE,EG,ER,ES,ET,EU,FI,FJ,FK,FM,FO,FR,GA,GB,GD,GE,GF,GG,GH,GI,GL,GM,GN,GOV,GP,GQ,GR,GS,GT,GU,GW,GY,HK,HM,HN,HR,HT,HU,ID,IE,IL,IM,IN,INFO,INT,IO,IQ,IR,IS,IT,JE,JM,JO,JOBS,JP,KE,KG,KH,KI,KM,KN,KP,KR,KW,KY,KZ,LA,LB,LC,LI,LK,LR,LS,LT,LU,LV,LY,MA,MC,MD,ME,MG,MH,MIL,MK,ML,MM,MN,MO,MOBI,MP,MQ,MR,MS,MT,MU,MUSEUM,MV,MW,MX,MY,MZ,NA,NAME,NC,NE,NET,NF,NG,NI,NL,NO,NP,NR,NU,NZ,OM,ORG,PA,PE,PF,PG,PH,PK,PL,PM,PN,PR,PRO,PS,PT,PW,PY,QA,RE,RO,RS,RU,RW,SA,SB,SC,SD,SE,SG,SH,SI,SJ,SK,SL,SM,SN,SO,SR,ST,SU,SV,SY,SZ,TC,TD,TEL,TF,TG,TH,TJ,TK,TL,TM,TN,TO,TP,TR,TRAVEL,TT,TV,TW,TZ,UA,UG,UK,US,UY,UZ,VA,VC,VE,VG,VI,VN,VU,WF,WS,YE,YT,YU,ZA,ZM,ZW"
    
	/* check if ONE @ is in the string by splitting by @ an check if we get exactly TWO parts */
    var aPart = s.split(at);
    if(aPart.length != 2) {
        return false;
    }

    var localPart = aPart[0];
    var domainPart = aPart[1];
    
    /* check domain part */    
        /* check for length */
    if(domainPart.length < 4 || domainPart.length > 254) {
        return false;
    }
        
        /* check for at least one dot */
    aPart = domainPart.split(dot);
    if(aPart.length < 2) {
        return false;
    }
    
        /* check TLD */
    var tld = aPart[aPart.length-1].toUpperCase();
    if(validTLDs.indexOf(tld) == -1) {
        return false;
    }
    
        /* check host name parts */
    for(var i = 0; i < aPart.length-1; i++)
    {
        var hostname = aPart[i]
        if (hostname.length < 1 || hostname.length > 63 ||
            hostname.substr(0, 1) == "-" || hostname.substr(hostname.length-1, 1) == "-" ||
            !util_validateString(hostname, validDomainPartChars)) {
            return false;
        }
    }

    /* check local part */
        /* check for length */
    if (localPart.length < 1 || localPart.length > 64) {
        return false;
    }
    
        /* check for valid parts */
    aPart = localPart.split(dot);
    
    for(var i = 0; i < aPart.length; i++)
    {
        if(aPart[i] == "" || !util_validateString(aPart[i], validLocalPartChars)) {
            return false;
        }
    }

    /* check DNS and mailserver */
    var responseXML = util_parseXML(ajax_call("ajax.aspx?a=validateemail&username=" + localPart + "&domain=" + domainPart, null, false));
    if (responseXML != null && responseXML.getElementsByTagName("notok").length > 0) {
        return false;
    }
    
    /* all OK */
    return true;
}

/**
* Validates a zip
*/
function util_validateSwissZIP(zip) {
    zip = util_trim(zip);
    if (zip != "" && /[0-9]{4}/.test(zip)) {
        /* check against valid ZIPs in database */
        var responseXML = util_parseXML(ajax_call("ajax.aspx?a=validatezip&zip=" + zip, null, false));
        if (responseXML != null && responseXML.getElementsByTagName("notok").length > 0) {
            return false;
        }

        var city = responseXML.getElementsByTagName("city")[0];
        return util_getNamedItem(city.attributes, "name");
    }

    return false;
}

/**
* Validates a phone number
*/
function util_validateSwissPhonenumber(phone, allowLandline, allowMobile, allowFree, allowChargable, allowPersonal) {
    phone = util_trim(phone);
    if (phone != "" && /^(\+?[0]{0,2}41[\s\.\-\_\/]*)?([0-9]{2}|0[0-9]{2})[\s\.\-\_\/]*([0-9]{3})[\s\.\-\_\/]*([0-9]{2})[\s\.\-\_\/]*([0-9]{2})$/.test(phone)) {
        var prefix = Number(RegExp.$2);
        var p1 = Number(RegExp.$3);
        var p2 = Number(RegExp.$4);
        var p4 = Number(RegExp.$5);

        var validLandlinePrefix = [21, 22, 24, 26, 27, 31, 32, 33, 34, 41, 43, 44, 52, 55, 56, 61, 62, 71, 81, 91];
        var validMobilePrefix = [76, 77, 78, 79];

        var isValidPrefix = false;
        if (allowLandline && util_inArray(validLandlinePrefix, prefix) !== false) {
            isValidPrefix = true;
        }
        if (allowMobile && util_inArray(validMobilePrefix, prefix) !== false) {
            isValidPrefix = true;
        }
        if (allowFree && prefix == 80 && String(p1).substring(0, 1) == "0") {
            isValidPrefix = true;
        }
        if (allowChargable && prefix == 84) {
            var n = String(p1).substring(0, 1);
            if (n == "0" || n == "2" || n == "4" || n == "8") {
                isValidPrefix = true;
            }
        }
        if (allowPersonal && prefix == 87 && String(p1).substring(0, 1) == "8") {
            isValidPrefix = true;
        }

        return isValidPrefix;
    }

    return false;
}

/**
* Parses an xml string into xml object
*/
function util_parseXML(text)
{
    var xmlDoc = null;
    
    try //Internet Explorer
    {
        xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async = "false";
        xmlDoc.loadXML(text);
    }
    catch (e)
    {
        try //Firefox, Mozilla, Opera, etc.
        {
            parser = new DOMParser();
            xmlDoc = parser.parseFromString(text, "text/xml");
        }
        catch (e)
        {
            return null;
        }
    }

    return xmlDoc;
}

/**
* Validates a date
*/
function util_validateDate(s, minYear, maxYear)
{
    var aSplit = s.split(".");
    if (aSplit.length != 3) {
        return false;
    }

    var dayString = util_trim(aSplit[0]);
    if (dayString.length != 2) {
        return false;
    }
    var day = Number(dayString);
    if (isNaN(day) || (day < 1 || day > 31)) {
        return false;
    }

    var monthString = util_trim(aSplit[1]);
    if (monthString.length != 2) {
        return false;
    }
    var month = Number(monthString);
    if (isNaN(month) || (month < 1 || month > 12)) {
        return false;
    }

    var yearString = util_trim(aSplit[2]);
    if (yearString.length != 4) {
        return false;
    }
    var year = Number(yearString);
    if (isNaN(year)) {
        return false;
    }
    if (year < 100) {
        year += 2000;
    }
    if (year < minYear || year > maxYear) {
        return false;
    }
    
    return true;
}

function util_passwordStrength(password, colorDiv)
{
    var score = 0;
    //if password bigger than 6 give 1 point
    if (password.length >= 6) score++;

    //if password has both lower and uppercase characters give 1 point      
    if ((password.match(/[a-z]/)) && (password.match(/[A-Z]/))) score++;

    //if password has at least one number give 1 point
    if (password.match(/\d+/)) score++;

    //if password has at least one special caracther give 1 point
    if (password.match(/.[!,@,#,$,%,^,&,*,?,_,~,-,(,),\{,\}]/)) score++;

    //if password bigger than 12 give another 1 point
    if (password.length >= 12) score++;
    
    colorDiv.className = "password-strength password-strength" + score;
}

function util_getNamedItem(aObj, name)
{
    for (var i = 0; i < aObj.length; i++)
    {
        if (aObj[i].name == name) {
            return aObj[i].value;
        }
    }

    return null;
}

/**
* Selektiert in einer Selectbox den angegebenen Wert
*/
function util_setSelectionValue(elSel, sValue) {
    for (var i = 0; i < elSel.options.length; i++) {
        if (elSel.options[i].value == sValue) {
            elSel.options[i].selected = true;
            return true;
        }
    }

    elSel.selectedIndex = -1;
    return false;
}

/**
* Konvertiert Dezimalzahlen in einen Hex-String (mit übergebener Länge (pad) wenn nötig)
*/
function util_decToHex(dec, pad) {
    var hex = '';
    while (dec > 0) {
        dig = dec & 0xF;
        dig = dig < 10 ? dig + 48 : dig + 55;
        hex = String.fromCharCode(dig) + hex;
        dec >>= 4;
    }

    if (pad) {
        if (hex.length < pad) {
            for (i = hex.length; i < pad; i++) {
                hex = '0' + hex;
            }
        }
    }

    return hex;
}

/**
* Konvertiert einen Hexstring in eine Dezimalzahl
*/
function util_hexToDec(hex) {
    var dec = 0;
    for (i = 0; i < hex.length; i++) {
        dig = hex.charCodeAt(i);
        dig = dig > 64 ? dig - 55 : dig - 48;
        dec = (dec << 4) | dig;
    }

    return dec;
}

/**
* Überprüft ob der übegebene String ein korrekter Hexwert ist
*/
function util_checkHexColor(hex) {
    hex = hex.toUpperCase();
    if (hex.length != 6) {
        return false;
    } else {
        for (i = 0; i < hex.length; i++) {
            c = hex.charCodeAt(i);
            if (c < 48 || (c > 57 && c < 65) || c > 70) {
                return false;
            }
        }
    }

    return true;
}

function util_correctHexColor(hex) {
    hex = hex.toUpperCase();

    var newHex = "";    
    for (i = 0; i < hex.length; i++) {
        c = hex.charCodeAt(i);
        if (c < 48 || (c > 57 && c < 65) || c > 70) {
            //
        } else {
            newHex += hex.substr(i, 1);
            if (hex.length == 3) {
                newHex += hex.substr(i, 1);
            }
        }
    }
    newHex = newHex.toLowerCase();
    if (newHex.length < 6) {
        for (var i = newHex.length; i < 6; i++) {
            newHex = "0" + newHex;
        }
    }

    return newHex;
}

function util_mergeSort(arr, l, h, orderfunc) {
    if (l < h) {
        var m = l + Math.floor((h - l) / 2);
        var a = util_mergeSort(arr, l, m, orderfunc);
        var b = util_mergeSort(arr, m + 1, h, orderfunc);
    } else if (arr.length == 0) {
        return [];
    }
    else {
        return [arr[l]];
    }

    //now merge
    var r = [];
    var ia = 0;
    var ib = 0;
    var al = a.length
    var bl = b.length
    while (ia < al && ib < bl) {
        if (orderfunc(b[ib], a[ia]) == 1) {
            r[r.length] = b[ib++];
        } else {
            r[r.length] = a[ia++];
        }
    }
    while (ia < al) r[r.length] = a[ia++];
    while (ib < bl) r[r.length] = b[ib++];

    return r;
}

function util_getChildNodesHeight(node) {
    var h = 0;
    for (var i = 0; i < node.childNodes.length; i++) {
        if (node.childNodes[i] && node.childNodes[i].nodeType == 1) {
            var dim = util_getElementDimensions(node.childNodes[i]);
            h += dim[1];
        }
    }

    return h;
}

/**
* Kopiert ein Objekt
*/
function util_cloneObject(objectOrig, deep) {
    var objectClone = new objectOrig.constructor();
    for (var property in objectOrig) {
        if (!deep) {
            objectClone[property] = objectOrig[property];
        } else if (typeof objectOrig[property] == 'object') {
            objectClone[property] = util_cloneObject(objectOrig[property], deep);
        } else {
            objectClone[property] = objectOrig[property];
        }
    }
    return objectClone;
}

/* -------------------------------------------------------------------------------------------- */
/* Detection functions */
/* -------------------------------------------------------------------------------------------- */

/**
* Browser detection
*/

    // IE
function util_isIE() {
    return (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent));
}
function util_getIEVersion() {
    if (/msie (\d+\.\d+);/i.test(navigator.userAgent)) {
        return RegExp.$1;
    }
    else {
        return false;
    }
}

    // Firefox
function util_isFirefox() {
    return (/firefox[\/\s](\d+\.\d+\.?\d*\.?\d*)/i.test(navigator.userAgent));
}
function util_getFirefoxVersion() {
    if (/firefox[\/\s](\d+\.\d+\.?\d*\.?\d*)/i.test(navigator.userAgent)) {
        return RegExp.$1;
    }
    else {
        return false;
    }
}

    // Opera
function util_isOpera() {
    return (/opera[\/\s](\d+\.\d+)/i.test(navigator.userAgent));
}
function util_getOperaVersion() {
    if (/opera[\/\s](\d+\.\d+)/i.test(navigator.userAgent)) {
        return RegExp.$1;
    }
    else {
        return false;
    }
}

    // Safari
function util_isSafari() {
    return (/version\/(\d+\.\d+\.?\d*)[\s]+safari/i.test(navigator.userAgent));
}
function util_getSafariVersion() {
    if (/version\/(\d+\.\d+\.?\d*)[\s]+safari/i.test(navigator.userAgent)) {
        return RegExp.$1;
    }
    else {
        return false;
    }
}

    // Chrome
function util_isChrome() {
    return (/chrome\/(\d+\.\d+\.?\d*\.?\d*)/i.test(navigator.userAgent));
}
function util_getSafariVersion() {
    if (/chrome\/(\d+\.\d+\.?\d*\.?\d*)/i.test(navigator.userAgent)) {
        return RegExp.$1;
    }
    else {
        return false;
    }
}

/**
* Operating system detection
*/
function util_getOperatingSystem() {
    var OSName = "Unknown OS";
    if (navigator.appVersion.indexOf("Win") != -1) OSName = "Windows";
    if (navigator.appVersion.indexOf("Mac") != -1) OSName = "MacOS";
    if (navigator.appVersion.indexOf("X11") != -1) OSName = "UNIX";
    if (navigator.appVersion.indexOf("Linux") != -1) OSName = "Linux";

    return OSName;
}

/**
* Transparent flash support (wmode=transparent | wmode=opaque)
* needs swfobject!!
*/
function util_checkTransparentFlashSupport() {
    var os = util_getOperatingSystem();
    if ((os == "Windows" || os == "MacOS") && swfobject.hasFlashPlayerVersion("9.0.0")) {
        var ieVersion = util_getIEVersion();
        var ffVersion = util_getFirefoxVersion();

        if (ieVersion !== false) {
            return Number(ieVersion) >= 6 && swfobject.hasFlashPlayerVersion("9.0.16");
        } else if (ffVersion !== false) {
            return swfobject.hasFlashPlayerVersion("10.0.12.36");
        } else {
            return true;
        }
    }

    return false;
}

/**
* Verhindert die weitere Ausführung eines Events
*/
function util_preventEvent(e) {
    e = util_fixEventObj(e);
    if (e) {
        if (e.returnValue) {
            e.returnValue = false;
        }
        if (e.preventDefault) {
            e.preventDefault();
        }
        if (e.stopPropagation) {
            e.stopPropagation();
        }
    }

    return false;
}

function util_addLoadingDiv(x, y, width, height) {
    if (!x) { x = '0px'; }
    if (!y) { y = '0px'; }
    if (!width) { width = '100%'; }
    if (!height) { height = '100%'; }
    var div = document.createElement('DIV');
    div.id = 'loadingDiv';
    div.className = 'loading';
    div.align = 'center';
    div.valign = 'middle';
    div.style.top = y;
    div.style.left = x;
    div.style.width = width;
    div.style.height = height;
    div.innerHTML = '<img src="images/cms/loading2.gif" alt="Loading... Please wait."><br/><span class="loading">Loading... Please wait.</span>';
    var helpDiv = document.createElement('DIV');
    helpDiv.appendChild(div);
    document.body.appendChild(helpDiv);
}

function util_removeLoadingDiv() {
    var div = document.getElementById('loadingDiv');
    if (div) {
        div.parentNode.removeChild(div);
    }
}

function util_rgbToGray(rgb) {
    return (
            0.299 * ((rgb >> 16) & 0xFF) +
            0.587 * ((rgb >> 8) & 0xFF) + +
            0.114 * (rgb & 0xFF)
           );
}

function util_getSelectedOptionsCSV(sel) {
    var value = "";
    var cnt = 0;
    for (var i = 0; i < sel.options.length; i++) {
        if (sel.options[i].selected) {
            if (cnt > 0) {
                value += ",";
            }
            value += '"' + util_makeJavaScriptSafe(sel.options[i].value) + '"';
            cnt++;
        }
    }
    return value;
}

/**
* ensures safe priting of a string in javascript
*/
function util_makeJavaScriptSafe(input) {
    input = input.replace(/"/g, "\\\"");
    input = input.replace(/\r/g, "\\r");
    input = input.replace(/\n/g, "\\n");
    return input;
}