// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

var PERMANENT_URL_PREFIX = '/static/';

var SLIDE_CLASSES = ['far-past', 'past', 'current', 'next', 'far-next'];

var PM_TOUCH_SENSITIVITY = 15;

var curSlide;

/* ---------------------------------------------------------------------- */
/* classList polyfill by Eli Grey
 * (http://purl.eligrey.com/github/classList.js/blob/master/classList.js) */

if (
  typeof document !== 'undefined' &&
  !('classList' in document.createElement('a'))
) {
  (function(view) {
    var classListProp = 'classList',
      protoProp = 'prototype',
      elemCtrProto = (view.HTMLElement || view.Element)[protoProp],
      objCtr = Object;
    (strTrim =
      String[protoProp].trim ||
      function() {
        return this.replace(/^\s+|\s+$/g, '');
      }),
      (arrIndexOf =
        Array[protoProp].indexOf ||
        function(item) {
          for (var i = 0, len = this.length; i < len; i++) {
            if (i in this && this[i] === item) {
              return i;
            }
          }
          return -1;
        }),
      // Vendors: please allow content code to instantiate DOMExceptions
      (DOMEx = function(type, message) {
        this.name = type;
        this.code = DOMException[type];
        this.message = message;
      }),
      (checkTokenAndGetIndex = function(classList, token) {
        if (token === '') {
          throw new DOMEx(
            'SYNTAX_ERR',
            'An invalid or illegal string was specified'
          );
        }
        if (/\s/.test(token)) {
          throw new DOMEx(
            'INVALID_CHARACTER_ERR',
            'String contains an invalid character'
          );
        }
        return arrIndexOf.call(classList, token);
      }),
      (ClassList = function(elem) {
        var trimmedClasses = strTrim.call(elem.className),
          classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [];
        for (var i = 0, len = classes.length; i < len; i++) {
          this.push(classes[i]);
        }
        this._updateClassName = function() {
          elem.className = this.toString();
        };
      }),
      (classListProto = ClassList[protoProp] = []),
      (classListGetter = function() {
        return new ClassList(this);
      });
    // Most DOMException implementations don't allow calling DOMException's toString()
    // on non-DOMExceptions. Error's toString() is sufficient here.
    DOMEx[protoProp] = Error[protoProp];
    classListProto.item = function(i) {
      return this[i] || null;
    };
    classListProto.contains = function(token) {
      token += '';
      return checkTokenAndGetIndex(this, token) !== -1;
    };
    classListProto.add = function(token) {
      token += '';
      if (checkTokenAndGetIndex(this, token) === -1) {
        this.push(token);
        this._updateClassName();
      }
    };
    classListProto.remove = function(token) {
      token += '';
      var index = checkTokenAndGetIndex(this, token);
      if (index !== -1) {
        this.splice(index, 1);
        this._updateClassName();
      }
    };
    classListProto.toggle = function(token) {
      token += '';
      if (checkTokenAndGetIndex(this, token) === -1) {
        this.add(token);
      } else {
        this.remove(token);
      }
    };
    classListProto.toString = function() {
      return this.join(' ');
    };

    if (objCtr.defineProperty) {
      var classListPropDesc = {
        get: classListGetter,
        enumerable: true,
        configurable: true,
      };
      try {
        objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
      } catch (ex) {
        // IE 8 doesn't support enumerable:true
        if (ex.number === -0x7ff5ec54) {
          classListPropDesc.enumerable = false;
          objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
        }
      }
    } else if (objCtr[protoProp].__defineGetter__) {
      elemCtrProto.__defineGetter__(classListProp, classListGetter);
    }
  })(self);
}
/* ---------------------------------------------------------------------- */

/* Slide movement */

function hideHelpText() {
  document.getElementById('help').style.display = 'none';
}

function getSlideEl(no) {
  if (no < 0 || no >= slideEls.length) {
    return null;
  } else {
    return slideEls[no];
  }
}

