// SIPServerAppDlg.cpp : implementation file
//

#include "stdafx.h"
#include "SIPServerApp.h"
#include "SIPServerAppDlg.h"
#include "FolderDialog.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSIPServerAppDlg dialog

CSIPServerAppDlg::CSIPServerAppDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSIPServerAppDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CSIPServerAppDlg)
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_pEnv = 0;
}

void CSIPServerAppDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSIPServerAppDlg)
	DDX_Control(pDX, IDC_EDIT_SIP_ADDR4, m_editSIPAddr4);
	DDX_Control(pDX, IDC_EDIT_SIP_ADDR3, m_editSIPAddr3);
	DDX_Control(pDX, IDC_EDIT_SIP_ADDR2, m_editSIPAddr2);
	DDX_Control(pDX, IDC_EDIT_SIP_ADDR1, m_editSIPAddr1);
	DDX_Control(pDX, IDC_BUTTON_DIAL4, m_btnDial4);
	DDX_Control(pDX, IDC_BUTTON_DIAL3, m_btnDial3);
	DDX_Control(pDX, IDC_BUTTON_DIAL2, m_btnDial2);
	DDX_Control(pDX, IDC_BUTTON_DIAL1, m_btnDial1);
	DDX_Control(pDX, IDC_EDIT_MAX_DTMF_DIGITS, m_editDTMFMaxDigits);
	DDX_Control(pDX, IDC_DTMF_TIMEOUT, m_editDTMFTimeout);
	DDX_Control(pDX, IDC_EDIT_DTMF_TERM_STR, m_editDTMFTermStr);
	DDX_Control(pDX, IDOK, m_btnExit);
	DDX_Control(pDX, IDC_EDIT_CFG, m_editCfg);
	DDX_Control(pDX, IDC_STATIC_CHAN4_STATUS, m_Status4);
	DDX_Control(pDX, IDC_STATIC_CHAN3_STATUS, m_Status3);
	DDX_Control(pDX, IDC_STATIC_CHAN2_STATUS, m_Status2);
	DDX_Control(pDX, IDC_STATIC_CHAN1_STATUS, m_Status1);
	DDX_Control(pDX, IDC_BUTTON_SOUND_FILE_BROWSE, m_btnFileBrowse);
	DDX_Control(pDX, IDC_BUTTON_SIP_STOP, m_btnSIPStop);
	DDX_Control(pDX, IDC_BUTTON_SIP_START, m_btnSIPStart);
	DDX_Control(pDX, IDC_EDIT_SOUND_FILE, m_SoundFile);
	DDX_Control(pDX, IDC_COMBO_APP_TYPE, m_cbxAppType);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSIPServerAppDlg, CDialog)
	//{{AFX_MSG_MAP(CSIPServerAppDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_SOUND_FILE_BROWSE, OnButtonSoundFileBrowse)
	ON_BN_CLICKED(IDC_BUTTON_SIP_START, OnButtonSipStart)
	ON_BN_CLICKED(IDC_BUTTON_SIP_STOP, OnButtonSipStop)
	ON_CBN_SELCHANGE(IDC_COMBO_APP_TYPE, OnSelchangeComboAppType)
	ON_BN_CLICKED(IDC_BUTTON_DIAL1, OnButtonDial1)
	ON_BN_CLICKED(IDC_BUTTON_DIAL2, OnButtonDial2)
	ON_BN_CLICKED(IDC_BUTTON_DIAL3, OnButtonDial3)
	ON_BN_CLICKED(IDC_BUTTON_DIAL4, OnButtonDial4)
	//ON_MESSAGE(WM_SDKAPP_OFFERED, OnSDKAppMessage)
	//ON_MESSAGE(WM_SDKAPP_DIALING, OnSDKAppMessage)
	//ON_MESSAGE(WM_SDKAPP_RINGING, OnSDKAppMessage)
	//ON_MESSAGE(WM_SDKAPP_CONNECTED, OnSDKAppMessage)
	//ON_MESSAGE(WM_SDKAPP_IDLE, OnSDKAppMessage)
	//ON_MESSAGE(WM_SDKAPP_REGSTATUS, OnSDKAppMessage)
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_BUTTON1, &CSIPServerAppDlg::OnBnClickedButton1)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSIPServerAppDlg message handlers

