// Copyright 2014-2025 Jesper Larsson
//
// This file is part of Klipspringer, <https://klipspringer.avadeaux.net/>
//
// Klipspringer is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// Klipspringer 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
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with Klipspringer. If
// not, see <https://www.gnu.org/licenses/>.

import java.io.IOException;
import java.nio.ByteBuffer;
import net.avadeaux.klipspringer.codec.*;
import net.avadeaux.klipspringer.alsa.Alsa;

/** Demonstration of Klipspringer FLAC decoding interface that reads a FLAC file and plays it using
  * net.avadeaux.klipspringeralsa.Alsa. Compile and run example:
  * <pre>
  *     javac -cp lib/klipcodec.jar examples/AlsaFlacPlayFile.java
  *     java -cp examples:lib/klipcodec.jar --enable-native-access=ALL-UNNAMED -Djava.library.path=lib AlsaFlacPlayFile some_audio_file.flac
  * </pre>
  */
public class AlsaFlacPlayFile {
    public static void main(String[] args) throws IOException {
        if (args.length != 1) {
            System.err.println("Expecting FLAC file argument");
            System.exit(1);
        }

        System.out.println("==== Available ALSA output devices ====");
        for (Device dev : Alsa.Player.devices.values()) {
            System.out.println(dev);
        }
        var cons = System.console();
        Device dev = Alsa.Player.devices.get(cons.readLine("enter device name (the part between \"quotes\"): "));

        FlacDecoder decoder = new FlacDecoder(args[0], new FlacDecoder.Target() {
                private Device.Player player = null;

                public synchronized void metadata(PcmFormat format, long totalSamples) throws IOException {
                    player = new Alsa.Player(dev, format, 2.0, 2);
                }

                public synchronized boolean write(ByteBuffer data) throws IOException {
                    return player.write(data);
                }

                public void close() throws IOException {
                    if (player != null) {
                        player.drain();
                        player.close();
                    }
                }
            });
        decoder.decodeAll(0);
        decoder.close();
    }
}
