import * as geo from "../models/Geometry";
import * as spas from "../models/SpatialAnalysis";
// import { Geometry as geo } from "../models/Geometry";
// import * as str from "./String";
// import * as arr from "../models/Array";
import * as ima from "../models/Image";
import * as fc from "../models/FeatureCollection";
import * as imc from "../models/ImageCollection";
import * as msd from "../models/MosaicData";
import * as plt from "../models/Palette";
import * as trr from "../models/Terrain";
import * as itpt from "../models/Interpolation";
import * as ft from "../models/Feature";
import * as bb from "../models/Blob";
import * as ai from "../models/AI";
// import * as algori from "../models/Algorithms";
import * as pt from "../models/Point";
import * as pg from "../models/Polygon";
import * as ls from "../models/LineString";
import * as bbo from "../models/BBox";
import * as mulpt from "../models/MultiPoint";
import * as mulls from "../models/MultiLineString";
import * as mulpg from "../models/MultiPolygon";
import * as rtg from "../models/Rectangle";
import * as lr from "../models/LinearRing";
import * as kn from "../models/Kernel";
// import { List } from "./List";

import * as nber from "../dataType/Number";
import * as ary from "../dataType/Array";
import * as lst from "../dataType/List";
import * as str from "../dataType/String";
import * as ptp from "../dataType/PixelType";
import * as cst from "../models/Clusterer";
import * as tbl from "../models/Table";
import * as rd from "../models/Reducer";
import * as flt from "../models/Filter";
import * as clsf from "../models/Classifier";
import * as dnt from "../models/Dictionary";
import * as cfmt from "../models/ConfusionMatrix";
import * as join from "../models/Join";

import * as fil from "../models/File";
import { codeParams as gveeCodeParams, ifOverLoadingObject, codeAllParams as gveeAllParams } from "../common/FunParams";

import * as svc from "../models/services/Services";
import * as svcAi from "../models/services/AI";
import * as svcImg from "../models/services/Image";
import * as svcSenE from "../models/services/SenseEarth";
import * as svcModel from "../models/services/Model";
import * as date from "../models/Date";
import * as daterange from "../models/DateRange";
import * as errormargin from "../models/ErrorMargin";
import * as projection from "../models/Projection";
// import { processGVE } from "./ExpressionHelper";
import { processGVE } from "@gvol-org/geovis-brain-core";

import * as algori from "../models/Algorithms/Algorithms";
import * as algoriImage from "../models/Algorithms/Image/Image";
import * as algoriImageSeg from "../models/Algorithms/Image/Segmentation";
/**
 * gve类
 * @summary sdk
 */
export class gve {
  static apply() {
    console.log("geb.apply");
  }

  static call() {
    console.log("geb.call");
  }
}





export namespace geeInternal {

  export import FeatureCollection = fc.FeatureCollection;
  export import Point = pt.Point;
  export import Polygon = pg.Polygon;
  export import LineString = ls.LineString;
  export import BBox = bbo.BBox;
  export import MultiPoint = mulpt.MultiPoint;
  export import MultiLineString = mulls.MultiLineString;
  export import MultiPolygon = mulpg.MultiPolygon;
  export import LinearRing = lr.LinearRing;
  export import Rectangle = rtg.Rectangle;
  export import ImageCollection = imc.ImageCollection;
  export import MosaicData = msd.MosaicData;
  export import Image = ima.Image;
  export import Palette = plt.Palette;

  // export import Terrain = trr.Terrain;

  export import Feature = ft.Feature;
  export import Blob = bb.Blob;

  export import Geometry = geo.Geometry;
  
  export import SpatialAnalysis = spas.SpatialAnalysis;
  export import interpolation = itpt.interpolation;

  export import AI = ai.AI;

  // export import Algorithms = algori.Algorithms;

  export import Kernel = kn.Kernel;
  export import Clusterer = cst.Clusterer;

  export import Number = nber.Number;
  export import PixelType = ptp.PixelType;
  export import Array = ary.Array;
  export import Table = tbl.Table;
  export import Reducer = rd.Reducer;
  export import Filter = flt.Filter;
  export import Classifier = clsf.Classifier;
  export import List = lst.List;
  export import String = str.String;
  export import Dictionary = dnt.Dictionary;
  export import File = fil.File;
  export import ConfusionMatrix = cfmt.ConfusionMatrix;