BOOL CSIPServerAppDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	m_editCfg.SetWindowText("c:\\sdk\\ini\\GTSIPServerApp.ini");
	m_cbxAppType.SetCurSel(0);
	
	m_btnSIPStart.EnableWindow(TRUE);
	m_btnSIPStop.EnableWindow(FALSE);

	m_editDTMFMaxDigits.SetWindowText("0");
	m_editDTMFTermStr.SetWindowText("");
	m_editDTMFTimeout.SetWindowText("0");

	m_btnDial1.EnableWindow(FALSE);
	m_btnDial2.EnableWindow(FALSE);
	m_btnDial3.EnableWindow(FALSE);
	m_btnDial4.EnableWindow(FALSE);

	m_editSIPAddr1.EnableWindow(FALSE);
	m_editSIPAddr2.EnableWindow(FALSE);
	m_editSIPAddr3.EnableWindow(FALSE);
	m_editSIPAddr4.EnableWindow(FALSE);

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CSIPServerAppDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CSIPServerAppDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CSIPServerAppDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CSIPServerAppDlg::Log(int ch, const char* info)
{
	switch(ch)
	{
	case 0:
		m_Status1.SetWindowText(info);
		break;
	case 1:
		m_Status2.SetWindowText(info);
		break;
	case 2:
		m_Status3.SetWindowText(info);
		break;
	case 3:
		m_Status4.SetWindowText(info);
		break;
	}
}

void CSIPServerAppDlg::InitSIPServer(int nCurSel, const char* iniCfgFile)
{
	m_pEnv = new CGTSIPServerAppEnv(iniCfgFile);
	m_pEnv->m_nCurSel = nCurSel;
	m_pEnv->m_pMainDlg = this;
	m_pEnv->SetMainWnd(m_hWnd);
	if(!m_pEnv->StartServer())
	{
		MessageBox("StartServer Failed! Please check if SIP port is being used by another application!", "Error");
	}
}

void CSIPServerAppDlg::FreeSIPServer()
{
	m_pEnv->StopServer();
	delete m_pEnv;
	m_pEnv = 0;
}

void CSIPServerAppDlg::OnSelchangeComboAppType() 
{
	// TODO: Add your control notification handler code here
	int nSel = m_cbxAppType.GetCurSel();
	if(nSel == 0 || nSel == 1)
	{
		m_SoundFile.EnableWindow(TRUE);
		m_btnFileBrowse.EnableWindow(TRUE);

		m_editDTMFMaxDigits.EnableWindow(TRUE);
		m_editDTMFTermStr.EnableWindow(TRUE);
		m_editDTMFTimeout.EnableWindow(TRUE);
	}
	else if(nSel == 5)
	{
		m_SoundFile.EnableWindow(TRUE);
		m_btnFileBrowse.EnableWindow(TRUE);

		m_editDTMFMaxDigits.EnableWindow(FALSE);
		m_editDTMFTermStr.EnableWindow(FALSE);
		m_editDTMFTimeout.EnableWindow(FALSE);
	}
	else if(nSel == 9)
	{
		m_SoundFile.EnableWindow(TRUE);
		m_btnFileBrowse.EnableWindow(TRUE);
	}
	else
	{
		m_SoundFile.EnableWindow(FALSE);
		m_btnFileBrowse.EnableWindow(FALSE);

		m_editDTMFMaxDigits.EnableWindow(FALSE);
		m_editDTMFTermStr.EnableWindow(FALSE);
		m_editDTMFTimeout.EnableWindow(FALSE);
	}	
}

void CSIPServerAppDlg::OnButtonSoundFileBrowse() 
{
	// TODO: Add your control notification handler code here
	CFileDialog* dlg = 0;

	int nSel = m_cbxAppType.GetCurSel();

	if(nSel == 0)
	{
		dlg = new CFileDialog(TRUE);
		if(dlg->DoModal() == IDOK)
		{
			m_SoundFile.SetWindowText(dlg->GetPathName());
		}
		delete dlg;
	}
	else if(nSel == 1)
	{
		dlg = new CFileDialog(FALSE);
		if(dlg->DoModal() == IDOK)
		{
			m_SoundFile.SetWindowText(dlg->GetPathName());
		}
		delete dlg;
	}
	else if(nSel == 5)
	{
		CFolderDialog  dirdlg;
		if(dirdlg.DoModal() == IDOK)
		{
			m_SoundFile.SetWindowText(dirdlg.GetPathName());
		}
	}
	else if(nSel == 9)
	{
		dlg = new CFileDialog(TRUE);
		if(dlg->DoModal() == IDOK)
		{
			m_SoundFile.SetWindowText(dlg->GetPathName());
		}
		delete dlg;
	}

}

