import EventEmitter from 'node:events';
import { Buffer } from 'node:buffer';
import PromiseDuplex from 'promise-duplex';
import DeviceClient from '../../DeviceClient.js';
import { Duplex } from 'node:stream';
import { type MotionEvent } from './ScrcpyConst.js';
import { KeyCodes } from '../../keycode.js';
import { Point, ScrcpyOptions, H264Configuration, VideoStreamFramePacket } from './ScrcpyModels.js';
/**
 * usage reference fron app/src/server.c in scrcpy
 * https://github.com/Genymobile/scrcpy/blob/master/app/src/server.c
 */
/**
 * by hand start:
 *
 * adb push scrcpy-server-v1.8.jar /data/local/tmp/scrcpy-server.jar
 * adb push scrcpy-server-v1.20.jar /data/local/tmp/scrcpy-server.jar
 *
 * CLASSPATH=/data/local/tmp/scrcpy-server.jar app_process / com.genymobile.scrcpy.Server 600 1000 true 9999:9999:0:0 true
 *
 * adb forward tcp:8099 localabstract:scrcpy
 */
/**
 * enforce EventEmitter typing
 */
interface IEmissions {
    frame: (data: VideoStreamFramePacket) => void;
    config: (data: H264Configuration) => void;
    raw: (data: Buffer) => void;
    error: (error: Error) => void;
    disconnect: () => void;
}
/**
 * How scrcpy works?
 *
 * Its a jar file that runs on an adb shell. It records the screen in h264 and offers it in a given tcp port.
 *
 * scrcpy params
 *   maxSize         (integer, multiple of 8) 0
 *   bitRate         (integer)
 *   tunnelForward   (optional, bool) use "adb forward" instead of "adb tunnel"
 *   crop            (optional, string) "width:height:x:y"
 *   sendFrameMeta   (optional, bool)
 *
 * The video stream contains raw packets, without time information. If sendFrameMeta is enabled a meta header is added
 * before each packet.
 * The "meta" header length is 12 bytes
 * [. . . . . . . .|. . . .]. . . . . . . . . . . . . . . ...
 *  <-------------> <-----> <-----------------------------...
 *        PTS         size      raw packet (of size len)
 *
 * WARNING:
 * Need USB Debug checked in developper option for MIUI
 */
export default class Scrcpy extends EventEmitter {
    private client;
    private config;
    private videoSocket;
    private audioSocket;
    private controlSocket;
    /**
     * used to recive Process Error
     */
    private scrcpyServer;
    private _name;
    private _codec;
    private _width;
    private _height;
    private _onTermination;
    private _firstFrame;
    private setCodec;
    private setName;
    private setWidth;
    private setHeight;
    private setFatalError?;
    private setFirstFrame?;
    private lastConf?;
    /**
     * closed had been call stop all new activity
     */
    private closed;
    constructor(client: DeviceClient, config?: Partial<ScrcpyOptions>);
    readonly strVersion: string;
    readonly major: number;
    readonly minor: number;
    readonly patch: number;
    on: <K extends keyof IEmissions>(event: K, listener: IEmissions[K]) => this;
    off: <K extends keyof IEmissions>(event: K, listener: IEmissions[K]) => this;
    once: <K extends keyof IEmissions>(event: K, listener: IEmissions[K]) => this;
    emit: <K extends keyof IEmissions>(event: K, ...args: Parameters<IEmissions[K]>) => boolean;
    get name(): Promise<string>;
    get width(): Promise<number>;
    get height(): Promise<number>;
    /**
     * Clever way to detect Termination.
     * return the Ending message.
     */
    get onTermination(): Promise<string>;
    /**
     * Promise to the first emited frame
     * can be used to unsure that scrcpy propery start
     */
    get firstFrame(): Promise<void>;
    /**
     * return the used codex can be "H264", "H265", "AV1", "AAC" or "OPUS"
     */
    get codec(): Promise<string>;
    /**
     * emit scrcpyServer output as Error
     * @param duplex
     * @returns
     */
    ListenErrors(duplex: PromiseDuplex<Duplex>): Promise<void>;
    private _setFatalError;
    /**
     * get last current video config
     */
    get videoConfig(): H264Configuration | undefined;
    /**
     * Read a message from the contoler Duplex
     *
     * @param duplex only supoport clipboard
     * @returns
     */
    readOneMessage(duplex: PromiseDuplex<Duplex>): Promise<string>;
    private _getStartupLine;
    /**
     * Will connect to the android device, send & run the server and return deviceName, width and height.
     * After that data will be offered as a 'data' event.
     */
    start(): Promise<this>;
    stop(): boolean;
    isRunning(): boolean;
    private startStreamRaw;
    /**
     * capture all video trafique in a loop
     * get resolve once capture stop
     */
    private startStreamWithMeta;
    /**
     * // will be convert in a android.view.KeyEvent
     * https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/KeyEvent.java
     * @param action
     * @param keyCode
     * @param repeatCount
     * @param metaState  combinaison of KeyEventMeta
     */
    injectKeycodeEvent(action: MotionEvent, keyCode: KeyCodes, repeatCount: number, metaState: number): Promise<void>;
    injectText(text: string): Promise<void>;
    /**
     * android.view.MotionEvent;
     * https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/MotionEvent.java
     * @param action
     * @param pointerId
     * @param position
     * @param screenSize
     * @param pressure
     *
     * see parseInjectTouchEvent()
     */
    injectTouchEvent(action: MotionEvent, pointerId: bigint, position: Point, screenSize: Point, pressure?: number): Promise<boolean>;
    injectScrollEvent(position: Point, screenSize: Point, HScroll: number, VScroll: number): Promise<void>;
    injectBackOrScreenOn(): Promise<void>;
    expandNotificationPanel(): Promise<void>;
    collapsePannels(): Promise<void>;
    getClipboard(): Promise<string>;
    setClipboard(text: string): Promise<void>;
    setScreenPowerMode(): Promise<void>;
    rotateDevice(): Promise<void>;
}
export {};
//# sourceMappingURL=Scrcpy.d.ts.map