(function(){
  function wheel(e){
    if(e.wheelDelta){
      delta = e.wheelDelta/120;
    }else if(e.detail){
      delta =- e.detail/3;
    }
    if(!delta){
      return;
    }
    var custom_event = Event.element(e).fire('mouse:wheel',{
      delta: delta
    });
    if(custom_event.stopped){
      Event.stop(e);
      return false;
    }
  }
  document.observe('mousewheel',wheel);
  document.observe('DOMMouseScroll',wheel);
})();

var fbf = {
  Grid : {
    // height : 310,
    // width : 410,
    elements : {
      proxy : [[],[],[]]
    },
    height:222,
    width: 322,
    cache : {},
    url : '/m.php',
    locked : false,
    count: 1,
    fontSize : 36
  }
};

fbf.Preload = function(url){
  var image = new Image();
  image.src = url;
};

fbf.Grid.Base = function(){
  var xoverlay;
  var element;
  var cm, ct, tfx;
  var C, N, NE, E, SE, S, SW, W, NW;
  var X = 0, Y = 0;
  var T = 0, L = 0;
  var _g = [[],[],[]];
  var g = {};
  var t = {};
  var cb = {};
  var modal;

  var history;

  function _onResize(e){
    var d = document.viewport.getDimensions();

    var l=L/fbf.Grid.width;
    var t=T/fbf.Grid.height;

    _setCss(d);
    _setProxy();

    L = l*fbf.Grid.width;
    T = t*fbf.Grid.height;
    X = -L;
    Y = -T;

    fbf.Grid.elements.grid.setStyle({
      left : -L+'px',
      top : -T+'px'
    });

    $('m_'+g.NW).setStyle({
      left : L+'px',
      top : T+'px'
    });

    $('m_'+g.N).setStyle({
      left : L+fbf.Grid.width+'px',
      top : T+'px'
    });

    $('m_'+g.NE).setStyle({
      left : L+(fbf.Grid.width*2)+'px',
      top : T+'px'
    });

    $('m_'+g.W).setStyle({
      left : L+'px',
      top : T+fbf.Grid.height+'px'
    });

    $('m_'+g.C).setStyle({
      left : L+fbf.Grid.width+'px',
      top : T+fbf.Grid.height+'px'
    });

    $('m_'+g.E).setStyle({
      left : L+(fbf.Grid.width*2)+'px',
      top : T+fbf.Grid.height+'px'
    });

    $('m_'+g.SW).setStyle({
      left : L+'px',
      top : T+(fbf.Grid.height*2)+'px'
    });

    $('m_'+g.S).setStyle({
      left : L+fbf.Grid.width+'px',
      top : T+(fbf.Grid.height*2)+'px'
    });

    $('m_'+g.SE).setStyle({
      left : L+(fbf.Grid.width*2)+'px',
      top : T+(fbf.Grid.height*2)+'px'
    });

  }

  function _setCenter(id){
    cm = $('m_'+id);
    ct = cm.down('div.title');
  }

  function _tween(x, y, callback){
    fbf.Grid.elements.grid.morph('top:'+y+'px; left:'+x+'px;', {
      duration: 0.5,
      after : function(){
        try {
          callback();
        }catch(e){}
        $('m_'+g.C).addClassName('center-module');
        X = x;
        Y = y;
        fbf.Grid.locked = false;
      },
      before : function(){
        $('m_'+g.C).removeClassName('center-module');
        fbf.Grid.locked = true;
      }
    });
  }

  function _mouseenter(pos, event){
    var title = $('m_'+g[pos]).down('div.title');
    $('m_'+g[pos]).addClassName('module-hover');
    if(title){
      t[pos]=title;
      tfx = new S2.FX.Morph(title, {
        'style' : 'margin-top: -'+title.offsetHeight+'px'
      });
      tfx.play();
    }
  }

  function _mouseleave(pos, event){
    $('m_'+g[pos]).removeClassName('module-hover');
    if(t[pos]){
      if(event.relatedTarget && event.relatedTarget.childOf(t[pos])) return;
      tfx = new S2.FX.Morph(t[pos], {
        'style' : 'margin-top: 0'
      });
      tfx.play();
    }
  }

  function _loadModule(p){
    var module = fbf.Grid.cache[g[p]];


    var url = module.url;

    if(url){
      if(url.indexOf('pages/display/engagement')!=-1){
        modal.overlay.options.height = 495;
        modal.overlay.options.width = 831;
      }else if(url.indexOf('casestudy')!=-1){
        modal.overlay.options.height = 536;
        modal.overlay.options.width = 974;
      }else if(url.indexOf('slide_show')!=-1){
        modal.overlay.options.height = 513;
        modal.overlay.options.width = 832;
      }else if(url.indexOf('video')!=-1){
        modal.overlay.options.height = 500;
        modal.overlay.options.width = 832;
      }else{
        modal.overlay.options.height = 495;
        modal.overlay.options.width = 974;
      }
      modal.load(url);
    }
  }

  function _load(e){
    if(!fbf.Grid.locked){
      e.stop();
      _loadModule('C');
    }
  }

  function _navigate(n, e){
    if(!fbf.Grid.locked){
      e.stop();
      _loadModule(n);
    }
  }

  function _history(e){
    return false;
  }

  function _setCss(d){
    var _style;
    var maxH = d.height-100;
    var maxW = d.width-40;
    var maxF = 26;

    var moduleH = Math.min(Math.floor(maxH/3), 310);
    var moduleW = Math.min(Math.floor(maxW/3), 410);

    var moduleHW = Math.floor((moduleH/3)*4);
    var moduleWH = Math.floor((moduleW/4)*3);

    if(maxW<maxH){
      fbf.Grid.height = moduleWH;
      fbf.Grid.width = moduleW;
    }else{
      fbf.Grid.height = moduleH;
      fbf.Grid.width = moduleHW;
    }

    _style = fbf.Grid.elements.start.style;
    _style.height = (fbf.Grid.height*3)+'px';
    _style.width = (fbf.Grid.width*3)+'px';

    _style = fbf.Grid.elements.content.style;
    _style.height = (fbf.Grid.height*3)+'px';
    _style.marginLeft = -((fbf.Grid.width*3)/2)+'px';
    _style.width = (fbf.Grid.width*3)+'px';

    fbf.Grid.elements.controls.style.width = Math.max((fbf.Grid.width*3), 820)+'px';
    fbf.Grid.elements.footer.style.width = (fbf.Grid.width*3)+'px';
    fbf.Grid.elements.footer.style.marginLeft = -((fbf.Grid.width*3)/2)+'px';
    fbf.Grid.elements.footer.style.top = (fbf.Grid.height*3)+'px';

    var scale = (fbf.Grid.width/410)*100;
    fbf.Grid.fontSize = Math.max(Math.ceil((maxF/100)*scale), 12);

    var st=document.styleSheets[document.styleSheets.length-1];
    (st.cssRules ? st.cssRules[0] : st.rules[0]).style.width=(fbf.Grid.width-22)+'px';
    (st.cssRules ? st.cssRules[0] : st.rules[0]).style.height=(fbf.Grid.height-22)+'px';
    (st.cssRules ? st.cssRules[1] : st.rules[1]).style.fontSize=(fbf.Grid.fontSize)+'px';
    (st.cssRules ? st.cssRules[2] : st.rules[2]).style.width=(fbf.Grid.width-22)+'px';
    (st.cssRules ? st.cssRules[2] : st.rules[2]).style.height=(fbf.Grid.height-22)+'px';
    (st.cssRules ? st.cssRules[3] : st.rules[3]).style.width=(fbf.Grid.width-22)+'px';
    (st.cssRules ? st.cssRules[3] : st.rules[3]).style.height=(fbf.Grid.height-22)+'px';
    (st.cssRules ? st.cssRules[4] : st.rules[4]).style.fontSize=(fbf.Grid.fontSize)+'px';
    (st.cssRules ? st.cssRules[5] : st.rules[5]).style.fontSize=(fbf.Grid.fontSize)+'px';
  }

  function _setProxy(){
    fbf.Grid.elements.proxy[0][0].setStyle({
      left : fbf.Grid.width*0+'px',
      top : fbf.Grid.height*0+'px'
    });

    fbf.Grid.elements.proxy[0][1].setStyle({
      left : fbf.Grid.width*1+'px',
      top : fbf.Grid.height*0+'px'
    });

    fbf.Grid.elements.proxy[0][2].setStyle({
      left : fbf.Grid.width*2+'px',
      top : fbf.Grid.height*0+'px'
    });

    fbf.Grid.elements.proxy[1][0].setStyle({
      left : fbf.Grid.width*0+'px',
      top : fbf.Grid.height*1+'px'
    });

    fbf.Grid.elements.proxy[1][1].setStyle({
      left : fbf.Grid.width*1+'px',
      top : fbf.Grid.height*1+'px'
    });

    fbf.Grid.elements.proxy[1][2].setStyle({
      left : fbf.Grid.width*2+'px',
      top : fbf.Grid.height*1+'px'
    });

    fbf.Grid.elements.proxy[2][0].setStyle({
      left : fbf.Grid.width*0+'px',
      top : fbf.Grid.height*2+'px'
    });

    fbf.Grid.elements.proxy[2][1].setStyle({
      left : fbf.Grid.width*1+'px',
      top : fbf.Grid.height*2+'px'
    });

    fbf.Grid.elements.proxy[2][2].setStyle({
      left : fbf.Grid.width*2+'px',
      top : fbf.Grid.height*2+'px'
    });

  }

  function initialize(e){
    var _style;
    fbf.Grid.elements = {
      'content' : $('content'),
      'grid' : $('grid'),
      'start' : $('start-page'),
      'controls' : $('navigation-inner'),
      'site' : $('site'),
      'footer' : $('footer'),
      proxy : [[],[],[]]
    };


    var d = document.viewport.getDimensions();
    _setCss(d);

    fbf.Grid.elements.site.setStyle({
      opacity: 0,
      visibility : 'visible'
    }).morph('opacity:1');

    var h = d.height/2;
    var w = d.width/2;
    var x = fbf.Grid.width/2;
    var y = fbf.Grid.height/2;

    var _pos = [
      ['NW', 'N', 'NE'],
      ['W','C','E'],
      ['SW','S','SE']
    ];

    Event.observe(window, 'resize', _onResize);

    fbf.Grid.elements.grid.select('div.module').reverse().each(function(module, i){
         var position = module.positionedOffset();
         _style = module.style;
         _style.float = 'none';
         _style.left = (position.left-5)+'px';
         _style.position = 'absolute';
         _style.top = (position.top-5)+'px';

         var token = module.identify().split('-');
         var link = module.down('.full-content');

         var m = new fbf.Grid.Module(token[1]);
         if(link){
           m.url = link.href;
         }
         m.slug = token[0];
         m.setContent(module.innerHTML);
         module.id = 'm_'+m.id;
         var x = Math.ceil((position.left-5)/fbf.Grid.width);
         var y = Math.ceil((position.top-5)/fbf.Grid.height);

         _g[x][y] = m.id;

         fbf.Grid.elements.proxy[x][y] = new Element('div', {className : 'proxy', id: 'proxy_'+x+'_'+y}).setStyle({
           top: (position.top-5)+'px',
           left: (position.left-5)+'px',
           zIndex : 1000,
           background : 'url(/img/site/magic.png) repeat 0 0'
           //background : 'blue'
         });
         fbf.Grid.elements.content.insert(fbf.Grid.elements.proxy[x][y]);
         fbf.Grid.elements.proxy[x][y].observe('mouseenter', _mouseenter.curry(_pos[x][y]));
         fbf.Grid.elements.proxy[x][y].observe('mouseleave', _mouseleave.curry(_pos[x][y]));
         fbf.Grid.elements.proxy[x][y].observe('click', _navigate.curry(_pos[x][y]));
       });

       _setProxy();

       g.N = _g[1][0];
       g.NE = _g[2][0];
       g.E = _g[2][1];
       g.SE = _g[2][2];
       g.S = _g[1][2];
       g.SW = _g[0][2];
       g.W = _g[0][1];
       g.NW = _g[0][0];
       g.C = _g[1][1];

       //_setCenter(g.C);

       var _t = 90;
       var _l = (d.width/2)-((fbf.Grid.width*3)/2);

       // N = new dd.util.Region(_t, _l+(fbf.Grid.width*2), _t+fbf.Grid.height, _l+fbf.Grid.width);
       // NE = new dd.util.Region(_t, _l+(fbf.Grid.width*3), _t+fbf.Grid.height, _l+(fbf.Grid.width*2));
       // E = new dd.util.Region(_t+fbf.Grid.height, _l+(fbf.Grid.width*3), _t+(fbf.Grid.height*2), _l+(fbf.Grid.width*2));
       // SE = new dd.util.Region(_t+(fbf.Grid.height*2), _l+(fbf.Grid.width*3), _t+(fbf.Grid.height*3), _l+(fbf.Grid.width*2));
       // S = new dd.util.Region(_t+(fbf.Grid.height*2), _l+(fbf.Grid.width*2), _t+(fbf.Grid.height*3), _l+fbf.Grid.width);
       // SW = new dd.util.Region(_t+(fbf.Grid.height*2), _l+fbf.Grid.width, _t+(fbf.Grid.height*3), _l);
       // W = new dd.util.Region(_t+fbf.Grid.height, _l+fbf.Grid.width, _t+(fbf.Grid.height*2), _l);
       // NW = new dd.util.Region(_t, _l+fbf.Grid.width, _t+fbf.Grid.height, _l);
       // C = new dd.util.Region(_t+fbf.Grid.height, _l+(fbf.Grid.width*2), _t+(fbf.Grid.height*2), _l+fbf.Grid.width);

       // N.observe('click', _navigate.curry('N'));
       // NE.observe('click', _navigate.curry('NE'));
       // E.observe('click', _navigate.curry('E'));
       // SE.observe('click', _navigate.curry('SE'));
       // S.observe('click', _navigate.curry('S'));
       // SW.observe('click', _navigate.curry('SW'));
       // W.observe('click', _navigate.curry('W'));
       // NW.observe('click', _navigate.curry('NW'));


       // C.observe('click', _load);

       // history = new dd.util.History.Module('m');
       // history.observe('history:change', _history);







    modal = new dd.ui.Overlay.AjaxModal({
      'height' : 495,
      'width' : 974,
      show : function(){
        this.overlay.resize();
        this.mask.resize();
        if(xoverlay && xoverlay.visible()){
          this.mask.element.show();
          this.overlay.element.show();
          $('overlay-mask').hide();
          xoverlay.hide();
        }else{
          fbf.Grid.locked = true;
          this.mask.element.show();
          this.overlay.element.show();
        }

        // this.overlay.resize();
        // if(xoverlay && xoverlay.visible()){
        //   this.mask.element.show();
        //   this.overlay.element.show();
        //   $('overlay-mask').hide();
        //   xoverlay.hide();
        // }else{
        //   var fx = new S2.FX.Parallel([
        //     new S2.FX.Morph(this.overlay.element, {
        //       style : 'opacity: 1; left: #{left}; top: #{top}; width: #{width}; height: #{height}'.interpolate(this.overlay.style)
        //     }),
        //     new S2.FX.Morph(this.mask.element, {style : 'opacity:'+this.mask.options.opacity})
        //   ], {
        //     before : function(){
        //       fbf.Grid.locked = true;
        //       this.overlay.resize();
        //       this.mask.element.setStyle({'opacity' : 0}).show();
        //       this.overlay.element.setStyle({
        //         'opacity' : 0,
        //         'width' : fbf.Grid.width+'px',
        //         'height' : fbf.Grid.height+'px',
        //         'left' : w-x+'px',
        //         'top' : h-y+'px'
        //       }).show();
        //     }.bind(this),
        //     'position' : 'end'
        //   });
        //   fx.play();
        // }
      },
      hide : function(){
        this.mask.element.hide();
        this.overlay.element.hide();
        fbf.Grid.locked = false;
        this.overlay.content.stopObserving();
        this.overlay.content.descendants().invoke('stopObserving');
        this.overlay.content.update('');

        // this.mask.hide();
        // this.overlay.hide();


        // var cfx = new S2.FX.Morph(this.overlay.content, {
        //   'style' : 'opacity:0;',
        //   'position' : 'end'
        // });
        // cfx.play();
        //
        // var fx = new S2.FX.Parallel([
        //   new S2.FX.Morph(this.mask.element, {style : 'opacity:0'}),
        //   new S2.FX.Morph(this.overlay.element, {
        //     style : 'opacity: 0; left: #{left}; top: #{top}; width: #{width}; height: #{height}'.interpolate({
        //       'width' : fbf.Grid.width+'px',
        //       'height' : fbf.Grid.height+'px',
        //       'left' : w-x+'px',
        //       'top' : h-y+'px'
        //     })
        //   })
        // ], {
        //   after : function(){
        //     this.mask.element.hide();
        //     this.overlay.element.hide();
        //     fbf.Grid.locked = false;
        //
        //     this.overlay.content.stopObserving();
        //     this.overlay.content.descendants().invoke('stopObserving');
        //     this.overlay.content.update('');
        //
        //   }.bind(this),
        //   'position' : 'end'
        // });
        // fx.play();
      }
    });

    fbf.Grid.elements.controls.observe('click', function(e){
      var element;
      if(element=e.findElement('a.modal')){
        e.stop();
        modal.overlay.options.height = 495;
        modal.overlay.options.width = 974;
        modal.load(element.href);
      }
    });

    fbf.Twitter.initialize('twitter-feed', 'fbfpeople', {
      count : 20,
      link: '<a href="#{url}">#{url}</a>',
      template: '<li><span>#{text} <a class="retweet" href="http://twitter.com/home?status=#{encoded_text}">retweet</a></span></li>'
    });

    xoverlay = $('overlay');
    if(xoverlay){
      fbf.Grid.locked = true;
      xoverlay.down('a.closeButton').observe('click', function(e){

        e.stop();

        var overlayMask = $('overlay-mask');
        var overlayContent = $('overlay-content');

        overlayMask.hide();
        xoverlay.hide();
        fbf.Grid.locked = false;
        xoverlay.stopObserving();
        xoverlay.descendants().invoke('stopObserving');
        xoverlay.update('');
        fbf.Grid.locked = false;


        // var cfx = new S2.FX.Morph(overlayContent, {
        //   'style' : 'opacity:0;',
        //   'position' : 'end'
        // });
        // cfx.play();
        //
        // var fx = new S2.FX.Parallel([
        //   new S2.FX.Morph(overlayMask, {style : 'opacity:0'}),
        //   new S2.FX.Morph(xoverlay, {
        //     style : 'opacity: 0; left: #{left}; top: #{top}; width: #{width}; height: #{height}'.interpolate({
        //       'width' : fbf.Grid.width+'px',
        //       'height' : fbf.Grid.height+'px',
        //       'left' : w-x+'px',
        //       'top' : h-y+'px'
        //     })
        //   })
        // ], {
        //   after : function(){
        //     overlayMask.hide();
        //     xoverlay.hide();
        //     fbf.Grid.locked = false;
        //     xoverlay.stopObserving();
        //     xoverlay.descendants().invoke('stopObserving');
        //     xoverlay.update('');
        //     fbf.Grid.locked = false;
        //   }.bind(this),
        //   'position' : 'end'
        // });
        // fx.play();


      });
    }

  }

  //Event.observe(window, 'load', _initialize);
  document.observe('dom:loaded', initialize);

  function get(id){
    return fbf.Grid.cache[id];
  }

  return {
    get : get,
    load : function(url){
      modal.load(url);
    },
    update : function(url){
      modal.reload(url);
    },
    debug : function(){
      console.dir(g);
    }
  }
}();

