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

namespace CSHumanDetect
{
    public partial class Form1 : Form
    {
        public MyGTAPIEnv env;
        public bool bShowingResult;
        public bool bBeepON;
        public DateTime connectedTime;

        public Form1()
        {
            InitializeComponent();
            bShowingResult = false;
            bBeepON = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            btnDial.Enabled = false;
            InitSIPServer();
        }


        void InitSIPServer()
        {
            env = new MyGTAPIEnv();
            env.CreateEnv();
            env.mainForm = this;
            env.SetMainWnd(Handle);

            env.CFG_SetValue("gtsrv.sip.server.model", "1"); //server application

            //SIP IP Address you want to use on local
            //Leave it unset if you want to listen on all the network interface
            //CFG_SetValue("gtsrv.sip.ip.address", "");

            //SIP Port, default 5060
            env.CFG_SetValue("gtsrv.sip.ip.port", "5062");

            //RTP PORT
            env.CFG_SetValue("gtsrv.sip.rtpstartrange", "8400");
            env.CFG_SetValue("gtsrv.sip.rtpendrange", "8800");

            //Log
            env.CFG_SetValue("gtsrv.log.level", "4");

            env.CFG_SetValue("gtsrv.log.filename", Application.StartupPath + "\\CSHumanDetect-log.txt");

            //channnel numbers, here we only use 1 channel
            env.CFG_SetValue("gtsrv.sip.boardnum.per.server", "1");
            env.CFG_SetValue("gtsrv.sip.spannum.per.board", "1");
            env.CFG_SetValue("gtsrv.sip.channum.per.span", "1");
            /*
            #We don’t recommend you set "gtsrv.sip.channum.per.span" more than 16.
            #Sugguested Configuration of CHANNELS, SPANS, and Boards:
            #Channels	gtsrv.sip.channum.per.span	gtsrv.sip.spannum.per.board	gtsrv.sip.boardnum.per.server
            #4			4				1				1
            #8			8				1				1
            #16			8				2				1
            #24			8				3				1
            #32			8				4				1
            #40			8				5				1
            #64			8				8				1
            #128			8				8				2
            #256			8				8				4
            #512			16				8				4 
            */


            //only use 20ms codecs
            env.CFG_SetValue("gtsrv.sip.prefered.codec", "102,3,0,8");

            //Internal communication port
            env.CFG_SetValue("gtsrv.net.port", "8924");

            //Configuration file, if you want to define parameters in a file
            //env.CFG_SetValue(GTSRV_CFG_FILENAME, "GTSimpelPhone.ini");

            //Application name, it is related to sdk licence
            //Please contact PCBest Network(www.pcbest.net) to get licence info
            env.SetAppName("CSHumanDetect");

            //define outbound route, leave them unset if you don't know
            //env.CFG_SetValue("gtsrv.sip.outbound.via.type", "0");
            //env.CFG_SetValue("gtsrv.sip.outbound.via.proxy", "");

            //set sip client user info here
            env.CFG_SetValue("gtsrv.sip.reg.client.num", "1");
            env.CFG_SetValue("gtsrv.sip.reg1.displayname", "Any");
            env.CFG_SetValue("gtsrv.sip.reg1.username", "12345678");
            env.CFG_SetValue("gtsrv.sip.reg1.domain", "pcbest.net");
            env.CFG_SetValue("gtsrv.sip.reg1.proxy", "pcbest.net");
            env.CFG_SetValue("gtsrv.sip.reg1.authorization", "12345678");
            env.CFG_SetValue("gtsrv.sip.reg1.password", "************");
            //env.CFG_SetValue("gtsrv.sip.reg1.expire", "3600");

            env.CFG_SetValue("gtsrv.human.detect.enabled", "1");
            env.CFG_SetValue("gtsrv.sip.on.in.vad", "1");

            //env.CFG_SetValue("gtsrv.human.detect.max.sound.level", "100");

            if (!env.StartServer())
            {
                this.Text = "C# Human or Answering Machine Detection(Error!)";
            }
            else
            {
                env.Send_GetRegStatus(0);
                btnDial.Enabled = true;
            }
        }

        void FreeSIPServer()
        {
            env.StopServer();
            env.DestroyEnv();
            env = null;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (env != null)
            {
                env.ProcessGTAPIEvent();
            }
        }

        public void On_RecvRinging(int ch)
        {
            btnDial.Text = "Hung up";
            lbResult.Text = "Ringing";
        }

