/*
    Message builder for communicating over the websocket
 */
(function(context, $) {

    "use strict";

    context.JK = context.JK || {};

    var msg = context.JK.MessageType = {
        LOGIN                     : "LOGIN",
        LOGIN_ACK                 : "LOGIN_ACK",
        LOGIN_MUSIC_SESSION       : "LOGIN_MUSIC_SESSION",
        LOGIN_MUSIC_SESSION_ACK   : "LOGIN_MUSIC_SESSION_ACK",
        FRIEND_SESSION_JOIN       : "FRIEND_SESSION_JOIN",
        MUSICIAN_SESSION_JOIN     : "MUSICIAN_SESSION_JOIN",
        MUSICIAN_SESSION_DEPART   : "MUSICIAN_SESSION_DEPART",
        LEAVE_MUSIC_SESSION       : "LEAVE_MUSIC_SESSION",
        LEAVE_MUSIC_SESSION_ACK   : "LEAVE_MUSIC_SESSION_ACK",
        HEARTBEAT                 : "HEARTBEAT",
        HEARTBEAT_ACK             : "HEARTBEAT_ACK",
        FRIEND_UPDATE             : "FRIEND_UPDATE",
        SESSION_INVITATION        : "SESSION_INVITATION",
        JOIN_REQUEST              : "JOIN_REQUEST",
        FRIEND_REQUEST            : "FRIEND_REQUEST",
        FRIEND_REQUEST_ACCEPTED   : "FRIEND_REQUEST_ACCEPTED",
        TEST_SESSION_MESSAGE      : "TEST_SESSION_MESSAGE",
        PING_REQUEST              : "PING_REQUEST",
        PING_ACK                  : "PING_ACK",
        PEER_MESSAGE              : "PEER_MESSAGE",
        SERVER_BAD_STATE_RECOVERED: "SERVER_BAD_STATE_RECOVERED",
        SERVER_GENERIC_ERROR      : "SERVER_GENERIC_ERROR",
        SERVER_REJECTION_ERROR    : "SERVER_REJECTION_ERROR",
        SERVER_BAD_STATE_ERROR    : "SERVER_BAD_STATE_ERROR"
    };

    var route_to = context.JK.RouteToPrefix = {
        CLIENT   : "client",
        SESSION  : "session",
        SERVER   : "server",
        USER     : "user"
    };

    var factory = {};

    function client_container(type, target, inner) {
        var type_field = type.toLowerCase();
        var body = { "type" : type, "route_to" : target};
        body[type_field] = inner;
        return body;
    }

    function route_to_client(client_id) {
        return route_to.CLIENT + ":" + client_id;
    }

    function route_to_session(session_id) {
        return route_to.SESSION + ":" + session_id;
    }

    // ping the provided client_id
    factory.ping = function(client_id) {
        var data = {};
        return client_container(msg.PING_REQUEST, route_to_client(client_id), data);
    };

    // Heartbeat message
    factory.heartbeat = function() {
        var data = {};
        return client_container(msg.HEARTBEAT, route_to.SERVER, data);
    };

    // create a login message using user/pass
    factory.login_with_user_pass = function(username, password) {
        var login = { username : username , password : password };
        return client_container(msg.LOGIN, route_to.SERVER, login);
    };

    // create a login message using token (a cookie or similiar)
    // reconnect_music_session_id is an optional argument that allows the session to be immediately associated
    // with a music session.
    factory.login_with_token = function(token, reconnect_music_session_id) {
	//context.JK.logger.debug("*** login_with_token: client_id = "+$.cookie("client_id"));
        var login = { token : token,
		      client_id : $.cookie("client_id")
		    };
        return client_container(msg.LOGIN, route_to.SERVER, login);
    };

    // create a music session login message
    factory.login_music_session = function(music_session) {
        var login_music_session = { music_session : music_session };
        return client_container(msg.LOGIN_MUSIC_SESSION, route_to.SERVER, login_music_session);
    };

    // client-to-client message
    factory.client_p2p_message = function(sender_client_id, receiver_client_id, message) {
        var peer_message = { "message" : message };
        var result = client_container(msg.PEER_MESSAGE, route_to_client(receiver_client_id), peer_message);
        result.from = sender_client_id;
        return result;
    };

    context.JK.MessageFactory = factory;

})(window, jQuery);