class RessourceList extends List {
  constructor(idOrElement, subscriberList, type, options={}) {
    if (!['corpus', 'job'].includes(type)) {
      console.error("Unknown Type!");
      return;
    }
    super(idOrElement, {...RessourceList.options['common'],
                        ...RessourceList.options[type],
                        ...options});
    this.type = type;
    subscriberList.push(this);
  }


  _init(ressources) {
    this.addRessources(Object.values(ressources));
    this.sort("creation_date", {order: "desc"});
  }


  _update(patch) {
    let item, pathArray;

    for (let operation of patch) {
      /* "/ressourceId/valueName" -> ["ressourceId", "valueName"] */
      pathArray = operation.path.split("/").slice(1);
      switch(operation.op) {
        case "add":
          if (pathArray.includes("results")) {break;}
          this.addRessources([operation.value]);
          break;
        case "remove":
          this.remove("id", pathArray[0]);
          break;
        case "replace":
          item = this.get("id", pathArray[0])[0];
          switch(pathArray[1]) {
            case "status":
              item.values({status: operation.value});
              break;
            default:
              break;
          }
        default:
          break;
      }
    }
  }


  addRessources(ressources) {
    this.add(ressources.map(x => RessourceList.dataMapper[this.type](x)));
  }
}
RessourceList.dataMapper = {
  corpus: corpus => ({creation_date: corpus.creation_date,
                      description: corpus.description,
                      id: corpus.id,
                      "analyse-link": `/corpora/${corpus.id}/analyse`,
                      "edit-link": `/corpora/${corpus.id}`,
                      status: corpus.status,
                      title: corpus.title}),
  job: job => ({creation_date: job.creation_date,
                description: job.description,
                id: job.id,
                link: `/jobs/${job.id}`,
                service: job.service,
                status: job.status,
                title: job.title})
};
RessourceList.options = {
  common: {page: 4, pagination: {innerWindow: 8, outerWindow: 1}},
  corpus: {item: `<tr>
                    <td>
                      <a class="btn-floating disabled">
                        <i class="material-icons service">book</i>
                      </a>
                    </td>
                    <td>
                      <b class="title"></b><br>
                      <i class="description"></i>
                    </td>
                    <td>
                      <span class="badge new status" data-badge-caption=""></span>
                    </td>
                    <td class="right-align">
                      <a class="btn-small edit-link waves-effect waves-light"><i class="material-icons">edit</i></a>
                      <a class="btn-small analyse-link waves-effect waves-light">Analyse<i class="material-icons right">search</i></a>
                    </td>
                  </tr>`,
           valueNames: ["creation_date", "description", "title",
                        {data: ["id"]},
                        {name: "analyse-link", attr: "href"},
                        {name: "edit-link", attr: "href"},
                        {name: "status", attr: "data-status"}]},
  job: {item: `<tr>
                 <td>
                   <a class="btn-floating disabled">
                     <i class="material-icons service"></i>
                   </a>
                 </td>
                 <td>
                   <b class="title"></b><br>
                   <i class="description"></i>
                 </td>
                 <td>
                   <span class="badge new status" data-badge-caption=""></span>
                 </td>
                 <td class="right-align">
                   <a class="btn-small link waves-effect waves-light">View<i class="material-icons right">send</i></a>
                 </td>
               </tr>`,
        valueNames: ["creation_date", "description", "title",
                     {data: ["id"]},
                     {name: "link", attr: "href"},
                     {name: "service", attr: "data-service"},
                     {name: "status", attr: "data-status"}]}
};


class ResultList extends List {

  createResultRowElement(item, chunk) {
    let values, cpos, token, matchRowElement, lcCellElement, hitCellElement, rcCellElement, textTitlesCellElement, matchNrElement;
    // gather values from item
    values = item.values();

    // get infos for full match row
    matchRowElement = document.createElement("tr");
    matchRowElement.setAttribute("data-index", values["index"])
    lcCellElement = document.createElement("td");
    lcCellElement.classList.add("left-context");
    matchRowElement.appendChild(lcCellElement);
    for (cpos of values["lc"]) {
      token = chunk["cpos_lookup"][cpos];
      lcCellElement.insertAdjacentHTML("beforeend", `<span class="token" data-cpos="${cpos}">${token["word"]} </span>`);
    }

    // get infos for hit of match
    let textTitles = new Set();
    hitCellElement = document.createElement("td");
    hitCellElement.classList.add("match-hit");
    textTitlesCellElement = document.createElement("td");
    textTitlesCellElement.classList.add("titles");
    matchNrElement = document.createElement("td");
    matchNrElement.classList.add("match-nr");
    matchRowElement.appendChild(hitCellElement);
    for (cpos of values["hit"]) {
      token = chunk["cpos_lookup"][cpos];
      hitCellElement.insertAdjacentHTML("beforeend", `<span class="token" data-cpos="${cpos}">${token["word"]} </span>`);
      // get text titles of every hit cpos token
      textTitles.add(chunk["text_lookup"][token["text"]]["title"]);
      // add button to trigger more context to every match td
      var inspectBtn = document.createElement("a");
      inspectBtn.setAttribute("class", "btn-floating btn-flat waves-effect waves-light grey right inspect");
      inspectBtn.innerHTML = '<i class="material-icons">search</i>';
      inspectBtn.onclick = function() {inspect(values["index"])};
    }
    // add text titles at front as first td of one row
    hitCellElement.appendChild(inspectBtn);
    textTitlesCellElement.innerText = [...textTitles].join(", ");
    matchRowElement.insertAdjacentHTML("afterbegin", textTitlesCellElement.outerHTML);
    matchNrElement.innerText = values["index"] + 1;
    matchRowElement.insertAdjacentHTML("afterbegin", matchNrElement.outerHTML);

    // get infos for right context of match
    rcCellElement = document.createElement("td");
    rcCellElement.classList.add("right-context");
    matchRowElement.appendChild(rcCellElement);
    for (cpos of values["rc"]) {
      token = chunk["cpos_lookup"][cpos];
      rcCellElement.insertAdjacentHTML("beforeend", `<span class="token" data-cpos="${cpos}">${token["word"]} </span>`);
    }
    return matchRowElement
  }
}
