001package jmri.jmrix.loconet.sdf;
002
003import jmri.util.StringUtil;
004
005/**
006 * Implement the PLAY macro from the Digitrax sound definition language
007 *
008 * @author Bob Jacobsen Copyright (C) 2007
009 */
010public class Play extends SdfMacro {
011
012    public Play(int byte1, int byte2) {
013        this.byte1 = byte1;
014        this.byte2 = byte2;
015        this.handle = byte2 & 0x3F;
016        this.wavebrkFlags = byte1 & 0x18;
017        this.brk = ((byte1 & 0x7) << 2) + ((byte2 & 0xC0) >> 6);
018        this.byte1 = byte1;
019        this.byte2 = byte2;
020    }
021
022    @Override
023    public String name() {
024        return "PLAY"; // NOI18N
025    }
026
027    int handle;
028    int brk;  // "break" is a reserved word
029    int wavebrkFlags;
030
031    int byte1, byte2;
032
033    public String handleVal() {
034        return "" + handle;
035    }
036
037    public void setHandle(int val) {
038        this.handle = val;
039        this.byte2 = (this.byte2 & 0xC0) | (val & 0x3f);
040    }
041
042    public String brkVal() {
043        return decodeState(brk, loopCodes, loopNames);
044    }
045
046    public void setBrk(String name) {
047        int val = jmri.util.StringUtil.getStateFromName(name, loopCodes, loopNames);
048        if (val == -1) {
049            val = 0; // no match found is defaulted to zero
050        }
051        setBrk(val);
052    }
053
054    public void setBrk(int n) {
055        // argument is 0 - 31
056        this.byte1 = (this.byte1 & 0xF8) | ((n >> 2) & 0x7);
057        this.byte2 = (this.byte2 & 0x3F) | ((n << 6) & 0xC0);
058        this.brk = ((byte1 & 0x7) << 2) + ((byte2 & 0xC0) >> 6);
059    }
060
061    public String wavebrkFlagsVal() {
062        return decodeFlags(wavebrkFlags, wavebrkCodes, wavebrkMasks, wavebrkNames);
063    }
064
065    public int getWaveBrkFlags() {
066        return this.wavebrkFlags >> 3;
067    }
068
069    // doesn't handle case of GLOBAL+INVERT!
070    public void setWaveBrkFlags(String name) {
071        int val = StringUtil.getStateFromName(name, wavebrkCodes, wavebrkNames);
072        if (val == -1) {
073            val = 0;  // no match found is defaulted to zero
074        }
075        setWaveBrkFlags(val >> 3);
076    }
077
078    public void setWaveBrkFlags(int n) {
079        // argument is 0,1,2,3
080        this.byte1 = (this.byte1 & 0xE7) | ((n << 3) & 0x18);
081        this.wavebrkFlags = byte1 & 0x18;
082    }
083
084    @Override
085    public int length() {
086        return 2;
087    }
088
089    static public SdfMacro match(SdfBuffer buff) {
090        // course match
091        if ((buff.getAtIndex() & 0xC0) != 0x40) {
092            return null;
093        }
094        int byte1 = buff.getAtIndexAndInc();
095        int byte2 = buff.getAtIndexAndInc();
096        return new Play(byte1, byte2);
097    }
098
099    /**
100     * Store into a buffer.
101     */
102    @Override
103    public void loadByteArray(SdfBuffer buffer) {
104        // data
105        buffer.setAtIndexAndInc(byte1);
106        buffer.setAtIndexAndInc(byte2);
107
108        // store children
109        super.loadByteArray(buffer);
110    }
111
112    @Override
113    public String toString() {
114        return "Play Fragment " + handleVal() + '\n'; // NOI18N
115    }
116
117    @Override
118    public String oneInstructionString() {
119        return name() + ' ' + handleVal() + ',' + brkVal() + ',' + wavebrkFlagsVal() + '\n';
120    }
121
122    @Override
123    public String allInstructionString(String indent) {
124        return indent + oneInstructionString();
125    }
126}