// AudioRecordDlg.cpp : implementation file
//

#include "stdafx.h"
#include "AudioRecord.h"
#include "AudioRecordDlg.h"
#include <mmsystem.h>
#include <mmreg.h>
#include "GTAPI_FACE2.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()

/////////////////////////////////////////////////////////////////////////////
// CAudioRecordDlg dialog

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

	m_hWavFile = 0;
}

void CAudioRecordDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAudioRecordDlg)
	DDX_Control(pDX, IDC_EDIT_ADDR, m_editAddr);
	DDX_Control(pDX, IDC_EDIT_WAV_FILE, m_editWavFile);
	DDX_Control(pDX, IDC_STATIC_LOG, m_staticLog);
	DDX_Control(pDX, IDC_COMBO_CHAN, m_cbxChannel);
	DDX_Control(pDX, IDC_BUTTON_DIAL, m_btnDial);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAudioRecordDlg, CDialog)
	//{{AFX_MSG_MAP(CAudioRecordDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_DIAL, OnButtonDial)
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAudioRecordDlg message handlers

BOOL CAudioRecordDlg::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_Env.m_pMainDlg = this;
	m_Env.SetMainWnd(m_hWnd);
	m_Env.StartServer();
	
	Log("LINE IDLE");

	char sTemp[20];

	for(int i=0; i<72; i++)
	{
		sprintf(sTemp, "%d", i);
		m_cbxChannel.AddString(sTemp);
	}
	m_cbxChannel.SetCurSel(0);

	m_editAddr.SetWindowText("8888@sip.pcbest.net");
	m_editWavFile.SetWindowText("c:\\aaa.wav");

	m_btnDial.SetWindowText("Dial");
	m_btnDial.EnableWindow(TRUE);

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

void CAudioRecordDlg::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 CAudioRecordDlg::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 CAudioRecordDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CAudioRecordDlg::OnButtonDial() 
{
	// TODO: Add your control notification handler code here
	char sAddr[255];

	CString s;

	int chanid = m_cbxChannel.GetCurSel();
	m_btnDial.GetWindowText(s);

	if(stricmp(s, "Dial") == 0)
	{
		m_editAddr.GetWindowText(s);
		sprintf(sAddr, "<sip:%s>", s);

		m_Env.Send_Make(chanid, sAddr, "");

		m_btnDial.SetWindowText("Hungup");
		m_btnDial.EnableWindow(TRUE);
		
		m_cbxChannel.EnableWindow(FALSE);
		m_editAddr.EnableWindow(FALSE);
		m_editWavFile.EnableWindow(FALSE);
	}
	else
	{
		m_Env.Send_HangUp(chanid, 0, "");
	}
}



void CAudioRecordDlg::On_RecvConnected(int ch)
{
	Log("LINE CONNECTED --- Start Recording!");
	char sWavFile[255];

	m_editWavFile.GetWindowText(sWavFile, 255);

	PCMWAVEFORMAT pwf;
	memset(&pwf, 0, sizeof(PCMWAVEFORMAT));

	pwf.wBitsPerSample = 8;
	pwf.wf.wFormatTag = WAVE_FORMAT_MULAW;
	pwf.wf.nAvgBytesPerSec = 8000;
	pwf.wf.nBlockAlign = 1;
	pwf.wf.nChannels = 1;
	pwf.wf.nSamplesPerSec = 8000;

	m_mtxAudio.Lock();
	m_hWavFile = GTAPI_WAV_FILE_Open(sWavFile, "wb", &pwf);
	m_mtxAudio.Unlock();
}

void CAudioRecordDlg::On_RecvOffered(int ch, const char* sCaller, const char* sCallee, const char* sDestAddr, \
		const char* sViaAddr, const char* sFromIP, unsigned short nFromPort)
{
	Log("NEW CALL IN - Hungup it anyway");

	//answer call anyway here
	m_Env.Send_HangUp(ch, 0, "");
}