fbf.Grid.Module = Class.create({
  initialize : function(id){
    this.id = fbf.Grid.count++;
    this._id = id;
    this.background = Math.floor(Math.random()*16777215).toString(16);
    this.content = '<div style="background:#'+this.background+';">'+this.id+'</div>';
    this.neighbours = {};
    this.controller = 'article';
    this.pending = $A(['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']);
    fbf.Grid.cache[this.id] = this;
  },
  setNeighbours : function(n){
    if(n){this.updateNeighbours(n);}
    if(this.pending.length>0){this.preload();};
  },
  updateNeighbours : function(n){
    this.neighbours = Object.extend(this.neighbours, n);
    if(this.pending.length<=8){
      var k = Object.keys(n).flatten();
      this.pending = this.pending.reject(function(r){
        return k.indexOf(r)!=-1
      });
    }
  },
  preload : function(){
    var url = fbf.Grid.url+'?slug='+this.slug+'&limit='+this.pending.length;
    new Ajax.Request(url, {
      'parameters' : {
        'test' : window.test ? 1 : 0
      },
      'method' : 'get',
      'onSuccess' : this.onSuccess.bind(this)
    });
  },
  preloadNeighbour : function(p){
    if(!this.neighbours[p]){
      this.onSuccess(p);
    }
  },
  render : function(){
    return this.content;
  },
  onSuccess : function(t){
    try{
      var j = t.responseText.evalJSON();
      this.pending.each(function(_c, i){
        var _j = j[i];
        if(_j.img){
          fbf.Preload(_j.img);
        }
        var id = _j.id;
        var m = new fbf.Grid.Module(id);
        m.content = _j.html;
        m.slug = _j.slug;
        m.url = _j.url;
        this.neighbours[_c] = m.id;
        this.pending = $A();
      }, this);
    }catch(e){
      fbf.Grid.Errors.log(fbf.Grid.url+this.slug+'/limit:'+this.pending.length+'.json', t.responseText);
    }
  },
  remove : function(){
    this.element.remove();
  },
  setContent : function(html){
    this.content = html;
  }
});

