/*
lyxy.cc
conversions between lilypond notation and coordinates notation
(C) 2020 by marnout à free pt fr  Released under the GPL
*/

#include <string>
#include <iostream>
#include <regex>
#include <fstream>

#include "lyxy.h"

using namespace std;

int main(int argc, char * argv[]) 
{
   const char *cname = argc == 1 ? "ptitchval": argv[1];
   if(argc == 3) scale = atoi(argv[2]);
   string name(cname);
   cout << "lyxy -- file: " << name + ".ly" << " to "<< name << endl;

   lytoxy(name);
   //xytoly(name);

}

bool lytoxy(const char* s, int& x, int& y)
{
   regex re("([a-gr])(es|is)?([',]{0,3})(1|2|4|8|16)?([.])?");
   cmatch m;
   static int D = 4;  // default duration
   static int P = NaN;  // default pitch
   if(regex_match(s, m, re)) {
      // duration
      if(m[4].str() != "") {
	 x = 16/stoi(m[4].str()); // duration
	 D = x;	     // set as default
      } else x = D;  // default duration
      if(m[5] == ".") x += x/2; // add half duration
      // pitch
      y = pitch[(m[1].str()[0])]; // natural pitch
      if(P == NaN) P = y;
      if(y != NaN) {
	 if(m[2].str() == "es") --y; // flat
	 if(m[2].str() == "is") ++y; // sharp
	 if(P - y > 6) y += 12;	  // under fourth
	 else if(P - y < -6) y -= 12;
	 string oct = m[3].str();
	 if(oct != "") {
	    for(unsigned c=0; c<oct.size(); ++c)
	       if(oct[c] == ',') y -= 12;
	       else y += 12;;
	 }
	 P = y;
      }
      printf("%-5s (%d, %2d)   ", s, x, y);
      return true;
   }
   else {
      cout << "syntax error at " << s << "\n";
      return false;
   }
}

void lytoxy(string name)
{
   ifstream input(name + ".ly");
   ofstream output(name);
   string word;
   while(input >> word) {
      if(word == "%lyxy") break;
      if(input.eof()) {
	 cout << "no tag %lyxy found\n";
	 return;
      }
   }
   int x, y;
   for(int c=0; input >> word; ++c) {
      char w = word[0];
      if(w!='a' && w!='b' && w!='c' && w!='d'
	 && w!='e' && w!='f' && w!='g' && w!='r') 
	 continue;
      cout << word << " ";
      if(lytoxy(word.c_str(), x, y))
	 output << x << " " << y << endl;
      if(c % 4 == 3) cout << endl;
   }
   input.close();
   output.close();
}
