using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Data.SqlClient;
using System.IO;
using Microsoft.Win32;
using VR2;
using System.Threading;

namespace VR2ManagerClient
{
    public partial class Form1 : Form
    {
        public string serverIP;
        public ushort serverPort;

        public MyVR2Client vr_client;
        public bool serverConnected;
        public bool waiting_general;

        public int MaxChanNum;

        public int timerCount;

        //public VR2Main vr2_main;
        public VR2.DBServerSetting db_set;

        //public int DataViewType;
        public MyGTAPIEnv env;

        public string licKey;
        public string RTSrvIP;
        public ushort RTSrvPort;

        public ushort RTSoftSIPPort;
        public ushort RTSoftRTPPort;

        public int RTListening;

        public Form1()
        {
            InitializeComponent();

            serverConnected = false;
            serverIP = "127.0.0.1";
            serverPort = 1376;
            MaxChanNum = 0;

            vr_client = new MyVR2Client();
            vr_client.main_form = this;

            timerCount = 0;

            //vr2_main = new VR2Main();
            db_set = null;

            //DataViewType = 0;

            licKey = "";
            RTSrvIP = "127.0.0.1";
            RTSrvPort = 5060;
            RTListening = 0;

            RTSoftSIPPort = 7832;
            RTSoftRTPPort = 18810;

            waiting_general = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            dataGridView1.Enabled = false;
            ConnectToServer();

            string xmlFileName = Application.StartupPath + "\\VR2Config.xml";

            XmlDocument xmlDoc = new XmlDocument();
            try
            {
                xmlDoc.Load(xmlFileName);
            }
            catch (Exception)
            {
                return;
            }

            XmlElement root = xmlDoc.DocumentElement;


            XmlNode tmpNode = root.SelectSingleNode("//VoiceRecorder/LicKey");
            if (tmpNode != null)
            {
                licKey = tmpNode.InnerText;
            }

            tmpNode = root.SelectSingleNode("//VoiceRecorder/EnableRTSrv");
            if (tmpNode != null)
            {
                RTListening = Convert.ToInt32(tmpNode.InnerText);
            }
            

            tmpNode = root.SelectSingleNode("//VoiceRecorder/Database/Enabled");
            if (tmpNode != null)
            {
                if (VR2.VR2Main.GetBooleanFromXMLNode(tmpNode))
                {
                    db_set = new DBServerSetting();

                    tmpNode = root.SelectSingleNode("//VoiceRecorder/Database/DBType");
                    if (tmpNode != null)
                        db_set.dbType = Convert.ToInt32(tmpNode.InnerText);

                    tmpNode = root.SelectSingleNode("//VoiceRecorder/Database/DBServer");
                    if (tmpNode != null)
                        db_set.sDBServer = tmpNode.InnerText;

                    tmpNode = root.SelectSingleNode("//VoiceRecorder/Database/DBName");
                    if (tmpNode != null)
                        db_set.sDBName = tmpNode.InnerText;

                    tmpNode = root.SelectSingleNode("//VoiceRecorder/Database/AuthType");
                    if (tmpNode != null)
                        db_set.authType = Convert.ToInt32(tmpNode.InnerText);

                    tmpNode = root.SelectSingleNode("//VoiceRecorder/Database/UserName");
                    if (tmpNode != null)
                        db_set.sUserName = tmpNode.InnerText;

                    tmpNode = root.SelectSingleNode("//VoiceRecorder/Database/Password");
                    if (tmpNode != null)
                        db_set.sPassword = tmpNode.InnerText;

                    tmpNode = root.SelectSingleNode("//VoiceRecorder/Database/CallLogTableName");
                    if (tmpNode != null)
                    {
                        if (tmpNode.InnerText.Length > 0)
                            db_set.CallLogTableName = tmpNode.InnerText;
                    }

                    tmpNode = root.SelectSingleNode("//VoiceRecorder/Database/ChannelStatusTableName");
                    if (tmpNode != null)
                    {
                        if (tmpNode.InnerText.Length > 0)
                            db_set.ChannelStatusTableName = tmpNode.InnerText;
                    }

                }
                else
                {
                }
            }

            if (db_set != null)
            {
                if (db_set.ConnectDB())
                {
                    db_set.TestTables();

                    //update channel status if possible
                    //catCMD.CommandText = "CREATE TABLE " + ChannelStatusTableName + "(ChanID SmallInt, CallerIP varchar(80) NULL, CallerID varchar(80) NULL, CalleeIP varchar(80) NULL, CalleeID varchar(80) NULL, TimeInit datetime NULL, TimeBegin datetime NULL, TimeEnd datetime NULL, UniqueID varchar(150) NULL, RecordPath varchar(250) NULL, DIR TINYINT, CallConnected TINYINT, ChanStatus TINYINT)";

                    db_set.DisconnectDB();
                }
            }

            //softphone method
            RegistryKey keyPCBest;
            try
            {
                keyPCBest = Registry.CurrentUser.OpenSubKey("PCBestNetworks");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                keyPCBest = null;
            }

            if (keyPCBest != null)
            {
                try
                {
                    using (RegistryKey
                        keyVR2 = keyPCBest.OpenSubKey("VR2"))
                    {
                        // Create data for the TestSettings subkey.
                        try
                        {
                            RTSrvIP = (string)keyVR2.GetValue("RTSrvIP");
                        }
                        catch(Exception)
                        {
                            RTSrvIP = "127.0.0.1";
                        }

                        try
                        {
                            RTSrvPort = Convert.ToUInt16((string)keyVR2.GetValue("RTSrvPort"));
                        }
                        catch (Exception)
                        {
                            RTSrvPort = 5060;
                        }

                        try
                        {
                            RTSoftSIPPort = Convert.ToUInt16((string)keyVR2.GetValue("RTSoftSIPPort"));
                        }
                        catch (Exception)
                        {
                            RTSoftSIPPort = 7832;
                        }

                        try
                        {
                            RTSoftRTPPort = Convert.ToUInt16((string)keyVR2.GetValue("RTSoftRTPPort"));
                        }
                        catch (Exception)
                        {
                            RTSoftRTPPort = 18810;
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }

            try
            {
                if (RTListening == 1)
                    InitSIPServer();
                else
                {
                    cbChanID.Enabled = false;
                    btnListen.Enabled = false;
                    btnOptions.Enabled = false;
                    btnOptions.Visible = false;
                    lbRTChanStatus.Text = "Set <EnableRTSrv> in VR2Config.xml";
                }
            }
            catch (Exception ex)
            {
            }
        }

        public void ConnectToServer()
        {
            IntPtr resConnect;

try_again:
            ConnectForm dlg = new ConnectForm();
            dlg.serverIP = serverIP;
            dlg.serverPort = serverPort;

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                serverIP = dlg.serverIP;
                if (serverIP.Length == 0)
                    serverIP = "127.0.0.1";

                serverPort = dlg.serverPort;

                resConnect = vr_client.ConnectTo(serverIP, serverPort);

                if (resConnect == IntPtr.Zero)
                {
                    MessageBox.Show("Cannot connect to server!");
                    vr_client.Disconnect();
                    goto try_again;
                }
            }
            /*
            else
            {
                Close();
            }
            */
        }

        public void ServerConnected(bool bConnected)
        {
/*
            if (bConnected)
            {
                btnConnect.Enabled = false;
                btnDisconnect.Enabled = true;
            }
            else
            {
                btnConnect.Enabled = true;
                btnDisconnect.Enabled = false;
            }
 */
            serverConnected = bConnected;
            if (!bConnected)
            {
                dataGridView1.Enabled = false;
                LogoutText("Lost connection to server");
                connectToolStripMenuItem.Enabled = true;
                disconnectToolStripMenuItem.Enabled = false;
            }
            else
            {
                LogoutText("Connected To Server " + serverIP + ":" + serverPort.ToString());
                vr_client.GetStatus("general");
                connectToolStripMenuItem.Enabled = false;
                disconnectToolStripMenuItem.Enabled = true;
            }
        }

/*
        public void LogoutText(string sLogInfo)
        {
            tbStatus.Text = sLogInfo;
        }
*/

        public void LogoutText(string sLogInfo/*, bool bTrace*/)
        {
            lock (this)
            {
                sLogInfo = "[" + DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss") + "]" + " " + sLogInfo;
                if (LogRichEdit.Text.Length > 1024 * 512)
                    LogRichEdit.Text = "";
                LogRichEdit.Text = LogRichEdit.Text + sLogInfo + "\r\n";
                LogRichEdit.Select(LogRichEdit.Text.Length - 2, 1);
                LogRichEdit.ScrollToCaret();
            }
        }

        public void Every5Seconds()
        {
        }

        public void Every10Seconds()
        {
        }

        public void Every2Seconds()
        {
            if (vr_client != null && !waiting_general && serverConnected)
            {
                vr_client.GetStatus("general");
                waiting_general = true;
            }
        }

        public void EverySecond()
        {
        }

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

                if (vr_client != null)
                {
                    vr_client.ProcessEvents();
                }
            }
            catch (Exception ex)
            {
                LogoutText(ex.ToString());
            }

