/*
 * 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.
 */

/* Note: This file is originally from the Apache Spark project. */

/* Custom JavaScript code in the MarkDown docs */

// Enable language-specific code tabs
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);
      var id = "tab_" + lang + "_" + 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_' + lang + '" 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);
  });
}

function makeCollapsable(elt, accordionClass, accordionBodyId, title) {
  $(elt).addClass("accordion-inner");
  $(elt).wrap('<div class="accordion ' + accordionClass + '"></div>')
  $(elt).wrap('<div class="accordion-group"></div>')
  $(elt).wrap('<div id="' + accordionBodyId + '" class="accordion-body collapse"></div>')
  $(elt).parent().before(
    '<div class="accordion-heading">' +
      '<a class="accordion-toggle" data-toggle="collapse" href="#' + accordionBodyId + '">' +
             title +
      '</a>' +
    '</div>'
  );
}

// Enable "view solution" sections (for exercises)
function viewSolution() {
  var counter = 0
  $("div.solution").each(function() {
    var id = "solution_" + counter
    makeCollapsable(this, "", id,
      '<i class="icon-ok-sign" style="text-decoration: none; color: #0088cc">' +
      '</i>' + "View Solution");
    counter++;
  });
}

// 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() {
  console.log("HERE");
  if (window.location.hash && $(window.location.hash).length) {
    console.log("HERE2", $(window.location.hash), $(window.location.hash).offset().top);
    var newTop = $(window.location.hash).offset().top - 57;
    $(window).scrollTop(newTop);
  }
}

$(function() {
  codeTabs();
  viewSolution();

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