"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MagickGeometry = void 0;
const image_magick_1 = require("./image-magick");
const geometry_flags_1 = require("./internal/geometry-flags");
const string_1 = require("./internal/native/string");
class MagickGeometry {
    constructor(widthOrValueOrX, heightOrY, width, height) {
        this._width = 0;
        this._height = 0;
        this._x = 0;
        this._y = 0;
        this._aspectRatio = false;
        this._fillArea = false;
        this._greater = false;
        this._isPercentage = false;
        this._ignoreAspectRatio = false;
        this._less = false;
        this._limitPixels = false;
        if (typeof widthOrValueOrX === 'number') {
            if (width !== undefined && height !== undefined) {
                this._width = width;
                this._height = height;
                this._x = widthOrValueOrX;
                this._y = heightOrY !== null && heightOrY !== void 0 ? heightOrY : 0;
            }
            else {
                this._width = widthOrValueOrX;
                this._height = heightOrY !== null && heightOrY !== void 0 ? heightOrY : this._width;
                this._x = 0;
                this._y = 0;
            }
            if (this._width < 0)
                throw new Error('negative width is not allowed');
            if (this._height < 0)
                throw new Error('negative height is not allowed');
        }
        else {
            const instance = image_magick_1.ImageMagick._api._MagickGeometry_Create();
            try {
                string_1._withString(widthOrValueOrX, valuePtr => {
                    const flags = image_magick_1.ImageMagick._api._MagickGeometry_Initialize(instance, valuePtr);
                    if (flags === geometry_flags_1.GeometryFlags.NoValue)
                        throw new Error('invalid geometry specified');
                    if (this.hasFlag(flags, geometry_flags_1.GeometryFlags.AspectRatio)) {
                        this.initializeFromAspectRation(instance, widthOrValueOrX);
                    }
                    else {
                        this.initialize(instance, flags);
                    }
                });
            }
            finally {
                image_magick_1.ImageMagick._api._MagickGeometry_Dispose(instance);
            }
        }
    }
    get aspectRatio() { return this._aspectRatio; }
    get fillArea() { return this._fillArea; }
    set fillArea(value) { this._fillArea = value; }
    get greater() { return this._greater; }
    set greater(value) { this._greater = value; }
    get ignoreAspectRatio() { return this._ignoreAspectRatio; }
    set ignoreAspectRatio(value) { this._ignoreAspectRatio = value; }
    get isPercentage() { return this._isPercentage; }
    set isPercentage(value) { this._isPercentage = value; }
    get less() { return this._less; }
    set less(value) { this._less = value; }
    get limitPixels() { return this._limitPixels; }
    set limitPixels(value) { this._limitPixels = value; }
    get height() { return this._height; }
    set height(value) { this._height = value; }
    get width() { return this._width; }
    set width(value) { this._width = value; }
    get x() { return this._x; }
    set x(value) { this._x = value; }
    get y() { return this._y; }
    set y(value) { this._y = value; }
    toString() {
        if (this._aspectRatio)
            return this._width + ":" + this._height;
        let result = '';
        if (this._width > 0)
            result += this._width.toString();
        if (this._height > 0)
            result += 'x' + this._height.toString();
        else
            result += 'x';
        if (this._x != 0 || this._y != 0) {
            if (this._x >= 0)
                result += '+';
            result += this._x;
            if (this.y >= 0)
                result += '+';
            result += this.y;
        }
        if (this._fillArea)
            result += '^';
        if (this._greater)
            result += '>';
        if (this._isPercentage)
            result += '%';
        if (this._ignoreAspectRatio)
            result += '!';
        if (this._less)
            result += '<';
        if (this._limitPixels)
            result += '@';
        return result;
    }
    initialize(instance, flags) {
        this._width = image_magick_1.ImageMagick._api._MagickGeometry_Width_Get(instance);
        this._height = image_magick_1.ImageMagick._api._MagickGeometry_Height_Get(instance);
        this._x = image_magick_1.ImageMagick._api._MagickGeometry_X_Get(instance);
        this._y = image_magick_1.ImageMagick._api._MagickGeometry_Y_Get(instance);
        this._ignoreAspectRatio = this.hasFlag(flags, geometry_flags_1.GeometryFlags.IgnoreAspectRatio);
        this._isPercentage = this.hasFlag(flags, geometry_flags_1.GeometryFlags.PercentValue);
        this._fillArea = this.hasFlag(flags, geometry_flags_1.GeometryFlags.FillArea);
        this._greater = this.hasFlag(flags, geometry_flags_1.GeometryFlags.Greater);
        this._less = this.hasFlag(flags, geometry_flags_1.GeometryFlags.Less);
        this._limitPixels = this.hasFlag(flags, geometry_flags_1.GeometryFlags.LimitPixels);
    }
    initializeFromAspectRation(instance, value) {
        this._aspectRatio = true;
        const ratio = value.split(':');
        this._width = this.parseNumber(ratio[0]);
        this._height = this.parseNumber(ratio[1]);
        this._x = image_magick_1.ImageMagick._api._MagickGeometry_X_Get(instance);
        this._y = image_magick_1.ImageMagick._api._MagickGeometry_Y_Get(instance);
    }
    parseNumber(value) {
        let index = 0;
        while (index < value.length && !this.isNumber(value[index]))
            index++;
        const start = index;
        while (index < value.length && this.isNumber(value[index]))
            index++;
        return parseInt(value.substr(start, index - start));
    }
    isNumber(character) {
        return character >= '0' && character <= '9';
    }
    hasFlag(flags, flag) {
        return (flags & flag) === flag;
    }
}
exports.MagickGeometry = MagickGeometry;
