/*

                       _ _ _____                      _   _

                      | | |  __ \                    | | (_)

    ___  ___ _ __ ___ | | | |__) |_____   _____  __ _| |  _ ___

   / __|/ __| '__/ _ \| | |  _  // _ \ \ / / _ \/ _` | | | / __|

   \__ \ (__| | | (_) | | | | \ \  __/\ V /  __/ (_| | |_| \__ \

   |___/\___|_|  \___/|_|_|_|  \_\___| \_/ \___|\__,_|_(_) |___/

                                                        _/ |

                                                       |__/



    "Declarative on-scroll reveal animations."



/*=============================================================================



    scrollReveal.js is inspired by cbpScroller.js, © 2014, Codrops.



    Licensed under the MIT license.

    http://www.opensource.org/licenses/mit-license.php



    scrollReveal.js, © 2014 https://twitter.com/julianlloyd



=============================================================================*/



;(function (window) {



  'use strict';



  var docElem = window.document.documentElement;



  function getViewportH () {

    var client = docElem['clientHeight'],

      inner = window['innerHeight'];



    return (client < inner) ? inner : client;

  }



  function getOffset (el) {

    var offsetTop = 0,

        offsetLeft = 0;



    do {

      if (!isNaN(el.offsetTop)) {

        offsetTop += el.offsetTop;

      }

      if (!isNaN(el.offsetLeft)) {

        offsetLeft += el.offsetLeft;

      }

    } while (el = el.offsetParent)



    return {

      top: offsetTop,

      left: offsetLeft

    }

  }



  function isElementInViewport (el, h) {

    var scrolled = window.pageYOffset,

        viewed = scrolled + getViewportH(),

        elH = el.offsetHeight,

        elTop = getOffset(el).top,

        elBottom = elTop + elH,

        h = h || 0;



    return (elTop + elH * h) <= viewed && (elBottom) >= scrolled;

  }



  function extend (a, b) {

    for (var key in b) {

      if (b.hasOwnProperty(key)) {

        a[key] = b[key];

      }

    }

    return a;

  }





  function scrollReveal(options) {

      this.options = extend(this.defaults, options);

      this._init();

  }







  scrollReveal.prototype = {

    defaults: {

      axis: 'y',

      distance: '60px',

      duration: '0.55s',

      delay: '0.15s',



  //  if 0, the element is considered in the viewport as soon as it enters

  //  if 1, the element is considered in the viewport when it's fully visible

      viewportFactor: 0.33

    },



    /*=============================================================================*/



    _init: function () {



      var self = this;



      this.elems = Array.prototype.slice.call(docElem.querySelectorAll('[data-scrollReveal]'));

      this.scrolled = false;



  //  Initialize all scrollreveals, triggering all

  //  reveals on visible elements.

      this.elems.forEach(function (el, i) {

        self.animate(el);

      });



      var scrollHandler = function () {

        if (!self.scrolled) {

          self.scrolled = true;

          setTimeout(function () {

            self._scrollPage();

          }, 60);

        }

      };



      var resizeHandler = function () {

        function delayed() {

          self._scrollPage();

          self.resizeTimeout = null;

        }

        if (self.resizeTimeout) {

          clearTimeout(self.resizeTimeout);

        }

        self.resizeTimeout = setTimeout(delayed, 200);

      };



      window.addEventListener('scroll', scrollHandler, false);

      window.addEventListener('resize', resizeHandler, false);

    },



    /*=============================================================================*/



    _scrollPage: function () {

        var self = this;



        this.elems.forEach(function (el, i) {

            if (isElementInViewport(el, self.options.viewportFactor)) {

                self.animate(el);

            }

        });

        this.scrolled = false;

    },



    /*=============================================================================*/



    parseLanguage: function (el) {



  //  Splits on a sequence of one or more commas or spaces.

      var words = el.getAttribute('data-scrollreveal').split(/[, ]+/),

          enterFrom,

          parsed = {};



      function filter (words) {

        var ret = [],



            blacklist = [

              "from",

              "the",

              "and",

              "then",

              "but"

            ];



        words.forEach(function (word, i) {

          if (blacklist.indexOf(word) > -1) {

            return;

          }

          ret.push(word);

        });



        return ret;

      }



      words = filter(words);



      words.forEach(function (word, i) {



        switch (word) {

          case "enter":

            enterFrom = words[i + 1];



            if (enterFrom == "top" || enterFrom == "bottom") {

              parsed.axis = "y";

            }



            if (enterFrom == "left" || enterFrom == "right") {

              parsed.axis = "x";

            }



            return;



          case "after":

            parsed.delay = words[i + 1];

            return;



          case "wait":

            parsed.delay = words[i + 1];

            return;



          case "move":

            parsed.distance = words[i + 1];

            return;



          case "over":

            parsed.duration = words[i + 1];

            return;



          case "trigger":

            parsed.eventName = words[i + 1];

            return;



          default:

        //  Unrecognizable words; do nothing.

            return;

        }

      });



  //  After all values are parsed, let’s make sure our our

  //  pixel distance is negative for top and left entrances.

  //

  //  ie. "move 25px from top" starts at 'top: -25px' in CSS.



      if (enterFrom == "top" || enterFrom == "left") {



        if (!typeof parsed.distance == "undefined") {

          parsed.distance = "-" + parsed.distance;

        }



        else {

          parsed.distance = "-" + this.options.distance;

        }



      }



      return parsed;

    },



    /*=============================================================================*/



    genCSS: function (el) {

      var parsed = this.parseLanguage(el);



      var dist   = parsed.distance || this.options.distance,

          dur    = parsed.duration || this.options.duration,

          delay  = parsed.delay    || this.options.delay,

          axis   = parsed.axis     || this.options.axis;



      var transition = "-webkit-transition: all " + dur + " ease " + delay + ";" +

                          "-moz-transition: all " + dur + " ease " + delay + ";" +

                            "-o-transition: all " + dur + " ease " + delay + ";" +

                           "-ms-transition: all " + dur + " ease " + delay + ";" +

                               "transition: all " + dur + " ease " + delay + ";";



      var initial = "-webkit-transform: translate" + axis + "(" + dist + ");" +

                       "-moz-transform: translate" + axis + "(" + dist + ");" +

                        "-ms-transform: translate" + axis + "(" + dist + ");" +

                            "transform: translate" + axis + "(" + dist + ");" +

                              "opacity: 0;";



      var target = "-webkit-transform: translate" + axis + "(0);" +

                      "-moz-transform: translate" + axis + "(0);" +

                       "-ms-transform: translate" + axis + "(0);" +

                           "transform: translate" + axis + "(0);" +

                             "opacity: 1;";

      return {

        transition: transition,

        initial: initial,

        target: target,

        totalDuration: ((parseFloat(dur) + parseFloat(delay)) * 1000)

      };

    },



    /*=============================================================================*/



    animate: function (el) {

      var css = this.genCSS(el);



      if (!el.getAttribute('data-sr-init')) {

        el.setAttribute('style', css.initial);

        el.setAttribute('data-sr-init', true);

      }



      if (el.getAttribute('data-sr-complete')) {

        return;

      }



      if (isElementInViewport(el, this.options.viewportFactor)) {

        el.setAttribute('style', css.target + css.transition);



        setTimeout(function () {

          el.removeAttribute('style');

          el.setAttribute('data-sr-complete', true);

        }, css.totalDuration);

      }



    }

  }; // end scrollReveal.prototype



  document.addEventListener("DOMContentLoaded", function (evt) {

    window.scrollReveal = new scrollReveal();

  });



})(window);