            timerCount++;

            if (timerCount % 5 == 0) //every second
            {
                EverySecond();
            }
            if (timerCount % 10 == 0) //every 2 seconds
            {
                Every2Seconds();
            }
            if (timerCount % 25 == 0) //every 5 seconds
            {
                Every5Seconds();
            }
            if (timerCount % 50 == 0) //every 10 seconds
            {
                Every10Seconds();
            }

            if (timerCount == 300)
                timerCount = 0; //reset to 0
        }

        //////////////////////////////////////////////////////////////////////
        //Softphone Methods and Events
        //////////////////////////////////////////////////////////////////////
        public bool InitSIPServer()
        {
            int rtpend;

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

            env.CFG_SetValue("gtsrv.sip.server.model", "0");

            //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", RTSoftSIPPort.ToString());

            //RTP PORT
            env.CFG_SetValue("gtsrv.sip.rtpstartrange", RTSoftRTPPort.ToString());
            rtpend = RTSoftRTPPort + 20;
            env.CFG_SetValue("gtsrv.sip.rtpendrange", rtpend.ToString());

            //Log
            env.CFG_SetValue("gtsrv.log.level", "4");
            env.CFG_SetValue("gtsrv.log.filename", Application.StartupPath + "\\RTSoftphone.txt");

            //Prefered codec list
            env.CFG_SetValue("gtsrv.sip.prefered.codec", "0,8,3");
            //env.CFG_SetValue("gtsrv.sip.prefered.video.codec", "34,115,124")

            //NAT or STUN
            /*
            if (cfgWrap.StunServer.Length > 0)
            {
                env.CFG_SetValue("gtsrv.sip.stun.server", cfgWrap.StunServer);
            }
            else
            {
                env.CFG_SetValue("gtsrv.sip.use.nat.addr", cfgWrap.UseNATAddr ? "1" : "0");
            }*/

            //JB buffer and dirctX buffer settings, DO NOT change
            //env.CFG_SetValue("gtsrv.sip.jb.min.delay", "0")
            //env.CFG_SetValue("gtsrv.sip.jb.max.delay", "5")
            //env.CFG_SetValue("gtsrv.sip.jb.adaptive", "0")
            //env.CFG_SetValue("gtsrv.sip.jb.get.all.data", "1")
            //env.CFG_SetValue("gtsrv.sip.dx.playback.delay", "2")

            //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");

            //define inbound and outbound channels, NOT USEFUL ANYMORE. DO NOT USE
            //env.CFG_SetValue("gtsrv.channel.inbound", "0-3");
            //env.CFG_SetValue("gtsrv.channel.outbound", "4-15");

            //Internal communication port
            env.CFG_SetValue("gtsrv.net.port", "9427"); //any port you like

            //conference room
            //env.CFG_SetValue("gtsrv.sip.conference.room", "1")

            //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("VR2RTSoftphone");
            env.CFG_SetValue("gtsrv.licence.key", licKey);
            env.CFG_SetValue("gtsrv.lic.file.dir", Application.StartupPath);

            //env.CFG_SetValue("gtsrv.sip.conference.room", "1")

            //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 ***** If you want to take incoming calls, you must set this value,
            // or you can only answer calls by your IP address
            //you must get an account from sip service provider first

            if (env.StartServer())
            {
                //env.Send_GetRegStatus(0);
                lbRTChanStatus.Text = "Idle";
                btnListen.Text = "Listen";

                return true;
            }
            else
            {
                MessageBox.Show("Realtime Softphone Start Failed! Please make sure the SIP port(6872) is not being used by another application!");
                lbRTChanStatus.Text = "ERROR: START PHONE";
                btnListen.Enabled = false;

                return false;
            }
        }