  export import Services = svc.Services;
  export import ServicesAI = svcAi.AI;
  export import ServicesImage = svcImg.Image;
  export import Model = svcModel.Model;
  export import SenseEarth = svcSenE.SenseEarth;

  export import Date = date.Date;
  export import DateRange = daterange.DateRange;
  export import ErrorMargin = errormargin.ErrorMargin;
  export import Projection = projection.Projection;

  export import Algorithms = algori.Algorithms;
  export import AlgorithmsImage = algoriImage.Image;
  export import AlgorithmsImageSeg = algoriImageSeg.Segmentation;

  export import Join = join.Join;
  

}

/**
 * gee命名空间,及内部类型定义
 */
// export namespace geeInternal{
function getOwnPropertyStatics(_obj: any) {
  const KNOWN_STATICS = {
    name: true,
    length: true,
    prototype: false,
    caller: true,
    callee: true,
    arguments: true,
    arity: true
  };

  let result = [];

  let keys = Object.getOwnPropertyNames(_obj);
  keys = keys.concat(Object.getOwnPropertySymbols(_obj) as any);
  for (let i = 0; i < keys.length; ++i) {
    const key = keys[i];
    if (!KNOWN_STATICS[key]) {
      result.push(key)
    }
  }

  return result;
}

export namespace gve {
  // function getOwnPropertyStatics(_obj: any) {
  //   const KNOWN_STATICS = {
  //     name: true,
  //     length: true,
  //     prototype: true,
  //     caller: true,
  //     callee: true,
  //     arguments: true,
  //     arity: true
  //   };

  //   let result = [];

  //   let keys = Object.getOwnPropertyNames(_obj);
  //   keys = keys.concat(Object.getOwnPropertySymbols(_obj) as any);
  //   for (let i = 0; i < keys.length; ++i) {
  //     const key = keys[i];
  //     if (!KNOWN_STATICS[key]) {
  //       result.push(key)
  //     }
  //   }

  //   return result;
  // }




  // Let's assume "class X {}". X itself (it has type "typeof X") can be called with "new" keyword,
  // thus "typeof X" extends this type
  type Constructor = new (...args: any[]) => any;

  // Extracts argument types from class constructor
  type ConstructorArgs<TConstructor extends Constructor> =
    TConstructor extends new (...args: infer TArgs) => any ? TArgs : never;

  // Extracts class instance type from class constructor
  type ConstructorClass<TConstructor extends Constructor> =
    TConstructor extends new (...args: any[]) => infer TClass ? TClass : never;

  // This is what we want: to be able to create new class instances
  // either with or without "new" keyword
  type CallableConstructor<TConstructor extends Constructor> =
    TConstructor & ((...args: ConstructorArgs<TConstructor>) => ConstructorClass<TConstructor>);
  function CreateCallableConstructor<TConstructor extends Constructor>(
    type: TConstructor
  ): CallableConstructor<TConstructor> {
    function createInstance(
      ...args: ConstructorArgs<TConstructor>
    ): ConstructorClass<TConstructor> {
      return new type(...args);
    }

    // var s = getOwnPropertyStatics(type)
    // // console.log("abdc", s, type);
    // createInstance.prototype = type.prototype;
    // for (var item of s) {
    //   createInstance[item] = type[item];
    // }
    CreateProperty(createInstance, type)
    return createInstance as CallableConstructor<TConstructor>;
  }
  function CreateProperty(func: any, type: any) {
    var s = getOwnPropertyStatics(type)
    // console.log("abdc", s, type);
    func.prototype = type.prototype;
    for (var item of s) {
      func[item] = type[item];
    }
  }


  /**

   * 构造Geometry对象
   * @hideconstructor
   * @param {Object} [geoJson] 几何形体的GeoJSON对象
   * @param {String} [proj] 可选参数,待转换的投影坐标,默认EPSG:4326
   * @returns gve.Geometry
   */

  export type Geometry = geeInternal.Geometry;

  export function Geometry(geoJson?: object, proj?: string) {
    return new geeInternal.Geometry(geoJson, proj);
    // let newGeometry: any = CreateExpression(geeInternal.Geometry, 'Geometry');
    // // console.log("geometry的函数需要加上expression重新封装", testt)
    // return new newGeometry(geoJson, proj);
  }
  CreateProperty(Geometry, geeInternal.Geometry);

