if(!tc){ var tc = {}; }
  
  if (!String.prototype.trim) {
    String.prototype.trim = function() {
    	return this.replace(/^\s+|\s+$/g,"");
    }
  }
  if (!String.prototype.ltrim) {
    String.prototype.ltrim = function() {
    	return this.replace(/^\s+/,"");
    }
  }
  if (!String.prototype.rtrim) {
    String.prototype.rtrim = function() {
    	return this.replace(/\s+$/,"");
    }
  }
  
  if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(obj, start) {
       for (var i = (start || 0), j = this.length; i < j; i++) {
           if (this[i] == obj) { return i; }
       }
       return -1;
     }
   }
  
  tc.glossary = function(app,options){
    var _me;
    _me = this;
    
    _me.terms = null;
    
    _me.preceding_chars = [
      " ",
      "(",
      ">"
    ];
    
    _me.following_chars = [
      " ",
      ",",
      "."
    ];
    
    _me.suffix_chars = [
      's',
      'es'
    ];
    
    this.initialize = function(){
      tc.util.log('glossary.initialize');
      _me.gather_terms();
      _me.create_links();
      return _me;
    }
    
    this.gather_terms = function(){
      var terms, sorted_terms, termNodes, i;
      terms = {};
      sorted_terms = [];
      termNodes = app.dom.all('.glossary-term');
      termNodes.each(function(node,index,list){
        sorted_terms.push(node.one('.definition-term')._node.innerHTML.trim());
        terms[node.one('.definition-term')._node.innerHTML.trim()] = {
          anchor:node.get('id'),
          body:node.one('.definition-body')
        }
      });
      sorted_terms.sort(function(a, b){
        return b.length - a.length;
      });
      _me.sorted_terms = sorted_terms;
      _me.terms = terms;
      return terms;
    }
    
    this.create_links = function(){
      var i, term, j, search_term, regex, start, end, myword, k;
      for(i in _me.terms){
        term = i;
        mytext = "".concat(_me.terms[term].body._node.innerHTML.trim());
        for(j in _me.sorted_terms){
          
          if(_me.sorted_terms[j] == term || !_me.sorted_terms[j] || typeof(_me.sorted_terms[j]) != 'string'){ continue; }
          
          search_term = _me.sorted_terms[j].toLowerCase();
          search_term = search_term.replace('(','').replace(')','');
          
          regex = new RegExp(search_term,'i');
          start = mytext.search(regex);
          
          if(start > -1){
            end = start + search_term.length;
            for(k = 0; k < _me.suffix_chars.length; k++){
              
              if(mytext.substr(end, _me.suffix_chars[k].length) === _me.suffix_chars[k]){
                end = end + _me.suffix_chars[k].length;
                regex = new RegExp(search_term.toLowerCase()+_me.suffix_chars[k],'i');
              }
            }
            
            myword = mytext.substring(start,end);
            
            if(_me.preceding_chars.indexOf(mytext.charAt(start-1)) > -1){
              mytext = mytext.replace(regex,'<a href="#'+_me.terms[_me.sorted_terms[j]].anchor+'">'+myword+'</a>');
            }
            
          }
        }
        _me.terms[term].body._node.innerHTML = mytext;
      }
    }
    
    return this.initialize();
  }
