(function() {

  /* 
    MLC JavaScript library
    
    Created by Gerrit Kaiser on 2011-11-14.
    Copyright 2011 Gerrit Kaiser. All rights reserved.
  */

  var mlc, stretchImg;
  var __hasProp = Object.prototype.hasOwnProperty, __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (__hasProp.call(this, i) && this[i] === item) return i; } return -1; };

  $.fn.interceptClick = function(action) {
    return this.click(function(e) {
      if (action) action();
      e.preventDefault();
      return e.stopPropagation();
    });
  };

  $.fn.openContent = function() {
    var $content, showContent;
    $content = this;
    showContent = function() {
      return $content.removeClass('closed').addClass('open');
    };
    setTimeout(showContent, 0);
    $content.show();
    $content.css({
      visibility: 'visible'
    });
    return $(window).scrollTop(0);
  };

  $.fn.closeContent = function() {
    var $content, hideContent;
    $content = this;
    hideContent = function() {
      if ($content.is('.details')) {
        return $content.css({
          visibility: 'hidden'
        });
      } else {
        return $content.hide();
      }
    };
    setTimeout(hideContent, 150);
    return $content.removeClass('open').addClass('closed');
  };

  $.fn.toggleContent = function() {
    if (this.is('.open')) {
      return this.closeContent();
    } else {
      return this.openContent();
    }
  };

  $.fn.toggleableDetails = function() {
    var $details, $nav;
    $details = this.addClass('open');
    if (!$details.children('nav.toggle').length) {
      $nav = $('<nav class="toggle"><a href="#" rel="up">Show/Hide</a></nav>');
      $nav.interceptClick(function() {
        return $details.toggleContent();
      });
      return $nav.prependTo($details);
    }
  };

  $.fn.swapInContent = function() {
    var $eventSrc, $newContent, openContent;
    $newContent = this;
    $('body>.open').closeContent();
    openContent = function() {
      return $newContent.openContent();
    };
    setTimeout(openContent, 0);
    $eventSrc = $newContent.length ? $newContent : $('body');
    return $eventSrc.trigger('swapInDone');
  };

  $.fn.setBodyclass = function() {
    var bodyclass;
    bodyclass = this.data('bodyclass') ? this.data('bodyclass') : '';
    return $('body').attr('class', bodyclass);
  };

  $.fn.setTitle = function() {
    if (!$('body').data('title')) $('body').data('title', $('title').text());
    return $('title').text(this.data('title'));
  };

  $.fn.ajaxNavigation = function() {
    var fetch, interceptInternalLinkClicks, markCurrentSection, navigate, navigateToNewState, trackWithGoogleAnalytics;
    markCurrentSection = function(nav, href) {
      var firstSegment;
      firstSegment = "/" + (href.split('/')[1]) + "/";
      return $(nav).find(':link').removeClass('current').filter("[href='" + firstSegment + "']").addClass('current');
    };
    fetch = function(href, callback) {
      return $.get(href, function(data) {
        var $page, $response;
        $response = $(data);
        $page = $response.filter('.page');
        $page.data('title', $response.filter('title').text());
        if ($page.length) {
          return callback($page);
        } else {

        }
      });
    };
    $.fn.filterPath = function(path) {
      var normalise;
      normalise = function(path) {
        return path.replace(/\/$/, '');
      };
      return this.filter(function() {
        return normalise($(this).data('path')) === normalise(path);
      });
    };
    navigate = function(href) {
      var $content;
      $(document).trigger('navigate');
      markCurrentSection('body>nav', href);
      $content = $('.page').filterPath(href);
      if (href === '/') {
        return $().swapInContent();
      } else if ($content.is('.closed')) {
        return $content.swapInContent();
      } else if (!$content.length) {
        return fetch(href, function(content) {
          return content.addClass('closed').appendTo('body').swapInContent();
        });
      }
    };
    navigateToNewState = function() {
      var href;
      href = location.pathname;
      if (!(href === '' || href === '/')) return navigate(href);
    };
    trackWithGoogleAnalytics = function() {
      if (window._gaq) {
        return window._gaq.push(['_trackPageview', location.pathname]);
      }
    };
    interceptInternalLinkClicks = function(e) {
      var commandOrMiddleClick, dummyLink, href;
      href = $(this).attr('href');
      commandOrMiddleClick = e.metaKey || e.which === 2;
      dummyLink = href === '#';
      if (commandOrMiddleClick || dummyLink) return true;
      navigate(href);
      history.pushState(null, null, href);
      return e.preventDefault();
    };
    $(window).on('popstate', navigateToNewState);
    $(window).on('popstate', trackWithGoogleAnalytics);
    return this.on('click', ':link', interceptInternalLinkClicks);
  };

  window.SwipeAlternative = function(container, options) {
    var old;
    if (Swipe.call(this, container, options) === null) return null;
    if ((old = container.getBoundingClientRect) && !container.getBoundingClientRect().width) {
      container.getBoundingClientRect = function() {
        var rect;
        rect = old();
        return {
          width: rect.right - rect.left
        };
      };
    }
    this.element.style.display = 'block';
    this.element.style.position = 'absolute';
    this.element.style.left = '0px';
    return this.setup();
  };

  SwipeAlternative.prototype = new Swipe;

  SwipeAlternative.prototype.constructor = SwipeAlternative;

  SwipeAlternative.prototype.slide = function(index, duration) {
    var props;
    var _this = this;
    if (this.index !== index) {
      props = {
        left: -(index * this.width) + 'px'
      };
      jQuery(this.element).animate(props, duration, function() {
        _this.callback(null, index, _this.slides[index]);
        if (_this.delay) return _this.begin();
      });
    }
    return this.index = index;
  };

  $.fn.swipeOnce = function(opts) {
    var swiper, wrapper;
    if (!this.data('swipe')) {
      wrapper = this.wrap('<div class="slider"></div>').parent()[0];
      swiper = Modernizr.csstransforms ? new Swipe(wrapper, opts || {}) : new SwipeAlternative(wrapper, opts || {});
      this.data('swipe', swiper);
    }
    return this.data('swipe');
  };

  stretchImg = function(img) {
    var $img, $root, bgCSS, bgHeight, bgOffset, bgWidth, imgRatio;
    $img = $(img);
    $root = __indexOf.call(window, 'onorientationchange') >= 0 ? $(document) : $(window);
    try {
      imgRatio = $img.width() / $img.height();
      bgCSS = {
        left: 0,
        top: 0
      };
      bgWidth = $root.width();
      bgHeight = bgWidth / imgRatio;
      if (bgHeight >= $root.height()) {
        bgOffset = (bgHeight - $root.height()) / 2;
        $.extend(bgCSS, {
          top: "-" + bgOffset + "px"
        });
      } else {
        bgHeight = $root.height();
        bgWidth = bgHeight * imgRatio;
        bgOffset = (bgWidth - $root.width()) / 2;
        $.extend(bgCSS, {
          left: "-" + bgOffset + "px"
        });
      }
      return $img.width(bgWidth).height(bgHeight).css(bgCSS);
    } catch (err) {

    }
  };

  $.fn.stretchBackgroundWithin = function() {
    var $imgs, containerStyles, imageStyles;
    containerStyles = {
      left: 0,
      top: 0,
      position: 'fixed',
      overflow: 'hidden',
      zIndex: 0,
      margin: 0,
      padding: 0,
      height: "100%",
      width: "100%"
    };
    imageStyles = {
      margin: 0,
      padding: 0,
      border: 'none',
      height: 'auto',
      width: 'auto',
      position: 'relative'
    };
    $imgs = this.css(containerStyles).find('img').css(imageStyles);
    $imgs.load(function(e) {
      return $(e.target).each(function() {
        return stretchImg(this);
      });
    });
    $imgs.each(function() {
      return stretchImg(this);
    });
    $(window).resize(function() {
      return $imgs.each(function() {
        return stretchImg(this);
      });
    });
    $imgs.load(function() {
      if ($(this).width() > $(window).width()) {
        $(this).css('width', '');
        return stretchImg(this);
      }
    });
    return this;
  };

  $.fn.backgroundSlideshow = function(delay, speed) {
    return this.each(function() {
      var $dots, $gallery, $galleryContainer, highlightDot, opts, show;
      $gallery = $(this);
      $gallery.stretchBackgroundWithin();
      $dots = $gallery.append('<nav class="dots"><ol></ol></nav>').find('nav.dots ol');
      highlightDot = function(event, index, slide) {
        var src;
        src = $(slide).children('img').attr('src');
        return $dots.find('a').removeClass('current').eq(index).addClass('current');
      };
      $galleryContainer = $gallery.children('ul');
      if ($galleryContainer.children().length < 2) return;
      opts = {
        auto: delay,
        speed: speed,
        callback: highlightDot
      };
      show = $galleryContainer.swipeOnce(opts);
      $gallery.find('img').each(function(index) {
        var $dot;
        $dot = $('<li><a href="#">' + (index + 1) + '</a></li>');
        $dot.interceptClick(function() {
          show.slide($dots.children().index($dot), speed);
          return show.stop();
        });
        return $dot.appendTo($dots);
      });
      return $dots.find('a').eq(0).addClass('current');
    });
  };

  $.fn.slidingGallery = function() {
    return this.each(function() {
      var $gallery, moreThanOneItem, navLink, show;
      $gallery = $(this);
      show = $gallery.children('ul').swipeOnce();
      navLink = function(dir) {
        return $('<a rel="' + dir + '" href="#">' + dir + '</a>').interceptClick(function() {
          return show[dir]();
        });
      };
      moreThanOneItem = $gallery.find('li').length > 1;
      if (moreThanOneItem) {
        return $gallery.prepend(navLink('prev')).append(navLink('next'));
      }
    });
  };

  $.fn.fakelink = function() {
    var addCurrent, removeCurrent;
    addCurrent = function() {
      return $(this).find('a').addClass('current');
    };
    removeCurrent = function() {
      return $(this).find('a').removeClass('current');
    };
    this.css('cursor', 'pointer').mousedown(addCurrent).mouseup(removeCurrent);
    return this.click(function(e) {
      if (!$(e.target).is('a')) return $(this).find('a').eq(0).trigger('click');
    });
  };

  mlc = window.mlc = window.mlc || {};

  mlc.createMap = function(canvas) {
    var london, map;
    london = new google.maps.LatLng(51.516, -0.129);
    map = new google.maps.Map(canvas, {
      zoom: 12,
      center: london,
      mapTypeId: google.maps.MapTypeId.TERRAIN,
      disableDefaultUI: true
    });
    google.maps.event.addListener(map, 'click', mlc.resetMarkers);
    return map;
  };

  mlc.sign = function(href, text) {
    return "<div class=\"sign\">\n  <span class=\"top\"></span>\n  <span class=\"right\"></span>\n  <span class=\"bottom\"></span>\n  <span class=\"left\"></span>\n  <span class=\"pointer\"></span>\n  <a href=\"" + href + "\">" + text + "<span class=\"icon\"></span></a>\n</div>";
  };

  mlc.resetMarkers = function() {
    mlc.activeSign && mlc.activeSign.close();
    return mlc.activeMarker && mlc.activeMarker.reset();
  };

  mlc.createSign = function(marker, loc) {
    var sign, signHeight, signWidth;
    signWidth = 210;
    signHeight = 81;
    sign = new InfoBox({
      content: $(mlc.sign(loc.href, loc.title))[0],
      pixelOffset: new google.maps.Size(1 - signWidth / 2, -(signHeight + 6)),
      closeBoxURL: '',
      infoBoxClearance: new google.maps.Size(10, 10)
    });
    sign.activate = function() {
      sign.open(mlc.projectsMap, marker);
      return mlc.activeSign = sign;
    };
    return sign;
  };

  mlc.markerIcon = function(suffix) {
    return "/javascripts/images/marker_" + suffix + ".png";
  };

  mlc.addMarker = function(loc) {
    return require(['/javascripts/infobox.js'], function() {
      var marker, sign;
      marker = new google.maps.Marker({
        map: mlc.projectsMap,
        position: new google.maps.LatLng(loc.position.lat, loc.position.lng),
        title: loc.title,
        shadow: mlc.markerIcon('shadow'),
        animation: google.maps.Animation.DROP,
        icon: loc.archived ? mlc.markerIcon('brown') : mlc.markerIcon('yellow')
      });
      marker.reset = function() {
        return this.setIcon(mlc.markerIcon('yellow'));
      };
      marker.activate = function() {
        marker.setIcon(mlc.markerIcon('white'));
        return mlc.activeMarker = marker;
      };
      sign = mlc.createSign(marker, loc);
      return google.maps.event.addListener(marker, 'click', function() {
        mlc.resetMarkers();
        sign.activate();
        return marker.activate();
      });
    });
  };

  mlc.randomPositionWithinMap = function(map) {
    var bounds, latSpan, lngSpan, northEast, pos, southWest;
    bounds = map.getBounds();
    southWest = bounds.getSouthWest();
    northEast = bounds.getNorthEast();
    lngSpan = northEast.lng() - southWest.lng();
    latSpan = northEast.lat() - southWest.lat();
    return pos = {
      lat: southWest.lat() + latSpan * Math.random(),
      lng: southWest.lng() + lngSpan * Math.random()
    };
  };

  $.fn.geoToCoords = function() {
    return {
      lat: $(this).find('.geo .latitude').text(),
      lng: $(this).find('.geo .longitude').text()
    };
  };

  mlc.markOnMap = function(vcards, map) {
    return vcards.each(function(i) {
      var loc, placeMarker;
      loc = {
        position: $(this).geoToCoords(),
        title: $(this).find('.fn').text(),
        href: $(this).find('.fn a').attr('href'),
        archived: $(this).is('.archived')
      };
      placeMarker = function() {
        return mlc.addMarker(loc);
      };
      return setTimeout(placeMarker, 100 * i);
    });
  };

  mlc.mapClickabilityChromeWorkaround = function() {
    return $('body>.background.gallery');
  };

  mlc.mapLoad = function() {
    if (!$('#map_canvas').length) {
      return require(['//maps.googleapis.com/maps/api/js?sensor=false&callback=mlcMapInit']);
    } else {
      $('#map_canvas').show();
      return mlc.mapClickabilityChromeWorkaround().hide();
    }
  };

  mlc.mapHide = function() {
    mlc.mapClickabilityChromeWorkaround().show();
    return $('#map_canvas').hide();
  };

  window.mlcMapInit = mlc.mapInit = function() {
    var alreadyMarked, canvas, map, markOnce;
    canvas = $('<div id="map_canvas"></div>').appendTo('body');
    map = mlc.createMap(canvas[0]);
    mlc.projectsMap = map;
    mlc.mapClickabilityChromeWorkaround().hide();
    alreadyMarked = false;
    markOnce = function() {
      if (!alreadyMarked) {
        mlc.markOnMap($('section .vcard'), mlc.projectsMap);
        return alreadyMarked = true;
      }
    };
    return google.maps.event.addListener(mlc.projectsMap, 'bounds_changed', markOnce);
  };

  $.fn.initSharingButtons = function() {
    if (this.find('.twitter-share-button, .twitter-follow-button').length) {
      $.ajax({
        url: '//platform.twitter.com/widgets.js',
        dataType: 'script',
        cache: true
      });
    }
    return this;
  };

  $.fn.initOnce = function() {
    var slideshowDelay, slideshowSpeed;
    if (!this.data('isInited')) {
      slideshowDelay = 7000;
      slideshowSpeed = 400;
      this.find('.background.gallery').backgroundSlideshow(slideshowDelay, slideshowSpeed);
      this.find('.content .gallery').slidingGallery();
      this.find('.details').toggleableDetails();
      this.find('.content>article').fakelink();
      this.initSharingButtons();
      this.data('isInited', true);
    }
    return this;
  };

  $.fn.activate = function() {
    var mainSlideShow, pageIsOpen, soFastItsBarelyNoticable;
    soFastItsBarelyNoticable = 30;
    if (this.is('.map')) {
      mlc.mapLoad();
    } else {
      mlc.mapHide();
    }
    this.find('.details').openContent();
    mainSlideShow = $('body>.background.gallery').find('ul').data('swipe');
    pageIsOpen = this.is('.page') || this.has('.page.open').length;
    if (pageIsOpen && mainSlideShow) {
      $('body>.background.gallery nav').fadeOut(soFastItsBarelyNoticable);
      mainSlideShow.stop();
    } else {
      $('body>.background.gallery nav').fadeIn(soFastItsBarelyNoticable);
      mainSlideShow && mainSlideShow.resume();
    }
    return this;
  };

  $(document).ready(function() {
    var supportsHTML5History;
    $('body>.page').addClass('open');
    $('body').initOnce().activate();
    if ($.browser.mozilla && Modernizr.csstransforms) {
      $(document).on('mouseenter', '.gallery iframe', function() {
        return $(this).parents().each(function() {
          var transform;
          transform = $(this).css('-moz-transform');
          if (transform !== 'none') {
            $(this).data('old-transform', transform);
            return $(this).css('-moz-transform', 'none');
          }
        });
      });
      $(document).on('click', ':link', function(e) {
        return $('.gallery iframe').parents().each(function() {
          var oldTransform;
          if (oldTransform = $(this).data('old-transform')) {
            $(this).css('-moz-transform', oldTransform);
            return $(this).removeData('old-transform');
          }
        });
      });
    }
    supportsHTML5History = window.history && window.history.pushState;
    if (supportsHTML5History) {
      $('body').ajaxNavigation();
      return $(document).on('swapInDone', function(e) {
        var $newContent;
        $newContent = $(e.target);
        $newContent.setTitle();
        $newContent.setBodyclass();
        return $newContent.initOnce().activate();
      });
    }
  });

}).call(this);

