001package jmri.jmrit.logixng.actions;
002
003import java.beans.PropertyChangeEvent;
004import java.beans.PropertyChangeListener;
005import java.util.*;
006
007import jmri.*;
008import jmri.jmrit.audio.AudioListener;
009import jmri.jmrit.audio.AudioSource;
010import jmri.jmrit.logixng.*;
011import jmri.jmrit.logixng.util.LogixNG_SelectEnum;
012import jmri.jmrit.logixng.util.LogixNG_SelectNamedBean;
013import jmri.jmrit.logixng.util.parser.*;
014import jmri.util.ThreadingUtil;
015
016/**
017 * This action controls an audio object.
018 *
019 * @author Daniel Bergqvist Copyright 2021
020 */
021public class ActionAudio extends AbstractDigitalAction
022        implements PropertyChangeListener {
023
024    private final LogixNG_SelectNamedBean<Audio> _selectNamedBean =
025            new LogixNG_SelectNamedBean<>(
026                    this, Audio.class, InstanceManager.getDefault(AudioManager.class), this);
027
028    private final LogixNG_SelectEnum<Operation> _selectEnum =
029            new LogixNG_SelectEnum<>(this, Operation.values(), Operation.Play, this);
030
031
032    public ActionAudio(String sys, String user)
033            throws BadUserNameException, BadSystemNameException {
034        super(sys, user);
035    }
036
037    @Override
038    public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws ParserException {
039        DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class);
040        String sysName = systemNames.get(getSystemName());
041        String userName = userNames.get(getSystemName());
042        if (sysName == null) sysName = manager.getAutoSystemName();
043        ActionAudio copy = new ActionAudio(sysName, userName);
044        copy.setComment(getComment());
045        _selectNamedBean.copy(copy._selectNamedBean);
046        _selectEnum.copy(copy._selectEnum);
047        return manager.registerAction(copy);
048    }
049
050    public LogixNG_SelectNamedBean<Audio> getSelectNamedBean() {
051        return _selectNamedBean;
052    }
053
054    public LogixNG_SelectEnum<Operation> getSelectEnum() {
055        return _selectEnum;
056    }
057
058    /** {@inheritDoc} */
059    @Override
060    public Category getCategory() {
061        return Category.ITEM;
062    }
063
064    /** {@inheritDoc} */
065    @Override
066    public void execute() throws JmriException {
067        Audio audio = _selectNamedBean.evaluateNamedBean(getConditionalNG());
068
069        if (audio == null) return;
070
071        Operation operation = _selectEnum.evaluateEnum(getConditionalNG());
072
073        ThreadingUtil.runOnLayoutWithJmriException(() -> {
074            if (audio.getSubType() == Audio.SOURCE) {
075                AudioSource audioSource = (AudioSource) audio;
076                switch (operation) {
077                    case Play:
078                        audioSource.play();
079                        break;
080                    case Stop:
081                        audioSource.stop();
082                        break;
083                    case PlayToggle:
084                        audioSource.togglePlay();
085                        break;
086                    case Pause:
087                        audioSource.pause();
088                        break;
089                    case Resume:
090                        audioSource.resume();
091                        break;
092                    case PauseToggle:
093                        audioSource.togglePause();
094                        break;
095                    case Rewind:
096                        audioSource.rewind();
097                        break;
098                    case FadeIn:
099                        audioSource.fadeIn();
100                        break;
101                    case FadeOut:
102                        audioSource.fadeOut();
103                        break;
104                    case ResetPosition:
105                        audioSource.resetCurrentPosition();
106                        break;
107                    default:
108                        break;
109                }
110            } else if (audio.getSubType() == Audio.LISTENER) {
111                AudioListener audioListener = (AudioListener) audio;
112                switch (operation) {
113                    case ResetPosition:
114                        audioListener.resetCurrentPosition();
115                        break;
116                    default:
117                        break; // nothing needed for others
118                }
119            }
120        });
121    }
122
123    @Override
124    public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException {
125        throw new UnsupportedOperationException("Not supported.");
126    }
127
128    @Override
129    public int getChildCount() {
130        return 0;
131    }
132
133    @Override
134    public String getShortDescription(Locale locale) {
135        return Bundle.getMessage(locale, "ActionAudio_Short");
136    }
137
138    @Override
139    public String getLongDescription(Locale locale) {
140        String namedBean = _selectNamedBean.getDescription(locale);
141        String operation = _selectEnum.getDescription(locale);
142
143        return Bundle.getMessage(locale, "ActionAudio_Long", operation, namedBean);
144    }
145
146    /** {@inheritDoc} */
147    @Override
148    public void setup() {
149        // Do nothing
150    }
151
152    /** {@inheritDoc} */
153    @Override
154    public void registerListenersForThisClass() {
155        _selectNamedBean.registerListeners();
156        _selectEnum.registerListeners();
157    }
158
159    /** {@inheritDoc} */
160    @Override
161    public void unregisterListenersForThisClass() {
162        _selectNamedBean.unregisterListeners();
163        _selectEnum.unregisterListeners();
164    }
165
166    /** {@inheritDoc} */
167    @Override
168    public void disposeMe() {
169    }
170
171
172    public enum Operation {
173        Play(Bundle.getMessage("ActionAudio_Operation_Play")),
174        PlayToggle(Bundle.getMessage("ActionAudio_Operation_PlayToggle")),
175        Pause(Bundle.getMessage("ActionAudio_Operation_Pause")),
176        PauseToggle(Bundle.getMessage("ActionAudio_Operation_PauseToggle")),
177        Resume(Bundle.getMessage("ActionAudio_Operation_Resume")),
178        Stop(Bundle.getMessage("ActionAudio_Operation_Stop")),
179        FadeIn(Bundle.getMessage("ActionAudio_Operation_FadeIn")),
180        FadeOut(Bundle.getMessage("ActionAudio_Operation_FadeOut")),
181        Rewind(Bundle.getMessage("ActionAudio_Operation_Rewind")),
182        ResetPosition(Bundle.getMessage("ActionAudio_Operation_ResetPosition"));
183
184        private final String _text;
185
186        private Operation(String text) {
187            this._text = text;
188        }
189
190        @Override
191        public String toString() {
192            return _text;
193        }
194
195    }
196
197    /** {@inheritDoc} */
198    @Override
199    public void getUsageDetail(int level, NamedBean bean, List<NamedBeanUsageReport> report, NamedBean cdl) {
200        _selectNamedBean.getUsageDetail(level, bean, report, cdl, this, LogixNG_SelectNamedBean.Type.Action);
201    }
202
203    /** {@inheritDoc} */
204    @Override
205    public void propertyChange(PropertyChangeEvent evt) {
206        getConditionalNG().execute();
207    }
208
209//    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ActionAudio.class);
210
211}