var ignoreUrlChange = false;
var ignoreWaypoints = true;

var deHash = function (hashString) {
  return hashString.slice(1);
};

Session.setDefault('urlHash', location.hash);
$(window).on('hashchange', function () {
  Session.set('urlHash', location.hash);
});

// need an actual function to only debounce inside the if statement
var actuallyUpdateUrl = _.debounce(function (el) {
  var docsType = Session.get("fullApi") ? "full" : "basic";
  var newHash = "#/" + docsType + "/" + el.id;

  if (window.location.hash !== newHash) {
    ignoreUrlChange = true;
    window.location.replace(newHash);
  }
}, 100);

var updateUrlFromWaypoint = function (el) {
  if (! ignoreWaypoints) {
    actuallyUpdateUrl(el);
  }
};

Tracker.autorun(function () {
  // returns a "location" like object with all of the url parts
  var current = Session.get('urlHash');

  // If the URL changes from a waypoint, do nothing
  if (ignoreUrlChange) {
    ignoreUrlChange = false;
    return;
  }

  // If the URL changes, close the sidebar
  Session.set("sidebarOpen", false);

  // redirect routes with no trailing slash
  if (current === "#/basic") {
    navigate("#/basic/");
    return;
  } else if (current === "#/full") {
    navigate("#/full/");
    return;
  }

  if (current.match(/^#\/basic\//)) {
    Session.set("fullApi", false);
  } else if (current.match(/^#\/full\//)) {
    Session.set("fullApi", true);
  } else {
    if (current) {
      // XXX COMPAT WITH old docs
      navigate("#/full/" + deHash(current));
    } else {
      if (localStorage.getItem("fullApi") === "true") {
        navigate("#/full/");
      } else {
        navigate("#/basic/");
      }
    }
    return;
  }

  Tracker.afterFlush(function () {
    setTimeout(function () {
      var id = current.split('/')[2];

      var targetLocation = 0;
      if (id) {
        // XXX this selector is tied to the structure of the document so tightly
        // because sometimes we have two elements with the same id.
        // For example: "Quick start" section appears in both basic docs and full
        // docs. Since we hide parts of DOM with CSS the user doesn't see both at
        // the same time but they are still both in the DOM. New browsers allow us
        // to query by id even if ids repeat themselves. We cannot change it
        // easily because the markdown parser always produces an id for headings.
        var selector = "#main>:not(.hidden) #" + id;
        var foundElement = $(selector);
        if (foundElement.get(0)) {
          targetLocation = $(".main-content").scrollTop() + foundElement.offset().top - $(".main-content").offset().top;
        }
      }

      ignoreWaypoints = true;
      $(".main-content").animate({
          scrollTop: targetLocation
      }, 500, function () {
        ignoreWaypoints = false;
      });
    }, 0);
  });
});

// Remember which docs page (full or basic) we were on last, and use it as
// the default next time when we visit docs.meteor.com
// 
// Make sure that this block is below the initial URL logic
Tracker.autorun(function () {
  localStorage.setItem("fullApi", !! Session.get("fullApi"));
});

var setHashFromCurrentPosition = _.debounce(function () {
  var tocClass = Session.get("fullApi") ? ".full-api-toc" : ".basic-toc";

  // get all IDs that are linked to from sidebar
  var ids = {};
  $("#nav " + tocClass + " a").each(function (i, el) {
    ids[_.last(el.href.split("/"))] = true;
  });

  var pageEls = $('.main-content :not(.hidden) [id]');
  var correctIndex = -1;
  var lastIndex = -1;

  // how far from the top of the page is the waypoint triggered?
  var distanceFromTop = 150;

  pageEls.each(function (i, el) {
    if (! ids[el.id]) {
      // only add waypoints to things that have sidebar links
      return;
    }

    if ($(el).offset().top > distanceFromTop) {
      if (correctIndex === -1) { // don't do this twice
        // If this element is below the cutoff, we want to set the URL to
        // link to the previous element
        correctIndex = lastIndex;
      }
    }

    lastIndex = i;
  });

  if (correctIndex !== -1) {
    updateUrlFromWaypoint(pageEls[correctIndex]);
  }
}, 200);

Template.body.events({
  "scroll .main-content": function () {
    setHashFromCurrentPosition();
  }
});


@@ -2379,16 +2379,220 @@
 adings.%0A
+        var cssEscape = function (selector) %7B%0A          // XXX maybe use https://github.com/mathiasbynens/CSS.escape/blob/master/css.escape.js?%0A          return selector.replace(/%5C$/g, %22%5C%5C$%22);%0A        %7D;%0A
         
@@ -2632,18 +2632,29 @@
 n) #%22 + 
+cssEscape(
 id
+)
 ;%0A      

Fix `http://docs.meteor.com/#/full/template_$` URL detection