/*
 * 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);

    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();
    MediaStream getStreamById(DOMString streamId);

    [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 onsignalingstatechange;
    attribute EventListener onaddstream;
    attribute EventListener onremovestream;
    attribute EventListener oniceconnectionstatechange;
    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);
};

