import { ErrorMargin } from "./ErrorMargin";
import { PrintObject } from "./PrintObject";
import { Projection } from "./Projection";
import { Number } from "../dataType/Number";
import { String } from "../dataType/String";
import { Array } from "../dataType/Array";
import { Boolean } from "../dataType/Boolean";
import { FeatureCollection } from "./FeatureCollection";
import { GeoJSONGeometry } from "../dataType/GeoJSONGeometry";
import { ImageCollection } from "./ImageCollection";

/**
 * @class gve.Geometry
 * @since gve
 */
export class Geometry extends PrintObject {
  gtype: string;
  coordinate: any;

  /**
   * 构造Geometry影像
   * @hideconstructor
   * @param {Object} [args] 几何形体的GeoJSON对象
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns gve.Geometry
   */
  constructor(args?: object, proj?: string) {
    super();
    if (!(this instanceof Geometry)) {
      return new Geometry(args);
    }
    if (args) {
      this.gtype = args["type"];
      this.coordinate = args["coordinates"];
    }
  }

  /**
   * 计算Geometry面积(以平方米为单位)
   * @returns Number
   */
  area() {
    return new Number();
  }
  /**
   * 计算两个Geometry的交集,返回交集geometry
   * @param {Geometry} geometry 矢量要素
   * @returns Geometry
   */
  intersection(geometry: Geometry) {
    return new Geometry();
  }

  /**
   * 生成泰森多边形
   * @param {FeatureCollection} featureCollection 待生成泰森多边形的矢量要素
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @param {Boolean} [only_edges] 可选参数,是否只保留泰森多边形边界,默认false,表示只保留面,true表示只保留边界线
   * @returns Geometry 面或线的Geometry
   */
  voronoi(
    featureCollection: FeatureCollection,
    proj?: string,
    only_edges?: boolean
  ) {
    return new Geometry();
  }

  /**
   *  投影转换
   * @returns GeoJSONGeometry geojson格式的Geometry
   */
  toGeoJSON() {
    return new GeoJSONGeometry();
  }

  /**
   * 投影转换 转换成GeoJSON对象字符串
   * @returns String geojson字符串格式的geometry
   */
  toGeoJSONString() {
    return new String();
  }

  /**
   * 将Geometry转换为特定的投影
   * @param {String} [proj] 要转成的投影,如'epsg:3857','epsg:4326'等
   * @returns Geometry
   */
  transform(proj: string) {
    return new Geometry();
  }

  /**
   * 计算图像的边界
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns Geometry
   */
  bounds(proj?: string) {
    return new Geometry();
  }
  /**
   * 获取Geometry周长
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns Number
   */
  length(proj?: string) {
    return new Number();
  }
  /**
   * 获取Geometry类型
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns String
   */
  type(proj?: string) {
    return new String();
  }
  /**
   * 获取Geometry质心
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns Geometry
   */
  centroid(proj?: string) {
    return new Geometry();
  }
  /**
   * 计算Geometry凸包
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns Geometry
   */
  convexHull(proj?: string) {
    return new Geometry();
  }
  /**
   * 计算Geometry缓冲区
   * @param {number} [bufferDist] 缓冲区半径
   * @returns Geometry
   */
  buffer(bufferDist: number) {
    return new Geometry();
  }
  /**
   * Geometry简化抽稀
   * @param {Object} [maxError] 可选参数,执行任何必要的重投影时所允许的最大错误量。
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns Geometry
   */
  simplify(maxError?: Object, proj?: string) {
    return new Geometry();
  }
  /**
   * 判断两个Geometry是否相离,相离返回True,相交返回False
   * @param {Geometry} geometry 矢量要素
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns Boolean
   */
  disjoint(geometry: Geometry, proj?: string) {
    return new Boolean();
  }
  /**
   * 判断左边Geometry是否包含右边Geometry,不包含返回false,包含返回true。
   * @param {Geometry} geometry 第二个矢量要素
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns Boolean
   */
  contains(geometry: Geometry, proj?: string) {
    return new Boolean();
  }
  /**
   * 对Geometry进行投影,并返回投影后的结果。具体的投影方式可能在代码的其他地方进行定义
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @return Projection
   */
  projection(proj?: string) {
    return new Projection();
  }
  /**
   * 计算两个Geometry的并集,返回合并后的多部件Geometry
   * @param {Geometry} geometry 矢量要素
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns Geometry
   */
  union(geometry: Geometry, proj?: string) {
    return new Geometry();
  }

