/// <reference path="./global.d.ts" />

import { AbstractBatchRenderer } from '@pixi/core';
import { BatchTextureArray } from '@pixi/core';
import { Buffer as Buffer_2 } from '@pixi/core';
import { Container } from '@pixi/display';
import { Dict } from '@pixi/utils';
import { DisplayObject } from '@pixi/display';
import { Filter } from '@pixi/core';
import { FilterSystem } from '@pixi/core';
import { Geometry } from '@pixi/core';
import { Graphics } from '@pixi/graphics';
import { IPoint } from '@pixi/math';
import { IPointData } from '@pixi/math';
import { Matrix } from '@pixi/math';
import { Mesh } from '@pixi/mesh';
import { MeshMaterial } from '@pixi/mesh';
import { ObjectRenderer } from '@pixi/core';
import { ObservablePoint } from '@pixi/math';
import { Point } from '@pixi/math';
import { QuadUv } from '@pixi/core';
import { Rectangle } from '@pixi/math';
import { Renderer } from '@pixi/core';
import { RenderTexture } from '@pixi/core';
import { Shader } from '@pixi/core';
import { SimpleMesh } from '@pixi/mesh-extras';
import { Sprite } from '@pixi/sprite';
import { State } from '@pixi/core';
import { Text as Text_2 } from '@pixi/text';
import { TextStyle } from '@pixi/text';
import { Texture } from '@pixi/core';
import { TilingSprite } from '@pixi/sprite-tiling';
import { Transform } from '@pixi/math';
import { ViewableBuffer } from '@pixi/core';

export declare class AbstractProjection {
    constructor(legacy: Transform, enable?: boolean);
    legacy: Transform;
    _enabled: boolean;
    get enabled(): boolean;
    set enabled(value: boolean);
    clear(): void;
}

export declare enum AFFINE {
    NONE = 0,
    FREE = 1,
    AXIS_X = 2,
    AXIS_Y = 3,
    POINT = 4,
    AXIS_XR = 5
}

export declare function applySpine2dMixin(spineClassPrototype: ISpineClass): void;

export declare function applySpine3dMixin(spineClassPrototype: ISpineClass): void;

export declare class Batch2dPluginFactory {
    static create(options: any): any;
}

export declare class Batch3dGeometry extends Geometry {
    _buffer: Buffer_2;
    _indexBuffer: Buffer_2;
    constructor(_static?: boolean);
}

export declare class BatchBilineardGeometry extends Geometry {
    _buffer: Buffer_2;
    _indexBuffer: Buffer_2;
    constructor(_static?: boolean);
}

export declare class BatchBilinearPluginFactory {
    static create(options: any): any;
}

export declare class BilinearSurface extends Surface {
    distortion: Point;
    clear(): void;
    apply(pos: IPointData, newPos?: IPointData): IPointData;
    applyInverse(pos: IPointData, newPos: IPoint): IPointData;
    mapSprite(sprite: Sprite, quad: Array<IPointData>, outTransform?: Transform): this;
    mapQuad(rect: Rectangle, quad: Array<IPointData>, outTransform: Transform): this;
    fillUniforms(uniforms: Dict<any>): void;
}

export declare class Camera3d extends Container3d {
    constructor();
    _far: number;
    _near: number;
    _focus: number;
    _orthographic: boolean;
    get far(): number;
    get near(): number;
    get focus(): number;
    get ortographic(): boolean;
    setPlanes(focus: number, near?: number, far?: number, orthographic?: boolean): void;
}

export declare class Container2d extends Container {
    constructor();
    proj: Projection2d;
    toLocal<P extends IPointData = Point>(position: IPointData, from?: DisplayObject, point?: P, skipUpdate?: boolean, step?: TRANSFORM_STEP): P;
    get worldTransform(): Matrix;
}

export declare const container2dToLocal: <P extends IPointData = Point>(position: IPointData, from?: DisplayObject, point?: P, skipUpdate?: boolean, step?: TRANSFORM_STEP) => P;

export declare function container2dWorldTransform(): Matrix;

export declare class Container3d extends Container implements IDisplayObject3d {
    constructor();
    proj: Projection3d;
    isFrontFace(forceUpdate?: boolean): boolean;
    getDepth(forceUpdate?: boolean): number;
    toLocal<P extends IPointData = Point>(position: IPointData, from?: DisplayObject, point?: P, skipUpdate?: boolean, step?: TRANSFORM_STEP): P;
    get worldTransform(): Matrix;
    get position3d(): IPointData;
    set position3d(value: IPointData);
    get scale3d(): IPointData;
    set scale3d(value: IPointData);
    get euler(): IEuler;
    set euler(value: IEuler);
    get pivot3d(): IPointData;
    set pivot3d(value: IPointData);
}

