﻿
var global_DefaultSchema = "http://www.SimpleConnexion.com/basic/1.0";
/*
SimpleConnection handles the connection with the server
it contains a MessageQueue, a MessageListeners and the following methods

*/
function SimpleConnection() {
    this._instanceName = null;
    this.messageSequenceID = 0;
    this.sessionId = null;
    this.userId = null;
    this.sending = false;
    this.started = false;
    this.connectStatus = false; // true = connected to the server, false = not connected to the server
    this.searchingNewUser = false;
    this.discussionStatus = 0; // 0 = not in discussion, 1 = in discussion
    this.discussionId = null;
    this.timerId = -1;
    this.errorCount = 0;
    this.totalErrorCount = 0;
    this.peerNickname = "Stranger";
    this.yourProfile = null; // holds an object containing your profile data
    this.peerProfile = null; // holds an object containing peer profile data
    this.isLoggedIn = false; // tells if the user logged in or not
    this.autoLatitude = 0;
    this.autoLongitude = 0;
    this.messageQueue = new MessageQueue(this); // outgoing message queue
    this.incomeMessageQueue = new MessageQueue(this);
    this.messageListeners = new MessageListeners(this);
    this.loggedin = new EventListeners(this);
    this.connected = new EventListeners(this);
    this.disconnected = new EventListeners(this);
    this.discussionChanged = new EventListeners(this);
    this.beforeSending = new  EventListeners(this); // tells listeners that messages are about to be sent
    this.requestCache = new Hashmap();
    this.contactsManager = new ContactsManager(this);
    this.mailDiscussionManager = new MailDiscussionManager(this);
    this.groupsManager = new GroupsManager(this);
    this.streamManager = new StreamManager(this);

    
    SimpleConnection_InternalInit(this);
}

SimpleConnection.prototype = {
    postMessageObject: SimpleConnection_PostMessageObject,
    postMessage: SimpleConnection_PostMessage,
    postAliveMessage: function(){
        var m = createAliveMessage();
        this.messageQueue.enqueue(m.toXml());
    },
    
    postConnectMessage: function(){
        var m = createConnectMessage(0, null, this.autoLatitude ,this.autoLongitude);
        this.messageQueue.enqueue(m.toXml());
    },
    
    send: SimpleConnection_Send,
    handleReceivedMessage: SimpleConnection_HandleReceivedMsg,
    connectionError: SimpleConnection_HandleConnectionError,
    start: SimpleConnection_Start,
    stop: SimpleConnection_Stop,
    run: SimpleConnection_Run,
    onNoMessage: SimpleConnection_OnNoMessage,
    
    searchNewUser: function(trgCypheredUUID) {
        var m = createNewChatMessage(this.userId);
        this.searchingNewUser = true;
//        var str = "<msg type='newchat' ";
//        if (typeof (trgCypheredUUID) != "undefined" && trgCypheredUUID != null && trgCypheredUUID != "") {
//            this.searchingNewUser = false;
//            str += "trgUUID='"+trgCypheredUUID+"'";
//        }
//        str += "/>";
        
        if(this.discussionStatus == 1){
            this.discussionId = null;
            this.discussionStatus = 0;
            this.discussionChanged.fireEvent({ status: 'ended' });
        }
        
        this.postMessageObject(m);
    },
    
    stopChat: function(){
        if(this.discussionStatus == 1){
            var m = createStopChatMessage(this.nextMessageID(), this.discussionId);
            this.postMessageObject(m);
        }
    },
    
    stopSearch: function(){
        if(this.discussionStatus == 0 && this.searchingNewUser == true){
            this.searchingNewUser = false;
            var m = createStopSearchMessage(this.nextMessageID());
            this.postMessageObject(m);
        }
    },
    
    preprocessMessage: SimpleConnection_PreprocessMessage,
   
    nextMessageID:function(){
        return ++this.messageSequenceID;
    },
    
    isConnected:function(){
        return this.userId != null && this.connectStatus;
    },

    isMiniProfileFilled:function() {
        if(this.yourProfile == null) return false;
        if(this.yourProfile.nickName == null || this.yourProfile.nickName == "") return false;
        if (this.yourProfile.gender == null || this.yourProfile.gender == "" || "MF".indexOf(this.yourProfile.gender) == -1) return false;
        if(this.yourProfile.ageRange == null || this.yourProfile.ageRange == "") return false;
        if(this.yourProfile.professionid == null || this.yourProfile.professionid == "") return false;
        if(this.yourProfile.loc_lat == null || this.yourProfile.loc_lat == "" || this.yourProfile.loc_lat == "0") return false;
        if(this.yourProfile.loc_lng == null || this.yourProfile.loc_lng == "" || this.yourProfile.loc_lng == "0") return false;

        return true;	
    }
};

