/client/src/ChatClient.js
enyo.kind({
    name: "ChatClient",
    kind: "Control",
    loggedIn: false,
    components: [
        {name: "mainPanels", kind: "Panels", arrangerKind: "CollapsingArranger", style: "height: 100%", components: [
            {name: "picker", kind: "Picker", onConversationSwitched: "conversationSwitched"},
            {name: "conversation", kind: "Conversation", classes: "panel-shadow"},
        ]},
        {name: "loginDialog", kind: "LoginDialog", onTryLogin: "tryLogin"},
        {kind: "Signals",
         onStartLogin: "startLogin",
         onStartLogout: "startLogout",
         onMessageSent: "messageSent"}
    ],
    create: function() {
        this.inherited(arguments);
    },
    socketSetup: function() {
        this.socket.onopen = function(event) {
            enyo.log('WebSocket open');
            this.ws_send_login(this.$.loginDialog.getData().password);
        }.bind(this);

        this.socket.onmessage = function(e) {
            try {
                var data = JSON.parse(e.data);
            } catch(e) {
                enyo.log('Malformed message: ' + e.data);
                return;
            }
            switch (data.type) {
            case 'login-successful':
                enyo.Signals.send('onLoginSuccessful', {
                    username: this.jid
                });
                this.ws_send('get-roster');
                break;

            case 'login-failed':
                enyo.Signals.send('onLoginFailed');
                break;

            case 'roster':
                this.$.picker.setRoster(data.contacts);
                break;

            case 'message':
                var mobj = {
                    jid: data.from,
                    message: data.body,
                    receivedTimestamp: (new Date()).getTime(),
                    outbound: false
                };
                conversationStore.appendConversation(data.from, mobj);
                enyo.Signals.send('onMessageReceived', mobj);
                this.$.picker.updateConversationList();
                break;

            case 'presence':
                this.$.picker.setPresence(data);
                break;

            case 'disconnect':
                enyo.Signals.send('onLogout');
                enyo.log('logged out');
                break;

            case 'error':
                socket.close();
                setTimeout(this.socketSetup.bind(this), 1000);
                break;
            }
        }.bind(this);
    },
    ws_send: function(type, args) {
        var d = {
            type: type
        };
        for (var i in args) {
            d[i] = args[i];
        }
        this.socket.send(JSON.stringify(d));
    },
    ws_send_login: function(password) {
        this.ws_send('login', {
            password: password
        });
    },
    startLogin: function(inSender, inEvent) {
        this.$.loginDialog.reset();
        this.$.loginDialog.show();
    },
    startLogout: function(inSender, inEvent) {
        this.ws_send('logout');
        this.socket.close();
        this.socket = null;
    },
    tryLogin: function(inSender, inEvent) {
        console.log('attempting login');
        var logindata = this.$.loginDialog.getData();
        this.jid = logindata.username;
        
        if (this.socket) {
            this.socket.close();
        }
        this.socket = new WebSocket('ws://' + location.host + '/chatnoir/ws/' + logindata.username);
        this.socketSetup();
    },
    messageSent: function(inSender, inEvent) {
        this.ws_send('message', {
            to: inEvent.jid,
            body: inEvent.message,
        });
        this.$.picker.updateConversationList();
    },
    conversationSwitched: function(inSender, inEvent) {
        this.$.conversation.setJid(inEvent.jid);
        this.$.conversation.setName(inEvent.name);
        if (enyo.Panels.isScreenNarrow()) {
            this.$.mainPanels.setIndex(1);
        }
    }
});