Lingr.Text = {
  
  SimpleDecorators: $A([
    { regex: /\b(https?:\/\/(?:[-_.!~*'()a-z0-9;\/?:@=+\$,%#]|(?:(?!(?:&lt;)|(?:&gt;)|(?:&quot;)|(?:<))&?))+[-_!~*'()a-z0-9;\/?:@=+\$#])/ig,
      replacement: '<a href="$1" rel="nofollow" target="_blank">$1</a>' },
    { regex: /\b(www\.[-_.!~*'()a-z0-9;\/?:@&=+\$,%#]+[-_!~*'()a-z0-9;\/?:@=+\$#])/ig,
      replacement: '<a href="http://$1" rel="nofollow" target="_blank">$1</a>' }
  ]),
  
  ComplexDecorators: $A([
    { regex: /^(https?:\/\/[-_.!~*'()a-z0-9;\/?:@&=+\$,%#]+\.(?:jpe?g|gif|png)[-_.!~*'()a-z0-9;\/?:@&=+\$,%#]*)/i,
      replacement: '<a href="$1" rel="nofollow" class="decorated" onclick="return lingr.ui.showImageModeless(this)"><img src="$1" alt="$1" /></a>' },
    { regex: /^(https?:\/\/[-_.!~*'()a-z0-9;\/?:@&=+\$,%#]+\.(?:mp3))[-_.!~*'()a-z0-9;\/?:@&=+\$,%#]*/i,
      replacement: '<object width="400" height="19" class="mp3 decorated" type="application/x-shockwave-flash" data="/mediaplayer.swf?file=$1"><param name="movie" value="/mediaplayer.swf?file=$1" /><param name="wmode" value="opaque" /><param name="flashvars" value="width=400&height=20" /></object> <a href="$1" class="source" rel="nofollow">(MP3)</a>' },
    { regex: /^(https?:\/\/[-_.!~*'()a-z0-9;\/?:@&=+\$,%#]+\.(?:flv))[-_.!~*'()a-z0-9;\/?:@&=+\$,%#]*/i,
      replacement: '<object width="425" height="344" class="flv decorated" type="application/x-shockwave-flash" data="/mediaplayer.swf?file=$1"><param name="movie" value="/mediaplayer.swf?file=$1"/><param name="wmode" value="opaque"/><param name="allowfullscreen" value="true"/><param name="flashvars" value="width=320&height=240" /></object> <a href="$1" class="source" rel="nofollow">(video)</a>' },
    { regex: /^http:\/\/(?:.*\.)?youtube\.com\/watch\?v=([a-z0-9_-]+)[-_.!~*'()a-z0-9;\/?:@&=+\$,%#]*/i,
      replacement: '<object width="425" height="344" class="youtube decorated" type="application/x-shockwave-flash" data="http://www.youtube.com/v/$1"><param name="movie" value="http://www.youtube.com/v/$1" /><param name="wmode" value="transparent" /></object> <a href="" onclick="return lingr.ui.showVideoModeless(this)">(show in drawer)</a>' },
    { regex: /^http:\/\/(?:www\.)?vimeo\.com\/([0-9]+)[-_.!~*'()a-z0-9;\/?:@&=+\$,%#]*/i,
      replacement: '<object  width="425" height="344" class="vimeo decorated" type="application/x-shockwave-flash" data="http://www.vimeo.com/moogaloop.swf?clip_id=$1&amp;fullscreen=1"><param name="movie" value="http://www.vimeo.com/moogaloop.swf?clip_id=$1&amp;fullscreen=1"/><param name="wmode" value="transparent" /><param name="allowfullscreen" value="true" /></object>' },
    { regex: /^http:\/\/www\.facebook\.com\/video\/video.php\?v=([0-9]+)[-_.!~*'()a-z0-9;\/?:@&=+\$,%#]*/i,
      replacement: '<object width="425" height="344" class="facebook decorated" type="application/x-shockwave-flash" data="http://www.facebook.com/v/$1"><param name="movie" value="http://www.facebook.com/v/$1" /><param name="wmode" value="transparent" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /></object>' },
    { regex: /^(http:\/\/gist\.github\.com\/[0-9]+)/i,
      replacement: "<iframe width=\"100%\" onload=\"this.contentDocument.write('<scr'+'ipt src=$1.js></scr'+'ipt>')\"></iframe>" },
    { regex: /^(http:\/\/pastie\.org\/[0-9]+)/i,
      replacement: "<iframe width=\"100%\" onload=\"this.contentDocument.write('<scr'+'ipt src=$1.js></scr'+'ipt>')\"></iframe>" }
  ]),
  
  sanitize: function(str)
  {
    return str.replace(/&/g, "&amp;").replace(/\"/g, "&quot;").replace(/>/g, "&gt;").replace(/</g, "&lt;");
  },
  
  decorate: function(str) {
    return str.split('\n').collect(function(s) {
      var ret = s;
      var decorated = false;
      
      if (s.match(/^<iframe /)) { decorated = true; }
      if (s.match(/^<object /)) { decorated = true; }
      //if (s.match(/^<script /)) { decorated = true; }
      
      if (!decorated) {
        ret = this.sanitize(s); // Should always run
        
        Lingr.Text.ComplexDecorators.each(function(d) { 
          if (s.match(d.regex)) {
            ret = ret.replace(d.regex, d.replacement);
            decorated = true
            throw $break;
          }
        });
      }
      
      if (!decorated) {
        Lingr.Text.SimpleDecorators.each(function(d) { 
          if (s.match(d.regex)) {
            ret = ret.replace(d.regex, d.replacement);
            throw $break;
          }
        });
      }
      
      return ret;
    }.bind(this)).join('</p><p>');
  },
  
  pluralize: function(count, singular, plural) {
    return count + ' ' + (count > 1 ? (plural || (singular + 's')) : singular);
  }
};