function notempty(str) { return (''+str != ""); }

function lengthAtLeast(num) {
  return function (str) { return num <= (''+str).length; }
}

function lengthLessThan(num) {
  return function (str) { return (''+str).length < num; }
}

function filenameShorterThan(num) {
  return function (path) {
    path=path.replace(/\\/g,'/').split('/');
    return path[path.length-1].length < num;
  }
}

function isNumber(str) {
  return !isNaN(Number(''+str));
}

function isNumberAtLeast(num) {
  return function (str) {
           var val = Number(''+str);
           return !isNaN(val) && num <= val;
         }
}

function isNumberLessThan(num) {
  return function (str) {
           var val = Number(''+str);
           return !isNaN(val) && val < num;
         }
}

function isEqual(str1) {
  return function (str2) { return (str1 == str2); }
}

function isNotEqual(str1) {
  return function (str2) { return (str1 != str2); }
}

RegExp.host = /(\d{1,3}(\.\d{1,3}){3}|([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z]([a-z0-9-]*[a-z0-9])?)/i;

RegExp.mailuser = /[^\0-\x20\x7f-\xff()\[\]<>@,:;\\"\.]+(\.[^\0-\x20\x7f-\xff()\[\]<>@,:;\\"\.]+)*/i;

function isEmail(email) {
  /* rfc822 email address with following restrinctions:
      NO quoted-strings in username
      ONLY hosts conforming to rfc1738 hostname|ipnumber syntax.
  */
  isEmail.INIT();
  return isEmail.PAT.test(''+email);
}

isEmail.INIT = function () {
  isEmail.PAT = new RegExp();
  with(RegExp) 
    isEmail.PAT.compile('^'+mailuser.source+'@'+host.source+'$','i');
  isEmail.INIT = function () {};
}

