(function(){
  /**
   * Events to track:
   * https://developer.vimeo.com/player/sdk/reference#events-for-playback-controls
   * To enable debugging/see fired events, just set a local cookie to vimeo_debug to 1
   * @constructor
   */
  VimeoTrackerClass = function() {
    VimeoTracker = this;

    this.data = {
      bDebug: false,
      oPlayer: null, // player instance
      fLastPercent: 0, // for no-chapter tracking
      fLastSeconds: 0, // for chapter tracking
      trackingObject: {}, // core data about the video, a "template" for any data object passed into tracking
      started: false, // have to use this because there is no 'start' event
      duration: 0,
      chapters: [],
    };

    this.init = function(oPlayer, oIFrame) {
      if (document.location.search.includes('vimeo_debug=1') || this.getCookie('vimeo_debug') == 1) {
        this.data.bDebug = true;
        console.log('Vimeo tracker in debug mode');
      }
      this.data.oPlayer = oPlayer;
      this.data.trackingObject = {
        video_title: oIFrame.getAttribute('data-video-title'),
        video_id: oIFrame.getAttribute('data-video-id'),
        video_type: 'Vimeo',
      };
      // try to get chapters
      this.data.oPlayer.getDuration().then(function(duration) {
        VimeoTracker.data.duration = duration;
        VimeoTracker.data.oPlayer.getChapters().then(function(chapters) {
          // decorate chapter info with endTime, duration
          for (let i=0; i<chapters.length-1; i++) {
            chapters[i].endTime = chapters[i+1].startTime;
          }
          chapters[chapters.length-1].endTime = VimeoTracker.data.duration;
          for (let i=0; i<chapters.length; i++) {
            chapters[i].duration = chapters[i].endTime - chapters[i].startTime;
          }
          if (chapters.length > 0) {
            VimeoTracker.data.chapters = chapters;
          }
          if (VimeoTracker.data.bDebug) {
            VimeoTracker.debug('Read chapter info:', chapters);
          }
        }).catch(function(error) {
          // do nothing, you have no chapters
        }).finally(function() {
          VimeoTracker.startTrackingAll();
        });
      });
    };
    this.getCookie = function(cname) {
      var name = cname + "=";
      var ca = document.cookie.split(';');
      for(var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
          c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
          return c.substring(name.length, c.length);
        }
      }
      return "";
    };
    this.debug = function(message, data) {
      if (VimeoTracker.data.bDebug) {
        if (data) {
          console.log(`Vimeo tracker debug: ${message}`, data);
        } else {
          console.log(`Vimeo tracker debug: ${message}`);
        }
      }
    };
    this.track = function(message, data) {
      if (VimeoTracker.data.bDebug) {
        console.log(`Vimeo tracker track event [${message}]`, data);
      }
      if (window.parent && window.parent.track) {
        window.parent.track(message, data);
      } else if (window.track) {
        window.track(message, data);
      } else {
        console.log(`Would track event '${message}', but I have no window.parent.track, or window.track. Tracking data:`, data);
      }
    };
    this.startTrackingAll = function() {
      // by this point, we have the knowledge of whether this is a chapter or a non-chapter video
      const bIsChapterVideo = this.data.chapters.length > 0;
      // events to track in common
      this.data.oPlayer.on('bufferstart', this.trackBufferStart);
      this.data.oPlayer.on('loaded', this.trackLoaded);
      this.data.oPlayer.on('pause', this.trackPaused);
      // chapter events vs. non-chapter events
      if (bIsChapterVideo) {
        this.data.oPlayer.on('chapterchange', this.trackChapterChange);
        this.data.oPlayer.on('timeupdate', this.trackProgressForChapters);
      } else {
        this.data.oPlayer.on('timeupdate', this.trackProgressNoChapters);
        this.data.oPlayer.on('ended', this.trackEnded);
      }
    };

    this.trackBufferStart = function(data) {
      VimeoTracker.track('youtube player buffering', VimeoTracker.data.trackingObject);
    };
    this.trackLoaded = function(data) {
      VimeoTracker.track('youtube player cued', VimeoTracker.data.trackingObject);
    };
    this.trackPaused = function(data) {
      if (data.percent !== 1) {
        const bIsChapterVideo = VimeoTracker.data.chapters.length > 0;
        if (bIsChapterVideo) {
          // get chapter that is paused, instead of the full video
          let iChapterIndexIn = VimeoTracker.getChapterIndexByTime(data.seconds);
          const currentChapter = VimeoTracker.data.chapters[iChapterIndexIn];
          const trackingEvent = {
            ...VimeoTracker.data.trackingObject,
            chapterTitle: currentChapter.title,
            video_title: currentChapter.title,
            video_id: VimeoTracker.data.trackingObject.video_id + '-' + VimeoTracker.chapterTitleToToken(currentChapter.title),
          };
          VimeoTracker.track('youtube player paused', trackingEvent);
        } else {
          VimeoTracker.track('youtube player paused', VimeoTracker.data.trackingObject);
        }
      }
    };
    this.trackEnded = function(data) {
      VimeoTracker.track('youtube player ended', VimeoTracker.data.trackingObject);
      VimeoTracker.data.started = false;
    };
    /**
     * Note: when data is undefined, that's the end of the last chapter
     * @param data
     */
    this.trackChapterChange = function(data) {
      // by default, make this
      let chapterEndedIndex = null; // which chapter just ended
      if (typeof data !== 'undefined') {
        const trackingEvent = {
          ...VimeoTracker.data.trackingObject,
          chapterTitle: data.title,
          video_title: data.title,
          video_id: VimeoTracker.data.trackingObject.video_id + '-' + VimeoTracker.chapterTitleToToken(data.title),
        };
        VimeoTracker.track('youtube player playing', trackingEvent);
        // making it the same as youtube, we'll make youtube use playing properly later
        VimeoTracker.track('youtube player unstarted', trackingEvent);
        chapterEndedIndex = data.index - 2;
      } else {
        chapterEndedIndex = VimeoTracker.data.chapters.length - 1;
      }
      if (chapterEndedIndex >= 0) {
        // meaning, it's not the very first one
        const chapterTitle = VimeoTracker.data.chapters[chapterEndedIndex].title;
        const trackingEvent = {
          ...VimeoTracker.data.trackingObject,
          chapterTitle: chapterTitle,
          video_title: chapterTitle,
          video_id: VimeoTracker.data.trackingObject.video_id + '-' + VimeoTracker.chapterTitleToToken(chapterTitle),
        };
        VimeoTracker.track('youtube player ended', trackingEvent);
      }
    };
    this.getChapterIndexByTime = function(atSeconds) {
      // find out which chapter we're in
      let iChapterIndexIn = null;
      for(let i=0; i<this.data.chapters.length; i++) {
        const chapter = this.data.chapters[i];
        if (chapter.startTime <= atSeconds && atSeconds < chapter.endTime) {
          iChapterIndexIn = i;
        }
      }
      if (iChapterIndexIn === null) {
        // we may be in the very last fraction of a second in the video
        iChapterIndexIn = this.data.chapters.length-1;
      }
      return iChapterIndexIn;
    };
    this.trackProgressForChapters = function(data) {
      if (typeof data.seconds === 'undefined') {
        return;
      }
      // find out which chapter we're in
      let iChapterIndexIn = VimeoTracker.getChapterIndexByTime(data.seconds);
      const currentChapter = VimeoTracker.data.chapters[iChapterIndexIn];
      // find percentage in the chapter, for the last reported position, and current position
      let lastSecondsIntoChapter = 0;
      let currentSecondsIntoChapter = 0;
      if (currentChapter.startTime < VimeoTracker.data.fLastSeconds && VimeoTracker.data.fLastSeconds < currentChapter.endTime) {
        lastSecondsIntoChapter = VimeoTracker.data.fLastSeconds - currentChapter.startTime;
      }
      if (currentChapter.startTime < data.seconds && data.seconds < currentChapter.endTime) {
        currentSecondsIntoChapter = data.seconds - currentChapter.startTime;
      }
      const fLastPercentInChapter = lastSecondsIntoChapter / currentChapter.duration;
      const fCurrentPercentInChapter = currentSecondsIntoChapter / currentChapter.duration;
      for(let i=0.25; i<=0.75; i+=0.25) {
        if (fLastPercentInChapter <= i && i < fCurrentPercentInChapter) {
          const trackingEvent = {
            ...VimeoTracker.data.trackingObject,
            chapterTitle: currentChapter.title,
            video_title: currentChapter.title,
            video_id: VimeoTracker.data.trackingObject.video_id + '-' + VimeoTracker.chapterTitleToToken(currentChapter.title),
            percentageComplete: i*100,
          };
          const pct = i*100;
          VimeoTracker.track('youtube player checkpoint reached', trackingEvent);
        }
      }
      VimeoTracker.data.fLastSeconds = data.seconds;
    };
    this.trackProgressNoChapters = function(data) {
      if (typeof data.percent === 'undefined') {
        return;
      }
      if (!VimeoTracker.data.started) {
        VimeoTracker.data.started = true;
        VimeoTracker.track('youtube player playing', VimeoTracker.data.trackingObject);
        // making it the same as youtube, we'll make youtube use playing properly later
        VimeoTracker.track('youtube player unstarted', VimeoTracker.data.trackingObject);
      }
      const fCurrentPercent = data.percent;
      for(let i=0.25; i<=0.75; i+=0.25) {
        if (VimeoTracker.data.fLastPercent <= i && i < fCurrentPercent) {
          const trackingEvent = {
            ...VimeoTracker.data.trackingObject,
            percentageComplete: i*100,
          };
          const pct = i*100;
          VimeoTracker.track('youtube player checkpoint reached', trackingEvent);
        }
      }
      VimeoTracker.data.fLastPercent = fCurrentPercent;
    };
    this.chapterTitleToToken = function(title) {
      const tokenizedTitle = title.toLowerCase().replace(/[^a-z0-9]/g, '');
      return tokenizedTitle;
    };
  };

  const x = setInterval(function() {
    if (typeof Vimeo !== 'undefined') {
      let vimeoIFrame = document.querySelector('#vimeo-player');
      if (!vimeoIFrame) {
        // find the first vimeo IFrame
        allIframes = document.querySelectorAll('iframe');
        for (i=0; i<allIframes.length; i++) {
          const src = allIframes[i].src;
          if (src.indexOf('.vimeo.com') !== -1) {
            vimeoIFrame = allIframes[i];
            break;
          }
        }
      }
      const oPlayer = new Vimeo.Player(vimeoIFrame);

      vimeoTracker = new VimeoTrackerClass();
      vimeoTracker.init(oPlayer, vimeoIFrame);

      clearInterval(x);
    } else {
      console.log('Vimeo library not found.');
    }
  }, 200);
})();
