/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * A recording of a Guacamole session. Given a {@link Guacamole.Tunnel} or Blob,
 * the Guacamole.SessionRecording automatically parses Guacamole instructions
 * within the recording source as it plays back the recording. Playback of the
 * recording may be controlled through function calls to the
 * Guacamole.SessionRecording, even while the recording has not yet finished
 * being created or downloaded. Parsing of the contents of the recording will
 * begin immediately and automatically after this constructor is invoked.
 *
 * @constructor
 * @param {!Blob|Guacamole.Tunnel} source
 *     The Blob from which the instructions of the recording should
 *     be read.
 */
Guacamole.SessionRecording = function SessionRecording(source) {

    /**
     * Reference to this Guacamole.SessionRecording.
     *
     * @private
     * @type {!Guacamole.SessionRecording}
     */
    var recording = this;

    /**
     * The Blob from which the instructions of the recording should be read.
     * Note that this value is initialized far below.
     *
     * @private
     * @type {!Blob}
     */
    var recordingBlob;

    /**
     * The tunnel from which the recording should be read, if the recording is
     * being read from a tunnel. If the recording was supplied as a Blob, this
     * will be null.
     *
     * @private
     * @type {Guacamole.Tunnel}
     */
    var tunnel = null;

    /**
     * The number of bytes that this Guacamole.SessionRecording should attempt
     * to read from the given blob in each read operation. Larger blocks will
     * generally read the blob more quickly, but may result in excessive
     * time being spent within the parser, making the page unresponsive
     * while the recording is loading.
     *
     * @private
     * @constant
     * @type {Number}
     */
    var BLOCK_SIZE = 262144;

    /**
     * The minimum number of characters which must have been read between
     * keyframes.
     *
     * @private
     * @constant
     * @type {Number}
     */
    var KEYFRAME_CHAR_INTERVAL = 16384;

    /**
     * The minimum number of milliseconds which must elapse between keyframes.
     *
     * @private
     * @constant
     * @type {Number}
     */
    var KEYFRAME_TIME_INTERVAL = 5000;

    /**
     * All frames parsed from the provided blob.
     *
     * @private
     * @type {!Guacamole.SessionRecording._Frame[]}
     */
    var frames = [];

    /**
     * The timestamp of the last frame which was flagged for use as a keyframe.
     * If no timestamp has yet been flagged, this will be 0.
     *
     * @private
     * @type {!number}
     */
    var lastKeyframe = 0;

    /**
     * Tunnel which feeds arbitrary instructions to the client used by this
     * Guacamole.SessionRecording for playback of the session recording.
     *
     * @private
     * @type {!Guacamole.SessionRecording._PlaybackTunnel}
     */
    var playbackTunnel = new Guacamole.SessionRecording._PlaybackTunnel();

    /**
     * Guacamole.Client instance used for visible playback of the session
     * recording.
     *
     * @private
     * @type {!Guacamole.Client}
     */
    var playbackClient = new Guacamole.Client(playbackTunnel);

    /**
     * The current frame rendered within the playback client. If no frame is
     * yet rendered, this will be -1.
     *
     * @private
     * @type {!number}
     */
    var currentFrame = -1;

    /**
     * The timestamp of the frame when playback began, in milliseconds. If
     * playback is not in progress, this will be null.
     *
     * @private
     * @type {number}
     */
    var startVideoTimestamp = null;

    /**
     * The real-world timestamp when playback began, in milliseconds. If
     * playback is not in progress, this will be null.
     *
     * @private
     * @type {number}
     */
    var startRealTimestamp = null;

    /**
     * An object containing a single "aborted" property which is set to
     * true if the in-progress seek operation should be aborted. If no seek
     * operation is in progress, this will be null.
     *
     * @private
     * @type {object}
     */
    var activeSeek = null;

    /**
     * The byte offset within the recording blob of the first character of
     * the first instruction of the current frame. Here, "current frame"
     * refers to the frame currently being parsed when the provided
     * recording is initially loading. If the recording is not being
     * loaded, this value has no meaning.
     *
     * @private
     * @type {!number}
     */
    var frameStart = 0;

    /**
     * The byte offset within the recording blob of the character which
     * follows the last character of the most recently parsed instruction
     * of the current frame. Here, "current frame" refers to the frame
     * currently being parsed when the provided recording is initially
     * loading. If the recording is not being loaded, this value has no
     * meaning.
     *
     * @private
     * @type {!number}
     */
    var frameEnd = 0;

    /**
     * Whether the initial loading process has been aborted. If the loading
     * process has been aborted, no further blocks of data should be read
     * from the recording.
     *
     * @private
     * @type {!boolean}
     */
    var aborted = false;

    /**
     * The function to invoke when the seek operation initiated by a call
     * to seek() is cancelled or successfully completed. If no seek
     * operation is in progress, this will be null.
     *
     * @private
     * @type {function}
     */
    var seekCallback = null;

    /**
     * Parses all Guacamole instructions within the given blob, invoking
     * the provided instruction callback for each such instruction. Once
     * the end of the blob has been reached (no instructions remain to be
     * parsed), the provided completion callback is invoked. If a parse
     * error prevents reading instructions from the blob, the onerror
     * callback of the Guacamole.SessionRecording is invoked, and no further
     * data is handled within the blob.
     *
     * @private
     * @param {!Blob} blob
     *     The blob to parse Guacamole instructions from.
     *
     * @param {function} [instructionCallback]
     *     The callback to invoke for each Guacamole instruction read from
     *     the given blob. This function must accept the same arguments
     *     as the oninstruction handler of Guacamole.Parser.
     *
     * @param {function} [completionCallback]
     *     The callback to invoke once all instructions have been read from
     *     the given blob.
     */
    var parseBlob = function parseBlob(blob, instructionCallback, completionCallback) {

        // Do not read any further blocks if loading has been aborted
        if (aborted && blob === recordingBlob)
            return;

        // Prepare a parser to handle all instruction data within the blob,
        // automatically invoking the provided instruction callback for all
        // parsed instructions
        var parser = new Guacamole.Parser();
        parser.oninstruction = instructionCallback;

        var offset = 0;
        var reader = new FileReader();

        /**
         * Reads the block of data at offset bytes within the blob. If no
         * such block exists, then the completion callback provided to
         * parseBlob() is invoked as all data has been read.
         *
         * @private
         */
        var readNextBlock = function readNextBlock() {

            // Do not read any further blocks if loading has been aborted
            if (aborted && blob === recordingBlob)
                return;

            // Parse all instructions within the block, invoking the
            // onerror handler if a parse error occurs
            if (reader.readyState === 2 /* DONE */) {
                try {
                    parser.receive(reader.result);
                }
                catch (parseError) {
                    if (recording.onerror) {
                        recording.onerror(parseError.message);
                    }
                    return;
                }
            }

            // If no data remains, the read operation is complete and no
            // further blocks need to be read
            if (offset >= blob.size) {
                if (completionCallback)
                    completionCallback();
            }

            // Otherwise, read the next block
            else {
                var block = blob.slice(offset, offset + BLOCK_SIZE);
                offset += block.size;
                reader.readAsText(block);
            }

        };

        // Read blocks until the end of the given blob is reached
        reader.onload = readNextBlock;
        readNextBlock();

    };

    /**
     * Calculates the size of the given Guacamole instruction element, in
     * Unicode characters. The size returned includes the characters which
     * make up the length, the "." separator between the length and the
     * element itself, and the "," or ";" terminator which follows the
     * element.
     *
     * @private
     * @param {!string} value
     *     The value of the element which has already been parsed (lacks
     *     the initial length, "." separator, and "," or ";" terminator).
     *
     * @returns {!number}
     *     The number of Unicode characters which would make up the given
     *     element within a Guacamole instruction.
     */
    var getElementSize = function getElementSize(value) {

        var valueLength = value.length;

        // Calculate base size, assuming at least one digit, the "."
        // separator, and the "," or ";" terminator
        var protocolSize = valueLength + 3;

        // Add one character for each additional digit that would occur
        // in the element length prefix
        while (valueLength >= 10) {
            protocolSize++;
            valueLength = Math.floor(valueLength / 10);
        }

        return protocolSize;

    };

    // Start playback client connected
    playbackClient.connect();

    // Hide cursor unless mouse position is received
    playbackClient.getDisplay().showCursor(false);

    /**
     * Handles a newly-received instruction, whether from the main Blob or a
     * tunnel, adding new frames and keyframes as necessary. Load progress is
     * reported via onprogress automatically.
     *
     * @private
     * @param {!string} opcode
     *     The opcode of the instruction to handle.
     *
     * @param {!string[]} args
     *     The arguments of the received instruction, if any.
     */
    var loadInstruction = function loadInstruction(opcode, args) {

        // Advance end of frame by overall length of parsed instruction
        frameEnd += getElementSize(opcode);
        for (var i = 0; i < args.length; i++)
            frameEnd += getElementSize(args[i]);

        // Once a sync is received, store all instructions since the last
        // frame as a new frame
        if (opcode === 'sync') {

            // Parse frame timestamp from sync instruction
            var timestamp = parseInt(args[0]);

            // Add a new frame containing the instructions read since last frame
            var frame = new Guacamole.SessionRecording._Frame(timestamp, frameStart, frameEnd);
            frames.push(frame);
            frameStart = frameEnd;

            // This frame should eventually become a keyframe if enough data
            // has been processed and enough recording time has elapsed, or if
            // this is the absolute first frame
            if (frames.length === 1 || (frameEnd - frames[lastKeyframe].start >= KEYFRAME_CHAR_INTERVAL
                    && timestamp - frames[lastKeyframe].timestamp >= KEYFRAME_TIME_INTERVAL)) {
                frame.keyframe = true;
                lastKeyframe = frames.length - 1;
            }

            // Notify that additional content is available
            if (recording.onprogress)
                recording.onprogress(recording.getDuration(), frameEnd);

        }

    };

    /**
     * Notifies that the session recording has been fully loaded. If the onload
     * handler has not been defined, this function has no effect.
     *
     * @private
     */
    var notifyLoaded = function notifyLoaded() {
        if (recording.onload)
            recording.onload();
    };

    // Read instructions from provided blob, extracting each frame
    if (source instanceof Blob)
        parseBlob(recordingBlob, loadInstruction, notifyLoaded);

    // If tunnel provided instead of Blob, extract frames, etc. as instructions
    // are received, buffering things into a Blob for future seeks
    else {

        tunnel = source;
        recordingBlob = new Blob();

        var errorEncountered = false;
        var instructionBuffer = '';

        // Read instructions from provided tunnel, extracting each frame
        tunnel.oninstruction = function handleInstruction(opcode, args) {

            // Reconstitute received instruction
            instructionBuffer += opcode.length + '.' + opcode;
            args.forEach(function appendArg(arg) {
                instructionBuffer += ',' + arg.length + '.' + arg;
            });
            instructionBuffer += ';';

            // Append to Blob (creating a new Blob in the process)
            if (instructionBuffer.length >= BLOCK_SIZE) {
                recordingBlob = new Blob([recordingBlob, instructionBuffer]);
                instructionBuffer = '';
            }

            // Load parsed instruction into recording
            loadInstruction(opcode, args);

        };

        // Report any errors encountered
        tunnel.onerror = function tunnelError(status) {
            errorEncountered = true;
            if (recording.onerror)
                recording.onerror(status.message);
        };

        tunnel.onstatechange = function tunnelStateChanged(state) {
            if (state === Guacamole.Tunnel.State.CLOSED) {

                // Append any remaining instructions
                if (instructionBuffer.length) {
                    recordingBlob = new Blob([recordingBlob, instructionBuffer]);
                    instructionBuffer = '';
                }

                // Consider recording loaded if tunnel has closed without errors
                if (!errorEncountered)
                    notifyLoaded();
            }
        };

    }

    /**
     * Converts the given absolute timestamp to a timestamp which is relative
     * to the first frame in the recording.
     *
     * @private
     * @param {!number} timestamp
     *     The timestamp to convert to a relative timestamp.
     *
     * @returns {!number}
     *     The difference in milliseconds between the given timestamp and the
     *     first frame of the recording, or zero if no frames yet exist.
     */
    var toRelativeTimestamp = function toRelativeTimestamp(timestamp) {

        // If no frames yet exist, all timestamps are zero
        if (frames.length === 0)
            return 0;

        // Calculate timestamp relative to first frame
        return timestamp - frames[0].timestamp;

    };

    /**
     * Searches through the given region of frames for the frame having a
     * relative timestamp closest to the timestamp given.
     *
     * @private
     * @param {!number} minIndex
     *     The index of the first frame in the region (the frame having the
     *     smallest timestamp).
     *
     * @param {!number} maxIndex
     *     The index of the last frame in the region (the frame having the
     *     largest timestamp).
     *
     * @param {!number} timestamp
     *     The relative timestamp to search for, where zero denotes the first
     *     frame in the recording.
     *
     * @returns {!number}
     *     The index of the frame having a relative timestamp closest to the
     *     given value.
     */
    var findFrame = function findFrame(minIndex, maxIndex, timestamp) {

        // Do not search if the region contains only one element
        if (minIndex === maxIndex)
            return minIndex;

        // Split search region into two halves
        var midIndex = Math.floor((minIndex + maxIndex) / 2);
        var midTimestamp = toRelativeTimestamp(frames[midIndex].timestamp);

        // If timestamp is within lesser half, search again within that half
        if (timestamp < midTimestamp && midIndex > minIndex)
            return findFrame(minIndex, midIndex - 1, timestamp);

        // If timestamp is within greater half, search again within that half
        if (timestamp > midTimestamp && midIndex < maxIndex)
            return findFrame(midIndex + 1, maxIndex, timestamp);

        // Otherwise, we lucked out and found a frame with exactly the
        // desired timestamp
        return midIndex;

    };

    /**
     * Replays the instructions associated with the given frame, sending those
     * instructions to the playback client.
     *
     * @private
     * @param {!number} index
     *     The index of the frame within the frames array which should be
     *     replayed.
     *
     * @param {function} callback
     *     The callback to invoke once replay of the frame has completed.
     */
    var replayFrame = function replayFrame(index, callback) {

        var frame = frames[index];

        // Replay all instructions within the retrieved frame
        parseBlob(recordingBlob.slice(frame.start, frame.end), function handleInstruction(opcode, args) {
            playbackTunnel.receiveInstruction(opcode, args);
        }, function replayCompleted() {

            // Store client state if frame is flagged as a keyframe
            if (frame.keyframe && !frame.clientState) {
                playbackClient.exportState(function storeClientState(state) {
                    frame.clientState = new Blob([JSON.stringify(state)]);
                });
            }

            // Update state to correctly represent the current frame
            currentFrame = index;

            if (callback)
                callback();

        });

    };

    /**
     * Moves the playback position to the given frame, resetting the state of
     * the playback client and replaying frames as necessary. The seek
     * operation will proceed asynchronously. If a seek operation is already in
     * progress, that seek is first aborted. The progress of the seek operation
     * can be observed through the onseek handler and the provided callback.
     *
     * @private
     * @param {!number} index
     *     The index of the frame which should become the new playback
     *     position.
     *
     * @param {function} callback
     *     The callback to invoke once the seek operation has completed.
     *
     * @param {number} [nextRealTimestamp]
     *     The timestamp of the point in time that the given frame should be
     *     displayed, as would be returned by new Date().getTime(). If omitted,
     *     the frame will be displayed as soon as possible.
     */
    var seekToFrame = function seekToFrame(index, callback, nextRealTimestamp) {

        // Abort any in-progress seek
        abortSeek();

        // Note that a new seek operation is in progress
        var thisSeek = activeSeek = {
            aborted : false
        };

        var startIndex = index;

        // Replay any applicable incremental frames
        var continueReplay = function continueReplay() {

            // Notify of changes in position
            if (recording.onseek && currentFrame > startIndex) {
                recording.onseek(toRelativeTimestamp(frames[currentFrame].timestamp),
                    currentFrame - startIndex, index - startIndex);
            }

            // Cancel seek if aborted
            if (thisSeek.aborted)
                return;

            // If frames remain, replay the next frame
            if (currentFrame < index)
                replayFrame(currentFrame + 1, continueReplay);

            // Otherwise, the seek operation is completed
            else
                callback();

        };

        // Continue replay after requested delay has elapsed, or
        // immediately if no delay was requested
        var continueAfterRequiredDelay = function continueAfterRequiredDelay() {
            var delay = nextRealTimestamp ? Math.max(nextRealTimestamp - new Date().getTime(), 0) : 0;
            if (delay)
                window.setTimeout(continueReplay, delay);
            else
                continueReplay();
        };

        // Back up until startIndex represents current state
        for (; startIndex >= 0; startIndex--) {

            var frame = frames[startIndex];

            // If we've reached the current frame, startIndex represents
            // current state by definition
            if (startIndex === currentFrame)
                break;

            // If frame has associated absolute state, make that frame the
            // current state
            if (frame.clientState) {
                frame.clientState.text().then(function textReady(text) {
                    playbackClient.importState(JSON.parse(text));
                    currentFrame = startIndex;
                    continueAfterRequiredDelay();
                });
                return;
            }

        }

        continueAfterRequiredDelay();
        
    };

    /**
     * Aborts the seek operation currently in progress, if any. If no seek
     * operation is in progress, this function has no effect.
     *
     * @private
     */
    var abortSeek = function abortSeek() {
        if (activeSeek) {
            activeSeek.aborted = true;
            activeSeek = null;
        }
    };

    /**
     * Advances playback to the next frame in the frames array and schedules
     * playback of the frame following that frame based on their associated
     * timestamps. If no frames exist after the next frame, playback is paused.
     *
     * @private
     */
    var continuePlayback = function continuePlayback() {

        // If frames remain after advancing, schedule next frame
        if (currentFrame + 1 < frames.length) {

            // Pull the upcoming frame
            var next = frames[currentFrame + 1];

            // Calculate the real timestamp corresponding to when the next
            // frame begins
            var nextRealTimestamp = next.timestamp - startVideoTimestamp + startRealTimestamp;

            // Advance to next frame after enough time has elapsed
            seekToFrame(currentFrame + 1, function frameDelayElapsed() {
                continuePlayback();
            }, nextRealTimestamp);

        }

        // Otherwise stop playback
        else
            recording.pause();

    };

    /**
     * Fired when loading of this recording has completed and all frames
     * are available.
     *
     * @event
     */
    this.onload = null;

    /**
     * Fired when an error occurs which prevents the recording from being
     * played back.
     *
     * @event
     * @param {!string} message
     *     A human-readable message describing the error that occurred.
     */
    this.onerror = null;

    /**
     * Fired when further loading of this recording has been explicitly
     * aborted through a call to abort().
     *
     * @event
     */
    this.onabort = null;

    /**
     * Fired when new frames have become available while the recording is
     * being downloaded.
     *
     * @event
     * @param {!number} duration
     *     The new duration of the recording, in milliseconds.
     *
     * @param {!number} parsedSize
     *     The number of bytes that have been loaded/parsed.
     */
    this.onprogress = null;

    /**
     * Fired whenever playback of the recording has started.
     *
     * @event
     */
    this.onplay = null;

    /**
     * Fired whenever playback of the recording has been paused. This may
     * happen when playback is explicitly paused with a call to pause(), or
     * when playback is implicitly paused due to reaching the end of the
     * recording.
     *
     * @event
     */
    this.onpause = null;

    /**
     * Fired whenever the playback position within the recording changes.
     *
     * @event
     * @param {!number} position
     *     The new position within the recording, in milliseconds.
     *
     * @param {!number} current
     *     The number of frames that have been seeked through. If not
     *     seeking through multiple frames due to a call to seek(), this
     *     will be 1.
     *
     * @param {!number} total
     *     The number of frames that are being seeked through in the
     *     current seek operation. If not seeking through multiple frames
     *     due to a call to seek(), this will be 1.
     */
    this.onseek = null;

    /**
     * Connects the underlying tunnel, beginning download of the Guacamole
     * session. Playback of the Guacamole session cannot occur until at least
     * one frame worth of instructions has been downloaded. If the underlying
     * recording source is a Blob, this function has no effect.
     *
     * @param {string} [data]
     *     The data to send to the tunnel when connecting.
     */
    this.connect = function connect(data) {
        if (tunnel)
            tunnel.connect(data);
    };

    /**
     * Disconnects the underlying tunnel, stopping further download of the
     * Guacamole session. If the underlying recording source is a Blob, this
     * function has no effect.
     */
    this.disconnect = function disconnect() {
        if (tunnel)
            tunnel.disconnect();
    };

    /**
     * Aborts the loading process, stopping further processing of the
     * provided data. If the underlying recording source is a Guacamole tunnel,
     * it will be disconnected.
     */
    this.abort = function abort() {
        if (!aborted) {

            aborted = true;
            if (recording.onabort)
                recording.onabort();

            if (tunnel)
                tunnel.disconnect();

        }
    };

    /**
     * Returns the underlying display of the Guacamole.Client used by this
     * Guacamole.SessionRecording for playback. The display contains an Element
     * which can be added to the DOM, causing the display (and thus playback of
     * the recording) to become visible.
     *
     * @return {!Guacamole.Display}
     *     The underlying display of the Guacamole.Client used by this
     *     Guacamole.SessionRecording for playback.
     */
    this.getDisplay = function getDisplay() {
        return playbackClient.getDisplay();
    };

    /**
     * Returns whether playback is currently in progress.
     *
     * @returns {!boolean}
     *     true if playback is currently in progress, false otherwise.
     */
    this.isPlaying = function isPlaying() {
        return !!startVideoTimestamp;
    };

    /**
     * Returns the current playback position within the recording, in
     * milliseconds, where zero is the start of the recording.
     *
     * @returns {!number}
     *     The current playback position within the recording, in milliseconds.
     */
    this.getPosition = function getPosition() {

        // Position is simply zero if playback has not started at all
        if (currentFrame === -1)
            return 0;

        // Return current position as a millisecond timestamp relative to the
        // start of the recording
        return toRelativeTimestamp(frames[currentFrame].timestamp);

    };

    /**
     * Returns the duration of this recording, in milliseconds. If the
     * recording is still being downloaded, this value will gradually increase.
     *
     * @returns {!number}
     *     The duration of this recording, in milliseconds.
     */
    this.getDuration = function getDuration() {

        // If no frames yet exist, duration is zero
        if (frames.length === 0)
            return 0;

        // Recording duration is simply the timestamp of the last frame
        return toRelativeTimestamp(frames[frames.length - 1].timestamp);

    };

    /**
     * Begins continuous playback of the recording downloaded thus far.
     * Playback of the recording will continue until pause() is invoked or
     * until no further frames exist. Playback is initially paused when a
     * Guacamole.SessionRecording is created, and must be explicitly started
     * through a call to this function. If playback is already in progress,
     * this function has no effect. If a seek operation is in progress,
     * playback resumes at the current position, and the seek is aborted as if
     * completed.
     */
    this.play = function play() {

        // If playback is not already in progress and frames remain,
        // begin playback
        if (!recording.isPlaying() && currentFrame + 1 < frames.length) {

            // Notify that playback is starting
            if (recording.onplay)
                recording.onplay();

            // Store timestamp of playback start for relative scheduling of
            // future frames
            var next = frames[currentFrame + 1];
            startVideoTimestamp = next.timestamp;
            startRealTimestamp = new Date().getTime();

            // Begin playback of video
            continuePlayback();

        }

    };

    /**
     * Seeks to the given position within the recording. If the recording is
     * currently being played back, playback will continue after the seek is
     * performed. If the recording is currently paused, playback will be
     * paused after the seek is performed. If a seek operation is already in
     * progress, that seek is first aborted. The seek operation will proceed
     * asynchronously.
     *
     * @param {!number} position
     *     The position within the recording to seek to, in milliseconds.
     *
     * @param {function} [callback]
     *     The callback to invoke once the seek operation has completed.
     */
    this.seek = function seek(position, callback) {

        // Do not seek if no frames exist
        if (frames.length === 0)
            return;

        // Abort active seek operation, if any
        recording.cancel();

        // Pause playback, preserving playback state
        var originallyPlaying = recording.isPlaying();
        recording.pause();

        // Restore playback when seek is completed or cancelled
        seekCallback = function restorePlaybackState() {

            // Seek is no longer in progress
            seekCallback = null;

            // Restore playback state
            if (originallyPlaying) {
                recording.play();
                originallyPlaying = null;
            }

            // Notify that seek has completed
            if (callback)
                callback();

        };

        // Perform seek
        seekToFrame(findFrame(0, frames.length - 1, position), seekCallback);

    };

    /**
     * Cancels the current seek operation, setting the current frame of the
     * recording to wherever the seek operation was able to reach prior to
     * being cancelled. If a callback was provided to seek(), that callback
     * is invoked. If a seek operation is not currently underway, this
     * function has no effect.
     */
    this.cancel = function cancel() {
        if (seekCallback) {
            abortSeek();
            seekCallback();
        }
    };

    /**
     * Pauses playback of the recording, if playback is currently in progress.
     * If playback is not in progress, this function has no effect. If a seek
     * operation is in progress, the seek is aborted. Playback is initially
     * paused when a Guacamole.SessionRecording is created, and must be
     * explicitly started through a call to play().
     */
    this.pause = function pause() {

        // Abort any in-progress seek / playback
        abortSeek();

        // Stop playback only if playback is in progress
        if (recording.isPlaying()) {

            // Notify that playback is stopping
            if (recording.onpause)
                recording.onpause();

            // Playback is stopped
            startVideoTimestamp = null;
            startRealTimestamp = null;

        }

    };

};