function updateSlideClass(slideNo, className) {
  var el = getSlideEl(slideNo);

  if (!el) {
    return;
  }

  if (className) {
    el.classList.add(className);
  }

  for (var i in SLIDE_CLASSES) {
    if (className != SLIDE_CLASSES[i]) {
      el.classList.remove(SLIDE_CLASSES[i]);
    }
  }
}

function updateSlides() {
  if (window.trackPageview) window.trackPageview();

  for (var i = 0; i < slideEls.length; i++) {
    switch (i) {
      case curSlide - 2:
        updateSlideClass(i, 'far-past');
        break;
      case curSlide - 1:
        updateSlideClass(i, 'past');
        break;
      case curSlide:
        updateSlideClass(i, 'current');
        break;
      case curSlide + 1:
        updateSlideClass(i, 'next');
        break;
      case curSlide + 2:
        updateSlideClass(i, 'far-next');
        break;
      default:
        updateSlideClass(i);
        break;
    }
  }

  triggerLeaveEvent(curSlide - 1);
  triggerEnterEvent(curSlide);

  window.setTimeout(function() {
    // Hide after the slide
    disableSlideFrames(curSlide - 2);
  }, 301);

  enableSlideFrames(curSlide - 1);
  enableSlideFrames(curSlide + 2);

  updateHash();
}

function prevSlide() {
  hideHelpText();
  if (curSlide > 0) {
    curSlide--;

    updateSlides();
  }

  if (notesEnabled) localStorage.setItem(destSlideKey(), curSlide);
}

function nextSlide() {
  hideHelpText();
  if (curSlide < slideEls.length - 1) {
    curSlide++;

    updateSlides();
  }

  if (notesEnabled) localStorage.setItem(destSlideKey(), curSlide);
}

/* Slide events */

function triggerEnterEvent(no) {
  var el = getSlideEl(no);
  if (!el) {
    return;
  }

  var onEnter = el.getAttribute('onslideenter');
  if (onEnter) {
    new Function(onEnter).call(el);
  }

  var evt = document.createEvent('Event');
  evt.initEvent('slideenter', true, true);
  evt.slideNumber = no + 1; // Make it readable

  el.dispatchEvent(evt);
}

function triggerLeaveEvent(no) {
  var el = getSlideEl(no);
  if (!el) {
    return;
  }

  var onLeave = el.getAttribute('onslideleave');
  if (onLeave) {
    new Function(onLeave).call(el);
  }

  var evt = document.createEvent('Event');
  evt.initEvent('slideleave', true, true);
  evt.slideNumber = no + 1; // Make it readable

  el.dispatchEvent(evt);
}

/* Touch events */

function handleTouchStart(event) {
  if (event.touches.length == 1) {
    touchDX = 0;
    touchDY = 0;

    touchStartX = event.touches[0].pageX;
    touchStartY = event.touches[0].pageY;

    document.body.addEventListener('touchmove', handleTouchMove, true);
    document.body.addEventListener('touchend', handleTouchEnd, true);
  }
}

function handleTouchMove(event) {
  if (event.touches.length > 1) {
    cancelTouch();
  } else {
    touchDX = event.touches[0].pageX - touchStartX;
    touchDY = event.touches[0].pageY - touchStartY;
    event.preventDefault();
  }
}

function handleTouchEnd(event) {
  var dx = Math.abs(touchDX);
  var dy = Math.abs(touchDY);

  if (dx > PM_TOUCH_SENSITIVITY && dy < (dx * 2) / 3) {
    if (touchDX > 0) {
      prevSlide();
    } else {
      nextSlide();
    }
  }

  cancelTouch();
}

function cancelTouch() {
  document.body.removeEventListener('touchmove', handleTouchMove, true);
  document.body.removeEventListener('touchend', handleTouchEnd, true);
}

/* Preloading frames */

function disableSlideFrames(no) {
  var el = getSlideEl(no);
  if (!el) {
    return;
  }

  var frames = el.getElementsByTagName('iframe');
  for (var i = 0, frame; (frame = frames[i]); i++) {
    disableFrame(frame);
  }
}

