var Punct = {
  oSrc : Object,
  aDest : Array,
  bPTag : Object,
  init : function(oSrc, aDest, bPTag) {
    if ((oSrc.nodeName.toLowerCase() != 'textarea' && oSrc.type.toLowerCase() != 'text') || bPTag.type.toLowerCase() != 'checkbox') {
      alert('Unable to initialise Punct\n\nSource is not an input or a textarea or "Add <p> tags" is not a checkbox!');
      return;
    }
    this.oSrc = oSrc;
    this.aDest = aDest;
    this.bPTag = bPTag;
  },
  event : function() {
    oSrc = Punct.oSrc;
    aDest = Punct.aDest;
    bPTag = Punct.bPTag;
    
    sConv = oSrc.value;
    sConv = Punct.encode(sConv, bPTag.checked);
    
    for (i=0;i<aDest.length;i++) {
      if (aDest[i].nodeName.toLowerCase() == 'textarea' || aDest[i].nodeName.toLowerCase() == 'input')
      {
        aDest[i].value = sConv;
      }
      else
      {
        // I'm using innerHTML here because it saves A LOT
        // of stress. I know you'll hate this Stuart (http://www.muffinresearch.co.uk)
        // but Jonathan Snook said it was sexy! (http://domscripting.com/blog/display/35)
        aDest[i].innerHTML = sConv;
      }
    }
  },
  encode : function(sConv, bPTag) {
    return (bPTag) ? this.insertP(this.stripwhitespace(this.punctuate(sConv))) : this.punctuate(sConv);
  },
  stripwhitespace : function(sConv) {
    sConv = sConv.replace(/(\r|\n|\r\n|^)\s*?(\S)/g,'$1$2');
    sConv = sConv.replace(/(\S)\s*?(\r|\n|\r\n|$)/g,'$1$2');
    sConv = sConv.replace(/(\r|\n|\r\n|^)(\s*)(\r|\n|\r\n|$)/g,'$1$3');
    
    return sConv;
  },
  punctuate : function(sConv) {
    sConv = sConv.replace(/&amp;/g, "&");
    sConv = sConv.replace(/&#039;/g, "'");
    sConv = sConv.replace(/&apos;/g, "'");
    sConv = sConv.replace(/&quot;/g, "\"");
    
    sConv = sConv.replace(/\u00A9/g, "&copy;");
    sConv = sConv.replace(/\u00AE/g, "&#174;");
    sConv = sConv.replace(/\u2122/g, "&#8482;");
    sConv = sConv.replace(/\u00A3/g, "&pound;");
    sConv = sConv.replace(/</g, "&lt;");
    sConv = sConv.replace(/>/g, "&gt;");
    sConv = sConv.replace(/&mdash;|--|\u2014/g, "&#8212;");
    sConv = sConv.replace(/&ndash;|\u2013/g, "&#8211;");
    sConv = sConv.replace(/\.\.\.|\u2026|&hellip;/g, "&#8230;");
    sConv = sConv.replace(/(\s|^)(\u0026|&)(\s|$)/g, "$1&amp;$3");
    
    sConv = sConv.replace(/(\s|^|\(|\{|\[)('|\u2018)/g, "$1&#8216;");
    sConv = sConv.replace(/('|\u2019)(\s|$|\)|\}|\])/g, "&#8217;$2");
    sConv = sConv.replace(/(\S)('|\u2019)(\S)/g, "$1&#8217;$3");
    sConv = sConv.replace(/(\s|^|\(|\{|\[)("|\u201C)/g, "$1&#8220;");
    sConv = sConv.replace(/("|\u201D)(\s|$|\)|\}|\])/g, "&#8221;$2");
    
    return sConv;
  },
  insertP : function(sConv) {
    sConv = sConv.replace(/(\r|\n|\r\n|^)(\S)/g,'$1<p>$2');
    sConv = sConv.replace(/(\S)(\r|\n|\r\n|$)/g,'$1</p>$2');
    
    return sConv;
  }
}