// scrollEnd
(function ($, window, document) {
  var ScrollEnd, defaults, plugin;
  plugin = "scrollEnd";
  defaults = {
    delay: 250,
  };
  ScrollEnd = function (element, options, callback) {
    if (typeof options === "function") {
      callback = options;
      options = {};
    }
    callback = callback || null;
    this.element = element;
    this.settings = $.extend({}, defaults, options);
    this._defaults = defaults;
    this._name = plugin;
    this._timeout = false;
    this._callback = callback;
    return this.init();
  };
  ScrollEnd.prototype = {
    init: function () {
      var $el, _this;
      _this = this;
      $el = $(this.element);
      return $el.on("scroll", function () {
        return _this.initScroll();
      });
    },
    getUTCDate: function (d) {
      var curdate;
      d = d || new Date();
      curdate = Date.UTC(
        d.getUTCFullYear(),
        d.getUTCMonth(),
        d.getUTCDate(),
        d.getUTCHours(),
        d.getUTCMinutes(),
        d.getUTCSeconds(),
        d.getUTCMilliseconds()
      );
      return curdate;
    },
    initScroll: function () {
      var _this;
      _this = this;
      _this.controlTime = _this.getUTCDate();
      if (_this._timeout === false) {
        _this._timeout = true;
        return setTimeout(function () {
          return _this.runCallback(_this);
        }, _this.settings.delay);
      }
    },
    runCallback: function (_this) {
      var nowTime;
      nowTime = _this.getUTCDate();
      if (nowTime - _this.controlTime < _this.settings.delay) {
        return setTimeout(function () {
          return _this.runCallback(_this);
        }, _this.settings.delay);
      } else {
        _this._timeout = false;
        return _this._callback();
      }
    },
  };
  return ($.fn[plugin] = function (options, callback) {
    return this.each(function () {
      if (!$.data(this, "plugin_" + plugin)) {
        return $.data(
          this,
          "plugin_" + plugin,
          new ScrollEnd(this, options, callback)
        );
      }
    });
  });
})(jQuery, window, document);

// Main
if (!window.Marked) {
  var Marked = {};
}

