'use strict';

/**
 * 
 * @author Amir <amirsanni@gmail.com>
 * @date 24-Dec-2016
 */



var servers = {
    iceServers: []
};

var myPC;
var awaitingResponse;
var streamConstraints;
var myMediaStream;
let wsChat;
var recordedChunks = [];
var mediaRecorder = null;

const room = getRoom();


window.addEventListener('load', function(){
    wsChat = new WebSocket(`${wsUrl}/comm`);

    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */

    //startCounter();//shows the time spent in room
    
    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */

    //Get ice servers
    let xhr = new XMLHttpRequest();

    xhr.onreadystatechange = function(e){
        if(xhr.readyState == 4 && xhr.status == 200){
            let iceServers = JSON.parse(xhr.responseText);

            servers.iceServers = [iceServers];
        }
    }

    xhr.open("GET", appRoot+"Server.php", true);
    xhr.send();
    
    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */
    
    //add event listeners to the dial buttons
    var initCallElems = document.getElementsByClassName('initCall');
    
    for (var i = 0; i < initCallElems.length; i++) {
        initCallElems[i].addEventListener('click', initCall);
    }
    
    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */
    
    wsChat.onopen = function(){
        //subscribe to room
        wsChat.send(JSON.stringify({
            action: 'subscribe',
            room: room
        }));
        
        showSnackBar("Connected to the chat server!", 5000);
    };
    
    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */
    
    wsChat.onerror = function(){
        showSnackBar("Unable to connect to the chat server! Kindly refresh", 20000);
    };
    
    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */
    
    wsChat.onmessage = function(e){
        var data = JSON.parse(e.data);
        
        if(data.room === room){
            //above check is not necessary since all messages coming to this user are for the user's current room
            //but just to be on the safe side
            switch(data.action){
                case 'initCall':
                    //launch modal to show that user has a call with options to accept or deny and start ringtone
                    //start ringtone here
                    document.getElementById('calleeInfo').style.color = 'black';
                    document.getElementById('calleeInfo').innerHTML = data.msg;
                    
                    document.getElementById("rcivModal").style.display = 'block';
                    
                    document.getElementById('callerTone').play();
                    
                    //minimise chat pane if it is maximised to prevent it from covering the page on small screens
                    if (!$(".icon_minim").hasClass('panel-collapsed')) {
                        $(".icon_minim").parents('.panel').find('.panel-body').slideUp();
                        $(".icon_minim").addClass('panel-collapsed');
                        $(".icon_minim").removeClass('fa-minus').addClass('fa-plus');
                    }
                    
                    break;
                    
                case 'callRejected':
                    //get response to call initiation (if user is the initiator)
                    //show received message (i.e. reason for rejection) and end call
                    document.getElementById("callerInfo").style.color = 'red';
                    document.getElementById("callerInfo").innerHTML = data.msg;

                    setTimeout(function(){
                        document.getElementById("callModal").style.display = 'none';
                    }, 3000);
                    
                    //stop tone
                    document.getElementById('callerTone').pause();
                    
                    //enable call buttons
                    enableCallBtns();
                    
                    break;
                    
                case 'endCall':
                    //i.e. when the caller ends the call from his end (after dialing and before recipient respond)
                    //End call
                    document.getElementById("calleeInfo").style.color = 'red';
                    document.getElementById("calleeInfo").innerHTML = data.msg;

                    setTimeout(function(){
                        document.getElementById("rcivModal").style.display = 'none';
                    }, 3000);
                    
                    //stop tone
                    document.getElementById('callerTone').pause();
                    
                    break;
                    
                case 'startCall':
                    startCall(false);//to start call when callee gives the go ahead (i.e. answers call)
                    
                    document.getElementById("callModal").style.display = 'none';//hide call modal
                    
                    clearTimeout(awaitingResponse);//clear timeout
                    
                    //stop tone
                    document.getElementById('callerTone').pause();
                    break;

                case 'candidate':
                    //message is iceCandidate
                    myPC ? myPC.addIceCandidate(new RTCIceCandidate(data.candidate)) : "";
                    
                    break;

                case 'sdp':
                    //message is signal description
                    myPC ? myPC.setRemoteDescription(new RTCSessionDescription(data.sdp)) : "";
                    
                    break;

                case 'txt':
                    //it is a text chat
                    addRemoteChat(data.msg, data.date);

                    //play msg tone
                    document.getElementById('msgTone').play();
                    
                    break;

                case 'typingStatus':
                    if(data.status){
                        document.getElementById("typingInfo").innerHTML = "Remote is typing";
                    }
                    
                    else{
                        document.getElementById("typingInfo").innerHTML = "";
                    }
                    
                    break;
                    
                case 'terminateCall'://when remote terminates call (while call is ongoing)
                    handleCallTermination();
                    //play termination tone
                    //document.getElementById('terminationTone').play();
                    break;
                    
                case 'newSub':
                    setRemoteStatus('online');

                    //once the other user joined and current user has been notified, current user should also send a signal
                    //that he is online
                    wsChat.send(JSON.stringify({
                        action: 'imOnline',
                        room: room
                    }));

                    showSnackBar("Remote entered room", 10000);
                    
                    break;
                    
                case 'imOnline':
                    setRemoteStatus('online');
                    break;
                    
                case 'imOffline':
                    setRemoteStatus('offline');
        
                    showSnackBar("Remote left room", 10000);
                    enableCallBtns();
                    break;
            }  
        }
        
        else if(data.action === "subRejected"){
            //subscription on this device rejected cos user has subscribed on another device/browser
            showSnackBar("Maximum of two users allowed in room. Communication disallowed", 5000);
        }
    };
    
    
    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */
    
    //Indicate that user is typing
    document.getElementById("chatInput").addEventListener('keyup', function(){
        var msg = this.value.trim();
        
        //if user is typing
        if(msg){
            wsChat.send(JSON.stringify({
                action: 'typingStatus',
                status: true,
                room: room
            }));
        }
        
        //if no text in input
        else{
            wsChat.send(JSON.stringify({
                action: 'typingStatus',
                status: false,
                room: room
            }));
        }
        
    });
    
    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */
    
    //TO SEND MESSAGE TO REMOTE
    document.getElementById("chatSendBtn").addEventListener('click', function(e){
        e.preventDefault();
        
        var msg = document.getElementById("chatInput").value.trim();
        
        if(msg){
            var date = new Date().toLocaleTimeString();
            
            addLocalChat(msg, date, true);
            
            //clear text
            document.getElementById("chatInput").value = "";
            
            return false;
        }
    });
    
    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */
   
    
    //WHEN ENTER IS PRESSED TO SEND MESSAGE
    document.getElementById("chatInput").addEventListener('keypress', function(e){
        var msg = this.value.trim();

        if ( e.which === 13 && e.ctrlKey && msg ) {
            this.value = `${ this.value }\n`;
        }

        else if ( e.which === 13 && !e.shiftKey && msg ) {
            e.preventDefault();
            document.getElementById( "chatSendBtn" ).click();
        }
    });
    
    
    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */
    
    //WHEN USER CLICKS BTN TO ANSWER CALL
    //add event listener to the answer call buttons
    var answerCallElems = document.getElementsByClassName('answerCall');
    
    for (var i = 0; i < answerCallElems.length; i++) {
        answerCallElems[i].addEventListener('click', answerCall);
    }
    
    
    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */
    
    //TO REJECT CALL
    document.getElementById("rejectCall").addEventListener('click', function(e){
        e.preventDefault();
        
        wsChat.send(JSON.stringify({
            action: 'callRejected',
            msg: "Call rejected by Remote",
            room: room
        }));
        
        document.getElementById("rcivModal").style.display = 'none';
        
        document.getElementById('callerTone').pause();
    });
    
    
    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */
    
    //WHEN THE CALLER CLICK TO END THE CALL
    document.getElementById("endCall").addEventListener('click', function(e){
        e.preventDefault();
        
        endCall("Call ended by remote", false);
        
        //enable call buttons
        enableCallBtns();
    });
    
    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */
    //TO MAXIMISE/MINIMISE THE CHAT PANE
    $('.chat-pane').on('click', '.icon_minim', function (e) {
        var $this = $(this);
        
        if (!$this.hasClass('panel-collapsed')) {
            $this.parents('.panel').find('.panel-body').slideUp();
            $this.addClass('panel-collapsed');
            $this.removeClass('fa-minus').addClass('fa-plus');
        } 
        
        else {
            $this.parents('.panel').find('.panel-body').slideDown();
            $this.removeClass('panel-collapsed');
            $this.removeClass('fa-plus').addClass('fa-minus');
        }
        
        //fix scrollbar to bottom
        fixChatScrollBarToBottom();
    });
    
    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */
    
    //Maximise the chat pane when user focuses on the input and pane is collapsed
    $('.chat-pane').on('focus', '.chat-input', function () {
        var $this = $(this);
        
        if ($('#minim_chat_window').hasClass('panel-collapsed')) {
            $this.parents('.panel').find('.panel-body').slideDown();
            $('#minim_chat_window').removeClass('panel-collapsed');
            $('#minim_chat_window').removeClass('fa-plus').addClass('fa-minus');
            
            //fix scrollbar to bottom
            fixChatScrollBarToBottom();
        }
    });
    
    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */
    
    //WHEN USER CLICKS TO TERMINATE THE CALL
    document.getElementById("terminateCall").addEventListener('click', function(e){
        e.preventDefault();
        
        //close the connection
        myPC ? myPC.close() : "";
        
        //stop media stream
        stopMediaStream();
        
        //remove video playback src
        //$('video').attr('src', appRoot+'img/vidbg.png');
        document.querySelectorAll('video').src = appRoot+'img/vidbg.png';
        
        //inform peer to also end the connection
        wsChat.send(JSON.stringify({
            action: 'terminateCall',
            room: room
        }));
        
        //enable call buttons
        enableCallBtns();
    });
    
    /*
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    ********************************************************************************************************************************
    */

    
    document.getElementById('record').addEventListener('click', (e)=>{
        if(myMediaStream && myMediaStream.getTracks().length){
            if(mediaRecorder && mediaRecorder.state == 'recording'){
                //stop recording
                mediaRecorder.stop();

                e.setAttribute('title', 'Record');
                e.target.classList.remove('btn-danger');
            }

            else{
                //start recording
                mediaRecorder = new MediaRecorder(myMediaStream, {
                    mimeType: 'video/webm;codecs=vp9'
                });
    
                mediaRecorder.start(1000);

                //change the button to reflect that recording has started
                e.setAttribute('title', 'Stop recording');
                e.target.classList.add('btn-danger');
    
                mediaRecorder.ondataavailable = function(e){
                    recordedChunks.push(e.data);
                }
    
                mediaRecorder.onstop = function(){
                    saveRecordedStream(recordedChunks);
    
                    setTimeout(()=>{
                        recordedChunks = [];
                    }, 3000);
                }
    
                mediaRecorder.onerror = function(e){
                    console.error(e);
                }
            }
        }

        else{
            showSnackBar('Nothing to record', 5000);
        }
    });
});

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/
/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/