        public bool FreeSIPServer()
        {
            if (env != null)
            {
                env.StopServer();
                env.DestroyEnv();
                env = null;
            }
            return true;
        }

        public void On_RecvConnected(int ch)
        {
            env.StopSound(); //stop the ring tone or ringback tone

            //Send_SetChanInConference(0, -1, 1)
            //Send_SetChanInConference(0, ch, 1)
            env.Send_StartDXAudio(ch); //because this is a client phone, we start DirectX audio

            btnListen.Text = "Stop";
            lbRTChanStatus.Text = "Connected";

            cbChanID.Enabled = false;
            btnOptions.Enabled = false;
        }

        public void On_RecvOffered(int ch, string sCaller, string sCallee, string sDestAddr, string sViaAddr, string sFromIP, ushort nFromPort)
        {
            //reject incoming call
            env.Send_HangUp(ch, 0, "");
        }

        public void On_RecvDialing(int ch, string sCaller, string sCallee)
        {
            btnListen.Text = "Stop";
            lbRTChanStatus.Text = "Dialing";
        }

        public void On_RecvRinging(int ch)
        {
            btnListen.Text = "Stop";
            lbRTChanStatus.Text = "Ringing";

            env.StopSound();
            env.PlayRemoteRingSound();
        }

        public void On_RecvIdle(int ch, int code, string desc)
        {
            btnListen.Text = "Listen";
            lbRTChanStatus.Text = "Idle";

            cbChanID.Enabled = true;
            btnOptions.Enabled = true;

            env.StopSound();

            //Send_SetChanInConference(0, -1, 0)
            //Send_SetChanInConference(0, ch, 0)
        }

        public void On_RecvRegStatus(int user_id, int status, int regtime)
        {
        }

        public void On_RecvHolding(int ch, int hold_on)
        {
            GTAPIASM.GTAPIChan chan;

            chan = env.GetChannel(ch);

            if (chan.ch_status == GTAPIASM.GTAPI_CHANNEL_STATE.CONNECTED)
            {
            }

            if (chan.ch_status == GTAPIASM.GTAPI_CHANNEL_STATE.HOLDING)
            {
            }

            if (chan.ch_status == GTAPIASM.GTAPI_CHANNEL_STATE.BE_HOLDED)
            {
            }
        }

        private void btnListen_Click(object sender, EventArgs e)
        {
            int ch = Convert.ToInt32(cbChanID.Text);
            if (ch >= 1 && ch <= MaxChanNum)
            {
                if (btnListen.Text == "Stop")
                {
                    env.Send_HangUp(0, 0, "");
                }
                else
                    MakeCallOut(ch);
            }
        }

