﻿Networker.ChannelClient = {
    initialize: function(userSession) {
        try {
            if (!((jQuery.browser.msie || jQuery.browser.opera) && Networker.MasterDomain == 'localhost')) {
                document.domain = Networker.MasterDomain;
            }
        } catch (ex) {
            Networker.LogError("Failed to set domain for bridge 2: " + Networker.formatException(ex) + " - to " + Networker.MasterDomain);
        }

        try {
            Networker.ChannelClient.initializationAttempts++;
            Networker.ChannelClient.userSession = userSession;
            var frame = $("<iframe id='CommunicationFrame' style='width:0px; height:0px; border: 0px' src='" + (Networker.ChannelServerUrl + "/iframe") + "'></iframe>");
            $(document.body).append(frame);
            frame.load(function() {
                Networker.ChannelClient.bridgeFrameLoaded = true;
            });

        } catch (ex) {
            Networker.LogError("Failed to initialize chat 2: " + Networker.formatException(ex) + " attempt: " + Networker.ChannelClient.initializationAttempts + " iframe is: " + Networker.ChannelServerUrl);
        }

        setTimeout(function() {
            if (Networker.ChannelClient.bridgeLoaded == false) {
                if (Networker.ChannelClient.initializationAttempts > 3) {
                    Networker.LogError("Failed to initialize chat bridge after 3 attempts, frameLoaded: " + Networker.ChannelClient.bridgeFrameLoaded + " requests completed: " + Networker.ChannelClient.requestsCompleted + " iframe is: " + Networker.ChannelServerUrl);
                    return;
                }
                $("#CommunicationFrame").remove();
                Networker.ChannelClient.initialize(userSession);
            }
        }, 1000 * 10);
    },

    updateChannels: function(data) {
        try {
            Networker.ChannelClient.requestsCompleted++;
            var controlChannelData = null;
            for (var channelIndex in data) {
                if (data.hasOwnProperty(channelIndex)) {
                    var channelData = data[channelIndex];
                    if (channelData) {
                        var channel = Networker.ChannelClient.channels[channelData[0]];
                        if (channel && channel.ready) {
                            if (channelData[0] == Networker.ChannelClient.userSession) {
                                controlChannelData = channelData[1];
                            } else {
                                channel.update(channelData[1]);
                            }
                        }
                    }
                }
            }
            // Update the control channel last
            if (controlChannelData) {
                Networker.ChannelClient.channels[Networker.ChannelClient.userSession].update(controlChannelData);
            }
        } catch (ex) {
            Networker.LogError("Failure in update handler: " + Networker.formatException(ex));
        }
    },

    leaveAllChannels: function() {
        for (var channelIndex in Networker.ChannelClient.channels) {
            Networker.ChannelClient.channels[channelIndex].leaveChannel();
        }
    },

    error: function(XMLHttpRequest, textStatus, errorThrown) {
        if (typeof (console) != typeof (undefined)) {
            console.log("ChannelClient failure: " + errorThrown);
        }
    },

    channels: Array,
    requestsCompleted: 0,
    bridgeLoaded: false,
    bridgeFrameLoaded: false,
    initializationAttempts: 0
};

function ChannelHandler(channelId) {
    this.sequence = 0;
    this.channelId = channelId;
    this.ready = false;
    this.update = function(messages) {
        var requestedSequence = this.sequence;
        for (var messageIndex in messages) {
            var message = messages[messageIndex];
            var sequence = message[1];
            if (sequence > this.sequence || sequence < requestedSequence) {
                this.processMessage(message[0], sequence, message[2], requestedSequence);
                this.sequence = sequence;
            }
        }
    };
}