void CSIPServerAppDlg::OnButtonSipStart() 
{
	// TODO: Add your control notification handler code here
	int nSel = m_cbxAppType.GetCurSel();

	char cfgFile[MAX_PATH] = "";
	m_editCfg.GetWindowText(cfgFile, MAX_PATH);

	if (!PathFileExists(cfgFile))
	{
		MessageBox("Config File doesn't exist!", "ERROR!");
		return;
	}

	m_cbxAppType.EnableWindow(FALSE);

	m_SoundFile.EnableWindow(FALSE);
	m_btnFileBrowse.EnableWindow(FALSE);

	m_editDTMFMaxDigits.EnableWindow(FALSE);
	m_editDTMFTermStr.EnableWindow(FALSE);
	m_editDTMFTimeout.EnableWindow(FALSE);


	m_btnSIPStart.EnableWindow(FALSE);
	m_btnSIPStop.EnableWindow(TRUE);

	m_btnExit.EnableWindow(FALSE);

	m_btnDial1.EnableWindow(TRUE);
	m_btnDial2.EnableWindow(TRUE);
	m_btnDial3.EnableWindow(TRUE);
	m_btnDial4.EnableWindow(TRUE);

	m_editSIPAddr1.EnableWindow(TRUE);
	m_editSIPAddr2.EnableWindow(TRUE);
	m_editSIPAddr3.EnableWindow(TRUE);
	m_editSIPAddr4.EnableWindow(TRUE);

	InitSIPServer(nSel, cfgFile);
}

void CSIPServerAppDlg::OnButtonSipStop() 
{
	// TODO: Add your control notification handler code here
	m_cbxAppType.EnableWindow(TRUE);

	int nSel = m_cbxAppType.GetCurSel();

	if(nSel == 0 || nSel == 1)
	{
		m_SoundFile.EnableWindow(TRUE);
		m_btnFileBrowse.EnableWindow(TRUE);

		m_editDTMFMaxDigits.EnableWindow(TRUE);
		m_editDTMFTermStr.EnableWindow(TRUE);
		m_editDTMFTimeout.EnableWindow(TRUE);
	}
	else if(nSel == 5)
	{
		m_SoundFile.EnableWindow(TRUE);
		m_btnFileBrowse.EnableWindow(TRUE);

		m_editDTMFMaxDigits.EnableWindow(FALSE);
		m_editDTMFTermStr.EnableWindow(FALSE);
		m_editDTMFTimeout.EnableWindow(FALSE);
	}
	else if(nSel == 9)
	{
		m_SoundFile.EnableWindow(TRUE);
		m_btnFileBrowse.EnableWindow(TRUE);
	}
	else
	{
		m_SoundFile.EnableWindow(FALSE);
		m_btnFileBrowse.EnableWindow(FALSE);

		m_editDTMFMaxDigits.EnableWindow(FALSE);
		m_editDTMFTermStr.EnableWindow(FALSE);
		m_editDTMFTimeout.EnableWindow(FALSE);
	}

	m_btnSIPStart.EnableWindow(TRUE);
	m_btnSIPStop.EnableWindow(FALSE);

	m_btnDial1.EnableWindow(FALSE);
	m_btnDial2.EnableWindow(FALSE);
	m_btnDial3.EnableWindow(FALSE);
	m_btnDial4.EnableWindow(FALSE);

	m_editSIPAddr1.EnableWindow(FALSE);
	m_editSIPAddr2.EnableWindow(FALSE);
	m_editSIPAddr3.EnableWindow(FALSE);
	m_editSIPAddr4.EnableWindow(FALSE);
	
	FreeSIPServer();

	m_btnExit.EnableWindow(TRUE);
}


void CSIPServerAppDlg::On_RecvConnected(int ch)
{
	CButton *pButton = 0;
	CEdit *pEdit= 0;
	switch(ch)
	{
	case 0:
		pButton = &m_btnDial1;
		pEdit = &m_editSIPAddr1;
		break;
	case 1:
		pButton = &m_btnDial2;
		pEdit = &m_editSIPAddr2;
		break;
	case 2:
		pButton = &m_btnDial3;
		pEdit = &m_editSIPAddr3;
		break;
	case 3:
		pButton = &m_btnDial4;
		pEdit = &m_editSIPAddr4;
		break;
	}

	if(pButton)
	{
		pButton->EnableWindow(TRUE);
		pButton->SetWindowText("HangUp");
	}
	if(pEdit)
		pEdit->EnableWindow(FALSE);
}


