/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Custom JavaScript code in the MarkDown docs */

// Enable language-specific code tabs
// similar to spark code tabs, except can have spaces and periods
function codeTabs() {
  var counter = 0;
  var langImages = {
    "scala": "img/scala-sm.png",
    "python": "img/python-sm.png",
    "java": "img/java-sm.png"
  };
  $("div.codetabs").each(function() {
    $(this).addClass("tab-content");

    // Insert the tab bar
    var tabBar = $('<ul class="nav nav-tabs" data-tabs="tabs"></ul>');
    $(this).before(tabBar);

    // Add each code sample to the tab bar:
    var codeSamples = $(this).children("div");
    codeSamples.each(function() {
      $(this).addClass("tab-pane");
      var lang = $(this).data("lang");
      var image = $(this).data("image");
      var notabs = $(this).data("notabs");
      var capitalizedLang = lang.substr(0, 1).toUpperCase() + lang.substr(1);
      
      // for flexibility, allow spaces and periods
      var langConv = lang.replace(/\./g, "_");
      langConv = langConv.replace(/ /g, "_");
      
      var id = "tab_" + langConv + "_" + counter;
      $(this).attr("id", id);
      if (image != null && langImages[lang]) {
        var buttonLabel = "<img src='" +langImages[lang] + "' alt='" + capitalizedLang + "' />";
      } else if (notabs == null) {
        var buttonLabel = "<b>" + capitalizedLang + "</b>";
      } else {
        var buttonLabel = ""
      }
      tabBar.append(
        '<li><a class="tab_' + langConv + '" href="#' + id + '">' + buttonLabel + '</a></li>'
      );
    });

    codeSamples.first().addClass("active");
    tabBar.children("li").first().addClass("active");
    counter++;
  });
  $("ul.nav-tabs a").click(function (e) {
    // Toggling a tab should switch all tabs corresponding to the same language
    // while retaining the scroll position
    e.preventDefault();
    var scrollOffset = $(this).offset().top - $(document).scrollTop();
    $("." + $(this).attr('class')).tab('show');
    $(document).scrollTop($(this).offset().top - scrollOffset);
  });
}

// Code tabs that don't switch all tabs
//
// Note that codeTabs2() should be called after codeTabs(). If codeTabs2()
// were called first, 2 click events would get attached to the tabs since
// "ul.nav-tabs a" and "ul.nav-tabs2 a" would both apply. Note that 
// nav-tabs and nav-tabs2 are both used because css doesn't support
// inheritance, and nav-tabs has a significant amount of styling in
// bootstrap.css.
function codeTabs2() {
  var counter = 0;
  var langImages = {
    "scala": "img/scala-sm.png",
    "python": "img/python-sm.png",
    "java": "img/java-sm.png"
  };
  $("div.codetabs2").each(function() {
    $(this).addClass("tab-content");

    // Insert the tab bar
    var tabBar = $('<ul class="nav nav-tabs nav-tabs2" data-tabs="tabs"></ul>');
    $(this).before(tabBar);

    // Add each code sample to the tab bar:
    var codeSamples = $(this).children("div");
    codeSamples.each(function() {
      $(this).addClass("tab-pane");
      var lang = $(this).data("lang");
      var image = $(this).data("image");
      var notabs = $(this).data("notabs");
      
      // for flexibility, allow spaces and periods
      var langConv = lang.replace(/\./g, "_");
      langConv = langConv.replace(/ /g, "_");
      
      var id = "tab_" + langConv + "_" + counter;
      $(this).attr("id", id);
      if (image != null && langImages[lang]) {
        var buttonLabel = "<img src='" +langImages[lang] + "' alt='" + lang + "' />";
      } else if (notabs == null) {
          var buttonLabel = "<b>" + lang + "</b>";
      } else {
        var buttonLabel = ""
      }
      tabBar.append(
          '<li><a class="tab_' + langConv + '" href="#' + id + '">' + buttonLabel + '</a></li>'
      );
    });

    codeSamples.first().addClass("active");
    tabBar.children("li").first().addClass("active");
    counter++;
  });
  $("ul.nav-tabs2 a").click(function (e) {
    e.preventDefault();
    var scrollOffset = $(this).offset().top - $(document).scrollTop();
    $(this).tab('show'); // only switch current tab - makes comparisons feel slightly better on this page
    $(document).scrollTop($(this).offset().top - scrollOffset);
  });
}


// A script to fix internal hash links because we have an overlapping top bar.
// Based on https://github.com/twitter/bootstrap/issues/193#issuecomment-2281510
function maybeScrollToHash() {
  if (window.location.hash && $(window.location.hash).length) {
    var newTop = $(window.location.hash).offset().top - 57;
    $(window).scrollTop(newTop);
  }
}

$(function() {
  codeTabs();
  codeTabs2();
  // Display anchor links when hovering over headers. For documentation of the
  // configuration options, see the AnchorJS documentation.
  anchors.options = {
    placement: 'left'
  };
  anchors.add();

  $(window).bind('hashchange', function() {
    maybeScrollToHash();
  });

  // Scroll now too in case we had opened the page on a hash, but wait a bit because some browsers
  // will try to do *their* initial scroll after running the onReady handler.
  $(window).load(function() { setTimeout(function() { maybeScrollToHash(); }, 25); }); 
});
