import * as THREE from 'three'
import * as React from 'react'
import { TinyEmitter } from 'tiny-emitter'
import { ReactThreeFiber } from './three-types'
export declare type Camera = THREE.OrthographicCamera | THREE.PerspectiveCamera
export declare function isOrthographicCamera(def: THREE.Camera): def is THREE.OrthographicCamera
export declare type DomEvent =
  | React.MouseEvent<HTMLDivElement, MouseEvent>
  | React.WheelEvent<HTMLDivElement>
  | React.PointerEvent<HTMLDivElement>
export declare type Intersection = THREE.Intersection & {
  eventObject: THREE.Object3D
}
export declare type PointerEvent = DomEvent &
  Intersection & {
    stopped: React.MutableRefObject<boolean>
    unprojectedPoint: THREE.Vector3
    ray: THREE.Ray
    stopPropagation: () => void
    sourceEvent: DomEvent
    delta: number
  }
export declare type RenderCallback = (state: CanvasContext, delta: number) => void
export interface RectReadOnly {
  readonly x: number
  readonly y: number
  readonly width: number
  readonly height: number
  readonly top: number
  readonly right: number
  readonly bottom: number
  readonly left: number
}
export declare type SharedCanvasContext = {
  gl: THREE.WebGLRenderer
  aspect: number
  subscribe: (callback: React.MutableRefObject<RenderCallback>, priority?: number) => () => void
  setDefaultCamera: (camera: Camera) => void
  invalidate: () => void
  intersect: (event?: DomEvent) => void
  camera: Camera
  raycaster: THREE.Raycaster
  mouse: THREE.Vector2
  clock: THREE.Clock
  scene: THREE.Scene
  size: RectReadOnly
  viewport: {
    width: number
    height: number
    factor: number
  }
}
export declare type Subscription = {
  ref: React.MutableRefObject<RenderCallback>
  priority: number
}
export declare type CanvasContext = SharedCanvasContext & {
  captured: Intersection[] | undefined
  noEvents: boolean
  ready: boolean
  active: boolean
  manual: number
  vr: boolean
  invalidateFrameloop: boolean
  frames: number
  subscribers: Subscription[]
  initialClick: [number, number]
  initialHits: THREE.Object3D[]
  pointer: TinyEmitter
}
export declare type FilterFunction = (items: THREE.Intersection[], state: SharedCanvasContext) => THREE.Intersection[]
export declare type CanvasProps = {
  children: React.ReactNode
  vr?: boolean
  shadowMap?: boolean | Partial<THREE.WebGLShadowMap>
  orthographic?: boolean
  invalidateFrameloop?: boolean
  updateDefaultCamera?: boolean
  noEvents?: boolean
  gl?: Partial<THREE.WebGLRenderer>
  camera?: Partial<
    ReactThreeFiber.Object3DNode<THREE.Camera, typeof THREE.Camera> &
      ReactThreeFiber.Object3DNode<THREE.PerspectiveCamera, typeof THREE.PerspectiveCamera> &
      ReactThreeFiber.Object3DNode<THREE.OrthographicCamera, typeof THREE.OrthographicCamera>
  >
  raycaster?: Partial<THREE.Raycaster> & {
    filter?: FilterFunction
  }
  pixelRatio?: number
  style?: React.CSSProperties
  onCreated?: (props: CanvasContext) => Promise<any> | void
  onPointerMissed?: () => void
}
export declare type UseCanvasProps = CanvasProps & {
  gl: THREE.WebGLRenderer
  size: RectReadOnly
}
export declare type PointerEvents = {
  onClick(e: any): void
  onWheel(e: any): void
  onPointerDown(e: any): void
  onPointerUp(e: any): void
  onPointerLeave(e: any): void
  onPointerMove(e: any): void
  onGotPointerCapture(e: any): void
  onLostPointerCapture(e: any): void
}
export declare const stateContext: React.Context<SharedCanvasContext>
export declare const useCanvas: (props: UseCanvasProps) => PointerEvents