void CSIPServerAppDlg::On_RecvOffered(int ch, const char* sCaller, const char* sCallee, const char* sDestAddr, \
	const char* sViaAddr, const char* sFromIP, unsigned short nFromPort)
{
	CButton *pButton = 0;
	CEdit *pEdit= 0;
	switch(ch)
	{
	case 0:
		pButton = &m_btnDial1;
		pEdit = &m_editSIPAddr1;
		break;
	case 1:
		pButton = &m_btnDial2;
		pEdit = &m_editSIPAddr2;
		break;
	case 2:
		pButton = &m_btnDial3;
		pEdit = &m_editSIPAddr3;
		break;
	case 3:
		pButton = &m_btnDial4;
		pEdit = &m_editSIPAddr4;
		break;
	}

	if(pButton)
	{
		pButton->EnableWindow(TRUE);
		pButton->SetWindowText("HangUp");
	}
	if(pEdit)
		pEdit->EnableWindow(FALSE);
}

void CSIPServerAppDlg::On_RecvDialing(int ch, const char* sCaller, const char* sCallee)
{
	CButton *pButton = 0;
	CEdit *pEdit= 0;
	switch(ch)
	{
	case 0:
		pButton = &m_btnDial1;
		pEdit = &m_editSIPAddr1;
		break;
	case 1:
		pButton = &m_btnDial2;
		pEdit = &m_editSIPAddr2;
		break;
	case 2:
		pButton = &m_btnDial3;
		pEdit = &m_editSIPAddr3;
		break;
	case 3:
		pButton = &m_btnDial4;
		pEdit = &m_editSIPAddr4;
		break;
	}

	if(pButton)
	{
		pButton->EnableWindow(TRUE);
		pButton->SetWindowText("HangUp");
	}
	if(pEdit)
		pEdit->EnableWindow(FALSE);
}

void CSIPServerAppDlg::On_RecvIdle(int ch, int code, const char* desc)
{
	CButton *pButton = 0;
	CEdit *pEdit= 0;
	switch(ch)
	{
	case 0:
		pButton = &m_btnDial1;
		pEdit = &m_editSIPAddr1;
		break;
	case 1:
		pButton = &m_btnDial2;
		pEdit = &m_editSIPAddr2;
		break;
	case 2:
		pButton = &m_btnDial3;
		pEdit = &m_editSIPAddr3;
		break;
	case 3:
		pButton = &m_btnDial4;
		pEdit = &m_editSIPAddr4;
		break;
	}

	if(pButton)
	{
		pButton->EnableWindow(TRUE);
		pButton->SetWindowText("Dial");
	}
	if(pEdit)
		pEdit->EnableWindow(TRUE);
}

void CSIPServerAppDlg::On_RecvRinging(int ch)
{
	CButton *pButton = 0;
	CEdit *pEdit= 0;
	switch(ch)
	{
	case 0:
		pButton = &m_btnDial1;
		pEdit = &m_editSIPAddr1;
		break;
	case 1:
		pButton = &m_btnDial2;
		pEdit = &m_editSIPAddr2;
		break;
	case 2:
		pButton = &m_btnDial3;
		pEdit = &m_editSIPAddr3;
		break;
	case 3:
		pButton = &m_btnDial4;
		pEdit = &m_editSIPAddr4;
		break;
	}

	if(pButton)
	{
		pButton->EnableWindow(TRUE);
		pButton->SetWindowText("HangUp");
	}
	if(pEdit)
		pEdit->EnableWindow(FALSE);
}

void CSIPServerAppDlg::OnButtonDial1() 
{
	// TODO: Add your control notification handler code here
	CButton *pButton = &m_btnDial1;
	CEdit *pEdit= &m_editSIPAddr1;
	PressDialOrHangup(0, pButton, pEdit);
}

void CSIPServerAppDlg::OnButtonDial2() 
{
	// TODO: Add your control notification handler code here
	CButton *pButton = &m_btnDial2;
	CEdit *pEdit= &m_editSIPAddr2;
	PressDialOrHangup(1, pButton, pEdit);	
}

void CSIPServerAppDlg::OnButtonDial3() 
{
	// TODO: Add your control notification handler code here
	CButton *pButton = &m_btnDial3;
	CEdit *pEdit= &m_editSIPAddr3;
	PressDialOrHangup(2, pButton, pEdit);	
}