        public void MakeCallOut(int ch)
        {
            string calledNum;
            calledNum = "<sip:" + ch.ToString() + "@" + RTSrvIP + ":" + RTSrvPort.ToString() + ">";
            env.Send_Make(0, calledNum, "");
        }
        
        //////////////////////////////////////////////////////////////////////
        //Softphone Methods and Events Ending
        //////////////////////////////////////////////////////////////////////

        public void OnCallOffered(int ChanIndex, string CallerIP, string CallerID, string CalleeIP, string CalleeID, uint CallTime, string UniqueID, string AudioFile, int CallDir)
        {
            LogoutText("OnCallOffered event arrived. caller:" + CallerID + " called:" + CalleeID + " call dir: " + CallDir.ToString() + " file: " + AudioFile);

            try
            {
                //if (DataViewType == 0)
                {
                    dataGridView1.Rows[ChanIndex].Cells[0].Value = "Ringing";
                    dataGridView1.Rows[ChanIndex].Cells[1].Value = CallerIP;
                    dataGridView1.Rows[ChanIndex].Cells[2].Value = CallerID;
                    dataGridView1.Rows[ChanIndex].Cells[3].Value = CalleeIP;
                    dataGridView1.Rows[ChanIndex].Cells[4].Value = CalleeID;
                    dataGridView1.Rows[ChanIndex].Cells[5].Value = UniqueID;
                    dataGridView1.Rows[ChanIndex].Cells[6].Value = AudioFile;
                    dataGridView1.Rows[ChanIndex].Cells[7].Value = CallDir == 0 ? "Inbound" : "Outbound";
                }
            }
            catch (Exception)
            {
            }
        }

        public void OnCallConnected(int ChanIndex, string CallerIP, string CallerID, string CalleeIP, string CalleeID, uint InitTime, uint ConnectTime, string UniqueID, string AudioFile, int CallDir)
        {
            LogoutText("OnCallConnected event arrived. caller:" + CallerID + " called:" + CalleeID + " call dir: " + CallDir.ToString() + " file: " + AudioFile);

            try
            {
                //if (DataViewType == 0)
                {
                    dataGridView1.Rows[ChanIndex].Cells[0].Value = "Recording";
                    dataGridView1.Rows[ChanIndex].Cells[1].Value = CallerIP;
                    dataGridView1.Rows[ChanIndex].Cells[2].Value = CallerID;
                    dataGridView1.Rows[ChanIndex].Cells[3].Value = CalleeIP;
                    dataGridView1.Rows[ChanIndex].Cells[4].Value = CalleeID;
                    dataGridView1.Rows[ChanIndex].Cells[5].Value = UniqueID;
                    dataGridView1.Rows[ChanIndex].Cells[6].Value = AudioFile;
                    dataGridView1.Rows[ChanIndex].Cells[7].Value = CallDir == 0 ? "Inbound" : "Outbound";
                }
            }
            catch (Exception)
            {
            }
        }

        public void OnCallIdle(int ChanIndex, string CallerIP, string CallerID, string CalleeIP, string CalleeID, uint InitTime, uint ConnectTime, uint EndTime, string UniqueID, string AudioFile, int AudioFileNum, int Reason, int CallDir, string DTMFStr)
        {
            LogoutText("OnCallIdle event arrived. caller:" + CallerID + " called:" + CalleeID + " call dir: " + CallDir.ToString() + " file: " + AudioFile);

            try
            {
                //if (DataViewType == 0)
                {
                    dataGridView1.Rows[ChanIndex].Cells[0].Value = "Idle";
                    /*
                    dataGridView1.Rows[ChanIndex].Cells[1].Value = CallerIP;
                    dataGridView1.Rows[ChanIndex].Cells[2].Value = CallerID;
                    dataGridView1.Rows[ChanIndex].Cells[3].Value = CalleeIP;
                    dataGridView1.Rows[ChanIndex].Cells[4].Value = CalleeID;
                    dataGridView1.Rows[ChanIndex].Cells[5].Value = UniqueID;
                    dataGridView1.Rows[ChanIndex].Cells[6].Value = AudioFile;
                    dataGridView1.Rows[ChanIndex].Cells[7].Value = CallDir == 0 ? "Inbound" : "Outbound";
                    dataGridView1.Rows[ChanIndex].Cells[8].Value = DTMFStr;
                    */
                    dataGridView1.Rows[ChanIndex].Cells[1].Value = "";
                    dataGridView1.Rows[ChanIndex].Cells[2].Value = "";
                    dataGridView1.Rows[ChanIndex].Cells[3].Value = "";
                    dataGridView1.Rows[ChanIndex].Cells[4].Value = "";
                    dataGridView1.Rows[ChanIndex].Cells[5].Value = "";
                    dataGridView1.Rows[ChanIndex].Cells[6].Value = "";
                    dataGridView1.Rows[ChanIndex].Cells[7].Value = "";
                    dataGridView1.Rows[ChanIndex].Cells[8].Value = "";
                }
            }
            catch (Exception)
            {
            }
        }

