/*
 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

WI.BreakpointAction = class BreakpointAction
{
    constructor(breakpoint, type, data)
    {
        console.assert(breakpoint instanceof WI.Breakpoint);
        console.assert(Object.values(WI.BreakpointAction.Type).includes(type));

        this._breakpoint = breakpoint;
        this._type = type;
        this._data = data || null;
        this._id = WI.debuggerManager.nextBreakpointActionIdentifier();
    }

    // Import / Export

    static fromJSON(json, breakpoint)
    {
        return new BreakpointAction(breakpoint, json.type, json.data);
    }

    toJSON()
    {
        let json = {
            type: this._type,
        };
        if (this._data)
            json.data = this._data;
        return json;
    }

    // Public

    get breakpoint() { return this._breakpoint; }
    get id() { return this._id; }
    get type() { return this._type; }

    get data()
    {
        return this._data;
    }

    set data(data)
    {
        if (this._data === data)
            return;

        this._data = data;

        this._breakpoint.breakpointActionDidChange(this);
    }

    toProtocol()
    {
        let json = this.toJSON();
        json.id = this._id;
        return json;
    }
};

WI.BreakpointAction.Type = {
    Log: "log",
    Evaluate: "evaluate",
    Sound: "sound",
    Probe: "probe"
};