function get(id){
  return fbf.Grid.Base.get(id);
}

fbf.Grid.Errors = function(){
  var element, modal;

  function log(id, text){
    var d = new Element('div', {className : 'errors'}).update(text);
    d.insert({top: new Element('div', {className: 'title'}).update(id)})
    element.insert(d);
    modal.show();
    var t = d.positionedOffset();
    element.scrollTop = t[1];
  }

  function initialize(){
    modal = new dd.ui.Overlay.Modal({
      'height' : 600,
      'width' : 800
    });
    element = new Element('div', {id: 'errors'}).setStyle({
      'overflow' : 'scroll',
      'height' : '600px',
      'width' : '800px',
      'background' : '#fff',
      'fontSize' : '12px'
    });
    modal.update(element);
  }

  document.observe('dom:loaded', initialize);

  return {
    log : log
  }
}();

fbf.Scrollbar = Class.create({
  initialize : function(wrapper, element){
    this.wrapper = $(wrapper);
    this.element = $(element);

    this.scrollbar = new Element('div', {
      className: 'scrollbar'
    });

    this.handle = new Element('div', {
      className: 'scrollbar-handle'
    }).update('<span class="t"></span><span class="b"></span>');

    this.scrollbarWrapper = new Element('div', {
      className : 'scrollbar-wrapper'
    });

    this.wrapper.insert(this.scrollbarWrapper.insert(this.scrollbar.insert(this.handle)));

    this.slider = new Control.Slider(this.handle, this.scrollbar, {
      axis : 'vertical',
      onChange : this.onChange.bind(this),
      onSlide : this.onChange.bind(this)
    });


    this.onMouseWheelListener = this.onMouseWheel.bindAsEventListener(this);
    this.element.observe('mouse:wheel', this.onMouseWheelListener);

    this.up = new Element('a', {href: '#', className: 'up'}).update('Up');
    this.down = new Element('a', {href: '#', className: 'down'}).update('Down');

    this.scrollbarWrapper.insert(this.up);
    this.scrollbarWrapper.insert(this.down);

    this.up.observe('click', this.scrollUp.bindAsEventListener(this));
    this.down.observe('click', this.scrollDown.bindAsEventListener(this));

    this.handle.observe('mouseenter', this.onMouseEnter.bindAsEventListener(this));
    this.handle.observe('mouseleave', this.onMouseLeave.bindAsEventListener(this));

    this.render();


  },
  onMouseEnter : function(){
    this.handle.addClassName('scrollbar-handle-hover');
  },
  onMouseLeave : function(){
    this.handle.removeClassName('scrollbar-handle-hover');
  },
  onMouseWheel : function(e){
    this.slider.setValueBy(-(e.memo.delta / 20));
    e.stop();
    return false;
  },
  onChange : function(value){
    this.element.scrollTop = Math.round(value/this.slider.maximum * (this.element.scrollHeight - this.element.offsetHeight));
  },
  render : function(){

    var height = this.element.getHeight();
    var scrollHeight = this.element.scrollHeight;
    this.scrollAmount = height/scrollHeight;

    this.scrollbarWrapper[(scrollHeight>height) ? 'show' : 'hide']();

    this.slider.trackLength = this.slider.maximumOffset() - this.slider.minimumOffset();
    var h = Math.max((this.scrollbar.offsetHeight * (height / scrollHeight)), 100);
    if(!isNaN(h)){
      this.handle.style.height = h+'px';
      this.slider.handleLength = this.handle.style.height.replace(/px/,'');
    }
  },
  scrollDown : function(e){
    this.slider.setValueBy(this.scrollAmount);
    e.stop();

  },
  scrollUp : function(e){
    this.slider.setValueBy(-this.scrollAmount);
    e.stop();
  }
});

