import { LayoutBase, Utils, View, Screen } from '@nativescript/core';
import { Canvas } from '../Canvas';
import { Image } from './Image';
import { Paint } from './Paint';
var State;
(function (State) {
    State[State["None"] = 0] = "None";
    State[State["Pending"] = 1] = "Pending";
    State[State["Invalidating"] = 2] = "Invalidating";
})(State || (State = {}));
export class Dom extends LayoutBase {
    constructor() {
        super();
        this._children = [];
        this._state = State.None;
        this._isReady = false;
        this._onFrameCallback = null;
        this._canvas = new Canvas();
        this._canvas.on('ready', this._ready.bind(this));
        this._canvas.style.width = { unit: '%', value: 1 };
        this._canvas.style.height = 'auto';
    }
    createNativeView() {
        if (global.isIOS) {
            return UIView.new();
        }
        if (global.isAndroid) {
            return new android.widget.LinearLayout(this._context);
        }
        return null;
    }
    initNativeView() {
        super.initNativeView();
        this._addView(this._canvas);
    }
    onLoaded() {
        super.onLoaded();
        if (this._ready) {
            this._bindRaf();
        }
    }
    onUnloaded() {
        if (this._raf) {
            cancelAnimationFrame(this._raf);
            this._raf = undefined;
            this._state = State.Pending;
        }
        super.onUnloaded();
    }
    onLayout(left, top, right, bottom) {
        super.onLayout(left, top, right, bottom);
        View.layoutChild(this, this._canvas, left, top, right, bottom);
        this._canvas.width = this.getMeasuredWidth();
        this._canvas.height = this.getMeasuredHeight();
        // auto scale to screen size
        const ctx = this._canvas.getContext('2d');
        ctx.scale(Screen.mainScreen.scale, Screen.mainScreen.scale);
    }
    onMeasure(widthMeasureSpec, heightMeasureSpec) {
        const nativeView = this.nativeView;
        if (nativeView) {
            const width = Utils.layout.getMeasureSpecSize(widthMeasureSpec);
            const height = Utils.layout.getMeasureSpecSize(heightMeasureSpec);
            View.measureChild(this, this._canvas, width, height);
            this.setMeasuredDimension(width, height);
        }
    }
    set onFrameCallback(value) {
        this._onFrameCallback = value;
    }
    _ready(args) {
        this._isReady = true;
        this._dirty();
        this._draw(null);
    }
    _draw(ts) {
        const state = this._state & State.Pending;
        if (state === State.Pending) {
            const ctx = this._canvas.getContext('2d');
            this._state = State.Invalidating;
            ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
            for (const child of this._children) {
                child.draw();
            }
            this._state = State.None;
        }
        this._onFrameCallback?.(ts);
        this._bindRaf();
    }
    _bindRaf() {
        if (!this._isReady) {
            return;
        }
        this._raf = requestAnimationFrame(this._draw.bind(this));
    }
    _dirty() {
        this._state = this._state | State.Pending;
    }
    _addViewToNativeVisualTree(view, atIndex) {
        if (view === this._canvas) {
            if (global.isIOS) {
                this.nativeView.addSubview(this._canvas.nativeView);
            }
            if (global.isAndroid) {
                this.nativeView.addView(this._canvas.nativeView);
            }
            return true;
        }
        else if (view instanceof Paint || view instanceof Image) {
            view._addCanvas(this._canvas);
            this._children.push(view);
        }
        return false;
    }
}
//# sourceMappingURL=Dom.js.map