/** Cache of regEx objects */
var regExCache=new Object();


/**
 *
 * Create regEx object
 *
 * @param pm_Rex Regular expression
 * @param pm_Flg Regular expression flags (optional)
 *
 * @return RegEx object
 *
 */

function regExGet(pm_Rex,pm_Flg) {
  var lv_Flg=pm_Flg?pm_Flg:"";
  var lv_Cod="f_"+lv_Flg;
  if (!regExCache[lv_Cod]) {
    regExCache[lv_Cod]=new Object();
  }
  if (!regExCache[lv_Cod][pm_Rex]) {
    regExCache[lv_Cod][pm_Rex]=new RegExp(pm_Rex, lv_Flg);
  }
  return regExCache[lv_Cod][pm_Rex];
}


/**
 *
 * Create case insensitive regEx object
 *
 * @param pm_Rex Regular expression
 *
 * @return RegEx object
 *
 */

function regExGetIcase(pm_Rex) {
  return regExGet(pm_Rex,"i");
}


/**
 *
 * Test whether regular expression matches string
 *
 * @param pm_Str String to test
 * @param pm_Rex Regular expression
 * @param pm_Flg Regular expression flags (optional)
 *
 * @return Whether regular expression matches string
 *
 */

function regExTest(pm_Str,pm_Rex,pm_Flg) {
  var lv_Flg=pm_Flg?pm_Flg:"";
  var lv_RegExp=regExGet(pm_Rex, lv_Flg);
  return lv_RegExp.test(pm_Str);
}


/**
 *
 * Test whether regular expression matches string (case insensitive)
 *
 * @param pm_Str String to test
 * @param pm_Rex Regular expression
 *
 * @return Whether regular expression matches string (case insensitive)
 *
 */

function regExTestIcase(pm_Str,pm_Rex) {
  return regExTest(pm_Str, pm_Rex, "i");
}


/**
 *
 * Replace each match of regular expression by replacement string
 *
 * @param pm_Str String to test
 * @param pm_Fnd Regular expression
 * @param pm_Rpl Replacement string
 * @param pm_Flg Regular expression flags (optional)
 * @param pm_Sng Whether only first match should be replace (optional)
 *
 * @return String with each match of regular expression replaced
 *         by replacement string
 *
 */

function regExReplace(pm_Str,pm_Fnd,pm_Rpl,pm_Flg,pm_Sng) {
  var lv_Flg=pm_Flg?pm_Flg:"";
  var lv_RegExp=regExGet(pm_Fnd, lv_Flg);

  var lv_Str=pm_Str;
  var lv_Rtv="";
  var lv_Arr=lv_Str.length==0?null:lv_RegExp.exec(lv_Str);
  var lv_Ind=0;
  var lv_Rpl;

  while (lv_Arr!=null) {
    if (lv_Arr[0].length>0) {
      lv_Ind=RegExp.index;
      lv_Rpl=pm_Rpl;
      while (lv_Rpl.indexOf("$0") >= 0) {
        lv_Rpl=lv_Rpl.replace("$0",lv_Arr[0]);
      }
      for (var i=1;i<=9;i++) {
        while (lv_Rpl.indexOf("$"+i) >= 0) {
          lv_Rpl=lv_Rpl.replace("$"+i,eval("RegExp.$"+i));
        }
      }
      lv_Rtv+=lv_Str.substring(0,lv_Ind)+lv_Rpl;
      lv_Str=lv_Str.substring(lv_Ind+lv_Arr[0].length,lv_Str.length);
    }
    else {
      lv_Rtv+=lv_Str.charAt(0);
      lv_Str=lv_Str.substring(1,lv_Str.length);
    }
    lv_Arr=(pm_Sng||lv_Str.length==0)?null:lv_RegExp.exec(lv_Str);
  }
  return lv_Rtv+lv_Str;
}


