using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace OCXCSharpSIPServerApp
{
    public partial class Form1 : Form
    {
        public int m_nCurSel;
        public int[] m_RTPInCount;
        public int[] m_RTPOutCount;

        public Form1()
        {
            InitializeComponent();

            m_nCurSel = 0;
            m_RTPInCount = new int[4];
            m_RTPOutCount = new int[4];
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            axGTSIPAPI1.ProcessGTAPIEvent();
        }

        private void axGTSIPAPI1_OnCallOffered(object sender, AxGTSIPCTRLLib._DGTSIPAPIEvents_OnCallOfferedEvent e)
        {
            int ch = e.chanID;
            if (ch == 0)
            {
                tbSIPAddr1.Enabled = false;
                btnDial1.Enabled = true;
                btnDial1.Text = "Hangup";
            }
            else if (ch == 1)
            {
                tbSIPAddr2.Enabled = false;
                btnDial2.Enabled = true;
                btnDial2.Text = "Hangup";
            }
            else if (ch == 2)
            {
                tbSIPAddr3.Enabled = false;
                btnDial3.Enabled = true;
                btnDial3.Text = "Hangup";
            }
            else if (ch == 3)
            {
                tbSIPAddr4.Enabled = false;
                btnDial4.Enabled = true;
                btnDial4.Text = "Hangup";
            }

            string strlog;
            strlog = "New call from " + e.caller + " to " + e.callee;
            Log(ch, strlog);

            axGTSIPAPI1.SendAnswer(ch);
        }

        private void axGTSIPAPI1_OnCallIdleEx(object sender, AxGTSIPCTRLLib._DGTSIPAPIEvents_OnCallIdleExEvent e)
        {
            int ch = e.chanID;

            Log(ch, "IDLE");

            axGTSIPAPI1.StopTimer(ch);

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

        private void axGTSIPAPI1_OnCallDialing(object sender, AxGTSIPCTRLLib._DGTSIPAPIEvents_OnCallDialingEvent e)
        {
            int ch = e.chanID;

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

        }

        private void axGTSIPAPI1_OnCallConnected(object sender, AxGTSIPCTRLLib._DGTSIPAPIEvents_OnCallConnectedEvent e)
        {
            int nSel;
            string LogStr;
            int ch = e.chanID;

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

            nSel = m_nCurSel; //m_pMainWnd.cbxApplicationType.SelectedIndex
            if (nSel == 0)
            {
                axGTSIPAPI1.SendPlayAudioEx(ch, editSoundFile.Text, Convert.ToInt32(dtmfMaxDigits.Text), dtmfTermStr.Text, Convert.ToInt32(dtmfTimeout.Text), 0);
                LogStr = "Connected! Playing sound " + editSoundFile.Text;
                Log(ch, LogStr);
                axGTSIPAPI1.StartTimer(ch, 2000);
            }

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

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

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

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

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

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

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

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

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

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

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

            if (nSel == 9)
            {
                LogStr = "Connected! Detecting fax tone...";
                Log(ch, LogStr);
                axGTSIPAPI1.SendClearToneList(ch);
                axGTSIPAPI1.SendAddTone(ch, 1100, 400);
                axGTSIPAPI1.SendAddTone(ch, 2100, 2200);
                axGTSIPAPI1.SendStartToneDetection(ch);
            }
        }

        private void axGTSIPAPI1_OnCallRinging(object sender, AxGTSIPCTRLLib._DGTSIPAPIEvents_OnCallRingingEvent e)
        {
            int ch = e.chanID;
            if (ch == 0)
            {
                tbSIPAddr1.Enabled = false;
                btnDial1.Enabled = true;
                btnDial1.Text = "Hangup";
            }
            else if (ch == 1)
            {
                tbSIPAddr2.Enabled = false;
                btnDial2.Enabled = true;
                btnDial2.Text = "Hangup";
            }
            else if (ch == 2)
            {
                tbSIPAddr3.Enabled = false;
                btnDial3.Enabled = true;
                btnDial3.Text = "Hangup";
            }
            else if (ch == 3)
            {
                tbSIPAddr4.Enabled = false;
                btnDial4.Enabled = true;
                btnDial4.Text = "Hangup";
            }
        }

        private void axGTSIPAPI1_OnRecvRegStatus(object sender, AxGTSIPCTRLLib._DGTSIPAPIEvents_OnRecvRegStatusEvent e)
        {
            string sTemp;
            if (e.status == 1)
            {
                sTemp = "VB.NET SIP Server Application Demo --- " + axGTSIPAPI1.CFGGetValue("gtsrv.sip.reg1.authorization", "");
            }
            else
            {
                sTemp = "VB.NET SIP Server Application Demo --- " + axGTSIPAPI1.CFGGetValue("gtsrv.sip.reg1.authorization", "") + "XXX!";
            }

            Text = sTemp;
        }

        private void axGTSIPAPI1_OnDTMFDone(object sender, AxGTSIPCTRLLib._DGTSIPAPIEvents_OnDTMFDoneEvent e)
        {
            axGTSIPAPI1.SendHangUp(e.chanID, 0, "");
        }

        private void axGTSIPAPI1_OnDTMFKeyDown(object sender, AxGTSIPCTRLLib._DGTSIPAPIEvents_OnDTMFKeyDownEvent e)
        {
            string strlog;
            strlog = "Connected! " + Convert.ToChar(e.keyValue).ToString() + " key down!";
            Log(e.chanID, strlog);
        }

        private void axGTSIPAPI1_OnDTMFKeyUp(object sender, AxGTSIPCTRLLib._DGTSIPAPIEvents_OnDTMFKeyUpEvent e)
        {
            string strlog;
            strlog = "Connected! " + Convert.ToChar(e.keyValue).ToString() + " key up!";
            Log(e.chanID, strlog);
        }

        private void axGTSIPAPI1_OnAudioStatus(object sender, AxGTSIPCTRLLib._DGTSIPAPIEvents_OnAudioStatusEvent e)
        {

        }

        private void axGTSIPAPI1_OnAudioStatusEx(object sender, AxGTSIPCTRLLib._DGTSIPAPIEvents_OnAudioStatusExEvent e)
        {
            string LogStr = "";
            int ch = e.chanID;

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

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

                Log(ch, LogStr);
            }

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

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

                Log(ch, LogStr);
            }
        }

        private void axGTSIPAPI1_OnRecvTimer(object sender, AxGTSIPCTRLLib._DGTSIPAPIEvents_OnRecvTimerEvent e)
        {
            string LogStr;
            int ch = e.chanID;

            if (m_nCurSel == 0 || m_nCurSel == 1)
            {
                axGTSIPAPI1.SendGetAudioStatus(ch);

                if (axGTSIPAPI1.GetChanStatus(ch) == 3)
                    axGTSIPAPI1.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();
                Log(ch, LogStr);

                if (axGTSIPAPI1.GetChanStatus(ch) == 3)
                    axGTSIPAPI1.StartTimer(ch, 1000);
            }
        }

        private void axGTSIPAPI1_OnVoiceActivityDetected(object sender, AxGTSIPCTRLLib._DGTSIPAPIEvents_OnVoiceActivityDetectedEvent e)
        {
            string LogStr;
            if (e.voiceDir == 1 && m_nCurSel == 7)
            {
                if (e.voiceOn == 1)
                {
                    LogStr = "Connected! Voice is on.";
                    Log(e.chanID, LogStr);
                }
                else
                {
                    LogStr = "Connected! Voice is off.";
                    Log(e.chanID, LogStr);
                }
            }
        }

        private void axGTSIPAPI1_OnRecvToneDetected(object sender, AxGTSIPCTRLLib._DGTSIPAPIEvents_OnRecvToneDetectedEvent e)
        {
            if (m_nCurSel == 9)
            {
                Log(e.chanID, "Connected! Detected Fax");
                axGTSIPAPI1.SendStopToneDetection(e.chanID);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            cbxApplicationType.Items.Add("Play Sound");
            cbxApplicationType.Items.Add("Record Sound");
            cbxApplicationType.Items.Add("Echo Test");
            cbxApplicationType.Items.Add("Call Bridge");
            cbxApplicationType.Items.Add("DTMF Detector");
            cbxApplicationType.Items.Add("Music On Hold");
            cbxApplicationType.Items.Add("Conference");
            cbxApplicationType.Items.Add("Voice Activity Detection");
            cbxApplicationType.Items.Add("RTP Access");
            //cbxApplicationType.Items.Add("Proxy calls to 8888@pcbest.net");
            cbxApplicationType.Items.Add("Fax Detection");

            cbxApplicationType.SelectedIndex = 0;

            btnSIPStart.Enabled = true;
            btnSIPStop.Enabled = false;

            dtmfMaxDigits.Enabled = true;
            dtmfTermStr.Enabled = true;
            dtmfTimeout.Enabled = true;

            dtmfMaxDigits.Text = "0";
            dtmfTermStr.Text = "";
            dtmfTimeout.Text = "0";

            btnDial1.Enabled = false;
            btnDial2.Enabled = false;
            btnDial3.Enabled = false;
            btnDial4.Enabled = false;

            tbSIPAddr1.Enabled = false;
            tbSIPAddr2.Enabled = false;
            tbSIPAddr3.Enabled = false;
            tbSIPAddr4.Enabled = false;

        }

        private void cbxApplicationType_SelectedIndexChanged(object sender, EventArgs e)
        {
            int nSel;
            nSel = cbxApplicationType.SelectedIndex;
            if (nSel == 0 || nSel == 1)
            {
                editSoundFile.Enabled = true;
                btnBrowse.Enabled = true;
                dtmfMaxDigits.Enabled = true;
                dtmfTermStr.Enabled = true;
                dtmfTimeout.Enabled = true;
            }
            else if (nSel == 5)
            {
                editSoundFile.Enabled = true;
                btnBrowse.Enabled = false;
                dtmfMaxDigits.Enabled = false;
                dtmfTermStr.Enabled = false;
                dtmfTimeout.Enabled = false;
            }
            else
            {
                editSoundFile.Enabled = false;
                btnBrowse.Enabled = false;
                dtmfMaxDigits.Enabled = false;
                dtmfTermStr.Enabled = false;
                dtmfTimeout.Enabled = false;
            }
        }

        private void btnSIPStart_Click(object sender, EventArgs e)
        {
            cbxApplicationType.Enabled = false;
            editSoundFile.Enabled = false;
            btnBrowse.Enabled = false;
            btnSIPStart.Enabled = false;
            btnSIPStop.Enabled = true;
            btnExit.Enabled = false;

            dtmfMaxDigits.Enabled = false;
            dtmfTermStr.Enabled = false;
            dtmfTimeout.Enabled = false;

            InitSIPServer(cbxApplicationType.SelectedIndex);

            btnDial1.Enabled = true;
            btnDial2.Enabled = true;
            btnDial3.Enabled = true;
            btnDial4.Enabled = true;

            tbSIPAddr1.Enabled = true;
            tbSIPAddr2.Enabled = true;
            tbSIPAddr3.Enabled = true;
            tbSIPAddr4.Enabled = true;
        }

        private void btnSIPStop_Click(object sender, EventArgs e)
        {
            int nSel;

            cbxApplicationType.Enabled = true;
            nSel = cbxApplicationType.SelectedIndex;

            if (nSel == 0 || nSel == 1)
            {
                editSoundFile.Enabled = true;
                btnBrowse.Enabled = true;

                dtmfMaxDigits.Enabled = true;
                dtmfTermStr.Enabled = true;
                dtmfTimeout.Enabled = true;
            }
            else if (nSel == 5)
            {
                editSoundFile.Enabled = true;
                btnBrowse.Enabled = false;

                dtmfMaxDigits.Enabled = false;
                dtmfTermStr.Enabled = false;
                dtmfTimeout.Enabled = false;
            }
            else
            {
                editSoundFile.Enabled = false;
                btnBrowse.Enabled = false;

                dtmfMaxDigits.Enabled = false;
                dtmfTermStr.Enabled = false;
                dtmfTimeout.Enabled = false;
            }

            btnSIPStart.Enabled = true;
            btnSIPStop.Enabled = false;

            btnDial1.Enabled = false;
            btnDial2.Enabled = false;
            btnDial3.Enabled = false;
            btnDial4.Enabled = false;

            tbSIPAddr1.Enabled = false;
            tbSIPAddr2.Enabled = false;
            tbSIPAddr3.Enabled = false;
            tbSIPAddr4.Enabled = false;

            FreeSIPServer();

            btnExit.Enabled = true;
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Close();
        }

        public void InitSIPServer(int nCurSel)
        {
            axGTSIPAPI1.CreateEnv();
            m_nCurSel = nCurSel;

            axGTSIPAPI1.CFGSetValue("gtsrv.sip.callcontrol.auto.acceptcall", "1");
            axGTSIPAPI1.CFGSetValue("gtsrv.sip.callcontrol.auto.ringcall", "0");

            //axGTSIPAPI1.CFGSetValue("gtsrv.sip.proxy.sites.num", "1");
            //axGTSIPAPI1.CFGSetValue("gtsrv.sip.proxy.site1.domain", "");
            //axGTSIPAPI1.CFGSetValue("gtsrv.sip.proxy.site1.recordroute", "1");
            //axGTSIPAPI1.CFGSetValue("gtsrv.sip.proxy.site1.udp.relay", "0");

            if (nCurSel == 6)
                axGTSIPAPI1.CFGSetValue("gtsrv.sip.conference.room", "1");
            else
                axGTSIPAPI1.CFGSetValue("gtsrv.sip.conference.room", "0");

            if (nCurSel == 7)
                axGTSIPAPI1.CFGSetValue("gtsrv.sip.on.in.vad", "1");
            else
                axGTSIPAPI1.CFGSetValue("gtsrv.sip.on.in.vad", "0");

            if (nCurSel == 8)
                //set RTP access
                axGTSIPAPI1.CFGSetValue("gtsrv.sip.on.rtp.packet", "1");
            else
                axGTSIPAPI1.CFGSetValue("gtsrv.sip.on.rtp.packet", "0");

            //Configuration file, if you want to define parameters in a file
            axGTSIPAPI1.CFGSetValue("gtsrv.config.filename", "c:\\GTSIPServerApp.ini");

            if (!axGTSIPAPI1.StartServer())
                MessageBox.Show("StartServer Failed! Please make sure SIP port set in INI file is not being used by another application!");

            axGTSIPAPI1.SendGetRegStatus(0);

            //If axGTSIPAPI1.GetDetectedNATType() >= 12 And axGTSIPAPI1.CFG_GetIntValue("gtsrv.sip.use.nat.addr", 0) = 0 Then
            //MessageBox.Show("You have a blocked network. You may not be able to make Internet calls. Please config your network or firewall properly, then try again.")
            //End If

            if (m_nCurSel == 6)
            {
                //conference call
                axGTSIPAPI1.SendStartConference(0);
            }

        }

        public void FreeSIPServer()
        {
            if (m_nCurSel == 6)
                axGTSIPAPI1.SendStopConference(0);

            axGTSIPAPI1.StopServer();
            axGTSIPAPI1.DestroyEnv();
        }

        public void Log(int ch, string info)
        {
            if (ch == 0)
                Chan1Status.Text = info;
            else if (ch == 1)
                Chan2Status.Text = info;
            else if (ch == 2)
                Chan3Status.Text = info;
            else if (ch == 3)
                Chan4Status.Text = info;
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();

            openFileDialog1.InitialDirectory = "c:\\";
            openFileDialog1.Filter = "wav files (*.wav)|*.wav|All files (*.*)|*.*";
            openFileDialog1.FilterIndex = 2;
            openFileDialog1.RestoreDirectory = true;

            saveFileDialog1.InitialDirectory = "c:\\";
            saveFileDialog1.Filter = "wav files (*.wav)|*.wav|All files (*.*)|*.*";
            saveFileDialog1.FilterIndex = 2;
            saveFileDialog1.RestoreDirectory = true;

            if (cbxApplicationType.SelectedIndex == 0)
            {
                if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    editSoundFile.Text = openFileDialog1.FileName;
            }
            else
            {
                if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    editSoundFile.Text = saveFileDialog1.FileName;
            }

        }

        private void DialButtonPressed(int ch, string sAddr)
        {
            string sDestAddr;

            if (axGTSIPAPI1.GetChanStatus(ch) != 0)
            {
                axGTSIPAPI1.SendHangUp(ch, 0, "");
                return;
            }

            if (sAddr.IndexOf("<sip:") == 0)
                sDestAddr = sAddr;
            else if (sAddr.IndexOf("sip:") == 0)
                sDestAddr = "<" + sAddr + ">";
            else if (sAddr.IndexOf("@") > 0)
                sDestAddr = "<sip:" + sAddr + ">";
            else if (axGTSIPAPI1.CFGGetValue("gtsrv.sip.reg1.domain", "").Length > 0)
                sDestAddr = "<sip:" + sAddr + "@" + axGTSIPAPI1.CFGGetValue("gtsrv.sip.reg1.domain", "") + ">";
            else
                return;

            axGTSIPAPI1.SendMake(ch, sDestAddr, "");

        }

        private void btnDial1_Click(object sender, EventArgs e)
        {
            DialButtonPressed(0, tbSIPAddr1.Text);
        }

        private void btnDial2_Click(object sender, EventArgs e)
        {
            DialButtonPressed(1, tbSIPAddr1.Text);
        }

        private void btnDial3_Click(object sender, EventArgs e)
        {
            DialButtonPressed(2, tbSIPAddr1.Text);
        }

        private void btnDial4_Click(object sender, EventArgs e)
        {
            DialButtonPressed(3, tbSIPAddr1.Text);
        }

        private void axGTSIPAPI1_OnRTPPacket(object sender, AxGTSIPCTRLLib._DGTSIPAPIEvents_OnRTPPacketEvent e)
        {
            //string LogStr = "Packet Dir:" + e.inPacket.ToString();

            //Log(e.chanID, LogStr);
        }


    }
}