function enableSlideFrames(no) {
  var el = getSlideEl(no);
  if (!el) {
    return;
  }

  var frames = el.getElementsByTagName('iframe');
  for (var i = 0, frame; (frame = frames[i]); i++) {
    enableFrame(frame);
  }
}

function disableFrame(frame) {
  frame.src = 'about:blank';
}

function enableFrame(frame) {
  var src = frame._src;

  if (frame.src != src && src != 'about:blank') {
    frame.src = src;
  }
}

function setupFrames() {
  var frames = document.querySelectorAll('iframe');
  for (var i = 0, frame; (frame = frames[i]); i++) {
    frame._src = frame.src;
    disableFrame(frame);
  }

  enableSlideFrames(curSlide);
  enableSlideFrames(curSlide + 1);
  enableSlideFrames(curSlide + 2);
}

function setupInteraction() {
  /* Clicking and tapping */

  var el = document.createElement('div');
  el.className = 'slide-area';
  el.id = 'prev-slide-area';
  el.addEventListener('click', prevSlide, false);
  document.querySelector('section.slides').appendChild(el);

  var el = document.createElement('div');
  el.className = 'slide-area';
  el.id = 'next-slide-area';
  el.addEventListener('click', nextSlide, false);
  document.querySelector('section.slides').appendChild(el);

  /* Swiping */

  document.body.addEventListener('touchstart', handleTouchStart, false);
}

/* Hash functions */

function getCurSlideFromHash() {
  var slideNo = parseInt(location.hash.substr(1));

  if (slideNo) {
    curSlide = slideNo - 1;
  } else {
    curSlide = 0;
  }
}

function updateHash() {
  location.replace('#' + (curSlide + 1));
}

/* Event listeners */

function handleBodyKeyDown(event) {
  // If we're in a code element, only handle pgup/down.
  var inCode = event.target.classList.contains('code');

  switch (event.keyCode) {
    case 78: // 'N' opens presenter notes window
      if (!inCode && notesEnabled) toggleNotesWindow();
      break;
    case 72: // 'H' hides the help text
    case 27: // escape key
      if (!inCode) hideHelpText();
      break;

    case 39: // right arrow
    case 13: // Enter
    case 32: // space
      if (inCode) break;
    case 34: // PgDn
      nextSlide();
      event.preventDefault();
      break;

    case 37: // left arrow
    case 8: // Backspace
      if (inCode) break;
    case 33: // PgUp
      prevSlide();
      event.preventDefault();
      break;

    case 40: // down arrow
      if (inCode) break;
      nextSlide();
      event.preventDefault();
      break;

    case 38: // up arrow
      if (inCode) break;
      prevSlide();
      event.preventDefault();
      break;
  }
}

function scaleSmallViewports() {
  var el = document.querySelector('section.slides');
  var transform = '';
  var sWidthPx = 1250;
  var sHeightPx = 750;
  var sAspectRatio = sWidthPx / sHeightPx;
  var wAspectRatio = window.innerWidth / window.innerHeight;

  if (wAspectRatio <= sAspectRatio && window.innerWidth < sWidthPx) {
    transform = 'scale(' + window.innerWidth / sWidthPx + ')';
  } else if (window.innerHeight < sHeightPx) {
    transform = 'scale(' + window.innerHeight / sHeightPx + ')';
  }
  el.style.transform = transform;
}

function addEventListeners() {
  document.addEventListener('keydown', handleBodyKeyDown, false);
  var resizeTimeout;
  window.addEventListener('resize', function() {
    // throttle resize events
    window.clearTimeout(resizeTimeout);
    resizeTimeout = window.setTimeout(function() {
      resizeTimeout = null;
      scaleSmallViewports();
    }, 50);
  });

  // Force reset transform property of section.slides when printing page.
  // Use both onbeforeprint and matchMedia for compatibility with different browsers.
  var beforePrint = function() {
    var el = document.querySelector('section.slides');
    el.style.transform = '';
  };
  window.onbeforeprint = beforePrint;
  if (window.matchMedia) {
    var mediaQueryList = window.matchMedia('print');
    mediaQueryList.addListener(function(mql) {
      if (mql.matches) beforePrint();
    });
  }
}

