// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults

function boxChecked(id) {
  return $(id).checked == "1";
}

function callFunctionOnReturn(formElementID, enterFunction) {
  Event.observe(formElementID, 'keypress', function(e) {
    if (e.keyCode == Event.KEY_RETURN) {
      enterFunction();
      Event.stop(e);
      return false;
    }
  });
}

var _staticImgFormat = null;
var staticImgFormat = function() {
  return _staticImgFormat ||
    (_staticImgFormat = 
      ((BrowserDetect.browser == 'Explorer') &&
       (BrowserDetect.version < 7)) ? 'gif' : 'png');
}

String.prototype.trim=function(){
  return this.replace(/^\s*|\s*$/g,'');
}

String.prototype.ltrim=function(){
  return this.replace(/^\s*/g,'');
}

String.prototype.rtrim=function(){
  return this.replace(/\s*$/g,'');

}

String.prototype.hasText=function(){ 
  return this.trim().length > 0;
}

String.prototype.linkify=function(){
  return this.replace(/(^|\s)(www\.\S\S+)/g,"$1<a href=\"http://$2\" target=\"_blank\">$2</a>").replace(/(^|\s)(https?:\/\/\S\S+)/g, "$1<a href=\"$2\" target=\"_blank\">$2</a>");
}

String.prototype.newlinesToBR=function(){
  return this.replace(
    /\n|\r|\r\n|\\u2028/g, "<br />"
  ).replace(
    /\\u2029/, '<br /><br />'
  );
}

String.prototype.escapeJS=function(){
 return this.replace(/\'/g, "\\'")
}

var EMOTICON_MAP = {
  smile: /:-?\)/g,
  sad: /:-?\(/g,
  wink: /;-?\)/g
}

var DIM_ATTRS = 'width="15" height="15"'

String.prototype.emotify=function(){
  var s = this;
  for (var emote in EMOTICON_MAP) {
    s = s.replace(EMOTICON_MAP[emote], '<img src="/images/grey_smileys/icon_' + emote + '.gif" ' + DIM_ATTRS + ' class="smileys" />')
  }
  return s;
}

function atOrNearBottom(textAreaID, scrollMargin){
  var ta = $(textAreaID);
  return (ta.scrollTop > (ta.scrollHeight - ta.offsetHeight) - scrollMargin);
}

function scrollToBottom(textAreaID){
  with ($(textAreaID)) {
    scrollTop = scrollHeight;
  }
}

function preloadImages(image_urls) {
  if (!iePre7()) {
    console.log('beginning image preload');
      image_urls.each(preloadImage);
    console.log('ending image preload');
  }
}

function preloadImage(url) {
  (new Image()).src = url;
}

function imgPath(pathSuffix, format) {
  var format = format || staticImgFormat();
  return imgRoot + pathSuffix + '.' + format;
}

function imgURL(pathSuffix) {
    return "url('"+imgPath(pathSuffix)+"')";
}

function removeElementIfExists(id) {
  if ($(id) != undefined) {
    $(id).parentNode.removeChild($(id))
  }
}

var toPreload = [];

function iePre7() {
  return ((BrowserDetect.browser == 'Explorer') &&
          (BrowserDetect.version < 7.0));
}

var BrowserDetect = {
  init: function () {
    this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
    this.version = this.searchVersion(navigator.userAgent)
      || this.searchVersion(navigator.appVersion)
      || "an unknown version";
    this.OS = this.searchString(this.dataOS) || "an unknown OS";
  },
  searchString: function (data) {
    for (var i=0;i<data.length;i++)  {
      var dataString = data[i].string;
      var dataProp = data[i].prop;
      this.versionSearchString = data[i].versionSearch || data[i].identity;
      if (dataString) {
        if (dataString.indexOf(data[i].subString) != -1)
          return data[i].identity;
      }
      else if (dataProp)
        return data[i].identity;
    }
  },
  searchVersion: function (dataString) {
    var index = dataString.indexOf(this.versionSearchString);
    if (index == -1) return;
    return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
  },
  dataBrowser: [
    {   string: navigator.userAgent,
      subString: "OmniWeb",
      versionSearch: "OmniWeb/",
      identity: "OmniWeb"
    },
    {
      string: navigator.vendor,
      subString: "Apple",
      identity: "Safari"
    },
    {
      prop: window.opera,
      identity: "Opera"
    },
    {
      string: navigator.vendor,
      subString: "iCab",
      identity: "iCab"
    },
    {
      string: navigator.vendor,
      subString: "KDE",
      identity: "Konqueror"
    },
    {
      string: navigator.userAgent,
      subString: "Firefox",
      identity: "Firefox"
    },
    {
      string: navigator.vendor,
      subString: "Camino",
      identity: "Camino"
    },
    {    // for newer Netscapes (6+)
      string: navigator.userAgent,
      subString: "Netscape",
      identity: "Netscape"
    },
    {
      string: navigator.userAgent,
      subString: "MSIE",
      identity: "Explorer",
      versionSearch: "MSIE"
    },
    {
      string: navigator.userAgent,
      subString: "Gecko",
      identity: "Mozilla",
      versionSearch: "rv"
    },
    {     // for older Netscapes (4-)
      string: navigator.userAgent,
      subString: "Mozilla",
      identity: "Netscape",
      versionSearch: "Mozilla"
    }
  ],
  dataOS : [
    {
      string: navigator.platform,
      subString: "Win",
      identity: "Windows"
    },
    {
      string: navigator.platform,
      subString: "Mac",
      identity: "Mac"
    },
    {
      string: navigator.platform,
      subString: "Linux",
      identity: "Linux"
    }
  ]
};
BrowserDetect.init();

function getWordFromEvent(evt) {
  if (document.body && document.body.createTextRange) {
    var range = document.body.createTextRange();
    range.moveToPoint(evt.clientX, evt.clientY);
    range.expand('word');
    return range.text;
  }
  else if (evt.rangeParent && document.createRange) {
    var range = document.createRange();
    range.setStart(evt.rangeParent, evt.rangeOffset);
    range.setEnd(evt.rangeParent, evt.rangeOffset);
    expandRangeToWord(range);
    var word = range.toString();
    range.detach();
    return word;    
  }
  else {
    return null;
  }
}

/* The implementation below of expandRangeToWord is not meant to be a complete
   implementation of the functionality to expand a range to a word, with W3C DOM
   ranges allowing different types of start/endContainer and the offset being
   a text offset or a node offset depending on the container node type it would
   take more than the few lines below to have a complete implementation.
   So this function is here to demonstrate within this test case that finding a
   word from an event is possible but if you want to use it in complex cases you
   need a better implementation of expandRangeToWord as the one below can throw
   errors.
   Also the current implementation considers any \S+ between \s and \s a 'word',
   your aim when finding a word might differ.
*/
function expandRangeToWord (range) {
  var startOfWord = /^\s\S+$/;
  var endOfWord = /^\S+\s$/;
  var whitespace = /^\s+$/;
  // if offset is inside whitespace
  range.setStart(range.startContainer, range.startOffset - 1);
  while (whitespace.test(range.toString())) {
    range.setEnd(range.endContainer, range.endOffset + 1);
    range.setStart(range.startContainer, range.startOffset + 1);
  }
  while (!startOfWord.test(range.toString())) {
    range.setStart(range.startContainer, range.startOffset - 1);
  }
  range.setStart(range.startContainer, range.startOffset + 1);
  while (!endOfWord.test(range.toString())) {
    range.setEnd(range.endContainer, range.endOffset + 1);
  }
  range.setEnd(range.endContainer, range.endOffset - 1);
  return range.toString();
}
