// Copyright 2006 37signals <info@37signals.com>
// This file is part of Campfire <http://campfirenow.com/terms.html> and 
// may not be used outside of Campfire without express written permission.  

var Autolink = {
  Patterns: {
    url:   /((href=(?:'|")?)?(https?:\/\/|www\.)(\S+)(\/(?:\S+))?)//*'*/, 
    email: /([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/
  },
  
  Linkers: {
    url: function(string, tagOptions, replacement) {
      return Autolink.replaceURLs(string, function(url, extra) {
        var text = (replacement || Prototype.K)(url);
        return '<a href="' + url + '"' + 
          Autolink.htmlForTagOptions(tagOptions) + '>' + 
          text + '</a>' + extra;
      });
    },
    
    email: function(string, tagOptions, replacement) {
      replacement = replacement || Prototype.K;
      return string.gsub(Autolink.Patterns.email, function(match) {
        return '<a href="mailto:' + match[1] + '"' + 
          Autolink.htmlForTagOptions(tagOptions) + '>' +
          replacement(match[1]) + '</a>';
      });
    }
  },

  all: function(string, tagOptions, replacement) {
    for (var name in Autolink.Linkers)
      string = Autolink.Linkers[name](string, tagOptions, replacement);
    return string;
  },
  
  htmlForTagOptions: function(tagOptions) {
    return $H(tagOptions || {}).map(function(pair) {
      return pair.key + '="' + pair.value + '"';
    }).join(' ');
  },
  
  replaceURLs: function(string, replacement) {
    var extra = {};
    function trim(string) {
      if (!string) return;
      var pattern = /([^-0-9A-Za-z\/]+)$/, match;
      if (match = string.match(pattern))
        string = string.replace(match, '');
      extra.value = (match || [])[1];
      return string;
    }
    
    return string.gsub(Autolink.Patterns.url, function(match) {
      var all = match[1], existingLink = match[2], scheme = match[3],
        domain = match[4], path = match[5];
      if (existingLink) return all;
      if (scheme == 'www.') all = 'http://' + all;
      all = trim(all), path = trim(path);
      return replacement(all, extra.value || '');
    });
  }
}

Object.extend(Autolink, Autolink.Linkers);

/*--------------------------------------------------------------------------*/

Ajax.Popup = Class.create();
Object.extend(Object.extend(Ajax.Popup.prototype, Ajax.Updater.prototype), {
  initialize: function(url, options) {
    this.popup = this.createWindow(options || {});
    Ajax.Updater.prototype.initialize.call(this, 
      this.popup.document.getElementById('popup_body'), url, options);
    var onComplete = this.options.onComplete;
    this.options.onComplete = function() {
      if (this.popup.closed) return;
      onComplete.apply(this, arguments);
      this.popup.document.title = this.options.title || '';
    }.bind(this);
  },
  
  createWindow: function(options) {
    var defaults = $H({width: 480, height: 320, scrollbars: 'yes', status: 'no', 
      toolbar: 'no', location: 'no', menubar: 'no', directories: 'no', resizable: 'yes'});
    var parameters = defaults.merge(options.window || {}).invoke('join', '=').join(',');
    
    var popup = window.open('', options.name || 'popup', parameters);
    popup.document.write('<html><body id="popup_body"></body></html>');
    popup.document.close();
    
    return popup;
  }
});

/*--------------------------------------------------------------------------*/

var ShowHide = Class.create();
ShowHide.prototype = {
  initialize: function(element, callbacks) {
    this.element   = element = $(element);
    this.effect    = element.getAttribute('effect') || 'slide';
    this.duration  = parseFloat(element.getAttribute('duration')) || 0.25;
    this.activeClassName = element.getAttribute('activeclassname') || 'active';
    this.callbacks = callbacks;
    this.active    = Element.visible(element);
    this.element.showHide = this;
  },
  
  togglers: function() {
    return document.getElementsByClassName('show_hide_toggler_' + this.element.id);
  },
  
  toggle: function() {
    if (this.callbacks.beforeToggle) this.callbacks.beforeToggle(this);
    Effect.toggle(this.element, this.effect, {duration: this.duration, 
      afterFinish: (this.callbacks.afterToggle || Prototype.K).bind(null, this)});
    this.active = !this.active;
    this.togglers().concat(this.element).each(this.adjustClassName.bind(this));
  },
  
  show: function() {
    if (this.active) return;
    this.toggle();
  },
  
  hide: function() {
    if (!this.active) return;
    this.toggle();
  },
  
  adjustClassName: function(element) {
    Element[this.active ? 'addClassName' : 'removeClassName'](element, this.activeClassName);
  }
}

/*--------------------------------------------------------------------------*/

var Hover = {
  EXIT_DELAY  : 600,
  HOVER_CLASS : 'hover',
  
  lastTimer   : null,
  lastCommand : null,
  inhibit     : false,
  
  clearCurrent: function() {
    if(!this.lastTimer) return
    clearTimeout(this.lastTimer)
    eval(this.lastCommand)
    this.lastTimer = this.lastCommand = null
  },
  
  endWith: function(command) {
    if(this.inhibit) return
    this.lastCommand = command
    this.lastTimer = setTimeout(command, this.EXIT_DELAY)
  },
  
  toggle: function(on, container, nubbin) {
    if(this.inhibit) return
    
    if(on) {
      if($(container)) Element.addClassName(container, this.HOVER_CLASS)
      if($(nubbin)) Element.show(nubbin)
    } else {
      if($(container)) Element.removeClassName(container, this.HOVER_CLASS)
      if($(nubbin)) Element.hide(nubbin)
    }
  }
}

/*--------------------------------------------------------------------------*/

var transcript = {
  hover: {
    begin: function(id) {
      Hover.clearCurrent()
      Hover.toggle(true, 'file-' + id, 'nubbin_file_' + id)
    },
    
    end: function(id, delay) {
      if(delay)
        Hover.endWith('transcript.hover.end(' + id + ')')
      else
        Hover.toggle(false, 'file-' + id, 'nubbin_file_' + id)
    }
  }
}

/*--------------------------------------------------------------------------*/

function $T() {
  return new Date().getTime();
}

function $P(value) {
  return parseInt(document.documentElement.clientWidth * value / 100.0);
}

Form.forElement = function(element) {
  element = $(element);
  while (element && element.tagName.toLowerCase() != 'form')
    element = element.parentNode;
  return element;
}

/*--------------------------------------------------------------------------*/

String.prototype.blank = function() {
  return !!this.match(/^\s*$/);
}

/*--------------------------------------------------------------------------*/

function toggleSubmit(submit_element) {
  $(submit_element).disabled = !this.checked;
}

function updateChartWithSelectedLevel(level, price) {
  $('selected_plan_price').innerHTML = price;
  $$('table.pricing tr.shaded').first().className = '';
  $(level).className = 'shaded';
}

function changeTheme(theme) {
  var pattern = new RegExp('/' + theme + '\\.css');
  $$('link').each(function(link) {
    if (link.href.match(pattern)) {
      link.disabled = false;
    } else if (link.title == 'Theme' && 
        (link.rel == 'Stylesheet' || !link.disabled)) {
      link.disabled = true;
    }
  });
}

function uploadLogo() {
  if (!$('upload').value) return false;
  Element.show('upload_form_progress');
  Element.hide('upload_form_contents');
  $('upload_form_tag').target = 'upload_target';
  $('upload_form_tag').submit();
  return false;
}