void CSIPServerAppDlg::OnButtonDial4() 
{
	// TODO: Add your control notification handler code here
	CButton *pButton = &m_btnDial4;
	CEdit *pEdit= &m_editSIPAddr4;
	PressDialOrHangup(3, pButton, pEdit);	
}

void CSIPServerAppDlg::PressDialOrHangup(int ch, CButton* pButton, CEdit* pEdit)
{
	GTAPI_Channel* pChan = m_pEnv->GetChannel(ch);	
	if(pChan->ch_status != GTAPI_Channel::GTAPI_CHANNEL_IDLE)
	{
		m_pEnv->Send_HangUp(ch, 0, "");
	}
	else
	{
		char s[256];
		char sTemp[256];

		memset(s, 0, 256);
		memset(sTemp, 0, 256);

		pEdit->GetWindowText(s, 255);

		if(!*s) return;

		if(strstr(s, "sip:") == s) //there are NOT '<' and '>'
		{
			sprintf(sTemp, "<%s>", s);
		}
		else if(strstr(s, "<sip:") == s) //there are '<' and '>'
		{
			sprintf(sTemp, "%s", s);
		}
		else if(strchr(s, '@')) //there is '@' but without 'sip:'
		{
			sprintf(sTemp, "<sip:%s>", s);
		}
		else //there is not '@', and no 'sip:'
		{
			if(*m_pEnv->CFG_GetValue("gtsrv.sip.reg1.domain", ""))
			{
				sprintf(sTemp, "<sip:%s@%s>", s, m_pEnv->CFG_GetValue("gtsrv.sip.reg1.domain", ""));
			}
			else
			{
				//there is no sip account
				//cannot call, just return
				return;
			}
		}

		m_pEnv->Send_Make(ch, sTemp, "");
	}
}

/*
LRESULT CSIPServerAppDlg::OnSDKAppMessage(WPARAM wParam, LPARAM lParam)
{
	sdkapp_msg* msg = (sdkapp_msg*)lParam;
	if(!msg) return 0;
	
	switch(msg->eventID)
	{
		case WM_SDKAPP_OFFERED:
		On_RecvOffered(msg->chanID, msg->args[0], msg->args[1], msg->args[2], msg->args[3], msg->args[4], atoi(msg->args[5]));
		break;
		case WM_SDKAPP_DIALING:
		On_RecvDialing(msg->chanID, msg->args[0], msg->args[1]);
		break;
		case WM_SDKAPP_RINGING:
		On_RecvRinging(msg->chanID);
		break;
		case WM_SDKAPP_CONNECTED:
		On_RecvConnected(msg->chanID);
		break;
		case WM_SDKAPP_IDLE:
		On_RecvIdle(msg->chanID, atoi(msg->args[0]), msg->args[1]);
		break;
		case WM_SDKAPP_REGSTATUS:
		//On_RecvRegStatus(msg->chanID, atoi(msg->args[0]), atoi(msg->args[1]));
		break;
	}

	delete msg;
}
*/

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//CGTSIPServerAppEnv
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CGTSIPServerAppEnv::CGTSIPServerAppEnv(const char* cfgFile):CGTAPIEnv()
{
	m_pMainDlg = 0;
	m_bStopping = FALSE;
	strcpy_s(m_sCfgFile, sizeof(m_sCfgFile), cfgFile);
}

CGTSIPServerAppEnv::~CGTSIPServerAppEnv()
{

}

bool CGTSIPServerAppEnv::StartServer()
{
	//Configuration file, if you want to define parameters in a file
	CFG_SetValue(GTSRV_CFG_FILENAME, m_sCfgFile);

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

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

	if(m_nCurSel == 8) //Fax tone detection
	{
		CFG_SetValue("gtsrv.sip.prefered.codec", "0,8"); //only use G.711 Mulaw and Alaw for faxes
	}

	//Application name, it is related to sdk licence
	//Please contact http://www.pcbest.net/contactus.htm to get licence info
	SetAppName("TestServerApp");

	bool ret = CGTAPIEnv::StartServer();

	Send_GetRegStatus(0);

/*
	if(GetDetectedNATType() >= 0x0A && CFG_GetIntValue("gtsrv.sip.use.nat.addr", 0) == 0)
	{
		m_pMainDlg->MessageBox("You may not be able to make Internet calls becuase you have a blocked network.\n Check you network or config your firewall properly, then try again.");
	}
*/

	if(m_nCurSel == 6)
		Send_StartConference(0);

	if(m_nCurSel == 9)
	{
		for(int i=0; i<4; i++)
		{
			EnableChanVideo(i, GT_TRUE);
		}
	}

	return ret;
}

