import { checkProtocol, hasArgs, stringify, isDef } from './util.js';
import './stationxml.js';
import './quakeml.js';

/*
 * Philip Crotwell
 * University of South Carolina, 2019
 * http://www.seis.sc.edu
 */
let IRIS_HOST = "service.iris.edu";
const TEXT_FORMAT = "text";
const JSON_FORMAT = "json";
const SVG_FORMAT = "svg";
class TraveltimeQuery {
  /** @private */

  /** @private */

  /** @private */

  /** @private */

  /** @private */

  /** @private */

  /** @private */

  /** @private */

  /** @private */

  /** @private */

  /** @private */

  /** @private */

  /** @private */

  /** @private */
  constructor(host) {
    this._specVersion = "1";
    this._protocol = checkProtocol();

    if (!host) {
      this._host = IRIS_HOST;
    } else {
      this._host = host;
    }

    this._format = JSON_FORMAT;
    this._noheader = false; // only for text format
  }

  protocol(value) {
    return hasArgs(value) ? (this._protocol = value, this) : this._protocol;
  }

  host(value) {
    return hasArgs(value) ? (this._host = value, this) : this._host;
  }

  specVersion(value) {
    return hasArgs(value) ? (this._specVersion = value, this) : this._specVersion;
  }

  evdepth(value) {
    return hasArgs(value) ? (this._evdepth = value, this) : this._evdepth;
  }

  distdeg(value) {
    return hasArgs(value) ? (this._distdeg = value, this) : this._distdeg;
  }

  model(value) {
    return hasArgs(value) ? (this._model = value, this) : this._model;
  }

  phases(value) {
    return hasArgs(value) ? (this._phases = value, this) : this._phases;
  }

  stalat(value) {
    return hasArgs(value) ? (this._stalat = value, this) : this._stalat;
  }

  stalon(value) {
    return hasArgs(value) ? (this._stalon = value, this) : this._stalon;
  }

  latLonFromStation(station) {
    this.stalat(station.latitude);
    this.stalon(station.longitude);
    return this;
  }

  evlat(value) {
    return hasArgs(value) ? (this._evlat = value, this) : this._evlat;
  }

  evlon(value) {
    return hasArgs(value) ? (this._evlon = value, this) : this._evlon;
  }

  latLonFromQuake(quake) {
    this.evlat(quake.latitude);
    this.evlon(quake.longitude);
    this.evdepth(quake.depth / 1000);
    return this;
  }

  format(value) {
    return hasArgs(value) ? (this._format = value, this) : this._format;
  }

  noheader(value) {
    return hasArgs(value) ? (this._noheader = value, this) : this._noheader;
  }

  convertToArrival(ttimeline) {
    let items = ttimeline.trim().split(/\s+/);
    return {
      distdeg: parseFloat(items[0]),
      phase: items[2],
      time: parseFloat(items[3]),
      rayparam: parseFloat(items[4]),
      takeoff: parseFloat(items[5]),
      incident: parseFloat(items[6]),
      puristdist: parseFloat(items[7]),
      puristname: items[9]
    };
  }

  queryText() {
    this.format(TEXT_FORMAT);
    return fetch(this.formURL()).then(response => {
      if (response.ok) {
        return response.text();
      } else {
        throw new Error("Fetching over network was not ok: " + response.status + " " + response.statusText);
      }
    });
  }

  queryJson() {
    this.format(JSON_FORMAT);
    return fetch(this.formURL()).then(response => {
      if (response.ok) {
        return response.json();
      } else {
        throw new Error("Fetching over network was not ok: " + response.status + " " + response.statusText);
      }
    });
  }

  querySvg() {
    this.format(SVG_FORMAT);
    return fetch(this.formURL()).then(response => {
      if (response.ok) {
        return response.text().then(textResponse => new window.DOMParser().parseFromString(textResponse, "text/xml")).then(xml => {
          let elArray = xml.getElementsByTagName("svg");

          if (elArray.length > 0) {
            return elArray[0];
          } else {
            throw new Error("Can't find svg element in response");
          }
        });
      } else {
        throw new Error("Fetching over network was not ok: " + response.status + " " + response.statusText);
      }
    });
  }

  queryWadl() {
    return fetch(this.formWadlURL()).then(response => {
      if (response.ok) {
        return response.text().then(textResponse => new window.DOMParser().parseFromString(textResponse, "text/xml"));
      } else {
        throw new Error("Fetching over network was not ok: " + response.status + " " + response.statusText);
      }
    });
  }

  query() {
    if (this._format === JSON_FORMAT) {
      return this.queryJson();
    } else if (this._format === SVG_FORMAT) {
      return this.querySvg();
    } else if (this._format === TEXT_FORMAT) {
      return this.queryText();
    } else {
      throw new Error("Unknown format: " + this._format);
    }
  }

  makeParam(name, val) {
    return name + "=" + encodeURIComponent(stringify(val)) + "&";
  }

  formBaseURL() {
    let colon = ":";

    if (this._protocol.endsWith(colon)) {
      colon = "";
    }

    let url = this._protocol + colon + "//" + this._host + "/irisws/traveltime/" + this._specVersion + "/";
    return url;
  }

  formURL() {
    let url = this.formBaseURL() + 'query?';

    if (isDef(this._noheader) && this._noheader) {
      url = url + "noheader=true&";
    }

    if (isDef(this._evdepth)) {
      url = url + this.makeParam("evdepth", this.evdepth());
    }

    if (isDef(this._stalat) && isDef(this._stalon)) {
      url = url + this.makeParam("staloc", "[" + stringify(this.stalat()) + "," + stringify(this.stalon()) + "]");
    }

    if (isDef(this._evlat) && isDef(this._evlon)) {
      url = url + this.makeParam("evloc", "[" + stringify(this.evlat()) + "," + stringify(this.evlon()) + "]");
    }

    if (isDef(this._distdeg)) {
      url = url + this.makeParam("distdeg", this.distdeg());
    }

    if (isDef(this._model)) {
      url = url + this.makeParam("model", this.model());
    }

    if (isDef(this._phases)) {
      url = url + this.makeParam("phases", this.phases());
    }

    if (isDef(this._format)) {
      url = url + this.makeParam("format", this.format());
    }

    if (url.endsWith('&') || url.endsWith('?')) {
      url = url.substr(0, url.length - 1); // zap last & or ?
    }

    return url;
  }

  queryTauPVersion() {
    return fetch(this.formTauPVersionURL()).then(response => {
      if (response.ok) {
        return response.text();
      } else {
        throw new Error("Fetching over network was not ok: " + response.status + " " + response.statusText);
      }
    });
  }

  formTauPVersionURL() {
    return this.formBaseURL() + 'taupversion';
  }

  formWadlURL() {
    return this.formBaseURL() + 'application.wadl';
  }

}

export { IRIS_HOST, JSON_FORMAT, SVG_FORMAT, TEXT_FORMAT, TraveltimeQuery };
//# sourceMappingURL=traveltime.js.map