Marked.overview = (function () {
  var index,
    settings = {
      speed: ".5s",
      color: "transparent",
      colors: ["green", "blue"],
      mainColor: "rgb(57, 188, 237)",
      animatedIn: "fadeInLeft",
      animatedOut: "fadeOutLeft",
      configAnimatedIn: "zoomIn",
      configAnimatedOut: "zoomOut",
      zIndexIn: "9999",
      zIndexOut: "-9999",
      home: "home",
      configHome: "config-home",
      stepsFile: "../steps.html",
    },
    storedSettings = {},
    steps = [],
    titles = {},
    configSteps = [];

  var callbacks = {
    videoplay: function () {
      var vid = $("video:first")[0];
      $(vid).unbind("click");
      vid.addEventListener("ended", callbacks.videoended, false);
      $(vid).removeAttr("controls");
      vid.play();
    },
    videoended: function () {
      $(this).closest(".video").removeClass("video");
      $(this).attr("poster", $(this).data("poster"));
      this.load();
      $(this).on("click", function () {
        $(this).closest("figure").addClass("video");
        this.play();
      });
      // $(this).attr('controls', 'controls');
    },
  };

  // function updateOverflowIndicator() {
  // 	if ($(document).height() > $(window).height()) {
  // 		if ($(document).height() - $(window).scrollTop() == $(window).height()) {
  // 			$('#overflowIndicator').hide();
  // 		} else {
  // 			$('#overflowIndicator').show();
  // 		}
  // 	} else {
  // 		$('#overflowIndicator').hide();
  // 	}
  // }

  function configFor(key) {
    data = OVWebview.fetchSettings(key);

    if (data) {
      config = JSON.parse(data);
      return config.results;
    }
    return false;
  }

  // function getConfigs() {
  // 	var data = OVWebview.fetchSettings(), output;
  // 	if (data) {
  // 		try {
  // 			output = JSON.parse(data);
  // 		} catch(e) {
  // 			if (window.console) {
  // 				console.error('Error parsing configurations', e);
  // 				console.trace();
  // 			}
  // 			throw("Eror parsing config");
  // 		}
  // 	} else {
  // 		if (window.console) {
  // 			console.warn('Could not retrieve configurations');
  // 			console.trace();
  // 		}
  // 	}
  // 	return (output) ? output : false;
  // }

  function displayConfirmation(config) {
    var results = configFor(config);

    if (results) {
      loadStepHTML("config-confirm", "config", function () {
        var resultsHTML = resultsToHTML(results);
        $("#configconfirm").html(resultsHTML);
        $("#confirm").data("config-setting", config);
      });
    } else {
      loadStepHTML("config-error", "config");
    }
  }

  function resultsToHTML(results) {
    var enabled = [],
      disabled = [],
      configured = [],
      $resultsContainer = $("<div>"),
      i,
      c;

    for (i in results) {
      var newItem = $("<li>");
      var title = results[i].title;
      if (typeof results[i].state === "string") {
        title = "<strong>" + title + ":</strong> " + results[i].state;
        configured.push(newItem.html(title));
      } else if (results[i].state) {
        enabled.push(newItem.html(title));
      } else {
        disabled.push(newItem.html(title));
      }
    }
    if (configured.length > 0) {
      $resultsContainer.append("<h2>Settings</h2>");
      var $configured = $("<ul class=details id=config-settings>");
      for (c in configured) {
        $configured.append(configured[c]);
      }
      $resultsContainer.append($configured);
    }
    if (enabled.length > 0) {
      $resultsContainer.append("<h2>Enabled</h2>");
      var $enabled = $("<ul class=details id=config-enabled>");
      for (c in enabled) {
        $enabled.append(enabled[c]);
      }
      $resultsContainer.append($enabled);
    }
    if (disabled.length > 0) {
      $resultsContainer.append("<h2>Disabled</h2>");
      var $disabled = $("<ul class=details id=config-disabled>");
      for (c in disabled) {
        $disabled.append(disabled[c]);
      }
      $resultsContainer.append($disabled);
    }
    return $resultsContainer.html();
  }

  function parseConfigResults(json) {
    var data = JSON.parse(json);

    if (data && data.success) {
      loadStepHTML("config-saved", "config", function () {
        var resultHTML = resultsToHTML(data.results);
        $("#configresults").html(resultHTML);
      });
    } else {
      loadStepHTML("config-error", "config");
    }
  }

  function publicStart(step) {
    var idx;

    if (
      (!settings.home || typeof settings.home === "undefined") &&
      typeof step === "undefined"
    ) {
      idx = 0;
    } else {
      if (typeof step === "number") {
        idx = step;
      } else if (typeof step === "string") {
        idx = steps.indexOf(step);
      } else if (typeof settings.home === "number") {
        idx = settings.home;
      } else {
        idx = steps.indexOf(settings.home);
      }
    }

    Marked.overview.index = idx >= 0 ? idx : 0;

    var result = true;
    if (typeof settings.onInit === "function") {
      result = settings.onInit();
    } else if (typeof settings.onInit === "string") {
      result = eval(settings.onInit);
    }
    if (result || typeof result === "undefined") {
      loadStepHTML();
    }
  }

  function publicNextStep() {
    if ($("body").hasClass("config")) {
      return false;
    }
    if (Marked.overview.index < steps.length - 1) {
      publicOpenStep(Marked.overview.index + 1);
    } else {
      return false;
    }
    return true;
  }

  function publicPreviousStep() {
    if ($("body").hasClass("config")) {
      return false;
    }
    if (Marked.overview.index === 0) {
      return false;
    }

    publicOpenStep(Marked.overview.index - 1);
    return true;
  }

  function publicOpenStep(step) {
    var lastStep = Marked.overview.index,
      idx;

    if (typeof lastStep === "undefined" || lastStep < 0) {
      lastStep = 0;
    }

    if (typeof step === "number") {
      idx = step;
    } else {
      idx = steps.indexOf(step);
    }
    if (idx < 0 || typeof idx === "undefined") {
      $("#wrapper").empty();
      loadStepHTML(step, "config");

      return;
    }
    if (Marked.overview.index === idx) {
      return;
    }
    Marked.overview.index = idx;
    closeStep(lastStep, function () {
      $("#" + steps[lastStep]).remove();
      loadStepHTML();
    });
  }

  function loadStepHTML(stepName, kind, callback) {
    var id,
      initStyles = {
        position: "relative",
        width: "100%",
        height: "100%",
        top: "0px",
        left: "0px",
        "background-color": settings.color,
        "overflow-y": "hidden",
        "overflow-x": "hidden",
        "z-index": settings.zIndexOut,
        opacity: "0",
        "-webkit-animation-duration": settings.speed,
      },
      type = "step",
      cnum,
      c;
    $("body").removeClass("step config");

    if (!stepName || typeof stepName === "undefined") {
      stepName = steps[Marked.overview.index];
    } else {
      if (kind && typeof kind !== "undefined") {
        type = kind;
      }
    }

    if (type === "config") {
      swapConfig("animatedIn", settings.configAnimatedIn);
      swapConfig("animatedOut", settings.configAnimatedOut);
    } else {
      restoreConfig("animatedIn");
      restoreConfig("animatedOut");
    }

    $("#wrapper").load(settings.stepsFile + " #" + stepName, function () {
      $("body, html").css({ overflow: "hidden" });

      id = $("#" + stepName);
      for (c in settings.colors) {
        $("body").removeClass(settings.colors[c]);
        cnum = ((parseInt(c, 10) % settings.colors.length) + 1).toString();
        $("body").removeClass("color" + cnum);
      }
      if (id.data("color")) {
        $("body").addClass("color " + id.data("color"));
      } else {
        if (id.hasClass("step")) {
          cnum = (
            (Marked.overview.index % settings.colors.length) +
            1
          ).toString();
          $("body").addClass("color color" + cnum);
        } else {
          $("body").removeClass("color");
        }
      }
      id.css(initStyles);
      id.addClass("animated");
      id.addClass(stepName + "-off");

      if (id.hasClass(stepName + "-off")) {
        id.removeClass(settings.animatedOut);
        id.removeClass(stepName + "-off");
        id.addClass(stepName + "-on");
      }

      if (id.hasClass(stepName + "-on")) {
        id.css({ opacity: "1", "z-index": settings.zIndexIn });
        id.addClass(settings.animatedIn);
      }

      if (type === "step") {
        $("body").removeClass("config");
        $("body").addClass("step");
        $("#topnav").show();
        var $indicators = $("#topnav").find(".indicator");

        $indicators.each(function (i, n) {
          if (i === Marked.overview.index) {
            $(n).addClass("current");
          } else {
            $(n).removeClass("current");
          }
        });
        $("#topnav").removeClass("firstStep lastStep");
        if (Marked.overview.index === $indicators.length - 1) {
          $("#topnav").addClass("lastStep");
        } else if (Marked.overview.index === 0) {
          $("#topnav").addClass("firstStep");
        }
      } else {
        $("body").removeClass("step");
        $("body").addClass("config");
        $("#topnav").hide();
        $("body, html").css({ overflow: "hidden" });
      }

      retinaize(id);

      if (id.data("title")) {
        $("#steptitle").text(id.data("title"));
      }

      if (id.data("onshow") && callbacks.hasOwnProperty(id.data("onshow"))) {
        callbacks[id.data("onshow")]();
      }

      $("body, html").css({ overflow: "hidden" });
      // updateOverflowIndicator();

      // Ensure overflow stays hidden after animations
      setTimeout(function () {
        $("html, body").css({ overflow: "hidden" });
      }, 600);

      if (callback && typeof callback === "function") {
        callback();
      }

      $("a", id).on("click", function (ev) {
        ev.preventDefault();
        if ($(this).attr("id") === "closeoverview") {
          OVWebview.closeOverview();
        } else if ($(this).data("config-confirm")) {
          displayConfirmation($(this).data("config-confirm"));
        } else if ($(this).data("config-setting")) {
          var json = OVWebview.quickSetup($(this).data("config-setting"));
          if (json) {
            parseConfigResults(json);
          } else {
            loadStepHTML("config-error");
          }
          settings.onInit = null;
        } else if ($(this).data("config-next")) {
          if ($(this).data("config-next") === "last") {
            loadStepHTML(0, "step");
          } else if ($(this).data("config-next") === "home") {
            loadStepHTML();
          } else {
            loadStepHTML($(this).data("config-next"), "config");
          }
        }
      });

      $("#startOver").on("click", function (ev) {
        ev.preventDefault();
        publicStartConfig();
      });
    });
  }

  function publicStartConfig() {
    loadStepHTML(settings.configHome, "config");
    return false;
  }

  function swapConfig(setting, value) {
    if (!storedSettings[setting]) {
      storedSettings[setting] = settings[setting];
      settings[setting] = value;
    }
  }

  function restoreConfig(setting) {
    if (storedSettings[setting]) {
      settings[setting] = storedSettings[setting];
      delete storedSettings[setting];
    }
  }

  // function publicCloseAll() {
  // 	for (var i in steps) {
  // 		closeStep(i, null);
  // 	}
  // }

  function closeStep(step, callback) {
    var stepName, id;

    $("body, html").css({ overflow: "hidden" });

    $("body").removeClass("color");
    for (i = 0; i < 10; i++) {
      $("body").removeClass("color" + i);
    }

    if (typeof step === "number") {
      stepName = steps[step];
    } else {
      stepName = step;
    }

    id = $("#" + stepName);

    if (id.hasClass(stepName + "-on")) {
      id.removeClass(stepName + "-on");
      id.addClass(stepName + "-off");
    }

    if (id.hasClass(stepName + "-off")) {
      id.removeClass(settings.animatedIn);
      id.addClass(settings.animatedOut);
      if (id.data("onhide") && callbacks.hasOwnProperty(id.data("onhide"))) {
        callback = callbacks[id.data("onhide")]();
      }
      id.one(
        "webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",
        callback
      );
    }
  }

  function publicInit(options) {
    var o;
    if (typeof options === "object") {
      $.extend(settings, options);
      // for (o in options) {
      // 	settings[o] = options[o];
      // }
    }

    createIndex();

    // $(window).scrollEnd(function() {
    // 	updateOverflowIndicator();
    // });
  }

  function createIndex() {
    $("<div>").load(settings.stepsFile, function () {
      $(this)
        .find("section")
        .each(function (i, n) {
          var iid = $(n).attr("id");
          if ($(n).hasClass("step")) {
            steps.push(iid);
            if ($(n).data("title")) {
              titles[iid] = $(n).data("title");
            } else {
              titles[iid] = iid;
            }
          } else {
            configSteps.push(iid);
          }
        });
      buildMenu();
      publicStart();
    });
  }

  function buildMenu() {
    var $navUL = $("<ul>"),
      pad = 300 / steps.length + "px",
      indicators = [];

    $(steps).each(function (i, n) {
      var newItem = $("<li class=indicator>")
        .attr("title", titles[n])
        .on("click", function (ev) {
          ev.preventDefault();
          publicOpenStep(n);
        });
      if (i < steps.length - 1) {
        newItem.css({
          "padding-right": pad,
        });
      }
      indicators.push(newItem);
    });
    $navUL.append("<li id=navback class=stepBack>");
    $(indicators).each(function (i, n) {
      $navUL.append(n);
    });
    $navUL.append("<li id=navfwd class=stepForward>");
    $("#topnav").append($("<nav>").append($navUL));

    $(".stepForward, .stepBack").on("click", function (ev) {
      ev.preventDefault();
      if ($(this).hasClass("stepBack")) {
        Marked.overview.prev();
      } else {
        Marked.overview.next();
      }
    });
  }

  function retinaize(context) {
    if (!context) {
      context = document;
    }

    if (window.devicePixelRatio > 1) {
      $(context)
        .find("img[srcset]")
        .each(function (i, n) {
          $(n).attr("src", $(n).attr("srcset").replace(/ .*$/, ""));
        });
    }
    return;
  }

  //private

  return {
    settings: settings,
    storedSettings: storedSettings,
    steps: steps,
    titles: titles,
    index: index,
    callbacks: callbacks,

    init: publicInit,
    start: publicStart,
    next: publicNextStep,
    prev: publicPreviousStep,
    go: publicOpenStep,
    config: publicStartConfig,
  };
})();

$(document).ready(function () {
  // Ensure overflow is always hidden on html and body
  $("html, body").css({ overflow: "hidden" });

  var configure = false;
  var ov = Marked.overview;

  var stepSettings = {
    color: "transparent",
    colors: ["green", "darkgreen", "blue", "darkblue", "red", "yellow"],
    animatedIn: "fadeInLeft",
    animatedOut: "fadeOutLeft",
    speed: ".2s",
    home: "home",
    configHome: "config-home",
    stepsFile: "steps.html",
  };

  if (configure) {
    stepSettings.onInit = "publicStartConfig()";
  }

  ov.init(stepSettings);

  // Ensure overflow stays hidden after init
  setTimeout(function () {
    $("html, body").css({ overflow: "hidden" });
  }, 100);

  jwerty.key("right/space", function (ev) {
    ev.preventDefault();
    ov.next();
  });
  jwerty.key("left/shift+space", function (ev) {
    ev.preventDefault();
    ov.prev();
  });
  jwerty.key("escape", function (ev) {
    ev.preventDefault();
    $("#exitSetup").click();
  });

  $("#quickconfig").on("click", function (ev) {
    ev.preventDefault();
    ov.config();
  });
});