        public void OnCallInfo(int ChanIndex, string CallerIP, string CallerID, string CalleeIP, string CalleeID, string UniqueID, string AudioFile, int CallDir)
        {
            LogoutText("OnCallInfo event arrived. caller:" + CallerID + " called:" + CalleeID + " call dir: " + CallDir.ToString() + " file: " + AudioFile);
            try
            {
                //if (DataViewType == 0)
                {
                    dataGridView1.Rows[ChanIndex].Cells[1].Value = CallerIP;
                    dataGridView1.Rows[ChanIndex].Cells[2].Value = CallerID;
                    dataGridView1.Rows[ChanIndex].Cells[3].Value = CalleeIP;
                    dataGridView1.Rows[ChanIndex].Cells[4].Value = CalleeID;
                    dataGridView1.Rows[ChanIndex].Cells[5].Value = UniqueID;
                    dataGridView1.Rows[ChanIndex].Cells[6].Value = AudioFile;
                    dataGridView1.Rows[ChanIndex].Cells[7].Value = CallDir == 0 ? "Inbound" : "Outbound";
                }
            }
            catch (Exception)
            {
            }
        }

        public void OnStatusChannel(VR2Channel chan)
        {
            try
            {
                //if (DataViewType == 0)
                {
                    if (chan.ChanStatus == 0)
                        dataGridView1.Rows[chan.ChanIndex].Cells[0].Value = "Idle";
                    else if (chan.ChanStatus == 1)
                        dataGridView1.Rows[chan.ChanIndex].Cells[0].Value = "Ringing";
                    else if (chan.ChanStatus == 2)
                        dataGridView1.Rows[chan.ChanIndex].Cells[0].Value = "Recording";

                    if (chan.ChanStatus == 0)
                    {
                        dataGridView1.Rows[chan.ChanIndex].Cells[1].Value = "";
                        dataGridView1.Rows[chan.ChanIndex].Cells[2].Value = "";
                        dataGridView1.Rows[chan.ChanIndex].Cells[3].Value = "";
                        dataGridView1.Rows[chan.ChanIndex].Cells[4].Value = "";
                        dataGridView1.Rows[chan.ChanIndex].Cells[5].Value = "";
                        dataGridView1.Rows[chan.ChanIndex].Cells[6].Value = "";
                        dataGridView1.Rows[chan.ChanIndex].Cells[7].Value = "";
                        dataGridView1.Rows[chan.ChanIndex].Cells[8].Value = "";
                    }
                    else
                    {
                        dataGridView1.Rows[chan.ChanIndex].Cells[1].Value = chan.CallerIP;
                        dataGridView1.Rows[chan.ChanIndex].Cells[2].Value = chan.CallerID;
                        dataGridView1.Rows[chan.ChanIndex].Cells[3].Value = chan.CalleeIP;
                        dataGridView1.Rows[chan.ChanIndex].Cells[4].Value = chan.CalleeID;
                        dataGridView1.Rows[chan.ChanIndex].Cells[5].Value = chan.UniqueID;
                        dataGridView1.Rows[chan.ChanIndex].Cells[6].Value = chan.AudioFile;
                        dataGridView1.Rows[chan.ChanIndex].Cells[7].Value = chan.CallDir == 0 ? "Inbound" : "Outbound";
                        dataGridView1.Rows[chan.ChanIndex].Cells[8].Value = chan.DTMFStr;
                    }
                }
            }
            catch (Exception)
            {
            }            
        }

        public void OnCallDTMF(int ChanIndex, string KeyPressed, string DTMFStr)
        {
            try
            {
                //if (DataViewType == 0)
                {
                    dataGridView1.Rows[ChanIndex].Cells[8].Value = DTMFStr;
                }
            }
            catch (Exception)
            {
            }
        }