/**
 * A single frame of Guacamole session data. Each frame is made up of the set
 * of instructions used to generate that frame, and the timestamp as dictated
 * by the "sync" instruction terminating the frame. Optionally, a frame may
 * also be associated with a snapshot of Guacamole client state, such that the
 * frame can be rendered without replaying all previous frames.
 *
 * @private
 * @constructor
 * @param {!number} timestamp
 *     The timestamp of this frame, as dictated by the "sync" instruction which
 *     terminates the frame.
 *
 * @param {!number} start
 *     The byte offset within the blob of the first character of the first
 *     instruction of this frame.
 *
 * @param {!number} end
 *     The byte offset within the blob of character which follows the last
 *     character of the last instruction of this frame.
 */
Guacamole.SessionRecording._Frame = function _Frame(timestamp, start, end) {

    /**
     * Whether this frame should be used as a keyframe if possible. This value
     * is purely advisory. The stored clientState must eventually be manually
     * set for the frame to be used as a keyframe. By default, frames are not
     * keyframes.
     *
     * @type {!boolean}
     * @default false
     */
    this.keyframe = false;

    /**
     * The timestamp of this frame, as dictated by the "sync" instruction which
     * terminates the frame.
     *
     * @type {!number}
     */
    this.timestamp = timestamp;

    /**
     * The byte offset within the blob of the first character of the first
     * instruction of this frame.
     *
     * @type {!number}
     */
    this.start = start;

    /**
     * The byte offset within the blob of character which follows the last
     * character of the last instruction of this frame.
     *
     * @type {!number}
     */
    this.end = end;

    /**
     * A snapshot of client state after this frame was rendered, as returned by
     * a call to exportState(), serialized as JSON, and stored within a Blob.
     * Use of Blobs here is required to ensure the browser can make use of
     * larger disk-backed storage if the size of the recording is large. If no
     * such snapshot has been taken, this will be null.
     *
     * @type {Blob}
     * @default null
     */
    this.clientState = null;

};