export declare const container3dGetDepth: (forceUpdate?: boolean) => number;

export declare const container3dIsFrontFace: (forceUpdate?: boolean) => boolean;

export declare const container3dToLocal: <P extends IPointData = Point>(position: IPointData, from?: DisplayObject, point?: P, skipUpdate?: boolean, step?: TRANSFORM_STEP) => P;

export declare function container3dWorldTransform(): Matrix;

export declare class Euler {
    constructor(x?: number, y?: number, z?: number);
    _quatUpdateId: number;
    _quatDirtyId: number;
    quaternion: Float64Array;
    _x: number;
    _y: number;
    _z: number;
    _sign: number;
    get x(): number;
    set x(value: number);
    get y(): number;
    set y(value: number);
    get z(): number;
    set z(value: number);
    get pitch(): number;
    set pitch(value: number);
    get yaw(): number;
    set yaw(value: number);
    get roll(): number;
    set roll(value: number);
    set(x?: number, y?: number, z?: number): void;
    copyFrom(euler: IEuler): this;
    copyTo(p: IEuler): IEuler;
    equals(euler: IEuler): boolean;
    clone(): Euler;
    update(): boolean;
}

export declare function getIntersectionFactor(p1: IPointData, p2: IPointData, p3: IPointData, p4: IPointData, out: IPointData): number;

export declare function getPositionFromQuad(p: Array<IPointData>, anchor: IPointData, out: IPointData): IPointData;

export declare interface IDisplayObject3d {
    isFrontFace(forceUpdate?: boolean): boolean;
    getDepth(forceUpdate?: boolean): number;
    toLocal<P extends IPointData = Point>(position: IPointData, from?: DisplayObject, point?: P, skipUpdate?: boolean, step?: TRANSFORM_STEP): P;
    position3d: IPointData;
    scale3d: IPointData;
    euler: IEuler;
    pivot3d: IPointData;
}

export declare type IEuler = Euler | ObservableEuler;

export declare interface ISpineClass {
    newContainer(): Container;
    newSprite(tex: Texture): Sprite;
    newGraphics(): Graphics;
    newMesh(texture: Texture, vertices?: Float32Array, uvs?: Float32Array, indices?: Uint16Array, drawMode?: number): SimpleMesh;
    transformHack(): number;
}

export declare interface IWorldTransform {
    apply(pos: IPointData, newPos: IPointData): IPointData;
    applyInverse(pos: IPointData, newPos: IPointData): IPointData;
}

export declare class LinearProjection<T> extends AbstractProjection {
    updateLocalTransform(lt: Matrix): void;
    _projID: number;
    _currentProjID: number;
    _affine: AFFINE;
    affinePreserveOrientation: boolean;
    scaleAfterAffine: boolean;
    set affine(value: AFFINE);
    get affine(): AFFINE;
    local: T;
    world: T;
    set enabled(value: boolean);
    clear(): void;
}

export declare class Matrix2d {
    static readonly IDENTITY: Matrix2d;
    static readonly TEMP_MATRIX: Matrix2d;
    mat3: Float64Array;
    floatArray: Float32Array;
    constructor(backingArray?: ArrayLike<number>);
    get a(): number;
    set a(value: number);
    get b(): number;
    set b(value: number);
    get c(): number;
    set c(value: number);
    get d(): number;
    set d(value: number);
    get tx(): number;
    set tx(value: number);
    get ty(): number;
    set ty(value: number);
    set(a: number, b: number, c: number, d: number, tx: number, ty: number): this;
    toArray(transpose?: boolean, out?: Float32Array): Float32Array;
    apply(pos: IPointData, newPos: IPointData): IPointData;
    translate(tx: number, ty: number): this;
    scale(x: number, y: number): this;
    scaleAndTranslate(scaleX: number, scaleY: number, tx: number, ty: number): void;
    applyInverse(pos: IPointData, newPos: IPointData): IPointData;
    invert(): Matrix2d;
    identity(): Matrix2d;
    clone(): Matrix2d;
    copyTo2dOr3d(matrix: Matrix2d): Matrix2d;
    copyTo(matrix: Matrix, affine?: AFFINE, preserveOrientation?: boolean): Matrix;
    copyFrom(matrix: Matrix): this;
    setToMultLegacy(pt: Matrix, lt: Matrix2d): this;
    setToMultLegacy2(pt: Matrix2d, lt: Matrix): this;
    setToMult(pt: Matrix2d, lt: Matrix2d): this;
    prepend(lt: any): this;
}

