right now I use an animation class to handle my sprite sheets, I want to add a destorying ore animation with 3 frames per ore. the animation in total is only 1 row per ore, and theres 4 rows in total, each row index corresponds to the ore type, i.e row 1 (index 0) is for ore0's 3 states. I have this full ore sprite sheet and I want you to implement it into my game.

heres my animation class:

class Animation {
    int row;             // The row in the sprite sheet
    int frameCount;      // Total frames in this animation
    int frameDelay;      // Controls animation speed (frames per sprite frame)
    boolean loop;        // Should the animation loop?
    
    private int frameCounter = 0;       // Counts frames to control animation speed
    private int currentFrame = 0;       // Current frame index
    
    Animation(int row, int frameCount, int frameDelay, boolean loop) {
        this.row = row;
        this.frameCount = frameCount;
        this.frameDelay = frameDelay;
        this.loop = loop;
    }
    
    // Updates the animation frame based on frameDelay
    void update() {
        frameCounter++;
        if (frameCounter >= frameDelay) {
            frameCounter = 0;
            currentFrame++;
            if (currentFrame >= frameCount) {
                if (loop) {
                    currentFrame = 0;
                } else {
                    currentFrame = frameCount - 1; // Hold on the last frame if not looping
                }
            }
        }
    }
    
    // Resets the animation to the first frame
    void reset() {
        frameCounter = 0;
        currentFrame = 0;
    }
    
    // Retrieves the current frame index
    int getCurrentFrame() {
        return currentFrame;
    }
}

heres my tile class (where ores are considered tile objects)
class Tile {
    TileType type;
    int health;

    Tile(TileType type) {
        this.type = type;
        this.health = getMaxHealth();
    }

    void display(float x, float y) {
        switch (type){
        case EMPTY:
            //image(oreSprites[4], x, y, TILE_SIZE, TILE_SIZE);
            fill(48,48,48);
            rect(x, y, TILE_SIZE, TILE_SIZE);
            break;
        case ROCK:
            image(oreSprites[3], x, y, TILE_SIZE, TILE_SIZE);
            break;
        case ORE0 :
            image(oreSprites[0], x, y, TILE_SIZE, TILE_SIZE);
            break;
        case ORE1:
            image(oreSprites[1], x, y, TILE_SIZE, TILE_SIZE);
            break;
        case ORE2:
            image(oreSprites[2], x, y, TILE_SIZE, TILE_SIZE);
            break;
        case GOAL:
        fill(0, 255, 0);
        rect(x, y, TILE_SIZE, TILE_SIZE);
        break;
        }
    }


    TileType mine() {
    if (type != TileType.EMPTY && type != TileType.GOAL) {
      health--;
      if (health <= 0) {
        TileType minedType = type;
        type = TileType.EMPTY;
        soundManager.stopMiningSound();
        return minedType;
      }
    }
    return null;
  }


    void takeDamage(int damage) {
        if (type != TileType.EMPTY) {
            health -= damage;
            if (health <= 0) {
                type = TileType.EMPTY;
            }
        }
    }

    int getMaxHealth() {
        switch(type) {
            case ROCK : return 35;
            case ORE0 : return 200;
            case ORE1 : return 120;
            case ORE2 : return 75;
            default : return 0;
        }
    }
}

please adjust the code to the needs of my requirements