bool CGTSIPServerAppEnv::StopServer()
{
	m_bStopping = TRUE;

	if(m_nCurSel == 6)
		Send_StopConference(0);

	return CGTAPIEnv::StopServer();
}


void CGTSIPServerAppEnv::On_RecvConnected(int ch)
{
	char sLog[255];
	CString stemp;

	CGTAPIEnv::On_RecvConnected(ch);

	//when it is stopping, the GUI thread is in GUI function, but the backend thread trying to update GUI in Env On_ functions.
	//This makes backend thread stops and StopServer cannot run smoothly.
	//here I am using a flag to tell if it is stopping. If it is, then not run GUI related functions
	if(m_bStopping) 
		return;

	m_pMainDlg->On_RecvConnected(ch);

	m_pMainDlg->m_editDTMFMaxDigits.GetWindowText(stemp);
	int maxDigits = atoi(stemp);

	m_pMainDlg->m_editDTMFTimeout.GetWindowText(stemp);
	int timeout = atoi(stemp);

	CString termStr;
	m_pMainDlg->m_editDTMFTermStr.GetWindowText(termStr);

	int nSel = m_nCurSel; //m_pMainDlg->m_cbxAppType.GetCurSel();

	if(nSel == 0) //play sound
	{
		CString fn;
		m_pMainDlg->m_SoundFile.GetWindowText(fn);

		Send_PlayAudio(ch, fn, maxDigits, termStr, timeout, 0) ;

		sprintf(sLog, "Connected! Playing sound %s.", fn);
		m_pMainDlg->Log(ch, sLog);

		StartTimer(ch, 2000);
	}
	else if(nSel == 1) //record sound
	{
		char sTemp[255];
		char sTemp1[512];
		char *p = 0;

		m_pMainDlg->m_SoundFile.GetWindowText(sTemp, 255);

		//add channel id into file name to make sure files are unique for individual channels
		p = sTemp + strlen(sTemp) - 1;
		while(*p != '.' && p > sTemp) p--;

		if(*p == '.')
		{
			*p = 0;
			p++;
			sprintf(sTemp1, "%s-%d.%s", sTemp, ch, p);
		}
		else// p == sTemp, there is no extersion
		{
			sprintf(sTemp1, "%s-%d", sTemp, ch);
		}

		Send_RecordAudio(ch, sTemp1, maxDigits, termStr, timeout, 0);

		sprintf(sLog, "Connected! Recording sound to %s.", sTemp1);
		m_pMainDlg->Log(ch, sLog);

		StartTimer(ch, 2000);
	}
	else if(nSel == 2) //echo test
	{
		Send_HalfConnect(ch, ch);
		m_pMainDlg->Log(ch, "Connected! Echo testing...");
	}
	else if(nSel == 3) //call bridge
	{
		if(ch == 0)
		{
			m_pMainDlg->Log(ch, "Connected! Waiting for next channel to connect.");
		}
		else if(ch == 1)
		{
			Send_DuplexConnect(0, 1);
			m_pMainDlg->Log(0, "Connected! Chan 1 and 2 are connected!");
			m_pMainDlg->Log(1, "Connected! Chan 1 and 2 are connected!");
		}
		else if(ch == 2)
		{
			m_pMainDlg->Log(ch, "Connected! Waiting for next channel to connect.");
		}
		else if(ch == 3)
		{
			Send_DuplexConnect(2, 3);
			m_pMainDlg->Log(2, "Connected! Chan 3 and 4 are connected!");
			m_pMainDlg->Log(3, "Connected! Chan 3 and 4 are connected!");
		}
	}
	else if(nSel == 4) //DTMF detector
	{
		Send_EnableDTMF(ch, 0, "", 0);
		m_pMainDlg->Log(ch, "Connected! Waiting for DTMF digits.");
	}
	else if(nSel == 5) //music on hold
	{
		CString fn;
		m_pMainDlg->m_SoundFile.GetWindowText(fn);

		Send_StartMusicOnHold(ch, fn, 1, 0) ;
		sprintf(sLog, "Connected! Music on hold, playing music files in %s.", fn);
		m_pMainDlg->Log(ch, sLog);
	}
	else if(nSel == 6)
	{
		Send_SetChanInConference(0, ch, 1);
		sprintf(sLog, "Connected! In conference room");
		m_pMainDlg->Log(ch, sLog);
	}
	else if(nSel == 7)
	{
		sprintf(sLog, "Connected! Detecting voice ..., please talk.");
		m_pMainDlg->Log(ch, sLog);
	}
	else if(nSel == 8)
	{
		sprintf(sLog, "Connected! Detecting fax ...");
		m_pMainDlg->Log(ch, sLog);

		Send_ClearToneList(ch);
		Send_AddTone(ch, 2100, 2200); //T.30 standard, callee plays 2100HZ for 2.6s-4.s,
		Send_AddTone(ch, 1100, 400);  //T.30 standard, caller plays 1100HZ for 500ms,
		Send_StartToneDetection(ch);
	}
	else if(nSel == 9)
	{
		CString fn;
		m_pMainDlg->m_SoundFile.GetWindowText(fn);

		Send_PlayAndRecordVideo(ch, fn, 0);

		sprintf(sLog, "Connected! Playing video %s.", fn);
		m_pMainDlg->Log(ch, sLog);
	}


}

