/*
    Реализация спецификаций 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 malik.emulator.microedition.system.player;

import javax.microedition.media.*;
import javax.microedition.media.control.*;
import malik.emulator.media.sound.*;

public abstract class Volume extends Object implements Control, VolumeControl
{
    private boolean muted;
    private int level;
    protected final Object monitor;

    protected Volume(Object monitor) {
        this.level = 100;
        this.monitor = monitor == null ? new Object() : monitor;
    }

    public void setMute(boolean muted) {
        synchronized(monitor)
        {
            if(this.muted != (this.muted = muted))
            {
                int level = this.level;
                SoundPlayer player;
                if((player = getSystemPlayer()) != null)
                {
                    try
                    {
                        player.setVolume(muted ? 0 : level * SoundPlayer.MAX_VOLUME / 100);
                    }
                    catch(SoundPlayerException e)
                    {
                        e.printRealStackTrace();
                    }
                }
                volumeChanged(muted, level);
            }
        }
    }

    public boolean isMuted() {
        return muted;
    }

    public int setLevel(int level) {
        if(level < 0) level = 0;
        if(level > 100) level = 100;
        synchronized(monitor)
        {
            if(this.level != (this.level = level))
            {
                boolean muted;
                SoundPlayer player;
                if(!(muted = this.muted) && (player = getSystemPlayer()) != null)
                {
                    try
                    {
                        player.setVolume(level * SoundPlayer.MAX_VOLUME / 100);
                    }
                    catch(SoundPlayerException e)
                    {
                        e.printRealStackTrace();
                    }
                }
                volumeChanged(muted, level);
            }
        }
        return level;
    }

    public int getLevel() {
        return level;
    }

    protected abstract SoundPlayer getSystemPlayer();

    protected void volumeChanged(boolean muted, int level) {
    }

    protected void setupSystemPlayer(SoundPlayer player) throws SoundPlayerException {
        player.setVolume(muted ? 0 : level * SoundPlayer.MAX_VOLUME / 100);
    }
}