        public void OnStatusGeneral(string[] members)
        {
            int availableChannelNum = 0;
            int chStatus = 0;

            try
            {
                if (members.Length > 0)
                {
                    //first arg is total number of channels
                    MaxChanNum = Convert.ToInt32(members[0]);
                    tbTotalChannels.Text = MaxChanNum.ToString();

                    if (!dataGridView1.Enabled || dataGridView1.RowCount != MaxChanNum)
                    {
                        dataGridView1.Enabled = true;

                        dataGridView1.DataSource = null;
                        dataGridView1.ReadOnly = true;

                        dataGridView1.RowCount = MaxChanNum;
                        dataGridView1.ColumnCount = 9;

                        dataGridView1.Columns[0].HeaderText = "Status";
                        dataGridView1.Columns[1].HeaderText = "CallerIP";
                        dataGridView1.Columns[2].HeaderText = "CallerID";
                        dataGridView1.Columns[3].HeaderText = "CalleeIP";
                        dataGridView1.Columns[4].HeaderText = "calleeID";
                        dataGridView1.Columns[5].HeaderText = "UniqueID";
                        dataGridView1.Columns[6].HeaderText = "AudioFile";
                        dataGridView1.Columns[7].HeaderText = "Direction";
                        dataGridView1.Columns[8].HeaderText = "DTMF";

                        //dataGridView1.Rows[0].HeaderCell.OwningColumn.Width = 200;

                        for (int i = 0; i < MaxChanNum; i++)
                        {
                            int index = i + 1;
                            dataGridView1.Rows[i].HeaderCell.Value = index.ToString();
                            dataGridView1.Rows[i].Cells[0].Value = "Idle";
                        }

                    }

                    if(RTListening == 1)
                    {
                        if (cbChanID.Items.Count != MaxChanNum && MaxChanNum > 0)
                        {
                            cbChanID.Items.Clear();
                            for (int i = 1; i <= MaxChanNum; i++)
                            {
                                cbChanID.Items.Add(i.ToString());
                            }

                            cbChanID.SelectedIndex = 0;
                            lbRTChanStatus.Text = "Idle";
                        }
                    }
                }
                if (members.Length > 1)
                {
                    //second arg is total number of channels which is available(not offline)
                    tbTotalCalls.Text = members[1];
                }
                else
                {
                    //tbAvailableChannels.Text = MaxChanNum.ToString();
                }

                if (members.Length > 2)
                {
                    //second arg is total number of channels which is offline
                    tbConnectedCalls.Text = members[2];

                    tbFailedCalls.Text = Convert.ToString(Convert.ToInt32(members[1]) - Convert.ToInt32(members[2]));
                }
                else
                {
                    tbOfflineChannels.Text = "0";
                }

                if (members.Length > 3)
                {
                    for (int i = 0; i < MaxChanNum; i++)
                    {
                        chStatus = Convert.ToInt32(members[3 + i]);
                        if (chStatus == -1)
                        {
                            dataGridView1.Rows[i].Cells[0].Value = "Offline";
                        }
                        else if (chStatus == 0)
                        {
                            //if(dataGridView1.Rows[i].Cells[0].Value == "Offline")
                                dataGridView1.Rows[i].Cells[0].Value = "Idle";
                            availableChannelNum++;
                        }
                        else if (chStatus == 1)
                        {
                            //dataGridView1.Rows[i].Cells[0].Value = "Ringing";
                            availableChannelNum++;
                        }
                        else if (chStatus == 2)
                        {
                            //dataGridView1.Rows[i].Cells[0].Value = "Recording";
                            availableChannelNum++;
                        }
                    }

                    tbAvailableChannels.Text = availableChannelNum.ToString();
                    tbOfflineChannels.Text = Convert.ToString(MaxChanNum - availableChannelNum);
                }
            }
            catch (Exception ex)
            {
                LogoutText(ex.ToString());
            }

            waiting_general = false;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                if(RTListening == 1)
                    FreeSIPServer();
            }
            catch (Exception ex)
            {
            }

            if (vr_client != null)
            {
                vr_client.Disconnect();
                vr_client = null;
            }
        }

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

        private void connectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ConnectToServer();
        }

        private void disconnectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            vr_client.Disconnect();
        }