export declare class Matrix3d {
    static readonly IDENTITY: Matrix3d;
    static readonly TEMP_MATRIX: Matrix3d;
    mat4: Float64Array;
    floatArray: Float32Array;
    _dirtyId: number;
    _updateId: number;
    _mat4inv: Float64Array;
    cacheInverse: boolean;
    constructor(backingArray?: ArrayLike<number>);
    get a(): number;
    set a(value: number);
    get b(): number;
    set b(value: number);
    get c(): number;
    set c(value: number);
    get d(): number;
    set d(value: number);
    get tx(): number;
    set tx(value: number);
    get ty(): number;
    set ty(value: number);
    set(a: number, b: number, c: number, d: number, tx: number, ty: number): this;
    toArray(transpose?: boolean, out?: Float32Array): Float32Array;
    setToTranslation(tx: number, ty: number, tz: number): void;
    setToRotationTranslationScale(quat: Float64Array, tx: number, ty: number, tz: number, sx: number, sy: number, sz: number): Float64Array;
    apply(pos: IPointData, newPos: IPointData): IPointData;
    translate(tx: number, ty: number, tz: number): this;
    scale(x: number, y: number, z?: number): this;
    scaleAndTranslate(scaleX: number, scaleY: number, scaleZ: number, tx: number, ty: number, tz: number): void;
    applyInverse<P extends IPointData = Point>(pos: IPointData, newPos?: P): P;
    invert(): Matrix3d;
    invertCopyTo(matrix: Matrix3d): void;
    identity(): Matrix3d;
    clone(): Matrix3d;
    copyTo3d(matrix: Matrix3d): Matrix3d;
    copyTo2d(matrix: Matrix2d): Matrix2d;
    copyTo2dOr3d<P extends Matrix2d | Matrix3d>(matrix: P): P;
    copyTo(matrix: Matrix, affine?: AFFINE, preserveOrientation?: boolean): Matrix;
    copyFrom(matrix: Matrix): this;
    setToMultLegacy(pt: Matrix, lt: Matrix3d): this;
    setToMultLegacy2(pt: Matrix3d, lt: Matrix): this;
    setToMult(pt: Matrix3d, lt: Matrix3d): this;
    prepend(lt: any): void;
    static glMatrixMat4Invert(out: Float64Array, a: Float64Array): Float64Array;
    static glMatrixMat4Multiply(out: Float64Array, a: Float64Array, b: Float64Array): Float64Array;
}

export declare class Mesh2d extends Mesh {
    static defaultVertexShader: string;
    static defaultFragmentShader: string;
    constructor(geometry: Geometry, shader: MeshMaterial, state: State, drawMode?: number);
    vertexData2d: Float32Array;
    proj: Projection2d;
    calculateVertices(): void;
    _renderDefault(renderer: Renderer): void;
    toLocal<T extends IPointData>(position: IPointData, from?: DisplayObject, point?: T, skipUpdate?: boolean, step?: TRANSFORM_STEP): T;
    get worldTransform(): Matrix;
}

export declare class Mesh3d2d extends Mesh {
    constructor(geometry: Geometry, shader: MeshMaterial, state: State, drawMode?: number);
    vertexData2d: Float32Array;
    proj: Projection3d;
    calculateVertices(): void;
    get worldTransform(): Matrix;
    toLocal<T extends IPointData>(position: IPointData, from?: DisplayObject, point?: T, skipUpdate?: boolean, step?: TRANSFORM_STEP): T;
    isFrontFace(forceUpdate?: boolean): boolean;
    getDepth(forceUpdate?: boolean): boolean;
    get position3d(): IPointData;
    set position3d(value: IPointData);
    get scale3d(): IPointData;
    set scale3d(value: IPointData);
    get euler(): Euler;
    set euler(value: Euler);
    get pivot3d(): IPointData;
    set pivot3d(value: IPointData);
}

