class NetworkConnection {

    constructor(game)
    {
        this.game = game;
        this.socket = null;
        this.callbacks = [];
        this.listeners = [];
        this.nextMessageID = 1;

        this.onConnected = null;
        this.onClosed = null;
        this.connected = false;
    }

    connect(serverAddress)
    {
        var network = this;
        this.socket = new WebSocket(serverAddress);

        this.socket.onopen = function()
        {
            network.connected = true;
            if (network.onConnected != null) network.onConnected();
        }

        this.socket.onmessage = function(e)
        {
            var json = JSON.parse(e.data);
            var message = new NetworkMessage(network, json);
            network.processMessage(message);
        }

        this.socket.onclose = function()
        {
            network.connected = false;
            if (network.onClosed != null) network.onClosed();
        }

        this.addListener(this, 'error', function(message) {
            alert("ERROR: " + message.getParam('error'));
        });
    }

    addListener(obj, action, callback)
    {
        if (!this.listeners[action]) this.listeners[action] = new Action();
        this.listeners[action].addListener(obj, callback);
    }

    removeListener(obj, action)
    {
        if (!this.listeners[action]) return;
        this.listeners[action].removeListener(obj);
    }

    removeListeners(action)
    {
        if (!this.listeners[action]) return;
        this.listeners[action].clear();
    }

    sendMessage(message, callback)
    {
        if (callback)
        {           
            var message_id = this.nextMessageID;
            message.setMessageID(this.nextMessageID);
            this.nextMessageID++;

            if (!this.callbacks[message_id]) this.callbacks[message_id] = [];
            this.callbacks[message_id].push(callback);
        }
        var str = message.toString();
        this.socket.send(str);
    }

    processMessage(message)
    {
        // see if there's a specific callback for this message
        var message_id = message.getMessageID();
        if (message_id > 0 && this.callbacks[message_id])
        {
            for (var i = 0; i < this.callbacks[message_id].length; i++)
            {
                this.callbacks[message_id][i](message);
            }
            delete this.callbacks[message_id];
        }

        // pass the message to any listeners
        var action = message.getAction();
        if (action && this.listeners[action])
        {
            this.listeners[action].call(message);
        }
    }

}