/*
        public void SearchData(string caller, string callee, DateTime dt1, DateTime dt2)
        {
            if(db_set == null) return;

            string commandStr = "SELECT CallerID, CalleeID, TimeInit, TimeBegin, TimeEnd, Duration, RecordPath FROM " + db_set.CallLogTableName + " WHERE ";

            commandStr += "TimeInit >= '" + DateTimeToStr(dt1) + "' AND TimeInit <= '" + DateTimeToStr(dt2) + "' ";
            if (caller.Length > 0)
            {
                commandStr += "AND CallerID = '" + caller + "' ";
            }
            if (callee.Length > 0)
            {
                commandStr += "AND CalleeID = '" + callee + "' ";
            }

            if (db_set.ConnectDB())
            {
                string strCon = db_set.GetConnStr();
                string strSQL = commandStr;
                SqlDataAdapter dataAdapter = new SqlDataAdapter(strSQL, strCon);
                SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter);
                BindingSource dbBindSource = new BindingSource();

                // Populate a new data table and bind it to the BindingSource.
                DataTable table = new DataTable();
                table.Locale = System.Globalization.CultureInfo.InvariantCulture;
                dataAdapter.Fill(table);

                //if (table.Rows.Count > 0)
                {
                    //from channel status view
                    if (dataGridView1.DataSource == null)
                    {
                        dataGridView1.RowCount = 0;
                        dataGridView1.ColumnCount = 0;
                    }

                    DataViewType = 1;

                    dbBindSource.DataSource = table;

                    // Resize the DataGridView columns to fit the newly loaded content.
                    //dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);

                    if (!dataGridView1.Enabled)
                        dataGridView1.Enabled = true;

 
                    // you can make it grid readonly.
                    dataGridView1.ReadOnly = true;

                    // finally bind the data to the grid
                    dataGridView1.DataSource = dbBindSource;

                    searchResultToolStripMenuItem.Enabled = false;
                    channelStatusToolStripMenuItem.Enabled = true;
                }
            }

        }*/

        private void searchToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        /*
                 // Create a subkey named Test9999 under HKEY_CURRENT_USER.
                RegistryKey test9999 = 
                    Registry.CurrentUser.CreateSubKey("Test9999");
                // Create two subkeys under HKEY_CURRENT_USER\Test9999. The
                // keys are disposed when execution exits the using statement.
                using(RegistryKey 
                    testName = test9999.CreateSubKey("TestName"),
                    testSettings = test9999.CreateSubKey("TestSettings"))
                {
                    // Create data for the TestSettings subkey.
                    testSettings.SetValue("Language", "French");
                    testSettings.SetValue("Level", "Intermediate");
                    testSettings.SetValue("ID", 123);
                    testSettings.SetValue("Password", "Secret");
                }

                // Print the information from the Test9999 subkey.
                Console.WriteLine("There are {0} subkeys under {1}.", 
                    test9999.SubKeyCount.ToString(), test9999.Name);
                foreach(string subKeyName in test9999.GetSubKeyNames())
                {
                    using(RegistryKey 
                        tempKey = test9999.OpenSubKey(subKeyName))
                    {
                        Console.WriteLine("\nThere are {0} values for {1}.", 
                            tempKey.ValueCount.ToString(), tempKey.Name);
                        foreach(string valueName in tempKey.GetValueNames())
                        {
                            Console.WriteLine("{0,-8}: {1}", valueName, 
                                tempKey.GetValue(valueName).ToString());
                        }
                    }
                }

                using(RegistryKey 
                    testSettings = test9999.OpenSubKey("TestSettings", true))
                {
                    // Delete the non-secure password value.
                    testSettings.DeleteValue("password");

                    // Verify the deletion.
                    Console.WriteLine((string)testSettings.GetValue(
                        "password", "Password not found."));
                }

                // Delete or close the new subkey.
                Console.Write("\nDelete newly created registry key? (Y/N) ");
                if(Char.ToUpper(Convert.ToChar(Console.Read())) == 'Y')
                {
                    Registry.CurrentUser.DeleteSubKeyTree("Test9999");
                    Console.WriteLine("\nRegistry key {0} deleted.", 
                        test9999.Name);
                }
                else
                {
                    Console.WriteLine("\nRegistry key {0} closed.", 
                        test9999.ToString());
                    test9999.Close();
                }
        * 
        */
        private void btnOptions_Click(object sender, EventArgs e)
        {
            bool softPhoneSettingChanged = false;

            RTListenerOptions rt = new RTListenerOptions();
            rt.RTSrvIP = RTSrvIP;
            rt.RTSrvPort = RTSrvPort;
            rt.RTSoftSIPPort = RTSoftSIPPort;
            rt.RTSoftRTPPort = RTSoftRTPPort;

            if (rt.ShowDialog() == DialogResult.OK)
            {
                RTSrvIP = rt.RTSrvIP;
                RTSrvPort = rt.RTSrvPort;


                if (RTSoftSIPPort != rt.RTSoftSIPPort || RTSoftRTPPort != rt.RTSoftRTPPort)
                    softPhoneSettingChanged = true;

                RTSoftSIPPort = rt.RTSoftSIPPort;
                RTSoftRTPPort = rt.RTSoftRTPPort;

                RegistryKey keyPCBest;
                try
                {
                    keyPCBest = Registry.CurrentUser.CreateSubKey("PCBestNetworks");
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                    return;
                }

                if (keyPCBest == null)
                    return;

                try
                {
                    using (RegistryKey
                        keyVR2 = keyPCBest.CreateSubKey("VR2"))
                    {
                        // Create data for the TestSettings subkey.
                        keyVR2.SetValue("RTSrvIP", RTSrvIP);
                        keyVR2.SetValue("RTSrvPort", RTSrvPort.ToString());

                        keyVR2.SetValue("RTSoftSIPPort", RTSoftSIPPort.ToString());
                        keyVR2.SetValue("RTSoftRTPPort", RTSoftRTPPort.ToString());
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                    return;
                }

                if (softPhoneSettingChanged)
                {
                    FreeSIPServer();
                    Thread.Sleep(2000);
                    InitSIPServer();
                }

            }
        }

        private void quickSearchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (db_set == null)
            {
                string xmlFileName = Application.StartupPath + "\\VR2Config.xml";
                MessageBox.Show("Cannot Search DB! Please enable DB settings in " + xmlFileName + ".");
                return;
            }

            if (!db_set.ConnectDB())
            {
                string xmlFileName = Application.StartupPath + "\\VR2Config.xml";
                MessageBox.Show("Cannot Connect to DB! Please check DB settings in " + xmlFileName + ".");
                return;
            }
            else
            {
                db_set.DisconnectDB();
            }

            /*
            SearchForm dlg = new SearchForm();
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                SearchData(dlg.sCaller, dlg.sCallee, dlg.dtBegin, dlg.dtEnd);
            }*/

            SearchResult sr = new SearchResult();
            sr.db_set = db_set;
            sr.ShowDialog();
             
        }

        private void complexSearchToolStripMenuItem_Click(object sender, EventArgs e)
        {

            if (db_set == null)
            {
                string xmlFileName = Application.StartupPath + "\\VR2Config.xml";
                MessageBox.Show("Cannot Search DB! Please enable DB settings in " + xmlFileName + ".");
                return;
            }

            if (!db_set.ConnectDB())
            {
                string xmlFileName = Application.StartupPath + "\\VR2Config.xml";
                MessageBox.Show("Cannot Connect to DB! Please check DB settings in " + xmlFileName + ".");
                return;
            }
            else
            {
                db_set.DisconnectDB();
            }

            ComplexSearch sr = new ComplexSearch();
            sr.db_set = db_set;
            sr.maxChanNum = MaxChanNum;
            sr.ShowDialog();
        }