export declare class ObservableEuler {
    cb: any;
    scope: any;
    constructor(cb: any, scope: any, x?: number, y?: number, z?: number);
    _quatUpdateId: number;
    _quatDirtyId: number;
    quaternion: Float64Array;
    _x: number;
    _y: number;
    _z: number;
    _sign: number;
    get x(): number;
    set x(value: number);
    get y(): number;
    set y(value: number);
    get z(): number;
    set z(value: number);
    get pitch(): number;
    set pitch(value: number);
    get yaw(): number;
    set yaw(value: number);
    get roll(): number;
    set roll(value: number);
    set(x?: number, y?: number, z?: number): this;
    copyFrom(euler: IEuler): this;
    copyTo(p: IEuler): IEuler;
    equals(euler: IEuler): boolean;
    clone(): Euler;
    update(): boolean;
}

export declare class ObservablePoint3d extends ObservablePoint {
    _z: number;
    get z(): number;
    set z(value: number);
    set(x?: number, y?: number, z?: number): this;
    copyFrom(p: IPointData): this;
    copyTo<T extends IPoint>(p: T): T;
}

export declare class Point3d extends Point {
    z: number;
    constructor(x?: number, y?: number, z?: number);
    set(x?: number, y?: number, z?: number): this;
    copyFrom(p: IPointData): this;
    copyTo<T extends IPoint>(p: T): T;
}

export declare class Projection2d extends LinearProjection<Matrix2d> {
    constructor(legacy: Transform, enable?: boolean);
    matrix: Matrix2d;
    pivot: ObservablePoint<this>;
    reverseLocalOrder: boolean;
    onChange(): void;
    setAxisX(p: IPointData, factor?: number): void;
    setAxisY(p: IPointData, factor?: number): void;
    mapSprite(sprite: Sprite, quad: Array<IPointData>): void;
    mapQuad(rect: Rectangle, p: Array<IPointData>): void;
    updateLocalTransform(lt: Matrix): void;
    clear(): void;
}

export declare class Projection3d extends LinearProjection<Matrix3d> {
    constructor(legacy: Transform, enable?: boolean);
    cameraMatrix: Matrix3d;
    _cameraMode: boolean;
    get cameraMode(): boolean;
    set cameraMode(value: boolean);
    position: ObservablePoint3d;
    scale: ObservablePoint3d;
    euler: ObservableEuler;
    pivot: ObservablePoint3d;
    onChange(): void;
    clear(): void;
    updateLocalTransform(lt: Matrix): void;
}

export declare class ProjectionSurface extends AbstractProjection {
    _surface: Surface;
    _activeProjection: ProjectionSurface;
    set enabled(value: boolean);
    get surface(): Surface;
    set surface(value: Surface);
    applyPartial(pos: IPointData, newPos?: IPointData): IPointData;
    apply(pos: IPointData, newPos?: IPointData): IPointData;
    applyInverse(pos: IPointData, newPos: IPointData): IPointData;
    mapBilinearSprite(sprite: Sprite, quad: Array<IPointData>): void;
    _currentSurfaceID: number;
    _currentLegacyID: number;
    _lastUniforms: any;
    clear(): void;
    get uniforms(): any;
}

export declare class SimpleMesh2d extends Mesh2d {
    constructor(texture: Texture, vertices?: Float32Array, uvs?: Float32Array, indices?: Uint16Array, drawMode?: number);
    autoUpdate: boolean;
    get vertices(): Float32Array;
    set vertices(value: Float32Array);
    protected _render(renderer?: Renderer): void;
}

export declare class SimpleMesh3d2d extends Mesh3d2d {
    constructor(texture: Texture, vertices?: Float32Array, uvs?: Float32Array, indices?: Uint16Array, drawMode?: number);
    autoUpdate: boolean;
    get vertices(): Float32Array;
    set vertices(value: Float32Array);
    protected _render(renderer?: Renderer): void;
}

export declare class Sprite2d extends Sprite {
    constructor(texture: Texture);
    vertexData2d: Float32Array;
    proj: Projection2d;
    _calculateBounds(): void;
    calculateVertices(): void;
    calculateTrimmedVertices(): void;
    toLocal<P extends IPointData = Point>(position: IPointData, from?: DisplayObject, point?: P, skipUpdate?: boolean, step?: TRANSFORM_STEP): P;
    get worldTransform(): Matrix;
}

export declare class Sprite2s extends Sprite {
    constructor(texture: Texture);
    proj: ProjectionSurface;
    aTrans: Matrix;
    _calculateBounds(): void;
    calculateVertices(): void;
    calculateTrimmedVertices(): void;
    get worldTransform(): Matrix;
}

