import * as pnl from "./Panel";
import * as lyt from "./Layout";
import * as btn from "./Button";
import * as actDic from "./data";
import * as actList from "./ActiveList";
import * as cht from "./Chart";
import * as arrs from "./array";
import * as img from "./image";
import * as fture from "./feature";
import * as lab from "./Label";
import * as legend from "./Legend";
import * as echt from "./EChart";
import * as dates from "./DateSelect";
import { Widget } from "./Widget";
import { List } from "../dataType/List";
import { PrintObject } from "../models/PrintObject";
import * as cascader from "./Cascader";
import { codeParams, ifOverLoadingObject } from "../common/FunParams";
import * as picture from "./Img";
import * as map from "./Map";
import * as linker from "./Linker";
import * as geometryLayer from "./GeometryLayer";
import * as drawingTools from "./DrawingTools";
import { processUI} from "@gvol-org/geovis-brain-core";
/**
 * ui类
 * @summary ui
 */
export class ui {
  /**
   * @class ui.root
   * @since ui
   */
  static root: pnl.Panel = new pnl.Panel();

  constructor() { }
}

export namespace geeInternal {

  export import Button = btn.Button;
  export import Layout = lyt.Layout;
  export import ActiveDictionary = actDic.ActiveDictionary;
  export import ActiveList = actList.ActiveList;
  export import array = arrs.array;
  export import image = img.image;
  export import feature = fture.feature;
  export import echart = echt.echart;
  export import panel = pnl.Panel;
  export import Legend = legend.Legend;
  export import Label = lab.Label;
  export import DateSelect = dates.DateSelect;
  export import Cascader = cascader.Cascader;
  export import Img = picture.Img;
  export import Map = map.Map;
  export import Linker = linker.Linker;
  export import GeometryLayer = geometryLayer.GeometryLayer;
  export import DrawingTools = drawingTools.DrawingTools;
}
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;
}

/**
 * ui命名空间,及内部类型定义
 */
export namespace ui {
  // 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: Array<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: Array<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 CalLabelConstructor<TConstructor extends Constructor> =
    TConstructor & ((...args: ConstructorArgs<TConstructor>) => ConstructorClass<TConstructor>);
  function CreateCalLabelConstructor<TConstructor extends Constructor>(
    type: TConstructor
  ): CalLabelConstructor<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];
    }
    return createInstance as CalLabelConstructor<TConstructor>;
  }

  /**
   * 容器组件
   */
  // export class Panel extends panel.Panel { }
  export type Panel = geeInternal.panel;
  export function Panel(widgets?:Widget[]| Widget, layout?: lyt.Layout, style?: object) {
    return new geeInternal.panel(widgets, layout, style);
  }
  export module Panel {
    /**
     * 布局
     */
    export type Layout = geeInternal.Layout;
    export const Layout = CreateCalLabelConstructor(geeInternal.Layout);
  }

  /**
   * 按钮组件
   */
  export type Button = geeInternal.Button;
  export const Button = CreateCalLabelConstructor(geeInternal.Button);
  /**
    * 文本组件
    */
  export type Label = geeInternal.Label;
  export const Label = CreateCalLabelConstructor(geeInternal.Label);
  /**
  * 图例组件
  */
  export type Legend = geeInternal.Legend;
  export const Legend = CreateCalLabelConstructor(geeInternal.Legend);
  export type DateSelect = geeInternal.DateSelect;
  export const DateSelect = CreateCalLabelConstructor(geeInternal.DateSelect);

  export type Cascader = geeInternal.Cascader;
  export const Cascader = CreateCalLabelConstructor(geeInternal.Cascader);


  /**
 * 图片组件
 */
  export type Img = geeInternal.Img;
  export const Img = CreateCalLabelConstructor(geeInternal.Img);

  export type Map = geeInternal.Map;
  export function Map(center?: object, onClick?: Function, style?: object) {
    return new geeInternal.Map(center, onClick, style);
  }
  /**
   * @class ui.data
   * @since ui
   */
  export namespace data {

    /**
     * UI组件中使用的字典类型的数据容器
     */
    export type ActiveDictionary = geeInternal.ActiveDictionary;
    export const ActiveDictionary = CreateCalLabelConstructor(geeInternal.ActiveDictionary);
    /**
     * UI组件中使用的数组类型的数据容器
     */
    export type ActiveList = geeInternal.ActiveList;
    export const ActiveList = CreateCalLabelConstructor(geeInternal.ActiveList);
  }

  /**
   * 图表组件
   */
  //export class Chart extends cht.Chart { }

  export type Chart = cht.Chart;
  export function Chart(dataTable?: Array<Array<object>> | List<any>, chartType?: string, options?: object) {
    return new cht.Chart(dataTable, chartType, options);
  }
  export namespace Chart {
    /**
     * 数据图表组件
     */
    export type array = geeInternal.array;
    export const array = CreateCalLabelConstructor(geeInternal.array);
    /**
     * 影像图表组件
     */
    export type image = geeInternal.image;
    export const image = CreateCalLabelConstructor(geeInternal.image);
    /**
     * 矢量图表组件
     */
    export type feature = geeInternal.feature;
    export const feature = CreateCalLabelConstructor(geeInternal.feature);
    /**
    * EChart图表组件
    */
    export type echart = geeInternal.echart;
    export const echart = CreateCalLabelConstructor(geeInternal.echart);
  }
  export namespace Map {
    /**
     * 地图联动组件
     */
    export type Linker = geeInternal.Linker;
    export const Linker = CreateCalLabelConstructor(geeInternal.Linker);

    /**
    * GeometryLayer
    */
    export type GeometryLayer = geeInternal.GeometryLayer;
    export const GeometryLayer = CreateCalLabelConstructor(geeInternal.GeometryLayer);

    /**
     * 标绘工具
     */
    export type DrawingTools = geeInternal.DrawingTools;
    export const DrawingTools = CreateCalLabelConstructor(geeInternal.DrawingTools);
  }

  // export namespace Label{}

  // export namespace Legend{}
}

//重新封装构造函数和成员函数
processUI(ui,'ui',codeParams,ifOverLoadingObject);