/*

Browser detection script from http://www.quirksmode.org/js/detect.html

*/
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: "Chrome",
      identity: "Chrome"
    },
    {   string: navigator.userAgent,
      subString: "OmniWeb",
      versionSearch: "OmniWeb/",
      identity: "OmniWeb"
    },
    {
      string: navigator.vendor,
      subString: "Apple",
      identity: "Safari",
      versionSearch: "Version"
    },
    {
      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.userAgent,
         subString: "iPhone",
         identity: "iPhone/iPod"
      },
    {
      string: navigator.platform,
      subString: "Linux",
      identity: "Linux"
    }
  ]

};
BrowserDetect.init();


/*
To the poor soul that inherits this mess:

A lot of the code below is obsolete. Much of it is inherited
from earlier iterations of this site. Most of the stuff pertaining
to Grid is no longer used.

If you want to attempt to tidy it up, I wish you the best
of British luck.
*/


(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']
    // ];
    //
    //
    //
    // 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('');

        if($('wrapper').hasClassName('flash')){
          thisMovie("flashWrapper").onJSOverlayClosed();
        }

        // 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.Base.load('/pages/display/our_clients');
    // fbf.Grid.Base.load('/pages/display/engagement');
    // fbf.Grid.Base.load('/casestudy/twinings_employer_brand');


    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();


      });
    }

    // set initial content dimensions for both Flash and HTML fallback versions
    resizeContent();

    // if flash is supported, listen for browser resize and adjust content dims accordingly
    if(flashembed.isSupported([9,0])){
      $('wrapper').addClassName('flash');
      Event.observe(window, 'resize', resizeContent);
    }
  }

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

  function resizeContent(){
    var d = document.viewport.getDimensions(),
        headHeight = $('navigation').getHeight(),
        footHeight = $('footer').getHeight(),
        h;

    if ($('modulesWrapper')) {
      if($$('.flash').length){
        h = d.height-(headHeight+footHeight);
      } else {
        h = $('modulesWrapper').getHeight();
      }

      $('content').setStyle({
        height: h+'px'
      });
    } else {
      $('navigation').setStyle({
        height: '850px'
      });
    };
  }

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

  return {
    get : get,
    load : function(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 || url.indexOf('case_study')!=-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);
      }
    },
    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);
      }
    }
  }
}();

function insertVideo(containerId, options, fallbackOptions){
  flowplayer(containerId, {
    src: "/img/site/flash/flowplayer.commercial-3.1.5.swf",
    version: [9, 0],
    onFail: function(){
      var el = document.getElementById(containerId);
      var html = '';

      if(BrowserDetect.browser==="Safari"){
        html += '<video src="'+fallbackOptions.mp4Url+'" width="810" height="468" controls preload autoplay>';
        html += '</video>';
      }else{
        html += '<object width="810" height="468" data="'+fallbackOptions.wmvUrl+'" type="application/x-mplayer2">';
        html += '  <param type="application/x-mplayer2" valuetype="ref" value="'+fallbackOptions.wmvUrl+'" name="src">';
        html += '  <param value="1" name="animationatStart">';
        html += '  <param value="1" name="transparentatStart">';
        html += '  <param value="1" name="autoStart">';
        html += '  <param value="1" name="ShowControls">';
        html += '  <param value="0" name="ShowDisplay">';
        html += '  <param value="0" name="ShowStatusBar">';
        html += '  <param value="0" name="loop">';
        html += '  <param value="0" name="displaysize">';
        html += '  <embed type="application/x-mplayer2" src="'+fallbackOptions.wmvUrl+'" name="MediaPlayer" width="810" height="468" ShowControls="1" ShowStatusBar="0" ShowDisplay="0" autostart="0"> </embed>';
        html += '  <strong>Error:</strong> Embedding <a href="'+fallbackOptions.wmvUrl+'">'+fallbackOptions.wmvUrl+'</a> with the <a href="http://www.microsoft.com/windows/windowsmedia/download/plugin.aspx">Windows Media Plugin</a> failed.';
        html += '</object>';
      }

      el.innerHTML = html;
    }
  },options);
}

function thisMovie(movieName) {
  if (navigator.appName.indexOf("Microsoft") != -1) {
     return window[movieName];
  } else {
     return document[movieName];
  }
}


function loadModule(contentUrl){
  if(typeof contentUrl !== 'undefined'){
    fbf.Grid.Base.load(contentUrl);
  }
}