/**
 *
 * Replace each match of regular expression by replacement string
 * (case insensitive)
 *
 * @param pm_Str String to test
 * @param pm_Rex Regular expression
 * @param pm_Rpl Replacement string
 *
 * @return String with each match of regular expression replaced
 *         by replacement string (case insensitive)
 *
 */

function regExReplaceIcase(pm_Str,pm_Fnd,pm_Rpl) {
  return regExReplace(pm_Str,pm_Fnd,pm_Rpl,"i");
}


/**
 *
 * Replace first match of regular expression by replacement string
 *
 * @param pm_Str String to test
 * @param pm_Rex Regular expression
 * @param pm_Rpl Replacement string
 *
 * @return String with each match of regular expression replaced
 *         by replacement string (case insensitive)
 *
 */

function regExReplaceSingle(pm_Str,pm_Fnd,pm_Rpl) {
  return regExReplace(pm_Str,pm_Fnd,pm_Rpl,"",true);
}


/**
 *
 * Replace first match of regular expression by replacement string
 * (case insensitive)
 *
 * @param pm_Str String to test
 * @param pm_Rex Regular expression
 * @param pm_Rpl Replacement string
 *
 * @return String with each match of regular expression replaced
 *         by replacement string (case insensitive)
 *
 */

function regExReplaceSingleIcase(pm_Str,pm_Fnd,pm_Rpl) {
  return regExReplace(pm_Str,pm_Fnd,pm_Rpl,"i",true);
}


/**
 *
 * Replace each match of search string by replacement string
 *
 * @param pm_Str String to test
 * @param pm_Fnd Regular expression
 * @param pm_Rpl Replacement string
 * @param pm_Sng Whether only first match should be replace (optional)
 *
 * @return String with each match of search string replaced
 *         by replacement string
 *
 */

function regExSubstitute(pm_Str,pm_Fnd,pm_Rpl,pm_Sng) {
   var lv_Str=""+pm_Str;
   var lv_Rtv="";
   var lv_Ind=lv_Str.indexOf(pm_Fnd);
   while (lv_Ind>=0) {
      lv_Rtv+=lv_Str.substring(0,lv_Ind)+pm_Rpl;
      lv_Str=lv_Str.substring(lv_Ind+pm_Fnd.length,lv_Str.length);
      lv_Ind=pm_Sng?-1:lv_Str.indexOf(pm_Fnd);
   }
   return lv_Rtv+lv_Str;
}


/**
 *
 * Replace first match of search string by replacement string
 *
 * @param pm_Str String to test
 * @param pm_Fnd Regular expression
 * @param pm_Rpl Replacement string
 *
 * @return String with first match of search string replaced
 *         by replacement string
 *
 */

function regExSubstituteSingle(pm_Str,pm_Fnd,pm_Rpl) {
  return regExSubstitute(pm_Str,pm_Fnd,pm_Rpl,true);
}


/**
 *
 * Get index of pattern pm_Val in array pm_Arr
 *
 * @param pm_Arr Array to search
 * @param pm_Val Value to find
 * @param pm_Flg Regular expression flags (optional)
 *
 * @return Index of pattern or -1
 *
 */

function regExGetIndex(pm_Arr,pm_Val,pm_Flg) {
  var lv_Flg=pm_Flg?pm_Flg:"";
  var lv_Ind;
  var lv_RegExp=new RegExp("^"+pm_Val+"$",lv_Flg);
  for (lv_Ind=pm_Arr.length;lv_Ind-->0;) {
    if (lv_RegExp.exec(pm_Arr[lv_Ind])!=null) {
      break;
    }
  }
  return lv_Ind;
}


/**
 *
 * Get index of value pm_Val in pattern array pm_Arr (case insensitive)
 *
 * @param pm_Arr Array to search
 * @param pm_Val Value to find
 *
 * @return Index of value or -1
 *
 */

function regExGetIndexIcase(pm_Arr,pm_Val) {
  return regExGetIndex(pm_Arr,pm_Val,"i");
}