void CGTSIPServerAppEnv::On_RecvOffered(int ch, const char* sCaller, const char* sCallee, const char* sDestAddr, \
	const char* sViaAddr, const char* sFromIP, unsigned short nFromPort)
{
	CGTAPIEnv::On_RecvOffered(ch, sCaller, sCallee, sDestAddr, \
	sViaAddr, sFromIP, nFromPort);

	//when it is stopping, the GUI thread is in GUI function, but the backend thread trying to update GUI in Env On_ functions.
	//This makes backend thread stops and StopServer cannot run smoothly.
	//here I am using a flag to tell if it is stopping. If it is, then not run GUI related functions
	if(m_bStopping) 
		return;

	m_pMainDlg->On_RecvOffered(ch, sCaller, sCallee, sDestAddr, sViaAddr, sFromIP, nFromPort);

	char sTemp[255];

	sprintf(sTemp, "New call from %s to %s.", sCaller, sCallee);
	m_pMainDlg->Log(ch, sTemp);

	//Sleep(2000);

	Send_Answer(ch);
}

void CGTSIPServerAppEnv::On_RecvDialing(int ch, const char* sCaller, const char* sCallee)
{
	CGTAPIEnv::On_RecvDialing(ch, sCaller, sCallee);
	m_pMainDlg->On_RecvDialing(ch, sCaller, sCallee);
}

void CGTSIPServerAppEnv::On_RecvIdle(int ch, int code, const char* desc)
{
	CGTAPIEnv::On_RecvIdle(ch, code, desc);
	m_pMainDlg->On_RecvIdle(ch, code, desc);

	StopTimer(ch);

	//when it is stopping, the GUI thread is in GUI function, but the backend thread trying to update GUI in Env On_ functions.
	//This makes backend thread stops and StopServer cannot run smoothly.
	//here I am using a flag to tell if it is stopping. If it is, then not run GUI related functions
	if(m_bStopping) 
		return;

	m_pMainDlg->Log(ch, "IDLE");
}

void CGTSIPServerAppEnv::On_RecvRinging(int ch)
{
	CGTAPIEnv::On_RecvRinging(ch);
	m_pMainDlg->On_RecvRinging(ch);
}

void CGTSIPServerAppEnv::On_RecvRegStatus(int user_id, int status, int regtime)
{
	CGTAPIEnv::On_RecvRegStatus(user_id, status, regtime);

	//when it is stopping, the GUI thread is in GUI function, but the backend thread trying to update GUI in Env On_ functions.
	//This makes backend thread stops and StopServer cannot run smoothly.
	//here I am using a flag to tell if it is stopping. If it is, then not run GUI related functions
	if(m_bStopping) 
		return;

	char sTemp[100];
	if(status)
	{
		sprintf(sTemp, "C++ SIP Server Application Demo --- %s", CFG_GetValue("gtsrv.sip.reg1.authorization", ""));
	}
	else
	{
		sprintf(sTemp, "C++ SIP Server Application Demo --- %s XXX!",  CFG_GetValue("gtsrv.sip.reg1.authorization", ""));
	}

	m_pMainDlg->SetWindowText(sTemp);
}

void CGTSIPServerAppEnv::On_RecvAudioPlayDone(int ch, int doneReason, const char* dtmfBuffer)
{
}

void CGTSIPServerAppEnv::On_RecvAudioRecordDone(int ch, int doneReason, const char* dtmfBuffer)
{
}