export declare class Sprite3d extends Sprite {
    constructor(texture: Texture);
    vertexData2d: Float32Array;
    proj: Projection3d;
    culledByFrustrum: boolean;
    trimmedCulledByFrustrum: boolean;
    calculateVertices(): void;
    calculateTrimmedVertices(): void;
    _calculateBounds(): void;
    _render(renderer: Renderer): void;
    containsPoint(point: IPointData): boolean;
    get worldTransform(): Matrix;
    toLocal<T extends IPointData>(position: IPointData, from?: DisplayObject, point?: T, skipUpdate?: boolean, step?: TRANSFORM_STEP): T;
    isFrontFace(forceUpdate?: boolean): boolean;
    getDepth(forceUpdate?: boolean): boolean;
    get position3d(): IPointData;
    set position3d(value: IPointData);
    get scale3d(): IPointData;
    set scale3d(value: IPointData);
    get euler(): Euler;
    set euler(value: Euler);
    get pivot3d(): IPointData;
    set pivot3d(value: IPointData);
}

export declare class SpriteMaskFilter2d extends Filter {
    constructor(sprite: Sprite);
    maskSprite: Sprite;
    maskMatrix: Matrix2d;
    apply(filterManager: FilterSystem, input: RenderTexture, output: RenderTexture, clearMode?: number): void;
    static calculateSpriteMatrix(input: RenderTexture, mappedMatrix: Matrix2d, sprite: Sprite): Matrix2d;
}

export declare abstract class Surface implements IWorldTransform {
    surfaceID: string;
    _updateID: number;
    vertexSrc: string;
    fragmentSrc: string;
    fillUniforms(uniforms: Dict<any>): void;
    clear(): void;
    boundsQuad(v: ArrayLike<number>, out: any, after?: Matrix): void;
    abstract apply(pos: IPointData, newPos: IPointData): IPointData;
    abstract applyInverse(pos: IPointData, newPos: IPointData): IPointData;
}

export declare class Text2d extends Text_2 {
    constructor(text?: string, style?: TextStyle, canvas?: HTMLCanvasElement);
    proj: Projection2d;
    vertexData2d: Float32Array;
    get worldTransform(): Matrix;
}

export declare class Text2s extends Text_2 {
    constructor(text?: string, style?: TextStyle, canvas?: HTMLCanvasElement);
    proj: ProjectionSurface;
    aTrans: Matrix;
    get worldTransform(): Matrix;
}

export declare class Text3d extends Text_2 {
    constructor(text?: string, style?: TextStyle, canvas?: HTMLCanvasElement);
    proj: Projection3d;
    vertexData2d: Float32Array;
    get worldTransform(): Matrix;
    toLocal<T extends IPointData>(position: IPointData, from?: DisplayObject, point?: T, skipUpdate?: boolean, step?: TRANSFORM_STEP): T;
    isFrontFace(forceUpdate?: boolean): boolean;
    getDepth(forceUpdate?: boolean): boolean;
    get position3d(): IPointData;
    set position3d(value: IPointData);
    get scale3d(): IPointData;
    set scale3d(value: IPointData);
    get euler(): Euler;
    set euler(value: Euler);
    get pivot3d(): IPointData;
    set pivot3d(value: IPointData);
}

export declare class TilingSprite2d extends TilingSprite {
    constructor(texture: Texture, width: number, height: number);
    tileProj: Projection2d;
    proj: Projection2d;
    get worldTransform(): Matrix;
    toLocal<P extends IPointData = Point>(position: IPointData, from?: DisplayObject, point?: P, skipUpdate?: boolean, step?: TRANSFORM_STEP): P;
    _render(renderer: Renderer): void;
}

export declare class TilingSprite2dRenderer extends ObjectRenderer {
    constructor(renderer: Renderer);
    shader: Shader;
    simpleShader: Shader;
    quad: QuadUv;
    render(ts: any): void;
}

export declare enum TRANSFORM_STEP {
    NONE = 0,
    BEFORE_PROJ = 4,
    PROJ = 5,
    ALL = 9
}

export declare function transformHack(this: Transform, parentTransform: Transform): void;

export declare class UniformBatchRenderer extends AbstractBatchRenderer {
    _iIndex: number;
    _aIndex: number;
    _dcIndex: number;
    _bufferedElements: Array<any>;
    _attributeBuffer: ViewableBuffer;
    _indexBuffer: Uint16Array;
    vertexSize: number;
    forceMaxTextures: number;
    getUniforms(sprite: Sprite): any;
    syncUniforms(obj: Dict<any>): void;
    defUniforms: {};
    buildDrawCalls(texArray: BatchTextureArray, start: number, finish: number): void;
    drawBatches(): void;
    contextChange(): void;
}

export { }
