import { combine_hash } from "../../../core/collection/array/combine_hash.js";
import Vector1 from "../../../core/geom/Vector1.js";
import ObservedInteger from "../../../core/model/ObservedInteger.js";
import ObservedString from "../../../core/model/ObservedString.js";

export class AnimationClip {

    name = new ObservedString("");
    repeatCount = new ObservedInteger(1);

    /**
     *
     * @type {Vector1}
     */
    weight = new Vector1(1);

    /**
     *
     * @type {Vector1}
     */
    timeScale = new Vector1(1);

    /**
     *
     * @type {number}
     */
    flags = 0;

    /**
     *
     * @param {AnimationClip} other
     * @returns {boolean}
     */
    equals(other) {
        return this.name.equals(other.name)
            && this.repeatCount.equals(other.repeatCount)
            && this.weight.equals(other.weight)
            && this.timeScale.equals(other.timeScale)
            && this.flags === other.flags;
    }

    /**
     *
     * @returns {number}
     */
    hash() {
        return combine_hash(
            this.name.hash(),
            this.repeatCount.hash(),
            this.weight.hash(),
            this.timeScale.hash(),
            this.flags
        );
    }

    /**
     *
     * @param {number|AnimationClipFlag} v
     * @returns {boolean}
     */
    getFlag(v) {
        return (this.flags & v) !== 0;
    }

    /**
     *
     * @param j
     * @returns {AnimationClip}
     */
    static fromJSON(j){
        const r = new AnimationClip();

        r.fromJSON(j);

        return r;
    }

    fromJSON(json) {
        if (typeof json.name === "string") {
            this.name.fromJSON(json.name);
        }

        if (typeof json.repeatCount === "number") {
            this.repeatCount.fromJSON(json.repeatCount);
        } else {
            this.repeatCount.set(Number.POSITIVE_INFINITY);
        }

        if (typeof json.weight === "number") {
            this.weight.fromJSON(json.weight);
        } else {
            this.weight.set(1);
        }

        if (typeof json.timeScale === "number") {
            this.timeScale.fromJSON(json.timeScale);
        } else {
            this.timeScale.set(1);
        }

        if (typeof json.flags === "number") {
            this.flags = json.flags;
        } else {
            this.flags = 0;
        }
    }

    toJSON() {
        return {
            name: this.name.toJSON(),
            repeatCount: this.repeatCount.toJSON(),
            weight: this.weight.toJSON(),
            timeScale: this.timeScale.toJSON(),
            flags: this.flags
        };
    }

    /**
     *
     * @param {BinaryBuffer} buffer
     */
    toBinaryBuffer(buffer) {
        //write flags
        buffer.writeUint8(this.flags);

        this.name.toBinaryBuffer(buffer);
        this.repeatCount.toBinaryBuffer(buffer);
        this.weight.toBinaryBuffer(buffer);
        this.timeScale.toBinaryBuffer(buffer);
    }

    /**
     *
     * @param {BinaryBuffer} buffer
     */
    fromBinaryBuffer(buffer) {
        this.flags = buffer.readUint8();

        this.name.fromBinaryBuffer(buffer);
        this.repeatCount.fromBinaryBuffer(buffer);
        this.weight.fromBinaryBuffer(buffer);
        this.timeScale.fromBinaryBuffer(buffer);
    }
}
