/**
 * Description: Manage SoundFontsDB storage on the user's local computer.
 * Designed to store selected sound fonts in ArrayBuffer format.
 *
 * @package     midi-Synth
 * @category    module js
 * @author      Oleg Klenitsky <https://adminkov.bcr.by/midi/>
 * @copyright   2024 Oleg Klenitsky
 * @license     GPL-2.0-or-later
 */

"use strict";

const DB_NAME = "SoundFontsDB";
const DB_VERSION = 1;
const DB_STORE_1 = 'catalog';
const DB_STORE_2 = 'files';

var db;

function openSoundFontsDB() {
  return new Promise((resolve, reject) => {
    let timerid = setInterval(()=>{
      let req = indexedDB.open(DB_NAME, DB_VERSION);

      req.onsuccess = function (evt) {
        db = req.result;
        clearInterval(timerid);
        return resolve("SoundFontsDB successfully loaded");
      };
      req.onerror = function (evt) {
        reject("Error loaded SoundFontsDB.");
        console.error("SoundFontsDB:", evt.target.errorCode);
        clearInterval(timerid);
        return reject(evt.target.errorCode);
      };
      req.onupgradeneeded = function (evt) {
        let store1 = evt.currentTarget.result.createObjectStore(
          DB_STORE_1, { keyPath: 'id', autoIncrement: true });

        let store2 = evt.currentTarget.result.createObjectStore(
          DB_STORE_2, { keyPath: 'id', autoIncrement: true });

        console.log("openDb.onupgradeneeded");
        clearInterval(timerid);
        return resolve("SoundFontsDB successfully upgraded");
      };
    }, 2000);
  });
}
/**
 * @param {string} store_name
 * @param {string} mode either "readonly" or "readwrite"
 */
function getObjectStore(store_name, mode) {
  var tx = db.transaction(store_name, mode);
  return tx.objectStore(store_name);
}
/**
 * @param {string} file
 * @param {string} content
 */
function addLocalSoundFonts(file, content) {
  console.log("add local soundFonts to DB:", file);

  var store1 = getObjectStore(DB_STORE_1, 'readwrite');
  var req1;
  try {
    req1 = store1.add(file);
  } catch (e) {
    throw e;
  }
  req1.onsuccess = function (evt) {
    console.log("Insertion fileName="+file.name+" in SoundFontsDB successful");
  };
  req1.onerror = function() {
    console.error("add fileName local soundFonts error", this.error);
  };

  var store2 = getObjectStore(DB_STORE_2, 'readwrite');
  var req2;
  try {
    req2 = store2.add(content);
  } catch (e) {
    throw e;
  }
  req2.onsuccess = function (evt) {
    console.log("Insertion content of "+file.name+" in SoundFontsDB successful");
  };
  req2.onerror = function() {
    console.error("add content local soundFonts error", this.error);
  };
}
/**
 * Delete local soundFonts from local SoundFontsDB
 * @param  {[type]} fileName [description]
 * @return {[type]}          [description]
 */
function delLocalSoundFonts(fileName){
  //Поиск в "catalog" -> fileName => запоминаем id
  //Удалить строку из "catalog" по id
  //Удалить строку из "files" по id

  let transaction1 = db.transaction("catalog","readwrite");
  let catalog = transaction1.objectStore("catalog");
  let request1 = catalog.openCursor();

  // вызывается для каждой найденной курсором строки
  request1.onsuccess = function() {
    let cursor = request1.result;
    if (cursor) {
      let key = cursor.key; // ключ строки (поле id)
      let value = cursor.value; // объект строки

      if(value.name == fileName){
        catalog.delete(value.id);

        let transaction2 = db.transaction("files","readwrite");
        let files = transaction2.objectStore("files");
        files.delete(value.id);
        return;
      }else{
        cursor.continue();
      }
    }else{
      console.log("Строк больше нет");
    }
  };
  console.log("del local soundFonts from SoundFontsDB:", fileName);
}
/**
 * Get content of LocalSoundFonts
 * @param  {[type]} fileName [description]
 * @return {[type]}          [description]
 */
function getLocalSoundFonts(fileName, standard){
  return new Promise((resolve, reject) => {
    let transaction1 = db.transaction("catalog","readwrite");
    let catalog = transaction1.objectStore("catalog");
    let request1 = catalog.openCursor();
    let content;

    //loader on
    document.getElementById("inform_panel").innerHTML = "";
    let loader5 = document.createElement("div");
    loader5.className = "loader5";
    document.getElementById("inform_panel").appendChild(loader5);

    document.getElementById("editorBtn").setAttribute("disabled", true);
    document.getElementById("graphBtn").setAttribute("disabled", true);
    document.getElementById("sequencerBtn").setAttribute("disabled", true);

    // вызывается для каждой найденной курсором строки DB
    request1.onsuccess = function() {
      let cursor = request1.result;
      if (cursor) {
        let key = cursor.key; // ключ строки (поле id)
        let value = cursor.value; // объект строки

        if(value.name == fileName){
          let transaction2 = db.transaction("files","readonly");
          let files = transaction2.objectStore("files");
          const getRequest = files.get(key);

          getRequest.onsuccess = function(event) {
            content = event.target.result;
            return resolve(content);
          };
          getRequest.onerror = function(event) {
            return reject("");
          };
        }else{
          cursor.continue();
        }
      }else{
        console.log("SoundFontsDB not found:", fileName);
      }
    };
  });
}
/**
 * Get content of RemoteSoundFonts (used wp_ajax)
 *
 * @param  {[type]} fileName [description]
 * @param  {[type]} standard [description]
 * @return {[type]}          [description]
 */
function getRemoteSoundFonts(fileName, standard){
  return new Promise((resolve, reject) => {
    var xhr = new XMLHttpRequest();
    var formData = new FormData();

    //loader on
    document.getElementById("inform_panel").innerHTML = "";
    let loader5 = document.createElement("div");
    loader5.className = "loader5";
    document.getElementById("inform_panel").appendChild(loader5);

    document.getElementById("editorBtn").setAttribute("disabled", true);
    document.getElementById("graphBtn").setAttribute("disabled", true);
    document.getElementById("sequencerBtn").setAttribute("disabled", true);

    formData.append("action", "soundFontsContent");
    formData.append("fileName", fileName);
    formData.append("standard", standard);
    formData.append("nonce", midiSynth_nonce);

    xhr.open("POST", midiSynth_url_ajax);
    xhr.responseType = "arraybuffer";
    xhr.send(formData);

    xhr.onload = function(){
      if (xhr.status == 200) {
        return resolve(xhr.response);
      }
    };
    xhr.onerror = function(){
      console.log("error:", xhr.responseText);
      return reject("");
    };
  });
}