  /**
   * 计算两个Geometry的对称差,返回去除相交区域后剩下的Geometry
   * @param {Geometry} geometry 矢量要素
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns Geometry
   */
  symmetricDifference(
    geometry: Geometry,
    proj?: string
  ) {
    return new Geometry();
  }
  /**
   * 计算两个Geometry的差集
   * @param {Geometry} geometry 矢量要素
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns Geometry
   */
  difference(geometry: Geometry, proj?: string) {
    return new Geometry();
  }
  /**
   * 融合Geometry,返回融合后的Geometry
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns Geometry
   */
  dissolve(proj?: string) {
    return new Geometry();
  }

  /**
   * 判断两个Geometry的是否有交集,返回值为true或false
   * @param {Geometry} geometry 矢量要素
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns Boolean
   */
  intersects(geometry: Geometry, proj?: string) {
    return new Boolean();
  }

  /**
   * 判断两个Geometry空间包含关系(第一个矢量要素是否被包含于第二个矢量要素),不包含返回false,包含返回true
   * @param {Geometry} geometry 矢量要素
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns Boolean
   */
  containedIn(geometry: Geometry, proj?: string) {
    return new Boolean();
  }

  /**
   * 返回Geometry的坐标
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns Array
   */
  coordinates(proj?: string) {
    return new Array();
  }

  /**
   * 求Geometry的周长
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns Number
   */
  perimeter(proj?: string) {
    return new Number();
  }

  /**
   * 影像动态裁剪到WKT格式
   * @param {Geometry} [geo] 可选参数,矢量要素
   * @returns String
   */
  toWKT(geo?: Geometry) {
    return new String();
  }

  /**
   * 生成网格
   * @param {number[]} boundingbox 生成网格的外部范围
   * @param {string} crs 投影
   * @param {number} h_spacing 水平间隔
   * @param {number} v_spacing 垂直间隔
   * @returns Array<Object>
   */
  grid_custom(boundingbox: number[], crs: string, h_spacing: number, v_spacing: number) {
    return new Array<any>();
  }

  /**
   * 生成网格,返回网格数量
   * @param {number[]} boundingbox 生成网格的外部范围
   * @param {string} crs 投影
   * @param {number} h_spacing 水平间隔
   * @param {number} v_spacing 垂直间隔
   * @param {boolean} [count] 该参数为true时返回网格数量,为false时函数返回结果为Geometry
   * @returns Array<Object>|Object
   */
  grid_custom_count(boundingbox: number[], crs: string, h_spacing: number, v_spacing: number, count: boolean = false) {
    if (count) {
      return new PrintObject();
    } else {
      return new Array<any>();
    }
  }

  /**
   * 将网格数据转成Features数据
   * @param {Object[]} gridItemArray 网格数组
   * @returns Array<Feature>
   */
  mapGrid(gridItemArray: Object[]) {
    return new Array();
  }

  /**
   * 根据给定距离拆分线
   * @param {number[]} distance 数组类型,单位米
   * @param {number} [proj] 可选参数,默认值'EPSG:4326'
   * @returns Geometry
   */
  cutlines(distance: number[], proj: string = 'EPSG:4326') {
    return new Geometry();
  }

  /**
   * 返回文件下载路径
   * @param {number[]} distance 超像素分割的网格内部部边界
   * @param {number} source 文件下载的数据源
   * @param {string} format 文件格式
   * @param {number} buffer 外扩,单位为度
   * @param {boolean} savefile 是否保存到共享文件夹, true为保存
   * @returns Geometry
   */
  grid_save_path(boundingboxInner: number[], source: string, format: string, buffer: number, savefile: boolean) {
    return new Geometry();
  }

  /**
   * 网格数据生成featureCollection数据类型
   * @param {Array<any>} wkt wkt格式的Geometry
   * @returns FeatureCollection
   */
  wktToFeatureCollection(wkt: Array<any>) {
    return new FeatureCollection();
  }

  // /**
  //  * 将某一个网格转成一个ImageCollection对象
  //  * @param {string} wkt wkt格式的Geometry
  //  * @returns ImageCollection
  //  */
  // fromGrid(wkt: string) {
  //   return new ImageCollection();
  // }

  // /**
  //  * 获取建筑物的geojson文件路径
  //  * @param {ImageCollection} fromGridRes imageCollection实例
  //  * @returns string
  //  */
  // buildingSegmentation(fromGridRes: ImageCollection){
  //   return new String();
  // }

}