function initCall(){
    var callType = this.id === 'initVideo' ? "Video" : "Audio";
    var callerInfo = document.getElementById('callerInfo');
        
    //launch calling modal and await receiver's response by sending initCall to him (i.e. receiver)
    if(checkUserMediaSupport){
        //set media constraints based on the button clicked. Audio only should be initiated by default
        streamConstraints = callType === 'Video' ? {video:{facingMode:'user'}, audio:true} : {audio:true};

        //set message to display on the call dialog
        callerInfo.style.color = 'black';
        callerInfo.innerHTML = callType === 'Video' ? 'Video call to Remote' : 'Audio call to Remote';

        //start calling tone
        document.getElementById('callerTone').play();

        //notify callee that we're calling. Don't call startCall() yet
        wsChat.send(JSON.stringify({
            action: 'initCall',
            msg: callType === 'Video' ? "Video call from remote" : "Audio call from remote",
            room: room
        }));

        //disable call buttons
        disableCallBtns();

        //wait for response for 30secs
        awaitingResponse = setTimeout(function(){
            endCall("Call ended due to lack of response", true);
        }, 30000);
    }

    else{
        callerInfo.style.color = 'red';
        callerInfo.innerHTML = "Your browser/device does not have the capability to make call";
    }


    document.getElementById("callModal").style.display = 'block';
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

function answerCall(){
    //check whether user can use webrtc and use that to determine the response to send
    if(checkUserMediaSupport){
        //set media constraints based on the button clicked. Audio only should be initiated by default
        streamConstraints = this.id === 'startVideo' ? {video:{facingMode:'user'}, audio:true} : {audio:true};

        //show msg that we're setting up call (i.e. locating servers)
        document.getElementById("calleeInfo").innerHTML = "<i class='"+spinnerClass+"'></i> Setting up call...";

        //uncomment the lines below if you comment out the get request above
        startCall(true);

        //dismiss modal
        document.getElementById("rcivModal").style.display = 'none';

        //enable the terminateCall btn
        disableCallBtns();

    }

    else{
        //inform caller and current user (i.e. receiver) that he cannot use webrtc, then dismiss modal after a while
        wsChat.send(JSON.stringify({
            action: 'callRejected',
            msg: "Remote's device does not have the necessary requirements to make call",
            room: room
        }));

        document.getElementById("calleeInfo").innerHTML = "Your browser/device does not meet the minimum requirements needed to make a call";

        setTimeout(function(){
            document.getElementById("rcivModal").style.display = 'none';
        }, 3000);
    }

    document.getElementById('callerTone').pause();
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

function startCall(isCaller){
    if(checkUserMediaSupport){
        myPC = new RTCPeerConnection(servers);//RTCPeerconnection obj
        
        //When my ice candidates become available
        myPC.onicecandidate = function(e){
            if(e.candidate){
                //send my candidate to peer
                wsChat.send(JSON.stringify({
                    action: 'candidate',
                    candidate: e.candidate,
                    room: room
                }));
            }
        };
    
        //When remote stream becomes available
        myPC.ontrack = function(e){
            document.getElementById("peerVid").srcObject = e.streams[0];
        };
        
        
        //when remote connection state and ice agent is closed
        myPC.oniceconnectionstatechange = function(){
            switch(myPC.iceConnectionState){
                case 'disconnected':
                case 'failed':
                    console.log("Ice connection state is failed/disconnected");
                    showSnackBar("Call connection problem", 15000);
                    break;
                    
                case 'closed':
                    console.log("Ice connection state is 'closed'");
                    showSnackBar("Call connection closed", 15000);
                    break;
            }
        };
        
        
        //WHEN REMOTE CLOSES CONNECTION
        myPC.onsignalingstatechange = function(){
            switch(myPC.signalingState){
                case 'closed':
                    console.log("Signalling state is 'closed'");
                    showSnackBar("Signal lost", 15000);
                    break;
            }
        };
        
        //set local media
        setLocalMedia(streamConstraints, isCaller);
    }
    
    else{
        showSnackBar("Your browser does not support video call", 30000);
    }
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

function checkUserMediaSupport(){
    return !!(navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

//get and set local media
function setLocalMedia(streamConstraints, isCaller){
    navigator.mediaDevices.getUserMedia(
        streamConstraints
    ).then(function(myStream){
        document.getElementById("myVid").srcObject = myStream;
        
        // myPC.addStream(myStream);//add my stream to RTCPeerConnection
        //add my stream to RTCPeerConnection
        myStream.getTracks().forEach((track)=>{
            myPC.addTrack(track, myStream);
        });
        
        //set var myMediaStream as the stream gotten. Will be used to remove stream later on
        myMediaStream = myStream;
        
        if(isCaller){
            myPC.createOffer().then(description, function(e){
                console.log("Error creating offer", e.message);
                
                showSnackBar("Call connection failed", 15000);
            });
            
            //then notify callee to start call on his end
            wsChat.send(JSON.stringify({
                action: 'startCall',
                room: room
            }));
        }
        
        else{
            //myPC.createAnswer(description);
            myPC.createAnswer().then(description).catch(function(e){
                console.log("Error creating answer", e);
                
                showSnackBar("Call connection failed", 15000);
            });

        }
        
    }).catch(function(e){
        
        switch(e.name){
            case 'SecurityError':
                console.log(e.message);
                
                showSnackBar("Media sources usage is not supported on this browser/device", 10000);
                break;

            case 'NotAllowedError':
                console.log(e.message);
                
                showSnackBar("We do not have access to your audio/video sources", 10000);
                break;
                
            case 'NotFoundError':
                console.log(e.message);
                
                showSnackBar("The requested audio/video source cannot be found", 10000);
                break;
            
            case 'NotReadableError':
            case 'AbortError':
                console.log(e.message);
                showSnackBar("Unable to use your media sources", 10000);
                break;
        }
    });
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

/**
 * 
 * @param {type} msg
 * @param {type} date
 * @returns {undefined}
 */
function addRemoteChat(msg, date){
    new Promise(function(resolve, reject){
        var newNode = document.createElement('div');
        
        newNode.className = "row msg_container base_receive";
        
        return resolve(newNode);
    }).then(function(newlyCreatedNode){
        newlyCreatedNode.innerHTML = `<div class="col-sm-10 col-xs-10">
                <div class="messages msg_receive">
                    <p>${nl2br(msg)}</p>
                    <time>Remote • ${date}</time>
                </div>
            </div>`;
        
        document.getElementById('chats').appendChild(newlyCreatedNode);

        //open the chat just in case it is closed
        document.getElementById("chatInput").focus();

        fixChatScrollBarToBottom();
    });
}


/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

/**
 * 
 * @param {type} msg
 * @param {type} date
 * @param {type} sendToPartner
 * @returns {undefined}
 */
function addLocalChat(msg, date, sendToPartner){
    //if msg is to be sent to partner, (meaning the msg was typed on the current browser), leave the sent status to 'busy' until
    //it is actually sent.
    
    var msgId = randomString(5);//this will be used to change the sent status once it is sent (applicable if we're saving to db)
    
    new Promise(function(resolve, reject){
        var newNode = document.createElement('div');
        
        newNode.className = "row msg_container base_sent";
        
        return resolve(newNode);
    }).then(function(newlyCreatedNode){
        newlyCreatedNode.innerHTML = `<div class="col-sm-10 col-xs-10">
                <div class="messages msg_sent">
                    <p>${nl2br(msg)}</p>
                    <time>You • ${date} <i class="fa fa-clock-o sentStatus" id="${msgId}"></i></time>
                </div>
            </div>`;
        
        document.getElementById('chats').appendChild(newlyCreatedNode);
        
        if(sendToPartner){
            //use this if you just want to send via socket without saving in db
            sendChatToSocket(msg, date, msgId);
        }

        fixChatScrollBarToBottom();
    });
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

/**
 * 
 * @param {type} desc
 * @returns {undefined}
 */
function description(desc){
    myPC.setLocalDescription(desc);

    //send sdp
    wsChat.send(JSON.stringify({
        action: 'sdp',
        sdp: desc,
        room: room
    }));
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

/**
 * 
 * @param {type} msg
 * @param {type} setTimeOut
 * @returns {undefined}
 */
function endCall(msg, setTimeOut){
    wsChat.send(JSON.stringify({
        action: 'endCall',
        msg: msg,
        room: room
    }));

    if(setTimeOut){
        //display message
        document.getElementById("callerInfo").style.color = 'red';
        document.getElementById.innerHTML = "<i class='fa fa-exclamation-triangle'></i> No response";
        
        setTimeout(function(){
            document.getElementById("callModal").style.display = 'none';
        }, 3000);
        
        enableCallBtns();
    }
    
    else{
        document.getElementById("callModal").style.display = 'none';
    }
    
    clearTimeout(awaitingResponse);

    document.getElementById('callerTone').pause();

    //disable the record button
    document.getElementById('record').removeAttribute('disabled');

    stopMediaStream();
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

function fixChatScrollBarToBottom(){
    var msgPane = document.getElementById("chats");
    msgPane.scrollTop = msgPane.scrollHeight;
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

function enableCallBtns(){
    //enable dial btns and disable endcall btn
    var initCallElems = document.getElementsByClassName('initCall');
    
    for(let i = 0; i < initCallElems.length; i++){
        initCallElems[i].removeAttribute('disabled');
    }
    
    document.getElementById('terminateCall').setAttribute('disabled', true);
    document.getElementById('record').setAttribute('disabled', true);
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

function disableCallBtns(){
    //disable dial btns and enable endall btn
    var initCallElems = document.getElementsByClassName('initCall');
    
    for(let i = 0; i < initCallElems.length; i++){
        initCallElems[i].setAttribute('disabled', true);
    }
    
    document.getElementById('terminateCall').removeAttribute('disabled');
    document.getElementById('record').removeAttribute('disabled');
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

function sendChatToSocket(msg, date, msgId){
    wsChat.send(JSON.stringify({
        action: 'txt',
        msg: msg,
        date: date,
        room: room
    }));
    
    //change the sent status to indicate it has been sent
    //$(".sentStatus").last().removeClass('fa-clock-o').addClass('fa-check text-success');
    $("#"+msgId).removeClass('fa-clock-o').addClass('fa-check text-success');
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

function handleCallTermination(){
    myPC ? myPC.close() : "";//close connection as well
                    
    //tell user that remote terminated call
    showSnackBar("Call terminated by remote", 10000);

    //remove streams and free media devices
    stopMediaStream();
    
    //remove video playback src
    $('video').attr('src', appRoot+'img/vidbg.png');

    //enable 'call' button and disable 'terminate call' btn
    enableCallBtns();
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

//set the status of remote (online or offline)
function setRemoteStatus(status){
    if(status === 'online'){
        $("#remoteStatus").css('color', 'green');
        $("#remoteStatusTxt").css({color:'green'}).html("(Online)");
    }
    
    else{
        $("#remoteStatus").css('color', '');
        $("#remoteStatusTxt").css({color:'red'}).html("(Offline)");
    }
}


/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/


function startCounter(){
    var sec = "00";
    var min = "00";
    var hr = "00";
    
    var hrElem = document.querySelector("#countHr");
    var minElem = document.querySelector("#countMin");
    var secElem = document.querySelector("#countSec");
    
    hrElem.innerHTML = hr;
    minElem.innerHTML = min;
    secElem.innerHTML = sec;
        
    setInterval(function(){
        //display seconds and increment it by a sec
        ++sec;
        
        secElem.innerHTML = sec >= 60 ? "00" : (sec < 10 ? "0"+sec : sec);
        
        if(sec >= 60){
            //increase minute and reset secs to 00
            ++min;
            minElem.innerHTML = min < 10 ? "0"+min : min;
            
            sec = 0;
            
            if(min >= 60){
                //increase hr by one and reset min to 00
                ++hr;
                hrElem.innerHTML = hr < 10 ? "0"+hr : hr;
                
                min = 0;
            }
        }
        
    }, 1000);
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

function stopMediaStream(){    
    if(myMediaStream && myMediaStream.getTracks().length){
        myMediaStream.getTracks().forEach(track => track.stop())
    }
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

function showSnackBar(msg, displayTime){
    document.getElementById('snackbar').innerHTML = msg;
    document.getElementById('snackbar').className = document.getElementById('snackbar').getAttribute('class') + " show";
    
    setTimeout(function(){
        $("#snackbar").html("").removeClass("show");
    }, displayTime);
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

/**
 * 
 * @param {type} length
 * @returns {String}
 */
function randomString(length){
    var rand = Math.random().toString(36).slice(2).substring(0, length);
    
    return rand;
}

/*
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
********************************************************************************************************************************
*/

function getRoom(){
    var params = window.location.search.substr(1).split("&");
    
    if(params){
        for(let i = 0; i < params.length; i++){
            var key = params[i].split("=")[0];
            var value = params[i].split("=")[1];
            
            if(key === "room"){
                return value;
            }
        }
    }
    
    else{
        return "";
    }
}



function saveRecordedStream(chunk){
    let blob = new Blob(chunk, {type:'video/webm'});

    let file = new File([blob], `__${moment().unix()}-record.webm`);

    saveAs(file);
}

function nl2br( str, is_xhtml ) {
    if ( typeof str === 'undefined' || str === null ) {
        return '';
    }
    var breakTag = ( is_xhtml || typeof is_xhtml === 'undefined' ) ? '<br />' : '<br>';
    return ( str + '' ).replace( /([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2' );
}
