Scrollable = Class.create();
Scrollable.prototype = {
  topper: 0,
  initialize: function(element) {
    this.scrollelement = $(element);

    this.options = Object.extend({
      clipWidth: this.scrollelement.offsetWidth,
      clipHeight: 300,
      clipTop: 0
    }, arguments[1] || {});
    
    this.clipTop     = this.options.clipTop;
    this.clipBottom  = this.options.clipHeight;
    this.totalHeight = this.scrollelement.offsetHeight;

    $('scroll-container').makePositioned();

    $(this.scrollelement).style.clip = 'rect(0,'+this.options.clipWidth+'px,'+this.options.clipHeight+'px,0)';
    Position.absolutize(this.scrollelement);
    this.createScrollbar();
  },
  createScrollbar: function() {
    var scroller = this;

    Event.observe('scroller-up', 'mousedown', function(e) {
      scroller.scrollUp();
      e.preventDefault();
    });
    Event.observe('scroller-up', 'mouseup', function(e) {
      scroller.stopScroll();
      e.preventDefault();
    });

    track_height = this.options.trackHeight || this.options.clipHeight-18;
    handle_height = parseInt(track_height*(track_height/(this.totalHeight-40)));
    if (handle_height > track_height) return $('scrollbar').hide();
    else if (handle_height < 15) handle_height = 15;

    $('track').style.height = track_height+'px';
    $('handle').style.height = handle_height+'px';

    this.slider = new Control.Slider('handle', 'track',
      { axis:'vertical',
        onSlide: function(value) {
          var position = parseInt(((value * scroller.totalHeight)-(value * scroller.options.clipHeight)));
          scroller.clipTop = position;
          scroller.clipBottom = (position + scroller.options.clipHeight);
          clipstring = 'rect('+scroller.clipTop+'px,'+scroller.options.clipWidth+'px,'+scroller.clipBottom+'px,0)';
          scroller.scrollelement.style.clip = clipstring;
          scroller.scrollelement.style.top = (position*-1) + 'px';
          scroller.topper = (position*-1);
        },
        onChange: function(value) {
          var position = parseInt(((value * scroller.totalHeight)-(value * scroller.options.clipHeight)));
          scroller.clipTop = position;
          scroller.clipBottom = (position + scroller.options.clipHeight);
          clipstring = 'rect('+scroller.clipTop+'px,'+scroller.options.clipWidth+'px,'+scroller.clipBottom+'px,0)';
          scroller.scrollelement.style.clip = clipstring;
          scroller.scrollelement.style.top = (position*-1) + 'px';
          scroller.topper = (position*-1);
        }
    });

    Event.observe('scroller-down', 'mousedown', function(e) {
      scroller.scrollDown();
      e.preventDefault();
    });
    Event.observe('scroller-down', 'mouseup', function(e) {
      scroller.stopScroll();
      e.preventDefault();
    });
  },
  scrollUp: function(amount){
    this.amount = amount || -15;
    this.scroll();
  },
  scrollDown: function(amount){
    this.amount = amount || 15;
    this.scroll();
  },
  scroll: function(){
    this.scrollTo(this.amount);
    this.repeater = setTimeout(function(){
      this.scroll();
    }.bind(this), 40);
    return;
  },
  scrollTo: function(amount){
    this.clipTop    += amount;
    this.clipBottom += amount;
    this.topper     -= amount;
    if (this.clipTop+12 < 0 || (this.clipBottom-12) > this.totalHeight){
      this.clipTop -= amount;
      this.clipBottom -= amount;
      this.topper += amount;
      return;
    }
    this.slider.setValue((this.clipTop)/(this.totalHeight-this.options.clipHeight));
    clipstring = 'rect('+this.clipTop+'px,'+this.options.clipWidth+'px,'+this.clipBottom+'px,0)';
    this.scrollelement.style.clip = clipstring;
    this.scrollelement.style.top  = this.topper + 'px';
  },
  stopScroll: function(){
    return clearTimeout(this.repeater);
  }  
};

/**
 *
 * Event#onDOMReady
 * @see http://www.vivabit.com/bollocks/2006/06/21/a-dom-ready-extension-for-prototype
 * Functionas passed to the onDOMReady method fires as soon as the DOM-structure is availible to the javascript engine
 *
 * @param {FUNCTION} f function to run
 *
 */
