/*
 * Copyright (C) 2012 Google 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.
 * 3. Neither the name of Google Inc. nor the names of its contributors
 *    may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER OR 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.
 */

[
    Conditional=MEDIA_STREAM,
    ActiveDOMObject,
    Constructor(in Dictionary rtcIceServers, in [Optional] Dictionary mediaConstraints),
    ConstructorRaisesException,
    CallWith=ScriptExecutionContext,
    EventTarget
] interface RTCPeerConnection {
    void createOffer(in [Callback] RTCSessionDescriptionCallback successCallback, in [Callback,Optional=DefaultIsUndefined] RTCErrorCallback failureCallback, in [Optional] Dictionary mediaConstraints)
        raises(DOMException);

    void createAnswer(in [Callback] RTCSessionDescriptionCallback successCallback, in [Callback, Optional=DefaultIsUndefined] RTCErrorCallback failureCallback, in [Optional] Dictionary mediaConstraints)
        raises(DOMException);

    void setLocalDescription(in RTCSessionDescription description, in [Callback, Optional=DefaultIsUndefined] VoidCallback successCallback, in [Callback, Optional=DefaultIsUndefined] RTCErrorCallback failureCallback)
        raises(DOMException);
    readonly attribute RTCSessionDescription localDescription
        getter raises(DOMException);

    void setRemoteDescription(in RTCSessionDescription description, in [Callback, Optional=DefaultIsUndefined] VoidCallback successCallback, in [Callback, Optional=DefaultIsUndefined] RTCErrorCallback failureCallback)
        raises(DOMException);
    readonly attribute RTCSessionDescription remoteDescription
        getter raises(DOMException);

    // DEPRECATED
    readonly attribute DOMString readyState;

    readonly attribute DOMString signalingState;

    void updateIce(in [Optional] Dictionary configuration, in [Optional] Dictionary mediaConstraints)
        raises(DOMException);

    void addIceCandidate(in RTCIceCandidate candidate)
        raises(DOMException);

    readonly attribute DOMString iceGatheringState;
    readonly attribute DOMString iceConnectionState;

    sequence<MediaStream> getLocalStreams();
    sequence<MediaStream> getRemoteStreams();

    [StrictTypeChecking] void addStream(in MediaStream stream, in [Optional] Dictionary mediaConstraints)
        raises(DOMException);
    [StrictTypeChecking] void removeStream(in MediaStream stream)
        raises(DOMException);

    void getStats(in [Callback] RTCStatsCallback successCallback, in [Optional=DefaultIsUndefined] MediaStreamTrack selector);

    RTCDataChannel createDataChannel(in [TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString label, in [Optional] Dictionary options)
         raises(DOMException);

    RTCDTMFSender createDTMFSender(in MediaStreamTrack track)
         raises(DOMException);

    void close()
        raises(DOMException);

    attribute EventListener onnegotiationneeded;
    attribute EventListener onicecandidate;
    attribute EventListener onstatechange;
    attribute EventListener onaddstream;
    attribute EventListener onremovestream;
    attribute EventListener ongatheringchange;
    attribute EventListener onicechange;
    attribute EventListener ondatachannel;

    // EventTarget interface
    void addEventListener(in DOMString type,
                          in EventListener listener,
                          in [Optional] boolean useCapture);
    void removeEventListener(in DOMString type,
                             in EventListener listener,
                             in [Optional] boolean useCapture);
    boolean dispatchEvent(in Event event)
        raises(EventException);
};