/*
        private void channelStatusToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (DataViewType == 1)
            {
                DataViewType = 0;

                dataGridView1.Enabled = true;

                dataGridView1.DataSource = null;
                dataGridView1.ReadOnly = true;

                dataGridView1.RowCount = MaxChanNum;
                dataGridView1.ColumnCount = 9;

                dataGridView1.Columns[0].HeaderText = "Status";
                dataGridView1.Columns[1].HeaderText = "CallerIP";
                dataGridView1.Columns[2].HeaderText = "CallerID";
                dataGridView1.Columns[3].HeaderText = "CalleeIP";
                dataGridView1.Columns[4].HeaderText = "calleeID";
                dataGridView1.Columns[5].HeaderText = "UniqueID";
                dataGridView1.Columns[6].HeaderText = "AudioFile";
                dataGridView1.Columns[7].HeaderText = "Direction";
                dataGridView1.Columns[8].HeaderText = "DTMF";

                //dataGridView1.Rows[0].HeaderCell.OwningColumn.Width = 200;

                for (int i = 0; i < MaxChanNum; i++)
                {
                    int index = i + 1;
                    dataGridView1.Rows[i].HeaderCell.Value = index.ToString();
                    dataGridView1.Rows[i].Cells[0].Value = "Idle";
                }

                searchResultToolStripMenuItem.Enabled = true;
                channelStatusToolStripMenuItem.Enabled = false;
            }
        }

        private void searchResultToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (DataViewType == 0)
            {
                searchToolStripMenuItem_Click(sender, e);
            }
        }
*/

    }

    public class MyVR2Client : VR2Client
    {
        public Form1 main_form;

        public override void ServerConnected(bool bConnected)
        {
            main_form.ServerConnected(bConnected);
        }

        public override void OnCallOffered(int ChanIndex, string CallerIP, string CallerID, string CalleeIP, string CalleeID, uint CallTime, string UniqueID, string AudioFile, int CallDir)
        {
            base.OnCallOffered(ChanIndex, CallerIP, CallerID, CalleeIP, CalleeID, CallTime, UniqueID, AudioFile, CallDir);
            main_form.OnCallOffered(ChanIndex, CallerIP, CallerID, CalleeIP, CalleeID, CallTime, UniqueID, AudioFile, CallDir);
        }

        public override void OnCallConnected(int ChanIndex, string CallerIP, string CallerID, string CalleeIP, string CalleeID, uint InitTime, uint ConnectTime, string UniqueID, string AudioFile, int CallDir)
        {
            base.OnCallConnected(ChanIndex, CallerIP, CallerID, CalleeIP, CalleeID, InitTime, ConnectTime, UniqueID, AudioFile, CallDir);
            main_form.OnCallConnected(ChanIndex, CallerIP, CallerID, CalleeIP, CalleeID, InitTime, ConnectTime, UniqueID, AudioFile, CallDir);
        }

        public override void OnCallIdle(int ChanIndex, string CallerIP, string CallerID, string CalleeIP, string CalleeID, uint InitTime, uint ConnectTime, uint EndTime, string UniqueID, string AudioFile, int AudioFileNum, int Reason, int CallDir, string DTMFStr)
        {
            base.OnCallIdle(ChanIndex, CallerIP, CallerID, CalleeIP, CalleeID, InitTime, ConnectTime, EndTime, UniqueID, AudioFile, AudioFileNum, Reason, CallDir, DTMFStr);
            main_form.OnCallIdle(ChanIndex, CallerIP, CallerID, CalleeIP, CalleeID, InitTime, ConnectTime, EndTime, UniqueID, AudioFile, AudioFileNum, Reason, CallDir, DTMFStr);
        }

        public override void OnCallInfo(int ChanIndex, string CallerIP, string CallerID, string CalleeIP, string CalleeID, string UniqueID, string AudioFile, int CallDir)
        {
            base.OnCallInfo(ChanIndex, CallerIP, CallerID, CalleeIP, CalleeID, UniqueID, AudioFile, CallDir);
            main_form.OnCallInfo(ChanIndex, CallerIP, CallerID, CalleeIP, CalleeID, UniqueID, AudioFile, CallDir);
        }

        public override void OnStatusGeneral(string[] members)
        {
            base.OnStatusGeneral(members);
            main_form.OnStatusGeneral(members);
            
        }

        public override void OnStatusChannel(VR2Channel chan)
        {
            base.OnStatusChannel(chan);
            main_form.OnStatusChannel(chan);
        }

        public override void OnCallDTMF(int ChanIndex, string KeyPressed, string DTMFStr)
        {
            base.OnCallDTMF(ChanIndex, KeyPressed, DTMFStr);
            main_form.OnCallDTMF(ChanIndex, KeyPressed, DTMFStr);
        }

    }
}