/*
    Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
    и других спецификаций для функционирования компактных приложений на языке
    Java (мидлетов) в среде программного обеспечения Малик Эмулятор.

    Copyright © 2016–2017, 2019–2022 Малик Разработчик

    Это свободная программа: вы можете перераспространять ее и/или изменять
    ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она будет полезной,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <https://www.gnu.org/licenses/>.
*/

package com.samsung.util;

import java.io.*;
import javax.microedition.media.*;
import javax.microedition.media.control.*;
import malik.emulator.io.jar.*;
import malik.emulator.util.*;

public class AudioClip extends Object
{
    public static final int TYPE_MMF = 1;
    public static final int TYPE_MP3 = 2;
    public static final int TYPE_MIDI = 3;

    private static final String[] MIME_TYPES;

    static {
        MIME_TYPES = new String[] { "application/vnd.smaf", "audio/mpeg", "audio/midi" };
    }

    public static boolean isSupported() {
        return true;
    }

    private final Player implement;
    private final VolumeControl volume;

    public AudioClip(int format, byte[] src, int offset, int length) {
        Player implement;
        VolumeControl volume;
        if(--format < 0 || format >= MIME_TYPES.length)
        {
            throw new IllegalArgumentException("AudioClip: аргумент format имеет недопустимое значение.");
        }
        if(src == null)
        {
            throw new NullPointerException("AudioClip: аргумент src равен нулевой ссылке.");
        }
        Array.checkBound("AudioClip", src.length, offset, length);
        try
        {
            (implement = Manager.createPlayer(new ByteArrayInputStream(src, offset, length), MIME_TYPES[format])).prefetch();
            volume = (VolumeControl) implement.getControl("VolumeControl");
        }
        catch(Exception e)
        {
            throw new IllegalArgumentException(e.getMessage());
        }
        this.implement = implement;
        this.volume = volume;
    }

    public AudioClip(int format, String resourceName) throws IOException {
        InputStream stream;
        Player implement;
        VolumeControl volume;
        if(--format < 0 || format >= MIME_TYPES.length)
        {
            throw new IllegalArgumentException("AudioClip: аргумент format имеет недопустимое значение.");
        }
        if(resourceName == null)
        {
            throw new NullPointerException("AudioClip: аргумент resourceName равен нулевой ссылке.");
        }
        if(resourceName.length() <= 0 || resourceName.charAt(0) != '/') resourceName = "/".concat(resourceName);
        if((stream = getClass().getResourceAsStream(resourceName)) == null)
        {
            throw new ResourceNotFoundException((new StringBuilder()).append("AudioClip: ресурс ").append(resourceName).append(" не найден.").toString(), resourceName);
        }
        try
        {
            (implement = Manager.createPlayer(stream, MIME_TYPES[format])).prefetch();
            volume = (VolumeControl) implement.getControl("VolumeControl");
        }
        catch(Exception e)
        {
            throw new IllegalArgumentException(e.getMessage());
        }
        this.implement = implement;
        this.volume = volume;
    }

    public void resume() {
        try
        {
            implement.start();
        }
        catch(MediaException e)
        {
            e.printRealStackTrace();
        }
    }

    public void play(int loopCount, int volumeLevel) {
        if(loopCount < 0 || loopCount > 255)
        {
            throw new IllegalArgumentException("AudioClip.play: аргумент loopCount выходит из диапазона.");
        }
        if(volumeLevel < 0 || volumeLevel > 5)
        {
            throw new IllegalArgumentException("AudioClip.play: аргумент volumeLevel выходит из диапазона.");
        }
        if(loopCount == 0) loopCount = -1;
        try
        {
            Player implement;
            VolumeControl volume;
            (implement = this.implement).stop();
            if((volume = this.volume) != null) volume.setLevel(20 * volumeLevel);
            implement.setLoopCount(loopCount);
            implement.start();
        }
        catch(MediaException e)
        {
            e.printRealStackTrace();
        }
    }

    public void pause() {
        try
        {
            implement.stop();
        }
        catch(MediaException e)
        {
            e.printRealStackTrace();
        }
    }

    public void stop() {
        implement.close();
    }
}
