/* jshint esversion: 6 */

class MediaItem {
  constructor(url) {
    this.url = url;
    this.title = "";
    this.media_url = null;
  }
  update() {}
}

class GeneralItem extends MediaItem {
  static canHandle(url) {
    /*
    let media_sites = [/\/\/www\.ted\.com/i,
      /\/\/v\.nate\.com\/v\.sk\/movie\//i,
      /\/\/pann\.nate\.com\/video\//i,
      /\/\/soundcloud\.com\/.*\//i,
      /\/\/player\.soundcloud\.com\//i,
      /\/\/i\.imgur\.com\//i,
      /\/\/(www\.)?facebook\.com\/(.*\/)?(video\/video\.php|photo\.php|video\.php|video\/embed)\?(v|video_id)=/,
      /\/\/(www|touch)\.dailymotion\.[a-z]{2,3}\/(.*\/)?video/,
      /\/\/c\.brightcove\.com\//,
      /\/\/(www\.|play\.|video\.)?mgoon.com\//,
      /\/\/gfycat.com\//
    ];
    for (let site of media_sites) {
      if (url.search(site) != -1) {
        return true;
      }
    } */
    return false;
  }
}

class YouTubeItem extends MediaItem {
  static canHandle(url) {
    let media_sites = [
      /\/\/(www\.|player\.)?youtube(-nocookie)?\.com/i,
      /\/\/youtu\.be/i,
      /\/\/(www\.|player\.)?vimeo\.com/i,
      /\/\/www\.ted\.com/i,
      /\/\/v\.nate\.com\/v\.sk\/movie\//i,
      /\/\/pann\.nate\.com\/video\//i,
      /\/\/soundcloud\.com\/.*\//i,
      /\/\/player\.soundcloud\.com\//i,
      /\/\/i\.imgur\.com\//i,
      /\/\/(www\.)?facebook\.com\/(.*\/)?(video\/video\.php|photo\.php|video\.php|video\/embed)\?(v|video_id)=/,
      /\/\/(www|touch)\.dailymotion\.[a-z]{2,3}\/(.*\/)?video/,
      /\/\/c\.brightcove\.com\//,
      /\/\/(www\.|play\.|video\.)?mgoon.com\//,
      /\/\/gfycat.com\//,
    ];
    for (let site of media_sites) {
      if (url.search(site) !== -1) {
        return true;
      }
    }
    return false;
  }
  update() {
    this.media_url = this.url;
  }
}

class DaumItem extends MediaItem {
  static canHandle(url) {
    let media_sites = [
      /\/\/(tvpot|videofarm)\.daum\.net\/.*(\?|&)(vid|clipid)=/i,
      /\/\/tv.kakao.com/i,
      /\/\/kakaotv.daum.net/i,
    ];
    for (let site of media_sites) {
      if (0 <= url.search(site)) {
        return true;
      }
    }
    return false;
  }

  update() {
    let media_urls = [
      /\/\/tv.kakao.com\/channel\/[0-9]*\/cliplink\/[0-9]*/i,
      /\/\/kakaotv.daum.net\/v\/[0-9a-zA-z]*/i,
    ];
    for (let i of media_urls) {
      if (0 <= this.url.search(i)) {
        this.media_url = this.url;
        return;
      }
    }
    let result = document.querySelector('A[href*="/channel/"][href*="/cliplink/"]');
    if (null != result) {
      this.media_url = result.href;
      return;
    }
    result = document.documentElement.innerHTML.match(/kakaotv.daum.net\/v\/[0-9a-zA-z]*/);
    if (null != result && 0 < result.length) {
      this.media_url = "http://" + result[0];
      return;
    }
  }
}


class NaverItem extends MediaItem {
  static canHandle(url) {
    let media_sites = [
      /\.naver\.com\//i,
      /\/\/serviceapi\.nmv\.naver\.com\//i,
      /\/\/tv(cast)?\.naver\.com\/v\//i
    ];
    for (let site of media_sites) {
      if (url.search(site) !== -1) {
        return true;
      }
    }
    return false;
  }

  update() {
    let media_urls = [
      /\/\/tv(cast)?\.naver\.com\/v\//i,
    ];
    for (let i of media_urls) {
      if (0 <= this.url.search(i)) {
        this.media_url = this.url;
        return;
      }
    }
    let result = document.querySelector('A[data-cid]');
    if (null != result) {
      this.media_url = "http://tv.naver.com/v/" + result.getAttribute("data-cid");
      return;
    }
    let s = document.head.innerHTML;
    let p = s.indexOf("currentClipNo");
    if (p < 0) {
      return;
    }
    s = s.substr(p, 100);
    p = s.search(/'[0-9]*'/);
    if (p < 0) {
      return;
    }
    s = s.substr(p + 1);
    p = s.indexOf("'");
    s = s.substr(0, p);
    let clipid = parseInt(s);
    if (clipid > 0) {
      this.media_url = "http://tv.naver.com/v/" + clipid;
    }
  }
}

