/*
* scalelist.cc
* DIN Is Noise is copyright (c) 2006-2024 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/

#include <algorithm>
#include <fstream>
#include <iostream>
#include "scalelist.h"
#include "tokenizer.h"
#include "command.h"
#include <fstream>
using namespace std;

extern ofstream dlog;
extern cmdlist cmdlst;

#define result cmdlst.result
#define buf cmdlst.buf

scalelist::scalelist () {
  load ();
}

scalelist::~scalelist () {
  save ();
  dlog << "--- destroyed scalelist ---" << endl;
}

int scalelist::add (tokenizer& tz) { // used by add-scale command, see command.cc
  string nam; tz >> nam;
  if (nam != "") {
    scale r;
    r.name = nam;
    string notes;
    while (1) {
      string s; tz >> s;
      if (s == "") break; else {
        notes = notes + s + " ";
        ++r.num_notes;
      }
    }
    if (r.num_notes > 1) {
      r.notes = notes;
      scales.push_back (r);
      result = nam + ": added";
      return 1;
    } else {
      result = "need at least 2 notes.";
      return 0;
    }
  }

  result = "bad scale name";
  return 0;

}

void scalelist::ls () { // used by ls-scale, see command.cc
  result = "";
  for (int i = 0, j = scales.size(); i < j; ++i) {
    scale& r = scales[i];
    result = result + r.name + '\n';
  }
}

int scalelist::remove (const string& nam) { // used by remove-scale, see command.cc
  scale r; r.name = nam;
  vector<scale>::iterator i = find (scales.begin(), scales.end(), r);
  if (i != scales.end()) {
    scales.erase (i);
    result = nam + ": removed";
    return 1;
  }
  result = nam + ": not found";
  return 0;
}

void scalelist::load () {
  extern string user_data_dir;
  ifstream file ((user_data_dir + "scalelist").c_str(), ios::in);
  if (file) {
    int j;
    string ignore; file >> ignore >> j;
    for (int i = 0; i < j; ++i) {
      scale r;
      string nam; file >> nam; r.name = nam;
      file >> r.num_notes;
      for (int k = 0; k < r.num_notes; ++k) {
        string s; file >> s;
        r.notes = r.notes + s + ' ';
      }
      scales.push_back (r);
    }
  } else cout << "bad scalelist file" << endl;
}

void scalelist::save () {
  extern string user_data_dir;
  ofstream file ((user_data_dir + "scalelist").c_str(), ios::out);
  if (file) {
    int j = scales.size();
    file << "num_scales " << j << endl;
    for (int i = 0; i < j; ++i) {
      scale& r = scales[i];
      file << r.name << " " << r.num_notes << ' ' << r.notes << endl;
    }
  }
}

int scalelist::get (const string& n, scale& r) {
  r.name = n;
  vector<scale>::iterator i = find (scales.begin(), scales.end(), r);
  if (i != scales.end()) {
    r = *i;
    return 1;
  }
  return 0;
}