/**
 * A read-only Guacamole.Tunnel implementation which streams instructions
 * received through explicit calls to its receiveInstruction() function.
 *
 * @private
 * @constructor
 * @augments {Guacamole.Tunnel}
 */
Guacamole.SessionRecording._PlaybackTunnel = function _PlaybackTunnel() {

    /**
     * Reference to this Guacamole.SessionRecording._PlaybackTunnel.
     *
     * @private
     * @type {!Guacamole.SessionRecording._PlaybackTunnel}
     */
    var tunnel = this;

    this.connect = function connect(data) {
        // Do nothing
    };

    this.sendMessage = function sendMessage(elements) {
        // Do nothing
    };

    this.disconnect = function disconnect() {
        // Do nothing
    };

    /**
     * Invokes this tunnel's oninstruction handler, notifying users of this
     * tunnel (such as a Guacamole.Client instance) that an instruction has
     * been received. If the oninstruction handler has not been set, this
     * function has no effect.
     *
     * @param {!string} opcode
     *     The opcode of the Guacamole instruction.
     *
     * @param {!string[]} args
     *     All arguments associated with this Guacamole instruction.
     */
    this.receiveInstruction = function receiveInstruction(opcode, args) {
        if (tunnel.oninstruction)
            tunnel.oninstruction(opcode, args);
    };

};