using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpSIPServerApp
{
    public class CSSIPServerAppEnv : GTAPIASM.GTAPIEnv 
    {
        public CSharpSIPServerMainForm m_pMainWnd;
        public int m_nCurSel;
        public int[] m_RTPInCount;
        public int[] m_RTPOutCount;

        public CSSIPServerAppEnv()
            : base()
        {
            m_pMainWnd = null;
            m_nCurSel = 0;
            m_RTPInCount = new int[4];
            m_RTPOutCount = new int[4];
        }

        public override void On_RecvConnected(int ch)
        {
            base.On_RecvConnected(ch);

            int nSel;
            string LogStr;

            if(ch == 0)
            {
                m_pMainWnd.tbSIPAddr1.Enabled = false;
                m_pMainWnd.btnDial1.Enabled = true;
                m_pMainWnd.btnDial1.Text = "Hangup";
            }
            else if(ch == 1)
            {
                m_pMainWnd.tbSIPAddr2.Enabled = false;
                m_pMainWnd.btnDial2.Enabled = true;
                m_pMainWnd.btnDial2.Text = "Hangup";
            }
            else if(ch == 2)
            {
                m_pMainWnd.tbSIPAddr3.Enabled = false;
                m_pMainWnd.btnDial3.Enabled = true;
                m_pMainWnd.btnDial3.Text = "Hangup";
            }
            else if(ch == 3)
            {
                m_pMainWnd.tbSIPAddr4.Enabled = false;
                m_pMainWnd.btnDial4.Enabled = true;
                m_pMainWnd.btnDial4.Text = "Hangup";
            }
           
            nSel = m_nCurSel; //m_pMainWnd.cbxApplicationType.SelectedIndex
            if(nSel == 0)
            {
                Send_PlayAudio(ch, m_pMainWnd.editSoundFile.Text, Convert.ToInt32(m_pMainWnd.dtmfMaxDigits.Text), m_pMainWnd.dtmfTermStr.Text, Convert.ToInt32(m_pMainWnd.dtmfTimeout.Text), 0);
                LogStr = "Connected! Playing sound " + m_pMainWnd.editSoundFile.Text;
                m_pMainWnd.Log(ch, LogStr);
                StartTimer(ch, 2000);
            }

            if(nSel == 1)
            {
                Send_RecordAudio(ch, m_pMainWnd.editSoundFile.Text, Convert.ToInt32(m_pMainWnd.dtmfMaxDigits.Text), m_pMainWnd.dtmfTermStr.Text, Convert.ToInt32(m_pMainWnd.dtmfTimeout.Text), 0);
                LogStr = "Connected! Recording sound to " + m_pMainWnd.editSoundFile.Text;
                m_pMainWnd.Log(ch, LogStr);
                StartTimer(ch, 2000);
            }

            if(nSel == 2)
            {
                Send_HalfConnect(ch, ch);
                m_pMainWnd.Log(ch, "Connected! Echo testing...");
            }

            if(nSel == 3)
            {
                if(ch == 0)
                {
                    m_pMainWnd.Log(ch, "Connected! Waiting for next channel to connect.");
                }

                if(ch == 1)
                {
                    Send_DuplexConnect(0, 1);
                    m_pMainWnd.Log(0, "Connected! Chan 1 and 2 are connected!");
                    m_pMainWnd.Log(1, "Connected! Chan 1 and 2 are connected!");
                }

                if(ch == 2)
                {
                    m_pMainWnd.Log(ch, "Connected! Waiting for next channel to connect.");
                }

                if(ch == 3)
                {
                    Send_DuplexConnect(2, 3);
                    m_pMainWnd.Log(2, "Connected! Chan 3 and 4 are connected!");
                    m_pMainWnd.Log(3, "Connected! Chan 3 and 4 are connected!");
                }
            }

            if(nSel == 4)
            {
                Send_EnableDTMF(ch, 0, "", 0);
                m_pMainWnd.Log(ch, "Connected! Waiting for DTMF digits.");
            }

            if(nSel == 5)
            {
                Send_StartMusicOnHold(ch, m_pMainWnd.editSoundFile.Text, 1, 0);
                LogStr = "Connected! Music On Hold - Playing files in " + m_pMainWnd.editSoundFile.Text;
                m_pMainWnd.Log(ch, LogStr);
            }

            if(nSel == 6)
            {
                Send_SetChanInConference(0, ch, 1);
                LogStr = "Connected! In conference room.";
                m_pMainWnd.Log(ch, LogStr);
            }

            if(nSel == 7)
            {
                LogStr = "Connected! Detecting voice..., please talk.";
                m_pMainWnd.Log(ch, LogStr);
            }

            if(nSel == 8)
            {
                LogStr = "Connected!";
                m_pMainWnd.Log(ch, LogStr);
                m_RTPInCount[ch] = 0;
                m_RTPOutCount[ch] = 0;
                StartTimer(ch, 1000);
            }

            if(nSel == 9)
            {
                LogStr = "Connected! Detecting fax tone...";
                m_pMainWnd.Log(ch, LogStr);
                Send_ClearToneList(ch);
                Send_AddTone(ch, 1100, 400);
                Send_AddTone(ch, 2100, 2200);
                Send_StartToneDetection(ch);
            }


        }

        public override void On_RecvDialing(int ch, string sCaller, string sCallee)
        {
            base.On_RecvDialing(ch, sCaller, sCallee);

            if(ch == 0)
            {
                m_pMainWnd.tbSIPAddr1.Enabled = false;
                m_pMainWnd.btnDial1.Enabled = true;
                m_pMainWnd.btnDial1.Text = "Hangup";
            }
            else if(ch == 1)
            {
                m_pMainWnd.tbSIPAddr2.Enabled = false;
                m_pMainWnd.btnDial2.Enabled = true;
                m_pMainWnd.btnDial2.Text = "Hangup";
            }
            else if(ch == 2)
            {
                m_pMainWnd.tbSIPAddr3.Enabled = false;
                m_pMainWnd.btnDial3.Enabled = true;
                m_pMainWnd.btnDial3.Text = "Hangup";
            }
            else if(ch == 3)
            {
                m_pMainWnd.tbSIPAddr4.Enabled = false;
                m_pMainWnd.btnDial4.Enabled = true;
                m_pMainWnd.btnDial4.Text = "Hangup";
            }

        }

        public override void On_RecvOffered(int ch, string sCaller, string sCallee, string sDestAddr, string sViaAddr, string sFromIP, ushort nFromPort)
        {
            base.On_RecvOffered(ch, sCaller, sCallee, sDestAddr, sViaAddr, sFromIP, nFromPort);

            if(ch == 0)
            {
                m_pMainWnd.tbSIPAddr1.Enabled = false;
                m_pMainWnd.btnDial1.Enabled = true;
                m_pMainWnd.btnDial1.Text = "Hangup";
            }
            else if(ch == 1)
            {
                m_pMainWnd.tbSIPAddr2.Enabled = false;
                m_pMainWnd.btnDial2.Enabled = true;
                m_pMainWnd.btnDial2.Text = "Hangup";
            }
            else if(ch == 2)
            {
                m_pMainWnd.tbSIPAddr3.Enabled = false;
                m_pMainWnd.btnDial3.Enabled = true;
                m_pMainWnd.btnDial3.Text = "Hangup";
            }
            else if(ch == 3)
            {
                m_pMainWnd.tbSIPAddr4.Enabled = false;
                m_pMainWnd.btnDial4.Enabled = true;
                m_pMainWnd.btnDial4.Text = "Hangup";
            }

            string strlog;
            strlog = "New call from " + sCaller + " to " + sCallee;
            m_pMainWnd.Log(ch, strlog);

            Send_Answer(ch);
        }

        public override void On_RecvIdle(int ch, int code, string desc)
        {
            base.On_RecvIdle(ch, code, desc);

            m_pMainWnd.Log(ch, "IDLE");

            StopTimer(ch);

            if(ch == 0)
            {
                m_pMainWnd.tbSIPAddr1.Enabled = true;
                m_pMainWnd.btnDial1.Enabled = true;
                m_pMainWnd.btnDial1.Text = "Dial";
            }
            else if(ch == 1)
            {
                m_pMainWnd.tbSIPAddr2.Enabled = true;
                m_pMainWnd.btnDial2.Enabled = true;
                m_pMainWnd.btnDial2.Text = "Dial";
            }
            else if(ch == 2)
            {
                m_pMainWnd.tbSIPAddr3.Enabled = true;
                m_pMainWnd.btnDial3.Enabled = true;
                m_pMainWnd.btnDial3.Text = "Dial";
            }
            else if(ch == 3)
            {
                m_pMainWnd.tbSIPAddr4.Enabled = true;
                m_pMainWnd.btnDial4.Enabled = true;
                m_pMainWnd.btnDial4.Text = "Dial";
            }
        }

        public override void On_RecvRinging(int ch)
        {
            base.On_RecvRinging(ch);

            if(ch == 0)
            {
                m_pMainWnd.tbSIPAddr1.Enabled = false;
                m_pMainWnd.btnDial1.Enabled = true;
                m_pMainWnd.btnDial1.Text = "Hangup";
            }
            else if(ch == 1)
            {
                m_pMainWnd.tbSIPAddr2.Enabled = false;
                m_pMainWnd.btnDial2.Enabled = true;
                m_pMainWnd.btnDial2.Text = "Hangup";
            }
            else if(ch == 2)
            {
                m_pMainWnd.tbSIPAddr3.Enabled = false;
                m_pMainWnd.btnDial3.Enabled = true;
                m_pMainWnd.btnDial3.Text = "Hangup";
            }
            else if(ch == 3)
            {
                m_pMainWnd.tbSIPAddr4.Enabled = false;
                m_pMainWnd.btnDial4.Enabled = true;
                m_pMainWnd.btnDial4.Text = "Hangup";
            }
        }

        public override void On_RecvRegStatus(int user_id, int status, int regtime)
        {
            base.On_RecvRegStatus(user_id, status, regtime);

            string sTemp;
            if(status == 1)
            {
                sTemp = "VB.NET SIP Server Application Demo --- " + CFG_GetValue("gtsrv.sip.reg1.authorization", "");
            }
            else
            {
                sTemp = "VB.NET SIP Server Application Demo --- " + CFG_GetValue("gtsrv.sip.reg1.authorization", "") + "XXX!";
            }

            m_pMainWnd.Text = sTemp;
        }

        public override void On_RecvDTMFKeyDown(int ch, byte keyValue, uint ticks)
        {
            base.On_RecvDTMFKeyDown(ch, keyValue, ticks);
            string strlog;
            strlog = "Connected! " + Convert.ToChar(keyValue).ToString() + " key down!";
            m_pMainWnd.Log(ch, strlog);
        }

        public override void On_RecvDTMFKeyUp(int ch, byte keyValue, uint ticks)
        {
            base.On_RecvDTMFKeyUp(ch, keyValue, ticks);
            string strlog;
            strlog = "Connected! " + Convert.ToChar(keyValue).ToString() + " key up!";
            m_pMainWnd.Log(ch, strlog);
        }

        public override void On_RecvDTMFDone(int ch, int doneReason, string dtmfBuf)
        {
            base.On_RecvDTMFDone(ch, doneReason, dtmfBuf);

            Send_HangUp(ch, 0, "");
        }

        public override void On_VoiceActivityDetected(int ch, int voice_dir, int voice_on, int level, uint reserved)
        {
            base.On_VoiceActivityDetected(ch, voice_dir, voice_on, level, reserved);

            string LogStr;
            if(voice_dir == 1 && m_nCurSel == 7)
            {
                if(voice_on == 1)
                {
                    LogStr = "Connected! Voice is on.";
                    m_pMainWnd.Log(ch, LogStr);
                }
                else
                {
                    LogStr = "Connected! Voice is off.";
                    m_pMainWnd.Log(ch, LogStr);
                }
            }
        }

        public override string On_ProxyNewCallSession(uint pid, uint sid, IntPtr msg, string authid, string fromid, string toid, string suri, string via, string saddr, ushort nport, bool bCredit)
        {
            //return base.On_ProxyNewCallSession(pid, sid, msg, authid, fromid, toid, suri, via, saddr, nport, bCredit);
            if (m_nCurSel == 8)
                return "<sip:8888@sip.pcbest.net>";
            else
                return base.On_ProxyNewCallSession(pid, sid, msg, authid, fromid, toid, suri, via, saddr, nport, bCredit);
        }

        public override void On_Timer(int ch)
        {
            base.On_Timer(ch);

            string LogStr;

            if(m_nCurSel == 0 || m_nCurSel == 1)
            {
                Send_GetAudioStatus(ch);

                if(GetChannel(ch).ch_status == GTAPIASM.GTAPI_CHANNEL_STATE.CONNECTED)
                    StartTimer(ch, 2000);
            }

            if(m_nCurSel == 8)
            {
                LogStr = "Connected! In RTP packages " + m_RTPInCount[ch].ToString();
                LogStr = LogStr + " Out RTP packages " + m_RTPOutCount[ch].ToString();
                m_pMainWnd.Log(ch, LogStr);

                if(GetChannel(ch).ch_status == GTAPIASM.GTAPI_CHANNEL_STATE.CONNECTED)
                    StartTimer(ch, 1000);
            }
        }

        public override void On_RecvAudioStatus(int ch, int resType, int statusCode, uint OffsetByte)
        {
            base.On_RecvAudioStatus(ch, resType, statusCode, OffsetByte);

            string LogStr = "";

            if(m_nCurSel == 0)
            {
                if(statusCode == 1) //playing
                    LogStr = "Connected! Playing sound. Offset bytes now: " + OffsetByte.ToString();

                if(statusCode == 0) //idle
                    LogStr = "Connected! Playing done. Offset bytes now: " + OffsetByte.ToString();

                m_pMainWnd.Log(ch, LogStr);
            }

            if(m_nCurSel == 1)
            {
                if(statusCode == 2) //recording
                {
                    LogStr = "Connected! Recording sound to " + m_pMainWnd.editSoundFile.Text;
                    LogStr = LogStr + " Offset bytes now: " + OffsetByte.ToString();
                }

                if(statusCode == 0) //idle
                {
                    LogStr = "Connected! Recording done ";
                    LogStr = LogStr + " Offset bytes now: " + OffsetByte.ToString();
                }

                m_pMainWnd.Log(ch, LogStr);
            }
        }

        public override void On_RecvRTPPacket(int ch, int fmt, IntPtr buf, int buflen, ushort seq, uint timestamp, IntPtr pSysTime)
        {
            base.On_RecvRTPPacket(ch, fmt, buf, buflen, seq, timestamp, pSysTime);

            if(m_nCurSel == 8)
                m_RTPInCount[ch] = m_RTPInCount[ch] + 1;

        }

        public override void On_SentRTPPacket(int ch, int fmt, IntPtr buf, int buflen, ushort seq, uint timestamp, IntPtr pSysTime)
        {
            base.On_SentRTPPacket(ch, fmt, buf, buflen, seq, timestamp, pSysTime);

            if (m_nCurSel == 8)
                m_RTPOutCount[ch] = m_RTPOutCount[ch] + 1;

        }

        public override void On_RecvToneDetected(int ch, int freq)
        {
            base.On_RecvToneDetected(ch, freq);

            if(m_nCurSel == 9)
            {
                m_pMainWnd.Log(ch, "Connected! Detected Fax");
                Send_StopToneDetection(ch);
            }
        }
    }
}
