001package jmri.jmrix.loconet.sdf;
002
003import java.util.ArrayList;
004
005/**
006 * Implement the SKEME_START macro from the Digitrax sound definition language.
007 * <p>
008 * This nests until the next SKEME_START.
009 *
010 * @author Bob Jacobsen Copyright (C) 2007, 2008
011 */
012public class SkemeStart extends SdfMacro {
013
014    public SkemeStart(int byte1, int byte2, int byte3, int byte4) {
015        this.byte1 = byte1;
016        this.byte2 = byte2;
017        this.byte3 = byte3;
018        this.byte4 = byte4;
019
020        this.number = byte2;
021        this.length = byte3 * 256 + byte4;
022    }
023
024    int byte1, byte2, byte3, byte4;
025
026    int number;
027    int length;
028
029    public int getNumber() {
030        return number;
031    }
032
033    public void setNumber(int num) {
034        number = num;
035        byte2 = num;
036    }
037
038    @Override
039    public String name() {
040        return "SKEME_START"; // NOI18N
041    }
042
043    @Override
044    public int length() {
045        return 4;
046    }
047
048    static public SdfMacro match(SdfBuffer buff) {
049        // course match
050        if ((buff.getAtIndex() & 0xFF) != 0xF1) {
051            return null;
052        }
053
054        int byte1 = buff.getAtIndexAndInc(); // skip op code
055        int byte2 = buff.getAtIndexAndInc();
056        int byte3 = buff.getAtIndexAndInc();
057        int byte4 = buff.getAtIndexAndInc();
058
059        SkemeStart result = new SkemeStart(byte1, byte2, byte3, byte4);
060
061        // gather leaves underneath
062        SdfMacro next;
063        while (buff.moreData()) {
064            // look ahead at next instruction
065            int peek = buff.getAtIndex() & 0xFF;
066
067            // if SKEME_START, done
068            if (peek == 0xF1) {
069                break;
070            }
071
072            // next is leaf, keep it
073            next = decodeInstruction(buff);
074            if (result.children == null) {
075                result.children = new ArrayList<SdfMacro>(); // make sure it's initialized
076            }
077            result.children.add(next);
078        }
079        return result;
080    }
081
082    /**
083     * Store into a buffer.
084     */
085    @Override
086    public void loadByteArray(SdfBuffer buffer) {
087        // data
088        buffer.setAtIndexAndInc(byte1);
089        buffer.setAtIndexAndInc(byte2);
090        buffer.setAtIndexAndInc(byte3);
091        buffer.setAtIndexAndInc(byte4);
092
093        // store children
094        super.loadByteArray(buffer);
095    }
096
097    @Override
098    public String toString() {
099        return "Scheme " + number + "\n"; // NOI18N
100    }
101
102    @Override
103    public String oneInstructionString() {
104        return name() + ' ' + number + "; length=" + length + '\n'; // NOI18N
105    }
106
107    @Override
108    public String allInstructionString(String indent) {
109        StringBuilder output = new StringBuilder(indent);
110        output.append(oneInstructionString());
111        if (children == null) {
112            return output.toString();
113        }
114        for (int i = 0; i < children.size(); i++) {
115            output.append(children.get(i).allInstructionString(indent + "  "));
116        }
117        return output.toString();
118    }
119}