/*
 * Copyright (C) 2009 Google Inc.  All rights reserved.
 * Copyright (C) 2010, 2011 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * 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.
 */

module websockets {

    interface [
        Conditional=WEB_SOCKETS,
        ActiveDOMObject,
        CustomConstructor,
        ConstructorParameters=1,
        EventTarget,
        JSNoStaticTables
    ] WebSocket {
        readonly attribute DOMString URL; // Lowercased .url is the one in the spec, but leaving .URL for compatibility reasons.
        readonly attribute DOMString url;

        // ready state
        const unsigned short CONNECTING = 0;
        const unsigned short OPEN = 1;
        const unsigned short CLOSING = 2;
        const unsigned short CLOSED = 3;
        readonly attribute unsigned short readyState;

        readonly attribute unsigned long bufferedAmount;

        // networking
        attribute EventListener onopen;
        attribute EventListener onmessage;
        attribute EventListener onerror;
        attribute EventListener onclose;

        readonly attribute [TreatReturnedNullStringAs=Undefined] DOMString protocol;
        readonly attribute [TreatReturnedNullStringAs=Undefined] DOMString extensions;

        attribute [TreatReturnedNullStringAs=Undefined] DOMString binaryType
            setter raises(DOMException);

        // FIXME: Use overloading provided by our IDL code generator.
        // According to Web IDL specification, overloaded function with DOMString argument
        // should accept anything that can be converted to a string (including numbers,
        // booleans, null, undefined and objects except ArrayBuffer and Blob). Current code
        // generator does not handle this rule correctly.
        // boolean send(in ArrayBuffer data) raises(DOMException);
        // boolean send(in Blob data) raises(DOMException);
        // boolean send(in DOMString data) raises(DOMException);
        [Custom] boolean send(in DOMString data) raises(DOMException);

        // FIXME: Implement and apply [Clamp] attribute instead of [Custom].
        [Custom] void close(in [Optional] unsigned short code, in [Optional] DOMString reason) raises(DOMException);

        // 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 evt)
            raises(EventException);
    };
}