        public void On_RecvDialing(int ch, string sCaller, string sCallee)
        {
            btnDial.Text = "Hung up";
            lbResult.Text = "Dialing";
        }

        public void On_RecvConnected(int ch)
        {
            btnDial.Text = "Hung up";
            DateTime dt = connectedTime = DateTime.Now;
            
            string fdname = tbFolder.Text;
            if (fdname[fdname.Length - 1] != '\\')
                fdname += '\\';
            string fn = fdname + dt.Year.ToString() + "-" + dt.Month.ToString() + "-" + dt.Day.ToString() + " ";
            fn += dt.Hour.ToString() + "-" + dt.Minute.ToString() + "-" + dt.Second.ToString() +".wav";
            env.Send_RecordAudio(ch, fn, 0, "", 0, 0);

            lbResult.Text = "Connected! Detecting...";

            //For fax detection
            env.Send_AddTone(ch, 1100, 400); //1100HZ for 400ms. T30 standard for caller
            env.Send_AddTone(ch, 2100, 400); //2100HZ for 2400ms. T30 standard for callee
            env.Send_StartToneDetection(ch);
        }

        public void On_RecvIdle(int ch, int code, string desc)
        {
            btnDial.Text = "Dial";
            if (!bShowingResult)
                lbResult.Text = "Idle";

            //reset local variables
            bShowingResult = false;
            bBeepON = false;
        }

        public void On_DetectHumanVoiceDone(int ch, int result)
        {
            if (!bShowingResult) //otherwise, fax tone detected
            {
                switch (result)
                {
                    case 1:
                        lbResult.Text = "Human voice detected";
                        break;
                    case 0:
                        lbResult.Text = "Answering machine detected";
                        break;
                    case -1:
                        lbResult.Text = "Silence detected";
                        break;
                    case -2:
                        lbResult.Text = "Detected voice, but unknown";
                        break;
                }
                bShowingResult = true;
            }
            //env.Send_HangUp(0, 0, "");
        }

        public void On_RecvToneDetected(int ch, int freq)
        {
            lbResult.Text = "Fax tone detected";
            bShowingResult = true;
        }

        public void On_RecvRegStatus(int user_id, int status, int regtime)
        {
            string sip_acct_name = env.CFG_GetValue("gtsrv.sip.reg1.username", "");
            if (status == 1)
            {
                this.Text = "C# Human or Answering Machine Detection(" + sip_acct_name + " registered!)";
            }
            else
            {
                this.Text = "C# Human or Answering Machine Detection(" + sip_acct_name + " NOT registered!)";
            }
        }

        private void btnDial_Click(object sender, EventArgs e)
        {
            GTAPIASM.GTAPIChan chan = env.GetChannel(0);

            if (chan.ch_status == GTAPIASM.GTAPI_CHANNEL_STATE.IDLE)
            {
                //dial out
                string sip_acct_domain = env.CFG_GetValue("gtsrv.sip.reg1.domain", "");
                string dstNum = tbNumber.Text;
                if (dstNum.Contains("@"))
                {
                    if (dstNum.Contains("<sip:"))
                    {
                        env.Send_Make(0, dstNum, "");
                    }
                    else
                    {
                        dstNum = "<sip:" + dstNum + ">";
                        env.Send_Make(0, dstNum, "");
                    }
                }
                else
                {
                    dstNum = "<sip:" + dstNum;
                    dstNum += "@";
                    dstNum += sip_acct_domain;
                    dstNum += ">";

                    env.Send_Make(0, dstNum, "");
                }
                bShowingResult = false;
            }
            else
            {
                env.Send_HangUp(0, 0, "");
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            FreeSIPServer();
        }

        public void On_VoiceActivityDetected(int ch, int voice_dir, int voice_on, int level, uint reserved)
        {
            if (voice_dir == 1) //incoming voice
            {
                if (voice_on == 2 && !bBeepON) //beep on
                {
                    TimeSpan sp = DateTime.Now - connectedTime;
                    lbResult.Text = sp.TotalMilliseconds.ToString() + " BEEP ON";
                    bBeepON = true;
                }
                else if (voice_on == 0 && bBeepON) //beep off
                {
                    TimeSpan sp = DateTime.Now - connectedTime;
                    lbResult.Text = sp.TotalMilliseconds.ToString() + " BEEP OFF";
                    bBeepON = false;
                }

                if (voice_on == 3)
                {
                    //Final beep detected, you can play your voice message to be recorded into user's voice mailbox
                    lbFinalBeep.Text = "Final BEEP ON";
                }

            }
        }

    }


}