/**
 * 定义WKT方法提供类
 */
export default class WKTProvider {
  constructor() { }

  /**
   * GeoJSON几何图形转WKT坐标串
   * @param {Object} geometry -GeoJSON几何图形
   * @param {Boolean} exact -是否要求坐标精确
   *
   * @returns {String} WKT坐标串
   */
  static fromGeometry(geometry, exact=true) {
    switch (geometry.type.toLowerCase()) {
      case 'point':
        return this._fromPoint(geometry, exact);
      case 'linestring':
        return this._fromLineString(geometry, exact);
      case 'polygon':
        return this._fromPolygon(geometry, exact);
      case 'multipoint':
        return this._fromMultiPoint(geometry, exact);
      case 'multilinestring':
        return this._fromMultiLineString(geometry, exact);
      case 'multipolygon':
        return this._fromMultiPolygon(geometry, exact);
      default:
        return null;
    }
  }

  /**
   * GeoJSON点转WKT坐标串
   * @param {Object} geometry -GeoJSON点
   * @param {Boolean} exact -坐标是否精确
   *
   * @returns {String} WKT坐标串
   */
  static _fromPoint(geometry, exact=true) {
    let coords = geometry.coordinates;
    let wkt = exact ? 'POINT(' + coords[0] + ' ' + coords[1] + ')'
                    : 'POINT(' + coords[0].toFixed(6) + ' ' + coords[1].toFixed(6) + ')';

    return wkt;
  }

  /**
   * GeoJSON多点转WKT坐标串
   * @param {Object} geometry -GeoJSON点
   * @param {Boolean} exact -坐标是否精确
   *
   * @returns {String} WKT坐标串
   */
  static _fromMultiPoint(geometry, exact=true) {
    let wkt = 'MULTIPOINT';
    // 获取坐标串
    wkt += this._getCoordinatesString(geometry.coordinates, exact);

    return wkt;
  }

  /**
   * GeoJSON折线转WKT坐标串
   * @param {Object} geometry -GeoJSON折线
   * @param {Boolean} exact -坐标是否精确
   *
   * @returns {String} WKT坐标串
   */
  static _fromLineString(geometry, exact=true) {
    let wkt = 'LINESTRING';
    // 获取坐标串
    wkt += this._getCoordinatesString(geometry.coordinates, exact);

    return wkt;
  }

  /**
   * GeoJSON多折线转WKT坐标串
   * @param {Object} geometry -GeoJSON折线
   * @param {Boolean} exact -坐标是否精确
   *
   * @returns {String} WKT坐标串
   */
  static _fromMultiLineString(geometry, exact=true) {
    const coordinates = geometry.coordinates;

    let wkt = 'MULTILINESTRING(';
    for (let i = 0; i < coordinates.length; i++) {
      // 获取坐标串
      wkt += this._getCoordinatesString(coordinates[i], exact);
      wkt += ',';
    }
    if (wkt.length > 1) {
      wkt = wkt.substring(0, wkt.length - 1);
    }
    wkt += ')';

    return wkt;
  }

  /**
   * GeoJSON多边形转WKT坐标串
   * @param {Object} geometry -GeoJSON多边形
   * @param {Boolean} exact -坐标是否精确
   *
   * @returns {String} WKT坐标串
   */
  static _fromPolygon(geometry, exact=true) {
    const coordinates = geometry.coordinates;

    let wkt = 'POLYGON(';
    for (let i = 0; i < coordinates.length; i++) {
      // 获取坐标串
      wkt += this._getCoordinatesString(coordinates[i], exact);
      wkt += ',';
    }
    if (wkt.length > 1) {
      wkt = wkt.substring(0, wkt.length - 1);
    }
    wkt += ')';

    return wkt;
  }

  /**
   * GeoJSON多多边形转WKT坐标串
   * @param {Object} geometry -GeoJSON多边形
   * @param {Boolean} exact -坐标是否精确
   *
   * @returns {String} WKT坐标串
   */
  static _fromMultiPolygon(geometry, exact=true) {
    const coordinates = geometry.coordinates;

    let wkt = 'MULTIPOLYGON(';
    for (let i = 0; i < coordinates.length; i++) {
      const polygon = coordinates[i];

      wkt += '('
      for (let j = 0; j < polygon.length; j++) {
        // 获取坐标串
        wkt += this._getCoordinatesString(polygon[j], exact);
        wkt += ',';
      }
      if (wkt.length > 1) {
        wkt = wkt.substring(0, wkt.length - 1);
      }
      wkt += ')';
      wkt += ',';
    }
    if (wkt.length > 1) {
      wkt = wkt.substring(0, wkt.length - 1);
    }
    wkt += ')';

    return wkt;
  }

  /**
   * 获取坐标串
   * @param {Array} coordinates -坐标数组
   *
   * @returns {String}
   */
  static _getCoordinatesString(coordinates, exact=true) {
    let wkt = '(';
    coordinates.forEach(cs => {
      wkt += exact ? cs[0] + ' ' + cs[1] + ''
                   : cs[0].toFixed(6) + ' ' + cs[1].toFixed(6) + '';
      wkt += ',';
    });
    if (wkt.length > 1) {
      wkt = wkt.substring(0, wkt.length - 1);
    }
    wkt += ')';

    return wkt;
  }
}