void CGTSIPServerAppEnv::On_RecvAudioStatus(int ch, int resType, int statusCode, unsigned long bytesDone)
{
	char sLog[255];
	CString stemp;

	if(m_nCurSel == 0)
	{
		CString fn;
		m_pMainDlg->m_SoundFile.GetWindowText(fn);
		sprintf(sLog, "Connected! Playing sound %s. Offset bytes: %u", fn, bytesDone);
		m_pMainDlg->Log(ch, sLog);
	}
	else if(m_nCurSel == 1)
	{
		char sTemp[255];
		char sTemp1[512];
		char *p = 0;

		m_pMainDlg->m_SoundFile.GetWindowText(sTemp, 255);

		//add channel id into file name to make sure files are unique for individual channels
		p = sTemp + strlen(sTemp) - 1;
		while(*p != '.' && p > sTemp) p--;

		if(*p == '.')
		{
			*p = 0;
			p++;
			sprintf(sTemp1, "%s-%d.%s", sTemp, ch, p);
		}
		else// p == sTemp, there is no extersion
		{
			sprintf(sTemp1, "%s-%d", sTemp, ch);
		}

		sprintf(sLog, "Connected! Recording sound to %s. Offset bytes: %u", sTemp1, bytesDone);
		m_pMainDlg->Log(ch, sLog);
	}
}

void CGTSIPServerAppEnv::On_RecvDTMFDone(int ch, int reason, const char* dtmfBuf)
{
	//Send_HungUp(ch);
}

void CGTSIPServerAppEnv::On_RecvDTMFKeyDown(int ch, unsigned char keyValue, unsigned long ticks)
{
	char sTemp[255];

	//when it is stopping, the GUI thread is in GUI function, but the backend thread trying to update GUI in Env On_ functions.
	//This makes backend thread stops and StopServer cannot run smoothly.
	//here I am using a flag to tell if it is stopping. If it is, then not run GUI related functions
	if(m_bStopping) 
		return;

	sprintf(sTemp, "Connected! %c key down!", keyValue); 
	m_pMainDlg->Log(ch, sTemp);
}

void CGTSIPServerAppEnv::On_RecvDTMFKeyUp(int ch, unsigned char keyValue, unsigned long ticks)
{
	char sTemp[255];

	//when it is stopping, the GUI thread is in GUI function, but the backend thread trying to update GUI in Env On_ functions.
	//This makes backend thread stops and StopServer cannot run smoothly.
	//here I am using a flag to tell if it is stopping. If it is, then not run GUI related functions
	if(m_bStopping) 
		return;

	sprintf(sTemp, "Connected! %c key up!", keyValue); 
	m_pMainDlg->Log(ch, sTemp);
}

void CGTSIPServerAppEnv::On_VoiceActivityDetected(int ch, int voice_dir, int voice_on, int level, unsigned int reserved)
{
	char sLog[255];

	//when it is stopping, the GUI thread is in GUI function, but the backend thread trying to update GUI in Env On_ functions.
	//This makes backend thread stops and StopServer cannot run smoothly.
	//here I am using a flag to tell if it is stopping. If it is, then not run GUI related functions
	if(m_bStopping) 
		return;

	if(m_nCurSel == 7 && voice_dir == 1)
	{
		if(voice_on)
			sprintf(sLog, "Connected! Voice is on.");
		else
			sprintf(sLog, "Connected! Voice is off.");

		m_pMainDlg->Log(ch, sLog);
	}

}

void CGTSIPServerAppEnv::OnTimer(int ch)
{
	if(m_nCurSel == 0 || m_nCurSel == 1)
	{
		Send_GetAudioStatus(ch);

		if(GetChannel(ch)->ch_status == GTAPI_Channel::GTAPI_CHANNEL_CONNECTED)
		{
			StartTimer(ch, 2000);
		}
	}
}

void CGTSIPServerAppEnv::On_RecvToneDetected(int ch, int freq)
{
	char sLog[255];


	if(m_nCurSel == 8)
	{
		sprintf(sLog, "Connected! Fax tone detected. Frequency: %d", freq);
		m_pMainDlg->Log(ch, sLog);

		Send_StopToneDetection(ch);
	}
}



void CSIPServerAppDlg::OnBnClickedButton1()
{
	// TODO: Add your control notification handler code here
	CFileDialog fn(TRUE);
	if (fn.DoModal() == IDOK)
	{
		m_editCfg.SetWindowText(fn.GetPathName());
	}
}