void CAudioRecordDlg::On_RecvDialing(int ch, const char* sCaller, const char* sCallee)
{
	Log("DIALING");
}

void CAudioRecordDlg::On_RecvIdle(int ch, int code, const char* desc)
{
	Log("IDLE");

	m_btnDial.SetWindowText("Dial");
	m_btnDial.EnableWindow(TRUE);

	m_cbxChannel.EnableWindow(TRUE);
	m_editAddr.EnableWindow(TRUE);
	m_editWavFile.EnableWindow(TRUE);

	m_mtxAudio.Lock();
	if(m_hWavFile)
	{
		GTAPI_WAV_FILE_Close(m_hWavFile);
	}
	m_mtxAudio.Unlock();
}

void CAudioRecordDlg::On_RecvRinging(int ch)
{
	Log("Remote Side Ringing");
}

void CAudioRecordDlg::On_RecvRegStatus(int user_id, int status, int regtime)
{
}

void CAudioRecordDlg::Log(const char* info)
{
	m_staticLog.SetWindowText(info);
}


void CAudioRecordDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	// TODO: Add your message handler code here
	m_Env.StopServer();	
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//CGTSIPAudioRecordEnv
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CGTSIPAudioRecordEnv::CGTSIPAudioRecordEnv():CGTAPIEnv()
{
	m_pMainDlg = 0;
}

CGTSIPAudioRecordEnv::~CGTSIPAudioRecordEnv()
{

}

bool CGTSIPAudioRecordEnv::StartServer()
{
	//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
	CFG_SetValue("gtsrv.sip.ip.port", "5066");

	//RTP PORT
	CFG_SetValue("gtsrv.sip.rtpstartrange", "14400");
	CFG_SetValue("gtsrv.sip.rtpendrange", "14800");

	//Log 
	CFG_SetValue(GTSRV_INI_LOG_LEVEL, "4");
	CFG_SetValue(GTSRV_INI_LOG, "c:\\gtaudiorecord.txt");

	//G729 channel number, not support yet
	//CFG_SetValue("gtsrv.sip.g729a.channum", "0");

	//channnel numbers, here we only use 1 channel
	CFG_SetValue("gtsrv.sip.boardnum.per.server", "1");
	CFG_SetValue("gtsrv.sip.spannum.per.board", "9");
	CFG_SetValue("gtsrv.sip.channum.per.span", "8");
/*
#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
*/

	//define inbound and outbound channels
	//CFG_SetValue("gtsrv.channel.inbound", "0-3");
	//CFG_SetValue("gtsrv.channel.outbound", "4-15");

	//Internal communication port
	CFG_SetValue(GTSRV_INI_NET_PORT, "8814");

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

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

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

	//set sip client user info
	//you must get an account from sip service provider first
	/*
	CFG_SetValue("gtsrv.sip.reg.client.num", "1");

	CFG_SetValue("gtsrv.sip.reg1.displayname", m_sipAccDisplayName);
	CFG_SetValue("gtsrv.sip.reg1.username", m_sipAccUserName);
	CFG_SetValue("gtsrv.sip.reg1.domain", m_sipAccDomainName);
	CFG_SetValue("gtsrv.sip.reg1.proxy", m_sipAccProxyName);
	CFG_SetValue("gtsrv.sip.reg1.authorization", m_sipAccAuthName);
	CFG_SetValue("gtsrv.sip.reg1.password", m_sipAccPassword);
	CFG_SetValue("gtsrv.sip.reg1.expire", "3600");
	*/

	//0 = Not handle RTP packet
	//1 = Handle RTP Packet as mulaw format
	//2 = Handle RTP Packet as alaw format
	//3 = Handle RTP Packet as PCM 16bit format
	CFG_SetValue("gtsrv.sip.on.rtp.packet", "1");

	//if you use directx sound as input and output device
	//then you can also handle the audio data by setting
	//CFG_SetValue("gtsrv.sip.on.dx.audio", "1");

	bool ret = CGTAPIEnv::StartServer();

	if(!ret)
	{
		::MessageBox(NULL, "StartServer Failed! Please check if SIP port is being used by another application!", "ERROR", MB_OK);
	}

	Send_GetRegStatus(0);
	return ret;
}