fbf.ModalLinks = Class.create({
  initialize : function(element){
    this.element = $(element);
    this.element.observe('click', this.onClick.bindAsEventListener(this));
  },
  onClick : function(e){
    var element = e.findElement('a.modal');
    if(element){
      e.stop();
      if($('overlay') && $('overlay').visible()){
        fbf.Grid.Base.load(element.href);
      }else{
        fbf.Grid.Base.update(element.href);
      }
    }
  }
});

fbf.HowWeDoItTabs = function() {
  var element, tabs, panels;

  return {
    initialize : function(element) {

      element           = $(element);
      tabsContainer     = $('tabs');
      panelsContainer   = $('scrollbar-content');

      panels            = panelsContainer.select('.tab-panel');
      panels.invoke('hide');

      panels[0].show();
      panels[0].addClassName('active');

      tabsContainer.down('a').addClassName('selected');
      tabsContainer.observe('click', onClick);

      function onClick(e) {
        clicked = e.findElement('a');

        if(!clicked.hasClassName('selected')) {
          tabsContainer.down('a.selected').removeClassName('selected');
          clicked.addClassName('selected');

          panelsContainer.down('.active').removeClassName('active').hide();
          $(clicked.hash.substr(1)).addClassName('active').show();
        }

        e.stop();
      }
    }
  }
}();