Object.extend(Event, {
 _domReady: function() {
   if (arguments.callee.done) { return; }
   arguments.callee.done = true;
   if (this._timer) { clearInterval(this._timer); }
   this._readyCallbacks.each(function(f) {
     f();
   });
   this._readyCallbacks = null;
	},
 onDOMReady: function(f) {
   if (!this._readyCallbacks) {
     var domReady = this._domReady.bind(this);
     if (document.addEventListener) {
       document.addEventListener("DOMContentLoaded", domReady, false);
     }
     /*@cc_on @*/
     /*@if (@_win32)
         document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
         document.getElementById("__ie_onload").onreadystatechange = function() {
             if (this.readyState == "complete") domReady(); 
         };
     /*@end @*/
     if (/WebKit/i.test(navigator.userAgent)) { 
       this._timer = setInterval(function() {
         if (/loaded|complete/.test(document.readyState)) { domReady(); }
       }, 10);
     }
     Event.observe(window, 'load', domReady);
     Event._readyCallbacks =  [];
   }
   Event._readyCallbacks.push(f);
 }
});

/**
 * getElementsByClassName
 * Written by Jonathan Snook, http://www.snook.ca/jonathan
 * Add-ons by Robert Nyman, http://www.robertnyman.com
 *
 * To get all a elements in the document with a "info-links" class:
 * getElementsByClassName(document, "a", "info-links");
 * To get all div elements within the element named "container", with a "col" and a "left" class:
 * getElementsByClassName(document.getElementById("container"), "div", ["col", "left"]);
 *
 */
function getElementsByClassName(oElm, strTagName, oClassNames){
	var arrElements = (strTagName == "*" && oElm.all) ? oElm.all : oElm.getElementsByTagName(strTagName);
	var arrReturnElements = $A();
	var arrRegExpClassNames = $A();
	if(typeof oClassNames == "object"){
		for(var i=0; i<oClassNames.length; i++){
			arrRegExpClassNames.push(new RegExp("(^|\\s)" + oClassNames[i].replace(/\-/g, "\\-") + "(\\s|$)"));
		}
	} else {
		arrRegExpClassNames.push(new RegExp("(^|\\s)" + oClassNames.replace(/\-/g, "\\-") + "(\\s|$)"));
	}
	var oElement;
	var bMatchesAll;
	for(var j=0; j<arrElements.length; j++){
		oElement = arrElements[j];
		bMatchesAll = true;
		for(var k=0; k<arrRegExpClassNames.length; k++){
			if(!arrRegExpClassNames[k].test(oElement.className)){
				bMatchesAll = false;
				break;
			}
		}
		if(bMatchesAll) { arrReturnElements.push($(oElement)); }
	}
	if(arrReturnElements.length > 0) { return arrReturnElements; }
	return false;
}

//Leak free bind
//Written by Arrix, 2006-08-24 17:15:55 GMT+0800
//with input from Ross and Laurens
Function.prototype.bind = function() {
  var __method = this, args = $A(arguments), object = args.shift();
  return function() {
    return __method.apply(object, args.concat($A(arguments)));
  }.leak_free_closure();
};
Function.prototype.bindAsEventListener = function(object) {
  var __method = this, args = $A(arguments), object = args.shift();
  return function(event) {
    return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
  }.leak_free_closure();
};
Function.prototype.leak_free_closure = function() {
  if (!window.__funs) { window.__funs = []; }
  var fun = this;
  var funId = this.__funId;
  if (!funId) { __funs[funId = fun.__funId = __funs.length] = fun; }
  fun = null;
  return function () {
    return __funs[funId].apply(null, arguments);
  };
};

var PublicApp = {
  '.show-artist:mouseover': function(element) {
    if(this.current_artist && this.current_artist == element || !element.id) { return; }
    this.current_artist = element;
    $$('.artist-collage').each(function(el){
      el.hide();
    });
    $('collage-'+element.id).show();
  }
}

Event.onDOMReady(function(){
  if ((thumbs = $('thumb-nav'))) {
    var ThumbScroller = new Scrollable(thumbs, { clipHeight: 240, trackHeight: 203 });
    current_location = document.location.pathname.split('/'); 
    if ((page_id = parseInt(current_location[current_location.length-1])) && (page = $('page_'+page_id))) {
      var nodes = page.parentNode.getElementsByTagName('li');
      for (var i=0; i<nodes.length; i++){
        if (nodes[i] == page) {
          var num = i%2;
          var element_height = parseInt(page.offsetHeight);
          var scroll_pixels  = parseInt( ((i-num) * element_height) / 2 - element_height )+30;
          if (i == nodes.length-1) { scroll_pixels = scroll_pixels - element_height*2+30; }
          ThumbScroller.scrollTo(scroll_pixels);
        }
      }
    } 
  }
  EventSelectors.start(PublicApp);  
});
