(function(context) {  
  // Scott Andrew's simple addEvent function
  function addEvent(elm, type, fn) {

	  if (elm.addEventListener) { 
  		elm.addEventListener(type, fn, false); 
  		return true; 
  	} else if (elm.attachEvent) { 
  		var r = elm.attachEvent('on' + evType, fn); 
  		return r; 
  	}	else {
      elm['on' + type] = fn;
  	}
  	
  }
  
  function hasClass(element, cls) {
    var matcher = new RegExp("\\b" + cls + "\\b");
    
    return matcher.exec(element.className);
  }
    
  function Accordian(container, options) {
    var self = this;
    
    this.container = container;
    this.options = options;
    
    addEvent(this.container, 'click', function(e) {
      e = window.event || e;
      self.handleClick(e);
    });
  }
  
  Accordian.prototype.handleClick = function(e) {
    var target = e.target || e.srcElement;
    
    // Use simple event delegation to easily support many items
    if (hasClass(target, this.options.handleClass) &&
        hasClass(target.parentNode, this.options.itemClass)) {
      this.collapseAll();
      this.expand(target.parentNode);
    }
  }
  
  Accordian.prototype.expand = function(item) {
    item.className += " " + this.options.expandClass;
  }
  
  Accordian.prototype.collapse = function(item) {
    // Potentially expensive operation - compile regex once only
    if (!this.expandMatcher) {
      this.expandMatcher = new RegExp(" ?\\b" + this.options.expandClass + "\\b", 'gi');
    }
    
    item.className = item.className.replace(this.expandMatcher, '');
  }
  
  Accordian.prototype.getItems = function() {
    var allElements;
    
    // As this operation might be expensive only calculate this once
    // would need a way to bust this if we wanted to support dynamic numbers
    // of items
    if (!this.items) {
      if (typeof this.container.getElementsByClassName == 'function') {
        this.items = this.container.getElementsByClassName(this.options.itemClass);
      } else {
        var allElements = this.container.getElementsByTagName('*');
        
        for (var i, element; element = allElements[i]; i++) {
          if (hasClass(element, this.options.itemClass)) {
            this.items.push(element);
          }
        }
      }
    } 
    
    return this.items;
  }
  
  Accordian.prototype.collapseAll = function() {
    var items = this.getItems();
    
    for (var i, item; item = items[i]; i++) {
      this.collapse(item);
    }
  }
  
  Accordian.attach = function(container, items, options) {
    return new Accordian(container, items, options);
  }
  
  context.Accordian = Accordian;
}(this));
