package com.iailab.netsdk.demo.module;

import com.iailab.netsdk.lib.NetSDKLib;
import com.iailab.netsdk.lib.NetSDKLib.LLong;
import com.iailab.netsdk.lib.ToolKits;

import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;

/**
 * \if ENGLISH_LANG
 * Talk Interface
 * contains:start talk銆乻top talk and audio data callback implement class  
 * \else
 * 璇煶瀵硅鎺ュ彛瀹炵幇
 * 鍖呭惈: 寮€濮嬮€氳瘽銆佺粨鏉熼€氳瘽銆佽闊冲璁茬殑鏁版嵁鍥炶皟瀹炵幇绫�
 * \endif
 */
public class TalkModule {

	public static LLong m_hTalkHandle = new LLong(0); // 璇煶瀵硅鍙ユ焺 
	
	private static boolean m_bRecordStatus    = false; 			// 鏄惁姝e湪褰曢煶
	
	/**
	 * \if ENGLISH_LANG
	 * Start Talk
	 * \else
	 * 寮€濮嬮€氳瘽
	 * \endif
	 */
	public static boolean startTalk(int transferType, int chn) {
	
		// 璁剧疆璇煶瀵硅缂栫爜鏍煎紡
		NetSDKLib.NETDEV_TALKDECODE_INFO talkEncode = new NetSDKLib.NETDEV_TALKDECODE_INFO();
		talkEncode.encodeType = NetSDKLib.NET_TALK_CODING_TYPE.NET_TALK_PCM;
		talkEncode.dwSampleRate = 8000;
		talkEncode.nAudioBit = 16;
		talkEncode.nPacketPeriod = 25;
		talkEncode.write();
		if(LoginModule.netsdk.CLIENT_SetDeviceMode(LoginModule.m_hLoginHandle, NetSDKLib.EM_USEDEV_MODE.NET_TALK_ENCODE_TYPE, talkEncode.getPointer())) {
			System.out.println("Set Talk Encode Type Succeed!");
		} else {
			System.err.println("Set Talk Encode Type Failed!" + ToolKits.getErrorCodePrint());
			return false;
		}
		
		// 璁剧疆璇煶瀵硅鍠婅瘽鍙傛暟
		NetSDKLib.NET_SPEAK_PARAM speak = new NetSDKLib.NET_SPEAK_PARAM();
        speak.nMode = 0;
        speak.bEnableWait = false;
        speak.nSpeakerChannel = 0;
        speak.write();
        
        if (LoginModule.netsdk.CLIENT_SetDeviceMode(LoginModule.m_hLoginHandle, NetSDKLib.EM_USEDEV_MODE.NET_TALK_SPEAK_PARAM, speak.getPointer())) {
        	System.out.println("Set Talk Speak Mode Succeed!");
        } else {
        	System.err.println("Set Talk Speak Mode Failed!" + ToolKits.getErrorCodePrint());
			return false;
        }
		
		// 璁剧疆璇煶瀵硅鏄惁涓鸿浆鍙戞ā寮�
		NetSDKLib.NET_TALK_TRANSFER_PARAM talkTransfer = new NetSDKLib.NET_TALK_TRANSFER_PARAM();
		talkTransfer.bTransfer = transferType;
		talkTransfer.write();
		if(LoginModule.netsdk.CLIENT_SetDeviceMode(LoginModule.m_hLoginHandle, NetSDKLib.EM_USEDEV_MODE.NET_TALK_TRANSFER_MODE, talkTransfer.getPointer())) {
			System.out.println("Set Talk Transfer Mode Succeed!");
		} else {
			System.err.println("Set Talk Transfer Mode Failed!" + ToolKits.getErrorCodePrint());
			return false;
		}
		
		if (talkTransfer.bTransfer == 1) {  // 杞彂妯″紡璁剧疆杞彂閫氶亾
			
			IntByReference nChn = new IntByReference(chn);
			if(LoginModule.netsdk.CLIENT_SetDeviceMode(LoginModule.m_hLoginHandle, NetSDKLib.EM_USEDEV_MODE.NET_TALK_TALK_CHANNEL, nChn.getPointer())) {
				System.out.println("Set Talk Channel Succeed!");
			} else {
				System.err.println("Set Talk Channel Failed!" + ToolKits.getErrorCodePrint());
				return false;
			}
		}
		
		
		m_hTalkHandle = LoginModule.netsdk.CLIENT_StartTalkEx(LoginModule.m_hLoginHandle, AudioDataCB.getInstance(), null);
		
	    if(m_hTalkHandle.longValue() == 0) {
	  	    System.err.println("Start Talk Failed!" + ToolKits.getErrorCodePrint());
	  	    return false;
	    } else {
	  	    System.out.println("Start Talk Success");
			if(LoginModule.netsdk.CLIENT_RecordStart()){
				System.out.println("Start Record Success");
				m_bRecordStatus = true;
			} else {
				System.err.println("Start Local Record Failed!" + ToolKits.getErrorCodePrint());
				stopTalk();
				return false;
			}
	    }
		
		return true;
	}
	
	/**
	 * \if ENGLISH_LANG
	 * Stop Talk
	 * \else
	 * 缁撴潫閫氳瘽
	 * \endif
	 */
	public static void stopTalk() {
		if(m_hTalkHandle.longValue() == 0) {
			return;
		}
		
		if (m_bRecordStatus){
			LoginModule.netsdk.CLIENT_RecordStop();
			m_bRecordStatus = false;
		}
		
		if(LoginModule.netsdk.CLIENT_StopTalkEx(m_hTalkHandle)) {
			m_hTalkHandle.setValue(0);
		}else {
			System.err.println("Stop Talk Failed!" + ToolKits.getErrorCodePrint());
    	}
	}
	
	/**
	 * \if ENGLISH_LANG
	 * Audio Data Callback
	 * \else
	 * 璇煶瀵硅鐨勬暟鎹洖璋�
	 * \endif
	 */
	private static class AudioDataCB implements NetSDKLib.pfAudioDataCallBack {
		
		private AudioDataCB() {}
		private static AudioDataCB audioCallBack = new AudioDataCB();
		
		public static AudioDataCB getInstance() {
			return audioCallBack;
		}
		
		public void invoke(LLong lTalkHandle, Pointer pDataBuf, int dwBufSize, byte byAudioFlag, Pointer dwUser){
			
			if(lTalkHandle.longValue() != m_hTalkHandle.longValue()) {
				return;
			}
			
			if (byAudioFlag == 0) { // 灏嗘敹鍒扮殑鏈湴PC绔娴嬪埌鐨勫0鍗℃暟鎹彂閫佺粰璁惧绔�
				
				LLong lSendSize = LoginModule.netsdk.CLIENT_TalkSendData(m_hTalkHandle, pDataBuf, dwBufSize);
				if(lSendSize.longValue() != (long)dwBufSize) {
					System.err.println("send incomplete" + lSendSize.longValue() + ":" + dwBufSize);
				} 
			}else if (byAudioFlag == 1) { // 灏嗘敹鍒扮殑璁惧绔彂閫佽繃鏉ョ殑璇煶鏁版嵁浼犵粰SDK瑙g爜鎾斁
				LoginModule.netsdk.CLIENT_AudioDecEx(m_hTalkHandle, pDataBuf, dwBufSize);
			}
		}
	}
}