/*
 * js_utils.js - Javascript Utilities - mainly string functions
 *
 */
 
 String.PRINTPATTERN   = /[^a-zA-Z0-9\.\;:#\-_\?\,\<\>\'=\/\! ]/;
 String.ANUMPATTERN    = /[^a-zA-Z0-9]/;
 String.APATTERN       = /[^a-zA-Z]/;
 String.NUMPATTERN     = /[^0-9]/;
 String.FILEPATTERN    = /[^a-zA-Z0-9-_\. ]/;
 String.HEXPATTERN     = /[^a-fA-F0-9]/;
 String.EMAILPATTERN   = /^.+@.+\.[a-zA-Z]+$/;
 String.URLPATTERN     = /^([^:]*):\/\/+(?:([^\/]*):)?(?:([^\/]*)@)?([\w\-_.]*[^.])(\/[^?]*)?(?:\?(.*))?$/;
 String.LEFT           = -1
 String.BALANCE        = 0
 String.RIGHT          = 1
 String.ISOFORMAT      = "yyyy-MM-dd'T'HH:mm:ssZ";
 String.SPACE          = " ";
 String.EMPTY          = "";
 String.NULL           = String.EMPTY; // to be deprecated?
 
 String.EMAILUSER      = /[^a-zA-Z0-9\._]/;
 String.EMAILSLD       = /[^a-zA-Z0-9\-]/;
 
  /**
   * function returns true if the string contains
   * only a-z (case insensitive!)
   * @return Boolean true in case string is alpha, false otherwise
   */
  String.prototype.isAlpha = function() {
      if (!this.length)
          return false;
      return !String.APATTERN.test(this);
};

 /**
  * function checks if the string passed contains any characters that
  * are forbidden in URLs and tries to create a java.net.URL from it
  * FIXME: probably deprecated -> helma.Url
  * @return Boolean
  * @see helma.Url.PATTERN
  */
 String.prototype.isUrl = function() {
     if (String.URLPATTERN.test(this))
         return true;
     else
     	return false;
 };
 
 /**
  * function returns true if the string contains
  * only a-z and 0-9 (case insensitive!)
  * @return Boolean true in case string is alpha, false otherwise
  */
 String.prototype.isAlphanumeric = function() {
     if (!this.length)
         return false;
     return !String.ANUMPATTERN.test(this);
};

 /**
  * function returns true if the string contains
  * only a-z, A-Z, 0-9, starts with a letter, ends with a letter
  * and can contain an underscore or period as long as its not
  * they arent the first or last character 
  *
  * @return Boolean true in case string is a valid EMail User, false otherwise
  */
 String.prototype.isEmailUser = function() {
     if (!this.length)
         return false;
     return !String.EMAILUSER.test(this);
};

 /**
  * function returns true if the string contains
  * only a-z, A-Z, 0-9, starts with a letter, ends with a letter
  * and can contain underscores as long as its not
  * the first or last character 
  *
  * @return Boolean true in case string is a valid EMail User, false otherwise
  */
 String.prototype.isEmailSLD = function() {
     if (!this.length)
         return false;
     return !String.EMAILSLD.test(this);
};

/**
 * function returns true if the string contains
 * only 0-9
 * @return Boolean true in case string is numeric, false otherwise
 */
String.prototype.isNumeric = function() {
    if (!this.length)
        return false;
    return !String.NUMPATTERN.test(this);
};

/**
 * function returns true if the string contains
 * only 0-9, a-z, A-Z and several other allowed patterns
 * @return Boolean true in case string is numeric, false otherwise
 */
String.prototype.isPrint = function() {
    if (!this.length)
        return false;
    return !String.PRINTPATTERN.test(this);
};


/**
 * function returns true if the string starts with
 * the string passed as argument
 * @param String string pattern to search for
 * @return Boolean true in case it matches the beginning
 *            of the string, false otherwise
 */
String.prototype.startsWith = function(str, offset) {
    var javaObj = new java.lang.String(this);
    if (offset != null)
        return javaObj.startsWith(str, offset);
    return javaObj.startsWith(str);
};


/**
 * function returns true if the string ends with
 * the string passed as argument
 * @param String string pattern to search for
 * @return Boolean true in case it matches the end of
 *            the string, false otherwise
 */
String.prototype.endsWith = function(str) {
    var javaObj = new java.lang.String(this);
    return javaObj.endsWith(str);
};

/**
 * fills a string with another string up to a desired length
 * @param String the filling string
 * @param Number the desired length of the resulting string
 * @param Number the direction which the string will be padded in:
 *                    -1: left    0: both (balance)  1: right
 *                    (you can use the constants String.LEFT,
 *                     String.BALANCE and String.RIGHT here as well.)
 * @return String the resulting string
 */
String.prototype.pad = function(str, len, mode) {
    if (str  == null || len == null)
        return this;
    var diff = len - this.length;
    if (diff == 0)
        return this;
    var left, right = 0;
    if (mode == null || mode == String.RIGHT)
        right = diff;
    else if (mode == String.LEFT)
        left = diff;
    else if (mode == String.BALANCE) {
        right = Math.round(diff / 2);
        left = diff - right;
    }
    res.push();
    for (var i=0; i<left; i++)
        res.write(str);
    res.write(this);
    for (var i=0; i<right; i++)
        res.write(str);
    return res.pop();
};


/**
 * function returns true if a string contains the string
 * passed as argument
 * @param String string to search for
 * @param Int Position to start search
 * @param Boolean
 */
String.prototype.contains = function(str, fromIndex) {
    if (this.indexOf(str, fromIndex ? fromIndex : 0) > -1)
        return true;
    return false;
};

/**
 * remove leading and trailing whitespace
 */
String.prototype.trim = function () {
    var s = new java.lang.String(this);
    return String(s.trim());
};


/**
 * returns true if the string looks like an e-mail
 */
String.prototype.isEmail = function() {
    return String.EMAILPATTERN.test(this);
};

/**
 * returns the amount of occurences of one string in another
 */
String.prototype.count = function(str) {
    var count = 0;
    var offset = 0;
    while ((offset = this.indexOf(str, offset)) > -1) {
        count += 1;
        offset += 1;
    }
    return count;
};

/**
 * creates a random string (numbers and chars)
 * @param len length of key
 * @param mode determines which letters to use. null or 0 = all letters;
 *      1 = skip 0, 1, l and o which can easily be mixed with numbers;
 *      2 = use numbers only
 * @returns random string
 */
String.random = function(len, mode) {
    if (mode == 2) {
        var x = Math.random() * Math.pow(10,len);
        return Math.floor(x);
    }
    var keystr = String.NULL;
    for (var i=0; i<len; i++) {
        var x = Math.floor((Math.random() * 36));
        if (mode == 1) {
            // skip 0,1
            x = (x<2) ? x + 2 : x;
            // don't use the letters l (charCode 21+87) and o (24+87)
            x = (x==21) ? 22 : x;
            x = (x==24) ? 25 : x;
        }
        if (x<10) {
            keystr += String(x);
        }    else    {
            keystr += String.fromCharCode(x+87);
        }
    }
    return keystr;
};