/*
 * Copyright (C) 2014-2017 Eitan Isaacson
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see: <http://www.gnu.org/licenses/>.
 */

eSpeakNGWorker.prototype.list_voices = function() {
  var voices = [];
  var i;
  for (var voice = this.get_voices(i = 0); voice.ptr != 0; voice = this.get_voices(++i)) {
    var v = {
      name: voice.get_name(),
      identifier: voice.get_identifier(),
      languages: [],
    }

    var ii = 0;
    var byte = voice.get_languages(ii);

    function nullTerminatedString(offset) {
      var str = '';
      var index = offset;
      var b = voice.get_languages(index++);
      while (b != 0) {
        str += String.fromCharCode(b);
        b = voice.get_languages(index++);
      }

      return str;
    }

    while (byte != 0) {
      var lang = { priority: byte, name: nullTerminatedString(++ii) }
      v.languages.push(lang);
      ii += lang.name.length + 1;
      byte = voice.get_languages(ii);
    }

    voices.push(v);

  }
  return voices;
};

var eventTypes = [
  'list_terminated',
  'word',
  'sentence',
  'mark',
  'play',
  'end',
  'msg_terminated',
  'phoneme',
  'samplerate'
]

eSpeakNGWorker.prototype.synthesize = function (aText, aCallback) {
  var eventStructSize = this.getSizeOfEventStruct_();
  function cb(ptr, length, events_pointer) {
    var data = new Float32Array(length);
    for (var i = 0; i < length; i++) {
      data[i] = getValue(ptr + i*4, 'float');
    }
    var events = [];
    var ptr = events_pointer;
    for (ev = wrapPointer(ptr, espeak_EVENT);
         ev.get_type() != Module.espeakEVENT_LIST_TERMINATED;
         ev = wrapPointer((ptr += eventStructSize), espeak_EVENT)) {
      events.push({
        type: eventTypes[ev.get_type()],
        text_position: ev.get_text_position(),
        word_length: ev.get_length(),
        audio_position: ev.get_audio_position()
      });
    }
    return aCallback(data, events) ? 1 : 0;
  }

  var fp = addFunction(cb);
  this.synth_(aText, fp);
  removeFunction(fp);
};

eSpeakNGWorker.prototype.synthesize_ipa = function (aText, aCallback) {

  // Use a unique temp file for the worker. Avoid collisions, just in case.
  var ipaVirtualFileName = "espeak-ng-ipa-tmp-"  + Math.random().toString().substring(2);

  var res = "";
  var code = this.synth_ipa_(aText, ipaVirtualFileName);

  if(code == 0)
    res = FS.readFile(ipaVirtualFileName, { encoding: 'utf8' })

  // Clean up the tmp file
  FS.unlink(ipaVirtualFileName);

  var ret = {
    code: code,
    ipa: res
  }

  return ret;
};

// Make this a worker

if (typeof WorkerGlobalScope !== 'undefined') {
  var worker;
  
  Module.postRun = Module.postRun || [];

  Module.postRun.push(function () {
    worker = new eSpeakNGWorker();
    postMessage('ready');
  });

  onmessage = function(e) {

    if (!worker) {
      throw 'eSpeakNGWorker worker not initialized';
    }
    var args = e.data.args;
    var message = { callback: e.data.callback, done: true };
    if (e.data.method == 'synthesize') {
      args.push(function(samples, events) {
        postMessage(
          { callback: e.data.callback,
            result: [samples.buffer, events] }, [samples.buffer]);
      });
    }
    message.result = [worker[e.data.method].apply(worker, args)];
    if (e.data.callback)
      postMessage(message);
  }
}
