
if (!Function.prototype.bind) {
  Function.prototype.bind = function(oThis) {
    if (typeof this !== 'function') {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }

    var aArgs   = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP    = function() {},
        fBound  = function() {
          return fToBind.apply(this instanceof fNOP
                 ? this
                 : oThis,
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    if (this.prototype) {
      // Function.prototype doesn't have a prototype property
      fNOP.prototype = this.prototype;
    }
    fBound.prototype = new fNOP();

    return fBound;
  };
}



class Navigation {
    constructor () {
        // this.CSScurrent = 'c-nav--current';
        // this.CSSvisible = 'c-nav--visible';

        this.CSSanimatable = 's-nav--animatable';
        this.CSSvisible = 's-nav--visible';
        this.CSSinactive = 's-toggler--inactive';

        this.body = document.body;
        this.button = document.getElementById('toggler');
        this.navigation = document.getElementById('nav');

        // this.container = document.getElementById('nav-list');

        // Control whether the container's children can be focused
        // Set initial state to inert since the drawer is offscreen
        // this.detabinator = new Detabinator(this.container);              ?????? DO I need it really?
        // this.detabinator.inert = true;

        this.open = this.open.bind(this);
        this.close = this.close.bind(this);
        this.toggle = this.toggle.bind(this);
        // this.update = this.update.bind(this);

        // this.onTouchStart = this.onTouchStart.bind(this);
        // this.onTouchMove = this.onTouchMove.bind(this);
        // this.onTouchEnd = this.onTouchEnd.bind(this);
        this.onTransitionEnd = this.onTransitionEnd.bind(this);
        // this.setState = this.setState.bind(this);

        // this.startX = 0;
        // this.currentX = 0;
        // this.touching = false;

        // this.supportsPassive = undefined;

        if (!this.button || !this.navigation) {
            return;
        }

        this.init();
    }

    // apply passive event listening if it's supported
    applyPassive () {
        if (this.supportsPassive !== undefined) {
            return this.supportsPassive ? {passive: true} : false;
        }

        // feature detect
        let isSupported = false;

        try {
            document.addEventListener('test', null, { get passive () { isSupported = true; }});
        } catch (e) {
            console.error(e);
        }

        this.supportsPassive = isSupported;

        return this.applyPassive();
    }

    addEventListeners () {
        this.button.addEventListener('click', this.toggle);

        // this.navigation.addEventListener('click', this.closeNavigation);
        // this.container.addEventListener('click', (e) => { e.stopPropagation(); });

        // this.navigation.addEventListener('touchstart', this.onTouchStart, this.applyPassive());
        // this.navigation.addEventListener('touchmove', this.onTouchMove, this.applyPassive());
        // this.navigation.addEventListener('touchend', this.onTouchEnd);

        // events.subscribe('page-change', this.setState);
    }

    onTouchStart (e) {
        if (!this.navigation.classList.contains(this.CSSvisible)) {
            return;
        }

        this.startX = e.touches[0].pageX;
        this.currentX = this.startX;

        this.touching = true;
        requestAnimationFrame(this.update);
    }

    onTouchMove (e) {
        if (!this.touching) {
            return;
        }

        this.currentX = e.touches[0].pageX;
    }

    onTouchEnd () {
        if (!this.touching) {
            return;
        }

        this.touching = false;

        const translateX = Math.min(0, this.currentX - this.startX);
        this.container.style.transform = '';

        if (translateX < 0) {
            this.toggle();
        }
    }

    update () {
        if (!this.touching) {
            return;
        }

        requestAnimationFrame(this.update);

        const translateX = Math.min(0, this.currentX - this.startX);
        this.container.style.transform = `translateX(${translateX}px)`;
    }

    onTransitionEnd () {
        this.body.classList.remove(this.CSSanimatable);
        this.navigation.removeEventListener('transitionend', this.onTransitionEnd);
    }

    openNavigation() {
        this.button.classList.add('noster-apster');
        this.navigation.classList.add(this.CSSanimatable);
        this.navigation.classList.add(this.CSSvisible);
        this.button.classList.add(this.CSStoggler);
        // this.detabinator.inert = false;
    }

    open() {
        this.body.classList.add(this.CSSanimatable);
        this.body.classList.add(this.CSSvisible);
    }

    close() {
        this.body.classList.add(this.CSSanimatable);
        this.body.classList.remove(this.CSSvisible);
    }

    closeNavigation() {
        this.button.classList.add('noster-apster');
        this.navigation.classList.add(this.CSSanimatable);
        this.navigation.classList.remove(this.CSSvisible);

        this.button.classList.remove(this.CSStoggler);
        // this.detabinator.inert = true;
    }

    // toggleNavigation() {
    toggle() {

        // console.error('toggle XXXX');
        if (this.body.classList.contains(this.CSSvisible)) {
            this.close();
        } else {
            this.open();
        }

        // if (this.navigation.classList.contains(this.CSSvisible)) {
        //     this.closeNavigation();
        // } else {
        //     this.openNavigation();
        // }

        this.navigation.addEventListener('transitionend', this.onTransitionEnd);
    }

    setState (o = {}) {
        const p = o.path || window.location.pathname,
              current = (this.container || document).querySelector('.' + this.CSScurrent),
              target = (this.container || document).querySelector(`a[href="${p}"]`);

        this.closeNavigation();

        if (current) {
            current.classList.remove(this.CSScurrent)
        }

        if (target) {
            target.classList.add(this.CSScurrent)
        }
    }

    init () {
        // this.setState();

        this.button.classList.remove(this.CSSinactive);

        this.addEventListeners();
    }
}

new Navigation();
