/*
    Hurry Curry! - a game about cooking
    Copyright (C) 2026 Hurry Curry! Contributors

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, version 3 of the License only.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

*/

import { int, PacketC } from "../protocol.ts";
import { System } from "../system.ts";
import { V2 } from "../util.ts";
import { SMapItems } from "./item.ts";
import { MapLayer } from "./mod.ts";


export class SEffect extends System implements MapLayer {
    effects: Set<EffectRenderer> = new Set()

    constructor(public is: SMapItems) { super() }

    override packet(p: PacketC): void {
        if (p.type != "effect") return
        const pos = { ...this.is.get_item_location_tracking(p.location)! }
        if (p.effect == "points") this.effects.add(new PointsEffect(pos, p.amount))
    }

    override tick(dt: number): void {
        const remove = []
        for (const e of this.effects)
            if (!e.tick(dt)) remove.push(e)
        for (const e of remove)
            this.effects.delete(e)
    }

    draw_map_layer(ctx: CanvasRenderingContext2D): void {
        for (const e of this.effects)
            e.draw(ctx)
    }
}

abstract class EffectRenderer {
    timer = 0
    constructor(public pos: V2) { }
    abstract draw(ctx: CanvasRenderingContext2D): void;
    tick(dt: number): boolean {
        this.timer += dt * 2
        return this.timer < 3
    }
}

class PointsEffect extends EffectRenderer {
    constructor(pos: V2, public amount: int) { super(pos) }
    override draw(ctx: CanvasRenderingContext2D): void {
        ctx.save()
        ctx.translate(this.pos.x, this.pos.y)

        ctx.translate(0, this.timer * -0.2)

        ctx.scale(0.03, 0.03)
        if (this.timer < 0.5) ctx.scale(this.timer * 2, this.timer * 2)
        ctx.globalAlpha = this.timer > 2 ? 3 - this.timer : 1
        ctx.font = "10px sans-serif"
        ctx.fillStyle = this.amount < 0 ? "rgb(255, 106, 106)" : "rgb(157, 255, 124)"
        ctx.strokeStyle = "black"
        ctx.lineWidth = 2
        ctx.lineJoin = "round"
        ctx.lineCap = "round"
        const text = this.amount < 0 ? `${this.amount}` : `+${this.amount}`
        ctx.strokeText(text, 0, 0)
        ctx.fillText(text, 0, 0)


        ctx.restore()
    }
}