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

namespace CSharpSIPServerApp
{
    public partial class CSharpSIPServerMainForm : Form
    {
        public CSSIPServerAppEnv m_pEnv;

        public CSharpSIPServerMainForm()
        {
            InitializeComponent();
        }

        private void CSharpSIPServerMainForm_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@sip.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;

            editCfg.Text = System.IO.Directory.GetParent(Application.StartupPath) + "\\ini\\GTSIPServerApp.ini";
        }

        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)
        {
            if(!File.Exists(editCfg.Text))
            {
                MessageBox.Show("Config file doesn't exist!", "ERROR!");
                return;
            }

            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, editCfg.Text);

            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, string iniCfgFile)
        {
            m_pEnv = new CSSIPServerAppEnv();
            m_pEnv.m_nCurSel = nCurSel;
            m_pEnv.m_pMainWnd = this;
            m_pEnv.CreateEnv();
            m_pEnv.SetMainWnd(this.Handle);

            m_pEnv.CFG_SetValue("gtsrv.sip.callcontrol.auto.acceptcall", "1");
            m_pEnv.CFG_SetValue("gtsrv.sip.callcontrol.auto.ringcall", "0");

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

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

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

            if(nCurSel == 8)
                //set RTP access
                m_pEnv.CFG_SetValue("gtsrv.sip.on.rtp.packet", "1");
            else
                m_pEnv.CFG_SetValue("gtsrv.sip.on.rtp.packet", "0");
            
            //Configuration file, if you want to define parameters in a file
            m_pEnv.CFG_SetValue("gtsrv.config.filename", iniCfgFile);

            if (!m_pEnv.StartServer())
            {
                MessageBox.Show("StartServer failed! Please make sure the SIP port set in INI file is not being using by another application.");
            }

            m_pEnv.Send_GetRegStatus(0);

            //If m_pEnv.GetDetectedNATType() >= 12 And m_pEnv.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_pEnv.m_nCurSel == 6)
            {
                //conference call
                m_pEnv.Send_StartConference(0);
            }

        }

        public void FreeSIPServer()
        {
            if(m_pEnv.m_nCurSel == 6)
                m_pEnv.Send_StopConference(0);

            m_pEnv.StopServer();
            m_pEnv.DestroyEnv();
            m_pEnv = null;
        }

        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 = Application.StartupPath;
            openFileDialog1.Filter = "wav files (*.wav)|*.wav|All files (*.*)|*.*";
            openFileDialog1.FilterIndex = 2;
            openFileDialog1.RestoreDirectory = true;

            saveFileDialog1.InitialDirectory = Application.StartupPath;
            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 timer1_Tick(object sender, EventArgs e)
        {
            if (m_pEnv != null)
                m_pEnv.ProcessGTAPIEvent();
        }

        private void DialButtonPressed(int ch, string sAddr)
        {
            string sDestAddr;
            GTAPIASM.GTAPIChan apiChan;
 
            apiChan = m_pEnv.GetChannel(ch);

            if(apiChan.ch_status != GTAPIASM.GTAPI_CHANNEL_STATE.IDLE)
            {
                m_pEnv.Send_HangUp(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( m_pEnv.CFG_GetValue("gtsrv.sip.reg1.domain", "").Length > 0)
                sDestAddr = "<sip:" + sAddr + "@" + m_pEnv.CFG_GetValue("gtsrv.sip.reg1.domain", "") + ">";
            else
                return;

            m_pEnv.Send_Make(ch, sDestAddr, "");

        }

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

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

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

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

        private void btnBrowseINI_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();

            openFileDialog1.InitialDirectory = System.IO.Directory.GetParent(Application.StartupPath) + "\\ini\\";
            openFileDialog1.Filter = "ini files (*.ini)|*.ini|All files (*.*)|*.*";
            openFileDialog1.FilterIndex = 2;
            openFileDialog1.RestoreDirectory = true;

            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                editCfg.Text = openFileDialog1.FileName;

        }
    }
}