class MediaFinder {
  constructor(document) {
    this.site_url = document.baseURI;
    this.site_title = document.title;
    this.item = this.createMediaItem(this.site_url);
    this.videos = [];
    this.mediaURL = null;
  }

  createMediaItem(url) {
    if (NaverItem.canHandle(url)) {
      return new NaverItem(url);
    } else if (DaumItem.canHandle(url)) {
      return new DaumItem(url);
    } else if (YouTubeItem.canHandle(url)) {
      return new YouTubeItem(url);
    } else {
      return new GeneralItem(url);
    }
  }

  hasMedia() {
    return (null != this.mediaURL && 0 < this.mediaURL.length) ||
      0 < this.videos.length;
  }

  mediaInfo() {
    return {
      "url": this.mediaURL,
      "title": "",
    };
  }

  update() {
    let elements = document.querySelectorAll("video");
    for (let e of elements) {
      let url = e.src;
      if (url == undefined || url.length == 0) {
        continue;
      }
      if (url.startsWith("data:")) {
        continue;
      }
      this.videos.push(url);
    }
    this.item.update();
    this.mediaURL = this.item.media_url;
  }
}

/// ////////////////////////////////////////////////////////////////////////////////////////////////
// OPEN

/*global safari: true */

function onMovistOpen(aMessageEvent) {
  if (aMessageEvent.name == "movist_open") {
    replyMovistOpen();
  }
}

function replyMovistOpen() {
  safari.extension.dispatchMessage("movist_open", {
    "resource": {
      "url": document.location.href,
      "title": document.title,
    }
  });
}

/// ////////////////////////////////////////////////////////////////////////////////////////////////
// COMMAND

function onMovistCommand(aMessageEvent) {
  if (aMessageEvent.name != "movist_command") {
    return;
  }
  let command = aMessageEvent.message.command;
  if (command == "prepare") {
    // stop video
    let elements = document.querySelectorAll("video");
    for (let e of elements) {
      e.pause();
    }
    let finder = new MediaFinder(document);
    finder.update();
    if (finder.hasMedia()) {
      safari.extension.dispatchMessage("safari_page_resource", {
        "resource": finder.mediaInfo(),
      });
    }
  }
}

/// ////////////////////////////////////////////////////////////////////////////////////////////////
// Context Menu

function movistCanHandle(url) {
  return NaverItem.canHandle(url) || DaumItem.canHandle(url) || YouTubeItem.canHandle(url);
}

function onMovistContextMenu(event) {

  let url = undefined;
  let title = undefined;
  let resource = {};
  let e = event.srcElement;
  while (e != undefined) {
    if (e.tagName == 'A') {
      url = e.href;
      break;
    }
    if (e == e.parentElement) {
      break;
    }
    e = e.parentElement;
  }
  if (url == undefined) {
    url = document.location.href;
    title = document.title;
  }
  if (movistCanHandle(url)) {
    resource["url"] = url;
    if (title != undefined) {
      resource["title"] = title;
    }
  } else {
    resource["site_url"] = url;
  }
  safari.extension.dispatchMessage("movist_reply_url", {
    "resource": resource
  });
}

/// ////////////////////////////////////////////////////////////////////////////////////////////////
// Chrome

function prepareMovist_Chrome() {
  // stop video
  let elements = document.querySelectorAll("video");
  for (let e of elements) {
    e.pause();
  }
  let finder = new MediaFinder(document);
  finder.update();
  var resource = null;
  if (finder.hasMedia()) {
    resource = finder.mediaInfo();
  }
  return resource == null ? "" : JSON.stringify(resource);
}

function openMovist_Chrome(info) {
  if (0 == info.length) {
    info = JSON.stringify({
      "url": document.location.href,
      "title": document.title,
    });
  }
  let appURL = "movistpro:" + encodeURIComponent(info);
  window.location.assign(appURL);
}


/// ////////////////////////////////////////////////////////////////////////////////////////////////
// Safari Register

if (undefined != window.safari) {
  if (window === top) {
    window.safari.self.addEventListener("message", onMovistOpen);
  }
  window.safari.self.addEventListener("message", onMovistCommand);
  document.addEventListener('contextmenu', onMovistContextMenu, true);
}
