
// Warning: Please do not make any changes to this file.

function cVaxWebRTC() 
{
    var m_hPeerConnection = null;
    
    var m_hLocalAudioStream = null;
    var m_hLocalVideoStream = null;

    var m_hAudioMediaOut = null;
    var m_hVideoMediaOut = null;

    var m_nLineNo = 0;
        
    var m_sCallerName = '';
    var m_sCallerId = '';
    var m_sDialNo = '';

    var m_sCallId = '';

    //////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////

    var m_hProcOfferCreateSuccessWebRTC = null;
    var m_hProcAnswerCreateSuccessWebRTC = null;
            
    /////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////

    var m_hEventOnAttachedAudioRecvWebRTC = null;
    var m_hEventOnAttachedVideoRecvWebRTC = null;

    /////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////

    this.SetEvent = function (hEventOnAttachedAudioRecvWebRTC, hEventOnAttachedVideoRecvWebRTC)
    {
        m_hEventOnAttachedAudioRecvWebRTC = hEventOnAttachedAudioRecvWebRTC;
        m_hEventOnAttachedVideoRecvWebRTC = hEventOnAttachedVideoRecvWebRTC;
    }

    this.CreateOfferWebRTC = function (nLineNo, sCallerName, sCallerId, sDialNo, hLocalAudioStream, hLocalVideoStream, hAudioMediaOut, hVideoMediaOut, bRecvVideo, hProcOfferCreateSuccessWebRTC)
    {
        m_nLineNo = nLineNo;

        m_sCallerName = sCallerName;
        m_sCallerId = sCallerId;
        m_sDialNo = sDialNo;

        m_hProcOfferCreateSuccessWebRTC = hProcOfferCreateSuccessWebRTC;
        
        m_hLocalAudioStream = hLocalAudioStream;
        m_hLocalVideoStream = hLocalVideoStream;

        m_hAudioMediaOut = hAudioMediaOut;
        m_hVideoMediaOut = hVideoMediaOut;
                
        var hServers = null;
        m_hPeerConnection = new RTCPeerConnection(hServers);
        m_hPeerConnection.ontrack = OnAttachMediaOutWebRTC;
        
        m_hLocalAudioStream.getTracks().forEach(function (track)
        {
            if (track.kind == "audio")
            {
                m_hPeerConnection.addTrack(track, m_hLocalAudioStream);
            }
        });

        if (hLocalVideoStream != null)
        {
            m_hLocalVideoStream.getTracks().forEach(function (track)
            {
                if (track.kind == "video")
                {
                    m_hPeerConnection.addTrack(track, m_hLocalVideoStream);
                }
            });
        }
        
        VaxCreateOfferWebRTC(bRecvVideo);
    }

    async function VaxCreateOfferWebRTC(bRecvVideo)
    {
        var nRecvVideo = 0;

        if (bRecvVideo)
            nRecvVideo = 1;

        const offerOptions =
        {
            offerToReceiveAudio: 1,
            offerToReceiveVideo: nRecvVideo
        };

        try
        {
            const hOffer = await m_hPeerConnection.createOffer(offerOptions);
            await OnCreateOfferSuccess(hOffer);
        }
        catch (e)
        {
            OnCreateOfferFailed(e);
        }

        //m_hPeerConnection.createOffer(OnCreateOfferSuccess, OnCreateOfferFailed, offerOptions);
    }
            
    //////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////
        
    function OnAttachMediaOutWebRTC(e) 
    {
        const hStream = e.streams[0]; 
        const hTrack = e.track;

        if (m_hAudioMediaOut != null && hTrack.kind === "audio")
        {
            m_hAudioMediaOut.srcObject = hStream;
            m_hEventOnAttachedAudioRecvWebRTC(hStream);
        }
        else if (m_hVideoMediaOut != null && hTrack.kind === "video")
        {
            m_hVideoMediaOut.srcObject = hStream;
            m_hEventOnAttachedVideoRecvWebRTC(hStream);
        }
    }

    this.CloseConnection = function () 
    {
        if (m_hPeerConnection == null)
            return;

        m_hPeerConnection.close();
        m_hPeerConnection = null;
    }
        
    //////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////
       
    function OnCreateOfferFailed(objError) 
    {
        ShowDialog("Failed to create offer WebRTC: " + objError.toString());
    }

    async function OnCreateOfferSuccess(desc) 
    {
        try
        {
            await m_hPeerConnection.setLocalDescription(desc);
            m_hProcOfferCreateSuccessWebRTC(m_nLineNo, m_hPeerConnection.localDescription.sdp, m_sCallerName, m_sCallerId, m_sDialNo);
        }

        catch(e)
        {
            OnCreateOfferFailed(e);
        }
    }

    //////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////
        
    this.CreateAnswerWebRTC = function (nLineNo, sSDP, sCallId, hLocalAudioStream, hLocalVideoStream, hAudioMediaOut, hVideoMediaOut, bRecvVideo, hProcAnswerCreateSuccessWebRTC)
    {        
        m_nLineNo = nLineNo;
        m_sCallId = sCallId;

        m_hProcAnswerCreateSuccessWebRTC = hProcAnswerCreateSuccessWebRTC;
                
        m_hLocalAudioStream = hLocalAudioStream;
        m_hLocalVideoStream = hLocalVideoStream;

        m_hAudioMediaOut = hAudioMediaOut;
        m_hVideoMediaOut = hVideoMediaOut;
                        
        var hServers = null;
                
        m_hPeerConnection = new RTCPeerConnection(hServers);
        m_hPeerConnection.ontrack = OnAttachMediaOutWebRTC;
                
        m_hLocalAudioStream.getTracks().forEach(function (track)
        {
            if (track.kind == "audio")
            {
                m_hPeerConnection.addTrack(track, m_hLocalAudioStream);
            }
        });

        if (hLocalVideoStream != null)
        {
            m_hLocalVideoStream.getTracks().forEach(function (track)
            {
                if (track.kind == "video")
                {
                    m_hPeerConnection.addTrack(track, m_hLocalVideoStream);
                }
            });
        }

        SetRemoteSDP("offer", sSDP);

        VaxCreateAnswerWebRTC(bRecvVideo);
    }

    async function VaxCreateAnswerWebRTC(bRecvVideo)
    {
        var nRecvVideo = 0;

        if (bRecvVideo)
            nRecvVideo = 1;

        const offerOptions =
        {
            offerToReceiveAudio: 1,
            offerToReceiveVideo: nRecvVideo
        };

        try
        {
            const hAnswer = await m_hPeerConnection.createAnswer(offerOptions);
            await OnCreateAnswerSuccess(hAnswer);
        }
        catch (e)
        {
            OnCreateAnswerFailed(e);
        }

        //m_hPeerConnection.createAnswer(OnCreateAnswerSuccess, OnCreateAnswerFailed, offerOptions);
    }
        

    //////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////
    
    function OnCreateAnswerFailed(objError) 
    {
        ShowDialog("Failed to create answer WebRTC: " + objError.toString());
    }

    async function OnCreateAnswerSuccess(desc) 
    {
        try
        {
            await m_hPeerConnection.setLocalDescription(desc);
            m_hProcAnswerCreateSuccessWebRTC(m_nLineNo, m_hPeerConnection.localDescription.sdp, m_sCallId);
        }

        catch(e)
        {
            OnCreateAnswerFailed(e);
        }
    }

    this.SetOfferRemoteWebRTC = function (sSDP)
    {
        SetRemoteSDP("offer", sSDP);
    }

    this.SetAnswerRemoteWebRTC = function (sSDP)
    {
        SetRemoteSDP("answer", sSDP);
    }

    //////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////

    async function SetRemoteSDP(sType, sSDP)
    {
        var hWebSDP = { sdp: "", type: "" };

        hWebSDP.sdp = sSDP;
        hWebSDP.type = sType

        /*
        m_hPeerConnection.setRemoteDescription(hWebSDP, function ()
        {
            OnSetRemoteSuccessSDP();

        }, OnSetRemoteFailedSDP);
        */

        try
        {
            await m_hPeerConnection.setRemoteDescription(hWebSDP);
            OnSetRemoteSuccessSDP();
        }
        catch (e)
        {
            OnSetRemoteFailedSDP();
        }
    }

    function OnSetRemoteSuccessSDP()
    {
        
    }

    function OnSetRemoteFailedSDP(objError)
    {
        ShowDialog("Failed to set remote SDP: " + objError.toString());
    }

    //////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////

    this.ChangeMediaAudioInputWebRTC = function (hLocalAudioStream)
    {
        if (m_hPeerConnection == null)
            return;

        try
        {
            const newTrack = hLocalAudioStream.getAudioTracks()[0];

            const senders = m_hPeerConnection.getSenders();
            const audioSender = senders.find(sender => sender.track && sender.track.kind === "audio");

            if (audioSender)
            {
                audioSender.replaceTrack(newTrack);
                m_hLocalAudioStream = hLocalAudioStream;
            }
            else
            {
                console.warn("No audio sender found.");
            }
        }
        catch (error)
        {
            console.error("Error changing microphone: ", error);
        }
    }
}