bool CGTSIPAudioRecordEnv::StopServer()
{
	return CGTAPIEnv::StopServer();
}


void CGTSIPAudioRecordEnv::On_RecvConnected(int ch)
{
	CGTAPIEnv::On_RecvConnected(ch);

	//start directx audio control
	//if you are writing a server to handle media yourself, you don't need this
	//because we are writing a multipul channels server
	//so we don't start directx device
	//Send_StartDXAudio(ch);

	if(m_pMainDlg)
		m_pMainDlg->On_RecvConnected(ch);
}

void CGTSIPAudioRecordEnv::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);

	//GTAPI_Channel* pChan = (GTAPI_Channel*)GetChannel(ch);

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

void CGTSIPAudioRecordEnv::On_RecvDialing(int ch, const char* sCaller, const char* sCallee)
{
	CGTAPIEnv::On_RecvDialing(ch, sCaller, sCallee);

	if(m_pMainDlg)
		m_pMainDlg->On_RecvDialing(ch, sCaller, sCallee);
}

void CGTSIPAudioRecordEnv::On_RecvIdle(int ch, int code, const char* desc)
{
	CGTAPIEnv::On_RecvIdle(ch, code, desc);

	if(m_pMainDlg)
		m_pMainDlg->On_RecvIdle(ch, code, desc);
}

void CGTSIPAudioRecordEnv::On_RecvRinging(int ch)
{
	CGTAPIEnv::On_RecvRinging(ch);

	if(m_pMainDlg)
		m_pMainDlg->On_RecvRinging(ch);
}

void CGTSIPAudioRecordEnv::On_RecvRegStatus(int user_id, int status, int regtime)
{
	CGTAPIEnv::On_RecvRegStatus(user_id, status, regtime);
/*
	char sTemp[100];
	if(status)
	{
		sprintf(sTemp, "%s", CFG_GetValue("gtsrv.sip.reg1.authorization", ""));
	}
	else
	{
		sprintf(sTemp, "%s XXX!",  CFG_GetValue("gtsrv.sip.reg1.authorization", ""));
	}
*/

	if(m_pMainDlg)
		m_pMainDlg->On_RecvRegStatus(user_id, status, regtime);
}

void CGTSIPAudioRecordEnv::On_RecvRTPPacket(int ch, int fmt, char* buf, int buflen, unsigned short seq, unsigned int timestamp, SYSTEMTIME* pSysTime)
{
	//threads of span
	//must be really fast here
	m_pMainDlg->m_mtxAudio.Lock();
	if(m_pMainDlg->m_hWavFile)
	{
		GTAPI_FILE_Write(m_pMainDlg->m_hWavFile, buf, buflen);
	}
	m_pMainDlg->m_mtxAudio.Unlock();
}

void CGTSIPAudioRecordEnv::On_SentRTPPacket(int ch, int fmt, char* buf, int buflen, unsigned short seq, unsigned int timestamp, SYSTEMTIME* pSysTime)
{
	//threads of span
	//must be really fast here

}

/*
void CGTSIPAudioRecordEnv::On_CaptureDXAudio(int ch, int fmt, char* buf, int buflen, unsigned short seq, unsigned int timestamp, SYSTEMTIME* pSysTime)
{
	//threads of dx channel
	//must be really fast here

}
void CGTSIPAudioRecordEnv::On_RenderDXAudio(int ch, int fmt, char* buf, int buflen, unsigned short seq, unsigned int timestamp, SYSTEMTIME* pSysTime)
{
	//threads of dx channel
	//must be really fast here

}
*/