function SimpleConnection_InternalInit(con) {
    var defaultSchema = "http://www.SimpleConnexion.com/basic/1.0";
    con.messageListeners.addListener(new MessageListener("msg2", "response", "connect", defaultSchema, internalHandleConnectResponse));
    con.messageListeners.addListener(new MessageListener("msg2", "notify", "chatstart", defaultSchema, internalHandleChatNotify));
    con.messageListeners.addListener(new MessageListener("msg2", "notify", "chatend", defaultSchema, internalHandleChatNotify));
    con.messageListeners.addListener(new MessageListener("msg2", "response", "chatend", defaultSchema, internalHandleChatNotify));
}


function SimpleConnection_PostMessage(xmlMessage) {
    this.messageQueue.enqueue(xmlMessage);
}

function SimpleConnection_PostMessageObject(messageObject, callbackFunc) {
    if(this.isConnected()){ // post messages only if connected
        if(messageObject.id > 0 && typeof(callbackFunc) != "undefined" && callbackFunc != null){
            this.requestCache.set(messageObject.id, messageObject, callbackFunc);
        }
        this.messageQueue.enqueue(messageObject.toXml());
        return true;
    }
    return false;
}

function SimpleConnection_Send() {
    var _connection = this;
    var emptyPacket = true;
    if (this.sending) {
        return;
    }
    this.sending = true;
    this.beforeSending.fireEvent({"userid":this.userId,});

    try {
        var referer = j$("#fldReferer").val();
        var xml = "<msgenv src='" + this.userId + "'" + " session='" + this.sessionId + "'" 
        if (referer != null && referer != "") {
            xml += " referer='" + encodeXml(referer) + "'"
        }
        xml += ">";

        if (this.messageQueue.getCount() == 0 && this.isConnected()) {
            this.onNoMessage();
        }
        
        while (this.messageQueue.getCount() > 0) {
                var strMsg = this.messageQueue.dequeue();
                xml += strMsg;
                emptyPacket = false;
        } 

        xml += "</msgenv>";
        //xml = escape(xml);
        if(!emptyPacket){ // don't send any packet over the wire if it does not contain any message
            var req = new jQuery.ajax({url:'handler.aspx',
                    
                        contentType: 'application/xml',
                        type: 'POST',
                        success: function msgReceived(data, textStatus, XMLHttpRequest /*transport*/) {
                            // because this is a callback function called by an external thread
                            // calls must be synchronized.
                            //so all messages will be pushed into incomeMessageQueue
                            // then a call to the handler (SimpleConnection_HandleReceivedMsg) is
                            // queued to the current thread by using setTimeout with delay 0
                            // the name of the connection (_connection._instanceName) is passed to the handler
                            // so it can retreive a reference to the current connection
                            _connection.incomeMessageQueue.enqueue(data/*transport*/);
                            _connection.errorCount = 0;
                            setTimeout("SimpleConnection_HandleReceivedMsg('" + _connection._instanceName + "');", 0);
                        },
                        data: xml,
                        error: function(XMLHttpRequest, textStatus, errorThrown) {
                            _connection.errorCount++;
                            _connection.totalErrorCount++;
                            setTimeout("SimpleConnection_HandleConnectionError('" + _connection._instanceName + "');", 0);
                            //_connection.connectionError(); 
                        }
                    });
        }
    } finally {
        this.sending = false;
    }
}

function SimpleConnection_HandleReceivedMsg(instanceName) {
    var transport = null;
    var _this = window[instanceName];
//    if (_this.incomeMessageQueue.getCount() > 0) {
//        transport = _this.incomeMessageQueue.dequeue();
    //    }
    while (_this != null && _this.incomeMessageQueue.getCount() > 0) {
        transport = _this.incomeMessageQueue.dequeue();
        if (transport != null && transport != "" && transport.responseText != "") {
            var obj = jQuery.parseJSON(transport); //transport.responseText.evalJSON();
            //var obj = transport.evalJSON();
            var type = obj.type.toLowerCase();
            if (type == "registered") {
                _this.userId = obj.userid;
                _this.connected.fireEvent({"userid":_this.userId, "isLoggedIn": _this.isLoggedIn,});
            } else if (obj.type == "messages") {
                if (typeof (obj.messages) != "undefined" && obj.messages.length > 0) {
                    for (var i = 0; i < obj.messages.length; i++) {
                        //if (typeof (obj.messages[i]) != "undefined")
                         {
                            _this.preprocessMessage(obj.messages[i]);
                            
                            // check if there are pending requests in the cache waiting to get responses
                            var handled = false;
                            if(typeof(obj.messages[i].requestid) != "undefined" && obj.messages[i].requestid != null){
                                var index = _this.requestCache.findIndex(obj.messages[i].requestid);
                                if(index > -1){
                                    var reqMsg = _this.requestCache.getValue(index);
                                    var cbfunc = _this.requestCache.getObject(index);
                                    _this.requestCache.removeAt(index);
                                    // if the cached request provided a call back function then
                                    // call it and pass the request and response messages to it
                                    // the function must return true if the message is handled, false otherwise
                                    if(cbfunc != null){
                                        handled = cbfunc(reqMsg, obj.messages[i]);
                                    }
                                }
                            }
                            // fire messageReceived events and tell the listeners if the response has been handled by the callback function
                            _this.messageListeners.fireMessageReceived(obj.messages[i], handled);
                        }
                    }
                }
            }
        }
    }
}