fbf.SubmitComment = function(e){
  e.stop();
  $('CommentSubmit').disable();
  Form.request(this, {
    onSuccess : function(t){
      var response = t.responseText.evalJSON();
      if(response.success){
        var html = '<p>'+response.success+'</p>';
        $('CommentName').clear();
        $('CommentEmail').clear();
        $('CommentUrl').clear();
        $('CommentComment').clear();
        $('ajax-flash-message').className = 'success';
      }else{
        var html = $H(response.error).inject('<h4>Please correct the following errors:</h4>', function(h, item, i){
          return h+'<p>'+item.value+'</p>';
        });
        $('ajax-flash-message').className = 'error';
      }
      $('ajax-flash-message').update(html).show();
      $('CommentSubmit').enable();
    }
  });
}

fbf.Twitter = function(){
  var element, options, username, callback, loaded;
  var linkRegex = /(ftp|http|https|file):\/\/[\S]+(\b|$)/;
  var mentionRegex = /(^|[^a-z0-9_])@([a-z0-9_]+)/;
  var url = "http://twitter.com/status/user_timeline/#{username}.json?count=#{count}&callback=?";

  function linkUrl(url){
    return options.link.evaluate({url:url[0]});
  }

  function mentionUrl(mention){
    return mention[1]+options.mention.evaluate({username:mention[2]});
  }

  function relativeDate(date){
    date = Date.parse(date.replace(/( \+)/," UTC$1"));
    var diff = (((new Date()).getTime() - date) / 1000);
    var day_diff = Math.floor(diff / 86400)

    if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 ) return;

    return day_diff == 0 && (
        diff < 60 && "just now" ||
        diff < 120 && "1 minute ago" ||
        diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" ||
        diff < 7200 && "1 hour ago" ||
        diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") ||
      day_diff == 1 && "Yesterday" ||
      day_diff + " days ago";
  }

  function formattedDate(date){
    if(Prototype.Browser.IE){
      _date = new Date(Date.parse(date.replace(/( \+)/," UTC$1")));
    }else{
      _date = new Date(date);
    }
    return _date.strftime(options.date);
  }

  function getTweet(html, tweet){
    tweet.encoded_text = escape(tweet.text);
    tweet.raw_text = tweet.text;
    tweet.rel_date = relativeDate(tweet.created_at);
    tweet.date = formattedDate(tweet.created_at);
    tweet.text = tweet.text.gsub(linkRegex, linkUrl).gsub(mentionRegex, mentionUrl);
    return html+options.template.evaluate(tweet);
  }

  function updateTweets(tweets){
    tweets = $A(tweets);
    element.update(tweets.inject('', getTweet));
    loaded = true;
    if(callback){
      callback(element.innerHTML);
    }

    if($('twitter-latest-tweet') && $('twitter-latest-date')){
      $('twitter-latest-tweet').update(tweets.first().text);
      $('twitter-latest-date').update(tweets.first().date);
    }
  }

  return {
    initialize : function(id, username, _options){
      element = $(id);
      options = Object.extend({
        'count': 10,
        'link' : '<a href="#{url}" target="_blank">#{url}</a>',
        'mention' : '<a href="http://twitter.com/#{username}" target="_blank">@#{username}</a>',
        'template' : '<p>#{text}</p>',
        'date' : '%D %b %Y (%H:%M)'
      }, _options||{});
      options.link = new Template(options.link);
      options.mention = new Template(options.mention);
      options.template = new Template(options.template);
      getJSON(url.interpolate({username : username, count: options.count}), updateTweets);
    },
    onload : function(func){
      callback = func;
      if(loaded){
        callback(element.innerHTML);
      }
    }
  }
}();