var crssword = crssword || {};

crssword.setup = (function () {
  var gridComplete = false;
  var init = function () {
    _buildPreloader();
    crssword.clues.currentLang=puzzleData.options.defaultLanguage
    _buildPage();
    _buildGrid();
    crssword.clues.updateClues(puzzleData.options.defaultLanguage);
  };

  var _buildPreloader = function () {
    var preloader = crssword.repeats.newEls("div", body, {"id": "preloader"});
    crssword.repeats.updateClass("add", preloader, "show");
    var loader = crssword.repeats.newEls("div", preloader, {"id": "loader"});
    var loadSpinner = crssword.repeats.newEls("div", loader, {"id": "loaderSpinner"});
    var loaderTxt = crssword.repeats.newEls("div", loader, {"id": "loaderTxt"});
    loaderTxt.appendChild(document.createTextNode("Loading..."));
    _spinPreloader(loadSpinner.id);
  };

  var _spinPreloader = function (obj) {
    obj = document.getElementById(obj);
    if (obj) {
      setTimeout(function () {
        var degs = 0;
        if (obj.style.transform !== "") {
          degs = Number(obj.style.transform.split("(")[1].split("deg")[0]);
        }
        obj.style.transform = 'rotate(' + (degs + 5) + 'deg)';
        _spinPreloader(obj.id);
      }, 15);
    }
  };

  var preloader = function () {
    if (!gridComplete) {
      setTimeout(function () {
        crssword.repeats.updateClass("remove", document.getElementById("preloader"), "show");
        preloader();
      }, 2500);
    } else {
      document.getElementById("preloader").parentNode.removeChild(document.getElementById("preloader"));
    }
    crssword.vle.open();
  };
  var _buildPage = function () {
    _buildTopMenu();
    _buildLangContainer();
    var gridContainer = crssword.repeats.newEls("div", body, {"id": "gridContainer", "aria-labelledby": "gridDesc"});
    var gridDesc = crssword.repeats.newEls("div", gridContainer, {"id": "gridDesc"});
    gridDesc.appendChild(document.createTextNode(puzzleData.options.description));
    crssword.repeats.updateClass("add", gridDesc, "sr-only");
    crssword.repeats.newEls("div", gridContainer, {"id": "gridTxt"});
    crssword.repeats.newEls("div", gridContainer, {"id": "gridGfx"});
    _buildCluesContainers();
    _buildMenuContainer();
    crssword.repeats.newEls("div", body, {"id": "resultsContainer", "aria-live": "assertive", "aria-atomic": "true"});
    var srInputDesc = crssword.repeats.newEls("div", body, {"id": "srInputDesc", "aria-live": "assertive", "aria-atomic": "true", "tabindex":"0"});
    crssword.repeats.updateClass("add", srInputDesc, "sr-only");
  };

  var _buildTopMenu = function () {
    crssword.repeats.newEls("div", body, {"id": "topMenuContainer"});
  };

  var _buildLangContainer = function () {
    var languagesContainer = crssword.repeats.newEls("div", document.getElementById("topMenuContainer"), {"id": "languagesContainer"});
    if (puzzleData.options.additionalLanguages) {
      var numberOfLanguages = 0;
      for (var language in puzzleData.options.languages.types) {
        var langBtn = crssword.repeats.newEls("input", languagesContainer, {
          "type": "button",
          "lang":puzzleData.options.languages.types[language].code,
          "id": "btn" + language,
          "value": puzzleData.options.languages.types[language].label
        });
        numberOfLanguages++;
        langBtn.onclick = function () {
          crssword.clues.updateClues(this.id.split("btn")[1]);
        };
      }
      if (numberOfLanguages <= 1) {
        languagesContainer.parentNode.removeChild(languagesContainer);
      }
      if (!puzzleData.options.languages.include) {
        crssword.repeats.updateClass("add", languagesContainer, "hidden");
      }
    }
  };

  var _buildCluesContainers = function () {
    crssword.repeats.newEls("div", body, {"id": "cluesContainer"});
    crssword.repeats.newEls("div", cluesContainer, {"id": "cluesAcrossContainer"});
    crssword.repeats.newEls("div", cluesContainer, {"id": "cluesDownContainer"});
  };

  var _buildMenuContainer = function () {
    var menuContainer = crssword.repeats.newEls("div", body, {"id": "menuContainer"});
    crssword.repeats.newEls("input", menuContainer, {"type": "button", "id": "btnCheck", "value": "Check answers", "lang":"en"});
    crssword.repeats.newEls("input", menuContainer, {"type": "button", "id": "btnShowAnswers", "value": "Reveal answers", "lang":"en"});
    crssword.repeats.newEls("input", menuContainer, {"type": "button", "id": "btnReset", "value": "Reset crossword", "lang":"en"});
    crssword.repeats.newEls("input", menuContainer, {"type": "button", "id": "btnSave", "value": "Save", "lang":"en"});
    _addButtonFunctionality();
  };

  var _addButtonFunctionality = function () {
    // check answers
    document.getElementById("btnCheck").onclick = function () {
      checkAnswers("check");
    };
    // show answers
    document.getElementById("btnShowAnswers").onclick = function () {
      if (window.confirm("Please confirm you'd like to reveal the answers")) {
        checkAnswers("reveal");
      }
    };
    // reset crssword
    document.getElementById("btnReset").onclick = function () {
      if (window.confirm("Please confirm you'd like to reset the crossword. Any changes made after your last save will be lost.")) {
        resetcrssword();
      }
    };
    // reset crssword
    document.getElementById("btnSave").onclick = function () {
      if (window.confirm("Please confirm you'd like to save your current progress on the crossword. This will overwrite any previous save.")) {
        crssword.vle.save();
      }
    };

  };

  var checkAnswers = function (action) {
    var gridData = crssword.data.puzzle.grid.data;
    var results = {"correct": 0, "incorrect": 0};
    for (var item in gridData) {
      var el = document.getElementById("clue-txt-" + gridData[item].clueNumber + "-" + gridData[item].direction);
      var answerVal = gridData[item].answer.split(" ").join("").toLowerCase();
      if (action === "reveal") {
        el.value = gridData[item].answer;
        crssword.clues.updateText(el, "reveal");
      }
      var elVal = el.value.toLowerCase().split(" ").join("");
      if (action === "check") {
        clearAnswerClasses(el);
      }
      var checkAnswerSrOnly = document.getElementById("answeredSrOnly-" + gridData[item].clueNumber + "-" + gridData[item].direction);
      while (checkAnswerSrOnly.firstChild) {
        checkAnswerSrOnly.removeChild(checkAnswerSrOnly.firstChild);
      }
      if (elVal === answerVal) {
        el.value = gridData[item].answer;
        el.setAttribute("readonly", "readonly");
        crssword.repeats.updateClass("add", el, "correct");
        results.correct = results.correct + 1;
        checkAnswerSrOnly.appendChild(document.createTextNode(" Currently has the correct answer."));
      } else {
        if (elVal.length !== 0) {
          crssword.repeats.updateClass("add", el, "incorrect");
          checkAnswerSrOnly.appendChild(document.createTextNode(" Currently has an incorrect answer."));
        }
        results.incorrect = results.incorrect + 1;
      }
    }
    if (action === "check") {
      _clearResultsContainer();
      if (gridData.length === results.correct) {
        document.getElementById("resultsContainer").appendChild(document.createTextNode("All clues have been answered correctly."));
      } else if (results.correct > 0) {
        document.getElementById("resultsContainer").appendChild(document.createTextNode("Some answers submitted are correct but others are incorrect/unanswered. Please try again."));
      } else {
        document.getElementById("resultsContainer").appendChild(document.createTextNode("All answers submitted are incorrect/unanswered. Please try again."));
      }
    }
  };

  var _clearResultsContainer = function () {
    var resultsContainer = document.getElementById("resultsContainer");
    if (resultsContainer.firstChild) {
      resultsContainer.removeChild(resultsContainer.firstChild);
    }
  };

  var clearAnswerClasses = function (el) {
    var checkAnswerSrOnly = document.getElementById("answeredSrOnly-" + el.id.split("-")[2] + "-" + el.id.split("-")[3]);
    while (checkAnswerSrOnly.firstChild) {
      checkAnswerSrOnly.removeChild(checkAnswerSrOnly.firstChild);
    }
    el.removeAttribute("readonly");
    crssword.repeats.updateClass("remove", el, "correct");
    crssword.repeats.updateClass("remove", el, "incorrect");
  };

  var resetcrssword = function () {
    var allInputs = document.getElementById("cluesContainer").querySelectorAll("input");
    for (var input = 0; input < allInputs.length; input++) {
      allInputs[input].value = "";
      crssword.clues.updateText(allInputs[input]);
    }
    _clearResultsContainer();
  };

  var _buildGrid = function () {
    _setGridMaxSize();
    _displayGrid();
    _setStartCells();
    crssword.lang.switchLang(puzzleData.options.defaultLanguage);
    gridComplete = true;
  };

  var _setGridMaxSize = function () {
    puzzleData.grid.size = {"x": 0, "y": 0};
    for (var i = 0; i < puzzleData.grid.data.length; i++) {
      var strLength = puzzleData.grid.data[i].answer.split(" ").join("").length;
      var currX = 0;
      var currY = 0;
      if (puzzleData.grid.data[i].direction === "across") {
        currX = puzzleData.grid.data[i]["x"] + strLength;
        currY = puzzleData.grid.data[i]["y"] + 1;
      } else {
        currY = puzzleData.grid.data[i]["y"] + strLength;
        currX = puzzleData.grid.data[i]["x"] + 1;
      }
      if (puzzleData.grid.size["x"] < (currX + 1)) {
        puzzleData.grid.size["x"] = currX;
      }
      if (puzzleData.grid.size["y"] < currY) {
        puzzleData.grid.size["y"] = currY;
      }
    }
  };

  var _setStartCells = function () {
    var currentOrder = [];
    for (var i = 0; i < puzzleData.grid.data.length; i++) {
      puzzleData.grid.data[i]["startAt"] = (puzzleData.grid.size.x * puzzleData.grid.data[i].y) + puzzleData.grid.data[i].x;
      currentOrder.push(puzzleData.grid.data[i]["startAt"]);
    }
    _orderDataByStartCell();
    crssword.clues.setClueNumber();
  };

  var _orderDataByStartCell = function () {
    var sortingData = puzzleData.grid.data.sort(function (a, b) {
      return a.startAt - b.startAt;
    });
    puzzleData.grid.data = sortingData;
  };

  var _displayGrid = function () {
    var cellt;
    for (var row = 0; row < puzzleData.grid.size.y; row++) {
      var rowContainerGfx = crssword.repeats.newEls("div", document.getElementById("gridGfx"), {});
      crssword.repeats.updateClass("add", rowContainerGfx, "row");
      for (var cell = 0; cell < puzzleData.grid.size.x; cell++) {
        var cellElGfx = crssword.repeats.newEls("div", rowContainerGfx, {
          "id": "cell-" + cell + "-" + row,
          "aria-hidden": "true"
        });
        crssword.repeats.updateClass("add", cellElGfx, "cell");
        if (puzzleData.options.devmode) {
          var cellElDevGfx = crssword.repeats.newEls("div", cellElGfx, {});
          crssword.repeats.updateClass("add", cellElDevGfx, "devInfo");
          crssword.repeats.updateClass("add", cellElGfx, "dev");
          cellElDevGfx.appendChild(document.createTextNode(cell + "." + row));
        }
      }
    }
    //document.getElementById("gridGfx").style.width=(document.querySelector(".cell").offsetWidth*puzzleData.grid.size.x)+"px"
    console.log(document.querySelector(".cell").offsetWidth*puzzleData.grid.size.x)
    console.log(document.getElementById("gridGfx").style.width)
  };

  var displayCellInputs = function (data) {
    for (var letter = 0; letter < data.answer.split(" ").join("").length; letter++) {
      var x = 0;
      var y = 0;
      if (data.direction === "across") {
        x = data.x + letter;
        y = data.y;
      } else {
        y = data.y + letter;
        x = data.x;
      }
      crssword.repeats.updateClass("add", document.getElementById("cell-" + x + "-" + y), "cellInput");
      crssword.repeats.updateClass("add", document.getElementById("cell-" + x + "-" + y), "answer-" + data.clueNumber + "-" + data.direction);
      var input = crssword.repeats.newEls("input", document.getElementById("cell-" + x + "-" + y), {
        "type": "textbox",
        "readonly": "readonly",
        "id": data.clueNumber + "-" + data.direction + "-input-" + letter,
        "value": "",
        "tabindex": "-1"
      });
      crssword.repeats.updateClass("add", input, "answer-" + data.clueNumber + "-" + data.direction + "-input");
      input.onclick = function () {
        document.getElementById("clue-txt-" + this.id.split("-input")[0]).click();
      };
    }
  };

  return {
    init: init,
    displayCellInputs: displayCellInputs,
    clearAnswerClasses: clearAnswerClasses,
    preloader: preloader
  };

})();