function SimpleConnection_PreprocessMessage(msg){
    if(msg.tagName == "msg"){
        if (msg.type == "NewChat") {
            this.searchingNewUser = false;
            this.discussionStatus = 1;
            this.discussionChanged.fireEvent({ status: 'new' });
        } else if (msg.type == "PeerLeft" || msg.type == "Paused") {
            this.discussionStatus = 0;
            this.discussionChanged.fireEvent({ status: 'closed' });
            this.peerProfile = null;
        }
    }
}

function SimpleConnection_HandleConnectionError(instanceName) {

    var _this = window[instanceName];
    if (_this.started && _this.errorCount > 10) {
        _this.started = false;
        clearInterval(_this.timerId);
        if (g_dispMsg != null) {
            g_dispMsg.writeHtml(g_tr.connection_err, "DisplayMessageLine_ServerNotifError");
        }
    }
}

function SimpleConnection_OnNoMessage() {
    this.postAliveMessage();
}

function SimpleConnection_Start() {
    if (!this.started) {
        if(typeof(window.simpleConnection_Count) =="undefined"){
            window.simpleConnection_Count = 0;
        }
        window.simpleConnection_Count++;
        var strThis = "_simpleConnect_this_" + window.simpleConnection_Count;
        window[strThis] = this;
        this._instanceName = strThis;
        
        this.postConnectMessage()
        //this.postMessage("<msg type='Register'/>");
        this.timerId = setInterval("window." + strThis + ".run();", 750);
        this.started = true;
    }
}

function SimpleConnection_Run() {
    this.send();
}


function SimpleConnection_Stop() {
    if (this.started) {
        if (this.userId != null) {
            var msg = createQuitMessage(this.nextMessageID());
            this.postMessageObject(msg);
            this.send();
        }
        if (this._instanceName != null) {
            if (typeof (window[this._instanceName]) != "undefined") {
                window[this._instanceName] = undefined;
                //eval("delete window."+this._instanceName);
            }
        }
        clearInterval(this.timerId);
        this.disconnected.fireEvent(this.userId);
        this._instanceName = null;
        this.isLoggedIn = false;
        this.userId = null;
        this.sessionId = null;
        this.sending = false;
        this.started = false;
        this.searchingNewUser = false;
        this.timerId = -1;
        this.yourProfile = null;
        this.peerProfile = null;
        this.discussionId = null;
        this.connectStatus = false;
        this.messageQueue.clear();
    }
}


function internalHandleConnectResponse(sender, msg){
    if(msg.success == "1"){
        sender.userId =  msg.properties.userid;
        sender.sessionId = msg.properties.sessionid;
        sender.isLoggedIn = msg.properties.signedin == "true";
        sender.connectStatus = true;
        sender.connected.fireEvent({"userid":sender.userId, "isLoggedIn": sender.isLoggedIn,});
    }else{
        sender.connectStatus = false;
        alert("Error: " + msg.errcode + ", " + msg.errmsg);
    }
}


function internalHandleChatNotify(sender, msg){
    if(msg.command == "chatstart"){
        sender.discussionId = msg.properties.discussionid;
        sender.discussionStatus = 1;
        sender.discussionChanged.fireEvent({ status: 'started' });
    }else
    if(msg.command == "chatend"){
        sender.discussionStatus = 0;
        sender.discussionId = null;
        sender.peerProfile = null
        var _initiator = "you";
        if(msg.type == "notify"){
            _initiator = "peer";
        }
        sender.discussionChanged.fireEvent({ status: 'ended', initiator:_initiator });
    }
    sender.searchingNewUser = false;
}