  export module Geometry {

    export type Point = geeInternal.Point;
    /**
     * 坐标点构造点Geometry
     */
    export const Point = CreateCallableConstructor(geeInternal.Point);
    export type Polygon = geeInternal.Polygon;
    /**
     * 坐标点序列构造多边形Geometry
     */
    export const Polygon = CreateCallableConstructor(geeInternal.Polygon);
    export type LineString = geeInternal.LineString;
    /**
     * 坐标点序列构造线Geometry
     */
    export const LineString = CreateCallableConstructor(geeInternal.LineString);
    export type BBox = geeInternal.BBox;
    /**
     * 坐标点序列构造BBox
     */
    export const BBox = CreateCallableConstructor(geeInternal.BBox);
    export type MultiPoint = geeInternal.MultiPoint;
    /**
     * 多个坐标点构造多个点Geometry
     */
    export const MultiPoint = CreateCallableConstructor(geeInternal.MultiPoint);
    export type MultiLineString = geeInternal.MultiLineString;
    /**
     * 多个坐标点序列构造多个线Geometry
     */
    export const MultiLineString = CreateCallableConstructor(geeInternal.MultiLineString);
    export type MultiPolygon = geeInternal.MultiPolygon;
    /**
     * 多个坐标点构造多个多边形Geometry
     */
    export const MultiPolygon = CreateCallableConstructor(geeInternal.MultiPolygon);
    export type LinearRing = geeInternal.LinearRing;
    /**
     * 多个坐标点构造环Geometry
     */
    export const LinearRing = CreateCallableConstructor(geeInternal.LinearRing);
    export type Rectangle = geeInternal.Rectangle;
    /**
     * 坐标点序列构造矩形Geometry
     */
    export const Rectangle = CreateCallableConstructor(geeInternal.Rectangle);
  }

  export type FeatureCollection = geeInternal.FeatureCollection;
  /**
   * 通过矢量数据构造Feature集合
   */
  export const FeatureCollection = CreateCallableConstructor(geeInternal.FeatureCollection);

  export type ImageCollection = geeInternal.ImageCollection;
  /**
   * 构造影像集合
   */
  export const ImageCollection = CreateCallableConstructor(geeInternal.ImageCollection);

  export type MosaicData = geeInternal.MosaicData;
  /**
   * 构造Mosaic数据
   */
  export const MosaicData = CreateCallableConstructor(geeInternal.MosaicData);

  export type Image = geeInternal.Image;
  /**
   * 构造Image
   */
  export const Image = CreateCallableConstructor(geeInternal.Image);

  export type Palette = plt.Palette;
  /**
   * 图例颜色的构造方法,构造一个新的图例实例
   */
  export const Palette = CreateCallableConstructor(geeInternal.Palette);

  // export type Terrain = trr.Terrain;
  // export const Terrain = CreateCallableConstructor(geeInternal.Terrain);
  export import Terrain = trr.Terrain;

  export type Feature = ft.Feature;
  /**
   * 通过Geometry构造Feature对象
   */
  export const Feature = CreateCallableConstructor(geeInternal.Feature);


  export type Blob = bb.Blob;
  /**
   * 从云存储URL加载Blob
   */
  export const Blob = CreateCallableConstructor(geeInternal.Blob);

  export type AI = ai.AI;
  export const AI = CreateCallableConstructor(geeInternal.AI);
  // export import AI = ai.AI;

  // export type Algorithms = algori.Algorithms;
  // export const Algorithms = CreateCallableConstructor(geeInternal.Algorithms);
  // export import Algorithms = algori.Algorithms;

  export type Kernel = kn.Kernel;

  // export const Kernel= CreateCallableConstructor(geeInternal.Blob);
  /**
   * 构造Kernel对象
   */
  export const Kernel = CreateCallableConstructor(geeInternal.Kernel);
  // export import Kernel = kn.Kernel;

  export type Clusterer = cst.Clusterer;

  /**
   * 构造Clusterer对象
   */
  export const Clusterer = CreateCallableConstructor(geeInternal.Clusterer);
  
  /**

   * 构造SpatialAnalysis对象
   * @hideconstructor
   * @returns gve.SpatialAnalysis
   */

  export type SpatialAnalysis = geeInternal.SpatialAnalysis;

