/*
 * Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javax.sound.midi;

/**
 * <code>MidiMessage</code> is the base class for MIDI messages.  They include
 * not only the standard MIDI messages that a synthesizer can respond to, but also
 * "meta-events" that can be used by sequencer programs.  There are meta-events
 * for such information as lyrics, copyrights, tempo indications, time and key
 * signatures, markers, etc.  For more information, see the Standard MIDI Files 1.0
 * specification, which is part of the Complete MIDI 1.0 Detailed Specification
 * published by the MIDI Manufacturer's Association
 * (<a href = http://www.midi.org>http://www.midi.org</a>).
 * <p>
 * The base <code>MidiMessage</code> class provides access to three types of
 * information about a MIDI message:
 * <ul>
 * <li>The messages's status byte</li>
 * <li>The total length of the message in bytes (the status byte plus any data bytes)</li>
 * <li>A byte array containing the complete message</li>
 * </ul>
 *
 * <code>MidiMessage</code> includes methods to get, but not set, these values.
 * Setting them is a subclass responsibility.
 * <p>
 * <a name="integersVsBytes"></a>
 * The MIDI standard expresses MIDI data in bytes.  However, because
 * Java<sup>TM</sup> uses signed bytes, the Java Sound API uses integers
 * instead of bytes when expressing MIDI data.  For example, the
 * {@link #getStatus()} method of
 * <code>MidiMessage</code> returns MIDI status bytes as integers.  If you are
 * processing MIDI data that originated outside Java Sound and now
 * is encoded as signed bytes, the bytes can
 * can be converted to integers using this conversion:
 * <center><code>int i = (int)(byte & 0xFF)</code></center>
 * <p>
 * If you simply need to pass a known MIDI byte value as a method parameter,
 * it can be expressed directly as an integer, using (for example) decimal or
 * hexidecimal notation.  For instance, to pass the "active sensing" status byte
 * as the first argument to ShortMessage's
 * {@link ShortMessage#setMessage(int) setMessage(int)}
 * method, you can express it as 254 or 0xFE.
 *
 * @see Track
 * @see Sequence
 * @see Receiver
 *
 * @author David Rivas
 * @author Kara Kytle
 */

public abstract class MidiMessage implements Cloneable {

    // Instance variables

    /**
     * The MIDI message data.  The first byte is the status
     * byte for the message; subsequent bytes up to the length
     * of the message are data bytes for this message.
     * @see #getLength
     */
    protected byte[] data;


    /**
     * The number of bytes in the MIDI message, including the
     * status byte and any data bytes.
     * @see #getLength
     */
    protected int length = 0;


    /**
     * Constructs a new <code>MidiMessage</code>.  This protected
     * constructor is called by concrete subclasses, which should
     * ensure that the data array specifies a complete, valid MIDI
     * message.
     *
     * @param data an array of bytes containing the complete message.
     * The message data may be changed using the <code>setMessage</code>
     * method.
     *
     * @see #setMessage
     */
    protected MidiMessage(byte[] data) {
        this.data = data;
        if (data != null) {
            this.length = data.length;
        }
    }


    /**
     * Sets the data for the MIDI message.   This protected
     * method is called by concrete subclasses, which should
     * ensure that the data array specifies a complete, valid MIDI
     * message.
     */
    protected void setMessage(byte[] data, int length) throws InvalidMidiDataException {
        if (length < 0 || (length > 0 && length > data.length)) {
            throw new IndexOutOfBoundsException("length out of bounds: "+length);
        }
        this.length = length;

        if (this.data == null || this.data.length < this.length) {
            this.data = new byte[this.length];
        }
        System.arraycopy(data, 0, this.data, 0, length);
    }


    /**
     * Obtains the MIDI message data.  The first byte of the returned byte
     * array is the status byte of the message.  Any subsequent bytes up to
     * the length of the message are data bytes.  The byte array may have a
     * length which is greater than that of the actual message; the total
     * length of the message in bytes is reported by the <code>{@link #getLength}</code>
     * method.
     *
     * @return the byte array containing the complete <code>MidiMessage</code> data
     */
    public byte[] getMessage() {
        byte[] returnedArray = new byte[length];
        System.arraycopy(data, 0, returnedArray, 0, length);
        return returnedArray;
    }


    /**
     * Obtains the status byte for the MIDI message.  The status "byte" is
     * represented as an integer; see the
     * <a href="#integersVsBytes">discussion</a> in the
     * <code>MidiMessage</code> class description.
     *
     * @return the integer representation of this event's status byte
     */
    public int getStatus() {
        if (length > 0) {
            return (data[0] & 0xFF);
        }
        return 0;
    }


    /**
     * Obtains the total length of the MIDI message in bytes.  A
     * MIDI message consists of one status byte and zero or more
     * data bytes.  The return value ranges from 1 for system real-time messages,
     * to 2 or 3 for channel messages, to any value for meta and system
     * exclusive messages.
     *
     * @return the length of the message in bytes
     */
    public int getLength() {
        return length;
    }


    /**
     * Creates a new object of the same class and with the same contents
     * as this object.
     * @return a clone of this instance.
     */
    public abstract Object clone();
}
