/**
 * My father has a habit of posting comments in all uppercase letters on my
 * blog, so I have written a few scripts to put his abuse of the caps lock key
 * in check:
 *
 * (1) needs_formatting() checks if the comment needs to be reformatted
 * (2) format(str) reformats the string
 * (3) is_alpha(char) checks if the one-character string is a letter
 * (4) is_upper(char) checks if the one-character string is an uppercase letter
 *
 * Michael Bolin
 * http://www.bolinfest.com/india04/
 *
 * KNOWN ISSUES:
 *
 * (1) This script may not work if characters in the string have been escaped.
 *
 * This code may be copied and used freely so long as
 * the doc comments remain unchanged.
 */

/**
 * If the fraction of the letters that are capitalized in a string meets
 * or exceeds UPPERCASE_THRESHOLD, then needs_formatting() will return true for
 * for that string.
 */
UPPERCASE_THRESHOLD = 0.80;

/**
 * Returns true if the string has too many capital letters
 * and should be reformatted.
 */
function needs_formatting(str) {
  str = String(str); // may be a char
  strlen = str.length;
  alpha_count = 0;
  upper_count = 0;
  for (var i = 0; i < strlen; i++) {
    ch = str.charAt(i);
    if (is_alpha(ch)) {
      alpha_count++;
      if (is_upper(ch)) {
        upper_count++;
      }
    }
  }
  return (upper_count / (alpha_count)) >= UPPERCASE_THRESHOLD;
}

/**
 * Returns the string as all lowercase letters, except for what it
 * perceives to be the first letter of a sentence. It thinks that the
 * first letter of a sentence is the first alphabetic character of the
 * string, OR the first alphabetic character following a period,
 * question mark, or exclamation point.
 */
function format(str) {
  str = String(str); // may be a char
  strlen = str.length;
  newstr = '';
  capitalizeNextChar = true;
  for (var i = 0; i < strlen; i++) {
    ch = String(str.charAt(i));
    if (!is_alpha(ch)) {
      newstr += ch;
      if (ch == "." || ch == "?" || ch == "!") {
        capitalizeNextChar = true;
      }
    } else if (capitalizeNextChar) {
      ch = ch.toUpperCase();
      newstr += ch;
      capitalizeNextChar = false;
    } else {
      ch = ch.toLowerCase();
      newstr += ch;
    }
  }
  return newstr;
}

/**
 * Returns a boolean indicating if the first character of the string is
 * a letter.
 */
function is_alpha(str) {
  str = String(str); // may be a char
  code = str.charCodeAt(0);
  return (((65 <= code) && (code <= 90)) || ((97 <= code) && (code <= 122)));
}

/**
 * Returns a boolean indicating if the first character of the string is
 * an uppercase letter.
 */
function is_upper(str) {
  str = String(str); // may be a char
  code = str.charCodeAt(0);
  return ((65 <= code) && (code <= 90));
}