  export module SpatialAnalysis {
    export type interpolation = geeInternal.interpolation;
    export const interpolation = CreateCallableConstructor(geeInternal.interpolation);
  }

  /**

   * 构造Services对象
   * @hideconstructor
   * @returns gve.Services
   */

  export type Services = geeInternal.Services;

  export module Services {
    export type AI = geeInternal.ServicesAI;
    export const AI = CreateCallableConstructor(geeInternal.ServicesAI);
    export type Image = geeInternal.ServicesImage;
    export const Image = CreateCallableConstructor(geeInternal.ServicesImage);
    export type SenseEarth = geeInternal.SenseEarth;
    export const SenseEarth = CreateCallableConstructor(geeInternal.SenseEarth);
    export type Model = geeInternal.Model;
    export const Model = CreateCallableConstructor(geeInternal.Model);
  }

  /**

  * 构造Algorithms对象
  * @hideconstructor
  * @returns gve.Algorithms
  */

  export type Algorithms = geeInternal.Algorithms;

  export module Algorithms {
    /**
     * 构造Image对象
     * @hideconstructor
     * @returns gve.Algorithms.Image
     */
    export type Image = geeInternal.AlgorithmsImage;
    export module Image {
      export type Segmentation = geeInternal.AlgorithmsImageSeg;
      export const Segmentation = CreateCallableConstructor(geeInternal.AlgorithmsImageSeg);
    }
  }

  export type Number = nber.Number;
  /**
   * Number的构造方法,构造一个新数值
   */
  export const Number = CreateCallableConstructor(geeInternal.Number);

  export type PixelType = ptp.PixelType;
  /**
   * PixelType的构造方法
   */
  export const PixelType = CreateCallableConstructor(geeInternal.PixelType);

  export type Array = ary.Array<any>;
  /**
   * Array的构造方法,构造一个新数组
   */
  export const Array = CreateCallableConstructor(geeInternal.Array);

  export type List<T> = lst.List<T>;

  export const List = CreateCallableConstructor(geeInternal.List);

  export type String = str.String;

  export const String = CreateCallableConstructor(geeInternal.String);

  export type Table = tbl.Table;
  /**
   * 构造Table对象
   */
  export const Table = CreateCallableConstructor(geeInternal.Table);

  export type Reducer = rd.Reducer;
  /**
   * 构造Reducer对象
   */
  export const Reducer = CreateCallableConstructor(geeInternal.Reducer);

  export type Filter = flt.Filter;

  /**
   * 构造Filter对象
   */
  export const Filter = CreateCallableConstructor(geeInternal.Filter);

  export type Classifier = clsf.Classifier;

  /**
   * 构造Classifier对象
   */
  export const Classifier = CreateCallableConstructor(geeInternal.Classifier);

  export type Dictionary = dnt.Dictionary;

  /**
   * Dictionary
   */
  export const Dictionary = CreateCallableConstructor(geeInternal.Dictionary);

  export type File = fil.File;
  /**
   * 构造File对象
   */
  export const File = CreateCallableConstructor(geeInternal.File);

  export type ConfusionMatrix = cfmt.ConfusionMatrix;
  /**
   * 构造ConfusionMatrix对象
   */
  export const ConfusionMatrix = CreateCallableConstructor(geeInternal.ConfusionMatrix);

  export type Date = date.Date;
  /**
   * 构造Date对象
   */
  export const Date = CreateCallableConstructor(geeInternal.Date);

  export type DateRange = daterange.DateRange;
  /**
   * 构造DateRange对象
   */
  export const DateRange = CreateCallableConstructor(geeInternal.DateRange);

  export type ErrorMargin = errormargin.ErrorMargin;
  /**
   * 构造ErrorMargin对象
   */
  export const ErrorMargin = CreateCallableConstructor(geeInternal.ErrorMargin);

  export type Projection = projection.Projection;
  /**
   * 构造Projection对象
   */
  export const Projection = CreateCallableConstructor(geeInternal.Projection);

  /**
   * 构造Join对象
   */
  export type Join = join.Join;
  export const Join = CreateCallableConstructor(geeInternal.Join);
}

// }

//重新封装构造函数和成员函数

// process(Array);
// process(lst.List);
processGVE(gve, "gve",gveeAllParams,gveeCodeParams,ifOverLoadingObject);
// window['p00'] = process;
// window['get1'] = getOwnPropertyStatics;