import { CanvasGradient } from '../CanvasGradient';
import { Path2D } from '../Path2D';
import { ImageData } from '../ImageData';
import { TextMetrics } from '../TextMetrics';
import { ImageSource } from '@nativescript/core';
import { ImageAsset } from '../../ImageAsset';
import { CanvasPattern } from '../CanvasPattern';
import { Canvas } from '../../Canvas';
import { Helpers } from '../../helpers';
let ctor;
function ruleToEnum(rule) {
    switch (rule) {
        case 'nonzero':
            return 0;
        case 'evenodd':
            return 1;
        default:
            return -1; // will be ignored
    }
}
export class CanvasRenderingContext2D {
    constructor(context, contextOptions) {
        this._type = 'none';
        /*const width = context.getDrawingBufferWidth(); // can use  getMeasuredWidth / getMeasuredHeight
        const height = context.getDrawingBufferHeight();

        const ctxPtr = BigInt(context.getNativeContext().toString());
        let direction = 0;
        if (androidx.core.text.TextUtilsCompat.getLayoutDirectionFromLocale(java.util.Locale.getDefault()) === androidx.core.view.ViewCompat.LAYOUT_DIRECTION_RTL) {
            direction = 1;
        }
        this.context = ctor(ctxPtr, width, height, Screen.mainScreen.scale, contextOptions.antialias ? 4 : 0, contextOptions.alpha, contextOptions.fontColor, 1, direction);
        */
        const ctxPtr = BigInt(context.toString());
        this.context = ctor(ctxPtr);
    }
    get type() {
        return this._type;
    }
    get native() {
        return this.context;
    }
    get canvas() {
        return this._canvas;
    }
    get shadowColor() {
        return this.context.shadowColor;
    }
    set shadowColor(color) {
        this.context.shadowColor = color;
    }
    get font() {
        return this.context.font;
    }
    set font(value) {
        this.context.font = value;
    }
    get direction() {
        return this.context.direction;
    }
    set direction(value) {
        this.context.direction = value;
    }
    get globalAlpha() {
        return this.context.globalAlpha;
    }
    set globalAlpha(alpha) {
        this.context.globalAlpha = alpha;
    }
    get imageSmoothingEnabled() {
        return this.context.imageSmoothingEnabled;
    }
    set imageSmoothingEnabled(enabled) {
        this.context.imageSmoothingEnabled = enabled;
    }
    get imageSmoothingQuality() {
        return this.context.imageSmoothingQuality;
    }
    set imageSmoothingQuality(quality) {
        this.context.imageSmoothingQuality = quality;
    }
    get lineDashOffset() {
        return this.context.lineDashOffset;
    }
    set lineDashOffset(offset) {
        this.context.lineDashOffset = offset;
    }
    get letterSpacing() {
        return this.context.letterSpacing;
    }
    set letterSpacing(spacing) {
        this.context.letterSpacing = spacing;
    }
    get lineJoin() {
        return this.context.lineJoin;
    }
    set lineJoin(join) {
        this.context.lineJoin = join;
    }
    get lineCap() {
        return this.context.lineCap;
    }
    set lineCap(cap) {
        this.context.lineCap = cap;
    }
    get miterLimit() {
        return this.context.miterLimit;
    }
    set miterLimit(limit) {
        this.context.miterLimit = limit;
    }
    get shadowBlur() {
        return this.context.shadowBlur;
    }
    set shadowBlur(blur) {
        this.context.shadowBlur = blur;
    }
    get shadowOffsetX() {
        return this.context.shadowOffsetX;
    }
    set shadowOffsetX(x) {
        this.context.shadowOffsetX = x;
    }
    get shadowOffsetY() {
        return this.context.shadowOffsetY;
    }
    set shadowOffsetY(y) {
        this.context.shadowOffsetY = y;
    }
    get textAlign() {
        return this.context.textAlign;
    }
    set textAlign(alignment) {
        this.context.textAlign = alignment;
    }
    get textBaseline() {
        return this.context.textBaseline;
    }
    set textBaseline(baseline) {
        this.context.textBaseline = baseline;
    }
    get globalCompositeOperation() {
        return this.context.globalCompositeOperation;
    }
    set globalCompositeOperation(composite) {
        this.context.globalCompositeOperation = composite;
    }
    get fillStyle() {
        return this.context.fillStyle;
    }
    set fillStyle(color) {
        if (color === undefined || color === null) {
            return;
        }
        if (color instanceof CanvasGradient || color instanceof CanvasPattern) {
            this.context.fillStyle = color.native;
        }
        else {
            this.context.fillStyle = color;
        }
    }
    get filter() {
        return this.context.filter;
    }
    set filter(value) {
        this.context.filter = value;
    }
    get strokeStyle() {
        return this.context.strokeStyle;
    }
    set strokeStyle(color) {
        if (color === undefined || color === null) {
            return;
        }
        if (color instanceof CanvasGradient || color instanceof CanvasPattern) {
            this.context.strokeStyle = color.native;
        }
        else {
            this.context.strokeStyle = color;
        }
    }
    get lineWidth() {
        return this.context.lineWidth;
    }
    set lineWidth(width) {
        this.context.lineWidth = width;
    }
    get wordSpacing() {
        return this.context.wordSpacing;
    }
    set wordSpacing(spacing) {
        this.context.wordSpacing = spacing;
    }
    __toDataURL(type = 'image/jpg', quality = 92) {
        return this.context.__toDataURL(type, quality);
    }
    addHitRegion(region) { }
    arc(x, y, radius, startAngle, endAngle, anticlockwise = false) {
        this.context.arc(x, y, radius, startAngle, endAngle, anticlockwise ?? false);
    }
    arcTo(x1, y1, x2, y2, radius) {
        this.context.arcTo(x1, y1, x2, y2, radius);
    }
    beginPath() {
        this.context.beginPath();
    }
    bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) {
        this.context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
    }
    clearHitRegions() { }
    clearRect(x, y, width, height) {
        this.context.clearRect(x, y, width, height);
    }
    clip(...args) {
        if (typeof args[0] === 'string') {
            this.context.clip(ruleToEnum(args[0]));
        }
        else if (args[0] instanceof Path2D && typeof args[1] === 'string') {
            this.context.clip(args[0].native, ruleToEnum(args[1]));
        }
        else if (args[0] instanceof Path2D) {
            this.context.clip(args[0].native);
        }
        else {
            this.context.clip();
        }
    }
    closePath() {
        this.context.closePath();
    }
    createImageData(width, height) {
        if (width instanceof ImageData) {
            return new ImageData(width.width, width.height);
        }
        else {
            return new ImageData(width, height);
        }
    }
    createLinearGradient(x0, y0, x1, y1) {
        return CanvasGradient.fromNative(this.context.createLinearGradient(x0, y0, x1, y1));
    }
    createPattern(image, repetition) {
        if (repetition === undefined || typeof repetition !== 'string') {
            const e = new Error('The string did not match the expected pattern.');
            e.name = 'SyntaxError';
            throw e;
        }
        //const createPattern = this._getMethod('createPattern');
        //const createPattern = this.context.createPattern;
        let img;
        if (image?._type === '2d' || image?._type?.indexOf('webgl') > -1) {
            img = image.native;
        }
        else if (image instanceof ImageSource) {
            //const ptr = this.context.__getPointer; //this._getMethod('__getPointer');
            //const createPattern = this.context.__createPatternWithNative; //this._getMethod('__createPatternWithNative');
            if (global.isAndroid) {
                img = image.android;
                const pattern = org.nativescript.canvas.NSCCanvasRenderingContext2D.createPattern(long(this.context.__getPointer()), img, repetition);
                return new CanvasPattern(this.context.__createPatternWithNative(pattern));
            }
            if (global.isIOS) {
                img = image.ios;
                const pattern = NSCCanvasRenderingContext2D.createPattern(this.context.__getPointer(), img, repetition);
                return new CanvasPattern(this.context.__createPatternWithNative(pattern));
            }
            return null;
        }
        else if (global.isAndroid && image instanceof android.graphics.Bitmap) {
            //const ptr = this.context.__getPointer; //this._getMethod('__getPointer');
            const createPattern = this.context.__createPatternWithNative; //this._getMethod('__createPatternWithNative');
            if (global.isAndroid) {
                const pattern = org.nativescript.canvas.NSCCanvasRenderingContext2D.createPattern(long(this.context.__getPointer()), image, repetition);
                return new CanvasPattern(this.context.__createPatternWithNative(pattern));
            }
            if (global.isIOS) {
                const pattern = NSCCanvasRenderingContext2D.createPattern(this.context.__getPointer(), image, repetition);
                return new CanvasPattern(this.context.__createPatternWithNative(pattern));
            }
            return null;
        }
        else if (image instanceof ImageAsset) {
            img = image.native;
        }
        else if (image instanceof Canvas) {
            img = image.native;
        }
        else if (image && typeof image.tagName === 'string' && (image.tagName === 'IMG' || image.tagName === 'IMAGE')) {
            if (global.isAndroid && image._image instanceof android.graphics.Bitmap) {
                //todo ios
                img = image._image;
            }
            else if (image._asset instanceof ImageAsset) {
                img = image._asset.native;
            }
            else if (typeof image.src === 'string') {
                //const ptr = this.context.__getPointer; //this._getMethod('__getPointer');
                //const createPattern = this.context.__createPatternWithNative; //this._getMethod('__createPatternWithNative');
                if (global.isAndroid) {
                    img = ImageSource.fromFileSync(image.src).android;
                    const pattern = org.nativescript.canvas.NSCCanvasRenderingContext2D.createPattern(long(this.context.__getPointer()), img, repetition);
                    return new CanvasPattern(this.context.__createPatternWithNative(pattern));
                }
                if (global.isiOS) {
                    img = ImageSource.fromFileSync(image.src).android;
                    const pattern = NSCCanvasRenderingContext2D.createPattern(this.context.__getPointer(), img, repetition);
                    return new CanvasPattern(this.context.__createPatternWithNative(pattern));
                }
                return null;
            }
        }
        else if (image && typeof image.tagName === 'string' && image.tagName === 'CANVAS' && image._canvas instanceof Canvas) {
            img = image._canvas.native;
        }
        else if (image instanceof ImageBitmap) {
            img = image.native;
        }
        if (!img) {
            return null;
        }
        return new CanvasPattern(this.context.createPattern(img, repetition));
    }
    createRadialGradient(x0, y0, r0, x1, y1, r1) {
        return CanvasGradient.fromNative(this.context.createRadialGradient(x0, y0, r0, x1, y1, r1));
    }
    createConicGradient(startAngle, x, y) {
        return CanvasGradient.fromNative(this.context.createConicGradient(startAngle, x, y));
    }
    drawPaint(color) {
        this.context.drawPaint(color);
    }
    drawPoint(x, y) {
        this.context.drawPoint(x, y);
    }
    drawPoints(mode, points) {
        this.context.drawPoints(mode, points);
    }
    drawFocusIfNeeded(...args) { }
    drawImage(...args) {
        //const drawImage = this.context.drawImage; //this._getMethod('drawImage');
        const drawNativeImage = (args, image) => {
            //const ptr = this.context.__getPointer; //this._getMethod('__getPointer');
            //const makeDirty = this.context.__makeDirty; //this._getMethod('__makeDirty');
            let dirty = false;
            if (args.length === 3) {
                if (global.isAndroid) {
                    dirty = org.nativescript.canvas.NSCCanvasRenderingContext2D.drawImage(long(this.context.__getPointer()), image, args[1], args[2]);
                }
                if (global.isIOS) {
                    dirty = NSCCanvasRenderingContext2D.drawImage(this.context.__getPointer(), image, args[1], args[2]);
                }
            }
            else if (args.length === 5) {
                if (global.isAndroid) {
                    dirty = org.nativescript.canvas.NSCCanvasRenderingContext2D.drawImage(long(this.context.__getPointer()), image, args[1], args[2], args[3], args[4]);
                }
                if (global.isIOS) {
                    dirty = NSCCanvasRenderingContext2D.drawImage(this.context.__getPointer(), image, args[1], args[2], args[3], args[4]);
                }
            }
            else if (args.length === 9) {
                if (global.Android) {
                    dirty = org.nativescript.canvas.NSCCanvasRenderingContext2D.drawImage(long(this.context.__getPointer()), image, args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
                }
                if (global.isIOS) {
                    dirty = NSCCanvasRenderingContext2D.drawImage(this.context.__getPointer(), image, args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
                }
            }
            if (dirty) {
                this.context.__makeDirty();
            }
        };
        let image = args[0];
        if (image?._type === '2d' || image?._type?.indexOf('webgl') > -1) {
            image = image.native;
        }
        else if (image instanceof ImageAsset) {
            image = image.native;
        }
        else if (image instanceof ImageSource) {
            if (global.isAndroid) {
                drawNativeImage(args, image.android);
            }
            if (global.isIOS) {
                drawNativeImage(args, image.ios);
            }
            return;
        }
        else if (global.isAndroid && image instanceof android.graphics.Bitmap) {
            drawNativeImage(args, image);
            return;
        }
        else if (global.isIOS && image instanceof UIImage) {
            drawNativeImage(args, image);
            return;
        }
        else if (image instanceof Canvas) {
            image = image.native;
        }
        else if (image && typeof image.tagName === 'string' && (image.tagName === 'IMG' || image.tagName === 'IMAGE')) {
            if (image._imageSource instanceof ImageSource) {
                if (global.isAndroid) {
                    drawNativeImage(args, image._imageSource.android);
                }
                if (global.isIOS) {
                    drawNativeImage(args, image._imageSource.ios);
                }
                return;
            }
            else if (global.isAndroid && image._image instanceof android.graphics.Bitmap) {
                drawNativeImage(args, image._image);
                return;
            }
            else if (global.isIOS && image._image instanceof UIImage) {
                drawNativeImage(args, image._image);
                return;
            }
            else if (image._asset instanceof ImageAsset) {
                image = image._asset.native;
            }
            else if (typeof image.src === 'string') {
                image = ImageSource.fromFileSync(image.src).android;
                if (global.isAndroid) {
                    drawNativeImage(args, image.android);
                }
                if (global.isIOS) {
                    drawNativeImage(args, image.ios);
                }
                return;
            }
        }
        else if (image && typeof image.tagName === 'string' && image.tagName === 'CANVAS' && image._canvas instanceof Canvas) {
            image = image._canvas.native;
        }
        else if (image instanceof ImageBitmap) {
            image = image.native;
        }
        if (args.length === 3) {
            this.context.drawImage(image, args[1], args[2]);
        }
        else if (args.length === 5) {
            this.context.drawImage(image, args[1], args[2], args[3], args[4]);
        }
        else if (args.length === 9) {
            this.context.drawImage(image, args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
        }
    }
    ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise = false) {
        this.context.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise ?? false);
    }
    fill(...args) {
        if (typeof args[0] === 'string') {
            this.context.fill(ruleToEnum(args[0]));
        }
        else if (args[0] instanceof Path2D && typeof args[1] === 'string') {
            this.context.fill(args[0].native, ruleToEnum(args[1]));
        }
        else if (args[0] instanceof Path2D) {
            this.context.fill(args[0].native);
        }
        else {
            this.context.fill();
        }
    }
    fillRect(x, y, width, height) {
        this.context.fillRect(x, y, width, height);
    }
    fillText(text, x, y, maxWidth) {
        if (typeof maxWidth === 'number') {
            this.context.fillText(text + '', x, y, maxWidth);
        }
        else {
            this.context.fillText(text + '', x, y);
        }
    }
    getImageData(sx, sy, sw, sh) {
        return ImageData.fromNative(this.context.getImageData(sx, sy, sw, sh));
    }
    getLineDash() {
        return this.context.getLineDash();
    }
    isPointInPath(...args) {
        if (args.length === 2) {
            return this.context.isPointInPath(args[0], args[1]);
        }
        else if (args.length === 3) {
            return this.context.isPointInPath(args[0], args[1], ruleToEnum(args[2]));
        }
        else if (args.length === 4 && args[0] instanceof Path2D) {
            return this.context.isPointInPath(args[0].native, args[1], args[2], ruleToEnum(args[3]));
        }
        return false;
    }
    isPointInStroke(...args) {
        if (args.length === 2) {
            return this.context.isPointInStroke(args[0], args[1]);
        }
        else if (args.length === 3 && args[0] instanceof Path2D) {
            return this.context.isPointInStroke(args[0].native, args[1], args[2]);
        }
        return false;
    }
    lineTo(x, y) {
        this.context.lineTo(x, y);
    }
    measureText(text) {
        return new TextMetrics(this.context.measureText(text));
    }
    moveTo(x, y) {
        this.context.moveTo(x, y);
    }
    putImageData(...args) {
        if (!args) {
            return;
        }
        const data = args[0];
        if (args.length === 3) {
            this.context.putImageData(data.native, args[1], args[2]);
        }
        else if (args.length === 7) {
            this.context.putImageData(data.native, args[1], args[2], args[3], args[4], args[5], args[6]);
        }
    }
    quadraticCurveTo(cpx, cpy, x, y) {
        this.context.quadraticCurveTo(cpx, cpy, x, y);
    }
    rect(x, y, width, height) {
        this.context.rect(x, y, width, height);
    }
    roundRect(x, y, width, height, radii) {
        this.context.roundRect(x, y, width, height, radii);
    }
    removeHitRegion(id) { }
    resetTransform() {
        this.context.resetTransform();
    }
    restore() {
        this.context.restore();
    }
    rotate(angle) {
        this.context.rotate(angle);
    }
    save() {
        this.context.save();
    }
    scale(x, y) {
        this.context.scale(x, y);
    }
    scrollPathIntoView(path) { }
    setLineDash(segments) {
        this.context.setLineDash(segments);
    }
    setTransform(a, b, c, d, e, f) {
        this.context.setTransform(a, b, c, d, e, f);
    }
    stroke(path) {
        if (path) {
            this.context.stroke(path.native);
        }
        else {
            this.context.stroke();
        }
    }
    strokeRect(x, y, width, height) {
        this.context.strokeRect(x, y, width, height);
    }
    strokeText(text, x, y, maxWidth) {
        if (typeof maxWidth === 'number') {
            this.context.strokeText(text + '', x, y, maxWidth);
        }
        else {
            this.context.strokeText(text + '', x, y);
        }
    }
    transform(a, b, c, d, e, f) {
        this.context.transform(a, b, c, d, e, f);
    }
    translate(x, y) {
        this.context.translate(x, y);
    }
}
CanvasRenderingContext2D.isDebug = true;
(() => {
    Helpers.initialize();
    //ctor = global.CanvasJSIModule.create2DContext;
    ctor = global.CanvasModule.create2DContextWithPointer;
})();
//# sourceMappingURL=index.js.map