function isURL (url,allowunknown) {
  if((/[\0-\x1f "<>[\\\]^`{|}\x7f-\xff]/).test(url) ||  //illegal characters
     !(/^([^%]*(%[0-9a-f]{2}[^%]*)*)$/i).test(url)      // bare %
    ) return false;
  url = url.split('#')[0];
  var pr = (/^([a-z0-9.+-]+):/i).exec(url);
  if(!pr) return false                                // missing scheme;
  var scheme = pr[1].toLowerCase();
  url = url.substr(pr[0].length)
  if(isURL[scheme]) return !!isURL[scheme](url);
  if(allowunknown) !!isURL._generic(url);
  //try generic
  return false;
}

isURL._generic = function (url) {
  var pr = (/^\/\/([^\/]*)(\/([^?\/;][^?;]*)?((;[^?;]*)+)?(\?.*)?)?$/).exec(url);
  if(!pr) return null;
  var res = { path: pr[3], params: pr[4], query: pr[6] }
  var host = pr[1];
  pr = (/^[^\/:@]*(:[^\/:@]*)?@/).exec(host);
  if(pr) { res.login = pr[0]; host = host.substr(pr[0].length); }
  if(!isURL._isHost(host)) return null;
  res.host = host;
  return res;
}

isURL._isHost = function (host) {
  return (/^\d{1,3}(\.\d{1,3}){3}(:\d+)?$/).test(host) ||
    (/^([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z]([a-z0-9-]*[a-z0-9])?(:\d+)?$/i).test(host);
}

isURL.ftp = function (url) {
  var pr = isURL._generic(url);
  if(!pr || pr.query) return false;
  return !pr.params || (/^;type=[aid]$/i).test(pr.params);
}

isURL.file = function (url) { 
/* useless, since we insist on a network location (other than 'localhost') */
  var pr = isURL._generic(url);
  return !!pr && !pr.login && !pr.params && !pr.query;
}

isURL.http = function (url) {
  var pr = isURL._generic(url);
  return !!pr && !pr.params && !pr.login;
}

isURL.gopher = function (url) {
  var pr = (/^\/\/([^\/]*)(\/([^?\/;][^?;]*)?((;[^?;]*)+)?(\?.*)?)?$/).exec(url);
  if(!pr) return null;
  var res = { path: pr[3], params: pr[4], query: pr[6] }
  var host = pr[1];
  pr = (/^[^\/:@]*(:[^\/:@]*)?@/).exec(host);
  if(pr) { res.login = pr[0]; host = host.substr(pr[0].length); }
  if(!isURL._isHost(host)) return null;
  res.host = host;
  return res;
}

isURL.wais = function (url) {
  var pr = (/^\/\/([^\/]*)(\/([^?\/;][^?;]*)?((;[^?;]*)+)?(\?.*)?)?$/).exec(url);
  if(!pr) return null;
  var res = { path: pr[3], params: pr[4], query: pr[6] }
  var host = pr[1];
  pr = (/^[^\/:@]*(:[^\/:@]*)?@/).exec(host);
  if(pr) { res.login = pr[0]; host = host.substr(pr[0].length); }
  if(!isURL._isHost(host)) return null;
  res.host = host;
  return res;
}

isURL.prospero = function (url) {
  var pr = (/^\/\/([^\/]*)(\/([^?\/;][^?;]*)?((;[^?;]*)+)?(\?.*)?)?$/).exec(url);
  if(!pr) return null;
  var res = { path: pr[3], params: pr[4], query: pr[6] }
  var host = pr[1];
  pr = (/^[^\/:@]*(:[^\/:@]*)?@/).exec(host);
  if(pr) { res.login = pr[0]; host = host.substr(pr[0].length); }
  if(!isURL._isHost(host)) return null;
  res.host = host;
  return res;
}

isURL.mailto = function (url) {
  var addrs = url.split('?')[0];
  var pr = (/(\?|&)to=([^&]*)/i).exec(url);
  if(pr) addrs += ','+pr[2];
  addrs = addrs.replace(/%2c/gi,',').split(',');
  for(var i = 0; i < addrs.length; i++) 
    if(addrs[i] && !isEmail(addrs[i])) return false;
  return true;
}

isURL.news = function (url) {
  if((/^(\*|[a-z][a-z0-9_.+-]*)$/i).test(url)) return true;
  var pr = (/@(.*)$/).exec(url);
  return !!pr && isURL._isHost(pr[1]);
}

isURL.nntp = function (url) {
  var pr = isURL._generic(url);
  if(!pr || pr.login || pr.params || pr.query) return false;
  return (/^[a-z][a-z0-9_.+-]*(\/\d+)?$/i).test(pr.path);
}

isURL.telnet = function (url) {
  var pr = isURL._generic(url);
  return !!pr && !pr.path && !pr.params && !pr.query;
}

function isAlpha(str) {
  return (/^[a-z]*$/i).test(''+str);
}

function isMobilePhone(str) {
  return (/0\d{9}/).test(''+str);
}

function fromAlphabet(charset) {
  charset = charset.replace(/(\])/g,'\\$1');
  return function(str) {
    return (new RegExp('^['+charset+']*$')).test(''+str);
  }
}

function isGuid(str) {
  return (/^\{?[0-9A-F]{8}(-[0-9A-F]{4}){3}-[0-9A-F]{12}\}?$/i).test(''+str);
}

String.prototype.reverse = function () {
  return (this.length < 2)? this: 
          this.substr(1).reverse() + this.charAt(0);
}

String.prototype.contains = function (str) {
  return this.indexOf(str) >= 0 || this.indexOf(str.reverse()) >= 0;
}

function wfPassword (pwrd) {
   pwrd += '';
   alphas = pwrd.replace(/[^a-z]+/ig,'').length;
   return (/^(\w|-){8,16}$/).test(pwrd) &&
          2 <= alphas && alphas < pwrd.length;
}

function wfPasswordFor(user) {
  user = (''+user).toLowerCase();
  return function (pwrd) { 
           if(!wfPassword(pwrd)) return false;
           return (pwrd.length < user.length)? 
                    !user.contains(pwrd.toLowerCase()):
                    !pwrd.toLowerCase().contains(user);
         }
}

function isPostalCode(str) {
  return (/\d{4}[a-z]{2}/i).test(''+str)
}

function complain (complaint) {
  alert(complaint); return false;
}

function checkfield(inp,ok,warn) {
  var str =  inp.value.replace(/^\s+/,'').replace(/\s+$/,''); //trim leading & trailing spaces.
  if(inp.type != 'file') inp.value = str; 
  if(ok(str)) return true;                // process inputstring with the provided 'ok'-method.
  if(warn) alert(warn);
  var re = /^(button|checkbox|file|image|password|radio|reset|submit|text\w*)$/;
  if (inp.type.match(re)) inp.focus();
  return false
}