/* Initialization */

function addFontStyle() {
  var el = document.createElement('link');
  el.rel = 'stylesheet';
  el.type = 'text/css';
  el.href =
    '//fonts.googleapis.com/css?family=' +
    'Open+Sans:regular,semibold,italic,italicsemibold|Droid+Sans+Mono';

  document.body.appendChild(el);
}

function addGeneralStyle() {
  var el = document.createElement('link');
  el.rel = 'stylesheet';
  el.type = 'text/css';
  el.href = PERMANENT_URL_PREFIX + 'styles.css';
  document.body.appendChild(el);

  var el = document.createElement('meta');
  el.name = 'viewport';
  el.content = 'width=device-width,height=device-height,initial-scale=1';
  document.querySelector('head').appendChild(el);

  var el = document.createElement('meta');
  el.name = 'apple-mobile-web-app-capable';
  el.content = 'yes';
  document.querySelector('head').appendChild(el);

  scaleSmallViewports();
}

function handleDomLoaded() {
  slideEls = document.querySelectorAll('section.slides > article');

  setupFrames();

  addFontStyle();
  addGeneralStyle();
  addEventListeners();

  updateSlides();

  setupInteraction();

  if (
    window.location.hostname == 'localhost' ||
    window.location.hostname == '127.0.0.1' ||
    window.location.hostname == '::1'
  ) {
    hideHelpText();
  }

  document.body.classList.add('loaded');

  setupNotesSync();
}

function initialize() {
  getCurSlideFromHash();

  if (window['_DEBUG']) {
    PERMANENT_URL_PREFIX = '../';
  }

  if (window['_DCL']) {
    handleDomLoaded();
  } else {
    document.addEventListener('DOMContentLoaded', handleDomLoaded, false);
  }
}

// If ?debug exists then load the script relative instead of absolute
if (!window['_DEBUG'] && document.location.href.indexOf('?debug') !== -1) {
  document.addEventListener(
    'DOMContentLoaded',
    function() {
      // Avoid missing the DomContentLoaded event
      window['_DCL'] = true;
    },
    false
  );

  window['_DEBUG'] = true;
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = '../slides.js';
  var s = document.getElementsByTagName('script')[0];
  s.parentNode.insertBefore(script, s);

  // Remove this script
  s.parentNode.removeChild(s);
} else {
  initialize();
}

/* Synchronize windows when notes are enabled */

function setupNotesSync() {
  if (!notesEnabled) return;

  function setupPlayResizeSync() {
    var out = document.getElementsByClassName('output');
    for (var i = 0; i < out.length; i++) {
      $(out[i]).bind('resize', function(event) {
        if ($(event.target).hasClass('ui-resizable')) {
          localStorage.setItem('play-index', i);
          localStorage.setItem('output-style', out[i].style.cssText);
        }
      });
    }
  }
  function setupPlayCodeSync() {
    var play = document.querySelectorAll('div.playground');
    for (var i = 0; i < play.length; i++) {
      play[i].addEventListener('input', inputHandler, false);

      function inputHandler(e) {
        localStorage.setItem('play-index', i);
        localStorage.setItem('play-code', e.target.innerHTML);
      }
    }
  }

  setupPlayCodeSync();
  setupPlayResizeSync();
  localStorage.setItem(destSlideKey(), curSlide);
  window.addEventListener('storage', updateOtherWindow, false);
}

// An update to local storage is caught only by the other window
// The triggering window does not handle any sync actions
function updateOtherWindow(e) {
  // Ignore remove storage events which are not meant to update the other window
  var isRemoveStorageEvent = !e.newValue;
  if (isRemoveStorageEvent) return;

  var destSlide = localStorage.getItem(destSlideKey());
  while (destSlide > curSlide) {
    nextSlide();
  }
  while (destSlide < curSlide) {
    prevSlide();
  }

  updatePlay(e);
  updateNotes();
}
