package kr.co.icontrols.ilp300_700.call;

import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.util.Log;

import java.util.Timer;
import java.util.TimerTask;

import milsip.stack.sip.BSSVideo;
import milsip.stack.sip.SIPStack;
import cm.sip.hns.SIPController;
import kr.co.icontrols.V40IFCCD.V40IFCCD.SIPEventListener;
import kr.co.icontrols.ilp300_700.MainActivity;
import kr.co.icontrols.ilp300_700.ethernet.EthernetCtrl;
import kr.co.icontrols.ilp300_700.ethernet.iMAPServer;
import kr.co.icontrols.ilp300_700.ethernet.iMAPServer.ChatEventListener;
import kr.co.icontrols.ilp300_700.global.DataClasses.RemoteIDInfo;
import kr.co.icontrols.ilp300_700.global.Declare;
import kr.co.icontrols.ilp300_700.global.Declare.DeviceString;
import kr.co.icontrols.ilp300_700.global.Global;
import kr.co.icontrols.ilp300_700.global.ID;
import kr.co.icontrols.ilp300_700.global.LobbyAccessCtrl;

public class CallController extends CallManager implements SIPEventListener, ChatEventListener {

    String TAG = "CallController";

    static Timer DelayQuitMoIPCallTimer = null;
    private static int nDelayQuitMoIPCallSec = 0;   // Sec 단위
    public CallInfo mCallInfo;
    public CTT mCTT;
    public int SEC_DOOROPEN_DELAYQUITCALL = 3;

    boolean bLOG = true;   // true, false
    boolean bLOG_DEBUG = false;   // true, false
    boolean bLOG_INFO = true;   // true, false
    boolean bLOG_WARN = true;   // true, false

    Context mContext;

    public VideoJNI mVideoJNI;

    int nSIPPort = 5060;

    public interface CallEventListener {
        public void onCallEvent(CALLSTATUS eCallStatus, CALLTYPE eCallType, String strRemoteIP, String strRemoteSIPID, String strMessage);
        public void onVideoSet(final boolean bSet);
        public void onChatEvent(CHATEVENT eEventType, CALLTYPE eCallType, String strRemoteIP, String strRemoteSIPID, String strMessage);
        public void onChatMessage(String strMessage);
    }
    CallEventListener mCallEventListener;
    public void setCallEventListener(CallEventListener SIPEV) {
        mCallEventListener = SIPEV;
    }
    public void releaseCallEventListener() {
        mCallEventListener = null;
    }

    public CallController(Context context) {
        try {
            LOG_INFO("[CallController] ===== START =====");
            mContext = context;
            mVideoJNI = new VideoJNI(mContext);
            mVideoJNI.mV40IFCCD.setSIPEventListener(this);
            setCallManagerContext(mContext);
            if (Global.bSTTTTS) iMAPServer.setChatEventListener(this);
            mCallInfo = new CallInfo();
            mCallInfo.resetCallStatus();
            mCTT = new CTT();
        } catch (Exception e) {
            Log.e(TAG, "[Exception] CallController(context)");
            e.printStackTrace();
        }
    }

    public void releaseCallController() {
        try {
            LOG_INFO("[releaseCallController]");
            MainActivity.mCallController.mVideoJNI.mV40IFCCD.releaseV40IFCCD();
        } catch (Exception e) {
            Log.e(TAG, "[Exception] releaseCallController()");
            e.printStackTrace();
        }
    }

    private void LOG(String log) {
        if (bLOG) Log.v(TAG, log);
    }

    private void LOG_DEBUG(String log) {
        if (bLOG_DEBUG) Log.d(TAG, log);
    }

    private void LOG_INFO(String log) {
        if (bLOG_INFO) Log.i(TAG, log);
    }

    private void LOG_WARN(String log) {
        if (bLOG_INFO) Log.w(TAG, log);
    }

    public boolean tryMoIPCall(CALLTYPE eCallType, String strHeadID, String strTailID) {
        try {
            if (eCallType == CALLTYPE.RESIDENCE || eCallType == CALLTYPE.RENTRESIDENCE) {
                makeResidenceCall(eCallType, strHeadID, strTailID);
                mCallInfo.setCallStatus(CALLTYPE.RESIDENCE, CALLSTATUS.WAITNG_INVITE_ACK);
                setCallTimer(mCTT.WAITNG_INVITE_ACK);
                return true;
            } else if (eCallType == CALLTYPE.GUARD) {
                makeGuardCall(strHeadID, strTailID);
                mCallInfo.setCallStatus(CALLTYPE.GUARD, CALLSTATUS.WAITNG_INVITE_ACK);
                setCallTimer(mCTT.WAITNG_INVITE_ACK);
                return true;
            } else return false;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] tryMoIPCall(eCallType, strHeadID, strTailID)");
            e.printStackTrace();
            return false;
        }
    }

    public CALLTYPE tryAutoMoIPCall(String strTargetIP, String strTargetURI) {
        try {
            LOG_INFO("[tryAutoMoIPCall] strTargetIP [" + strTargetIP + "], strTargetURI [" + strTargetURI + "]");

            String[] strParsed_01 = strTargetURI.split("_");

            if (strTargetURI.contains("_Guard_")) {
                RemoteIDInfo.strDong = strParsed_01[2];
                RemoteIDInfo.strHo = strParsed_01[3];
                RemoteIDInfo.strIP = strTargetIP;
                RemoteIDInfo.strName = Integer.toString(Integer.parseInt(RemoteIDInfo.strDong)) + "동 " + Integer.toString(Integer.parseInt(RemoteIDInfo.strHo)) + "번";
                RemoteIDInfo.bAutoCall = true;
                return CALLTYPE.GUARD;
            } else if (strTargetURI.contains("_Lobby_")) {
                LOG_WARN("[tryAutoMoIPCall] Not supported Target -> Lobby");
                RemoteIDInfo.InitVariables();
                return CALLTYPE.LOBBY;
            } else if (strTargetURI.contains("_Resi_")) {
                RemoteIDInfo.strDong = strParsed_01[2];
                RemoteIDInfo.strHo = strParsed_01[3];
                RemoteIDInfo.strIP = strTargetIP;
                RemoteIDInfo.strName = Integer.toString(Integer.parseInt(RemoteIDInfo.strDong)) + "동 " + Integer.toString(Integer.parseInt(RemoteIDInfo.strHo)) + "호";
                RemoteIDInfo.bAutoCall = true;
                return CALLTYPE.RESIDENCE;
            } else {
                RemoteIDInfo.InitVariables();
                return CALLTYPE.NONE;
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] tryAutoMoIPCall(String strTargetIP, String strTargetURI)");
            e.printStackTrace();
            RemoteIDInfo.InitVariables();
            return CALLTYPE.ERROR;
        }
    }

    public void CallScenarioManager(CALLEVENTTYPE eEventType, CALLTYPE eCallType, String strRemoteIP, String strRemoteSIPID, String strMessage) {
        try {
            LOG_INFO("[CallScenarioManager] eEventType [" + eEventType + "], eCallType [" + eCallType + "], strRemoteIP [" + strRemoteIP + "], strRemoteSIPID [" + strRemoteSIPID + "], strMessage [" + strMessage + "]");

            if (eEventType == CALLEVENTTYPE.SIP_RECEIVE_CALL) {
                // SIP 호출 수신

//                if (mCallInfo.getIDLECnt() == mCallInfo.IDLECNT_MAX) {
//                    // SingleCall
//                    if (eCallType == CALLTYPE.RESIDENCE) {
//                        ((MainActivity) mContext).setChangeScreen(ID.SCREENS.Talk_Residence, false);
//                    } else if (eCallType == CALLTYPE.GUARD) {
//                        ((MainActivity) mContext).setChangeScreen(ID.SCREENS.Talk_Guard, false);
//                    } else {
//                        LOG_WARN("[CallScenarioManager] Incorrect eCallType!! [" + eCallType + "]");
//                        mCallInfo.setCallStatus(eCallType, CALLSTATUS.IDLE);
//                        return;
//                    }
//                }

                mCallInfo.setCallStatus(eCallType, CALLSTATUS.CALLED);

                if (mCallEventListener != null) {
                    mCallEventListener.onCallEvent(CALLSTATUS.CALLED, eCallType, strRemoteIP, strRemoteSIPID, strMessage);
                } else {
                    LOG_WARN("[CallScenarioManager] mCallEventListener is null!!");
                    mCallInfo.setCallStatus(eCallType, CALLSTATUS.IDLE);
                }
            } else if (eEventType == CALLEVENTTYPE.SIP_RECEIVE_CALL_ACK) {
                // SIP 호출응답 수신
                if (mCallInfo.getIDLECnt() < mCallInfo.IDLECNT_MAX) {

                    if (mCallInfo.getCallingType() == eCallType) {
                        // 월패드에서 로비통화를 2nd콜로 수신했을 경우, "수락"을 하면 SIP_RECEIVE_CALL_ACK를 전송하여 신호가 중복 전송되는 버그를 보완하기 위함
                        // 추후 월패드 수정예정 (JEFF, 2016.03.04.16)
                        LOG_WARN("[CallScenarioManager] Duplicated eEventType!! [" + eEventType + "]");
                        return;
                    }
                    mCallInfo.setCallStatus(eCallType, CALLSTATUS.CALLING);

                    if (mCallEventListener != null) {
                        mCallEventListener.onCallEvent(CALLSTATUS.CALLING, eCallType, strRemoteIP, strRemoteSIPID, strMessage);
                    } else {
                        LOG_WARN("[CallScenarioManager] mCallEventListener is null!!");
                        Global.stopMelodyRepeat();
                        mCallInfo.resetCallStatus();
                        ui_callEnd();
                    }
                } else {
                    LOG_WARN("[CallScenarioManager] Undefined scenario!!");
                    mCallInfo.setCallStatus(eCallType, CALLSTATUS.IDLE);
                }
            } else if (eEventType == CALLEVENTTYPE.SIP_CONNECT_CALL) {
                // SIP 통화 시작
                if (mCallInfo.getIDLECnt() < mCallInfo.IDLECNT_MAX) {
                    mCallInfo.setCallStatus(eCallType, CALLSTATUS.TALKING);

                    if (mCallEventListener != null) {
                        mCallEventListener.onCallEvent(CALLSTATUS.TALKING, eCallType, strRemoteIP, strRemoteSIPID, strMessage);
                    } else {
                        LOG_WARN("[CallScenarioManager] mCallEventListener is null!!");
                        Global.stopMelodyRepeat();
                        mCallInfo.resetCallStatus();
                        ui_callEnd();
                    }
                } else {
                    LOG_WARN("[CallScenarioManager] Undefined scenario!!");
                    mCallInfo.setCallStatus(eCallType, CALLSTATUS.IDLE);
                }
            } else if (eEventType == CALLEVENTTYPE.SIP_TERMINATE_CALL) {
                // SIP 통화 종료
                if (mCallInfo.getIDLECnt() == mCallInfo.IDLECNT_MAX) {
                    LOG("[CallScenarioManager] duplicated SIP_TERMINATE_CALL");
                    return;
                }
                mCallInfo.setCallStatus(eCallType, CALLSTATUS.END);
                if (mCallEventListener != null) {
                    mCallEventListener.onCallEvent(CALLSTATUS.END, eCallType, strRemoteIP, strRemoteSIPID, strMessage);
                } else {
                    LOG_WARN("[CallScenarioManager] mCallEventListener is null!!");
                    mCallInfo.resetCallStatus();
                    ui_callEnd();
                }
            } else if (eEventType == CALLEVENTTYPE.SIP_CANCEL_CALL) {
                // SIP 호출 취소
                mCallInfo.setCallStatus(eCallType, CALLSTATUS.CANCEL);
                if (mCallEventListener != null) {
                    mCallEventListener.onCallEvent(CALLSTATUS.CANCEL, eCallType, strRemoteIP, strRemoteSIPID, strMessage);
                } else {
                    LOG_WARN("[CallScenarioManager] mCallEventListener is null!!");
                    mCallInfo.resetCallStatus();
                    ui_callEnd();
                }
            } else if (eEventType == CALLEVENTTYPE.SIP_REJECT_CALL) {
                // SIP 호출 거절
                mCallInfo.setCallStatus(eCallType, CALLSTATUS.REJECT);
                if (mCallEventListener != null) {
                    mCallEventListener.onCallEvent(CALLSTATUS.REJECT, eCallType, strRemoteIP, strRemoteSIPID, strMessage);
                } else {
                    LOG_WARN("[CallScenarioManager] mCallEventListener is null!!");
                    mCallInfo.resetCallStatus();
                    ui_callEnd();
                }
            } else if (eEventType == CALLEVENTTYPE.SIP_REJECT_BUSY_CALL) {
                // SIP Busy 거절
                mCallInfo.setCallStatus(eCallType, CALLSTATUS.BUSY);
                if (mCallEventListener != null) {
                    mCallEventListener.onCallEvent(CALLSTATUS.BUSY, eCallType, strRemoteIP, strRemoteSIPID, strMessage);
                } else {
                    LOG_WARN("[CallScenarioManager] mCallEventListener is null!!");
                    mCallInfo.resetCallStatus();
                    ui_callEnd();
                }
            } else if (eEventType == CALLEVENTTYPE.SIP_FORWARD_CALL) {
                // SIP 착신전환
                mCallInfo.setCallStatus(eCallType, CALLSTATUS.FORWARD);

                if (mCallEventListener != null) {
                    mCallEventListener.onCallEvent(CALLSTATUS.FORWARD, eCallType, strRemoteIP, strRemoteSIPID, strMessage);
                } else {
                    LOG_WARN("[CallScenarioManager] mCallEventListener is null!!");
                    mCallInfo.resetCallStatus();
                    ui_callEnd();
                }
            } else if (eEventType == CALLEVENTTYPE.SIP_VIDEO_SET) {
                // SIP 영상 설정
            } else {
                // 기타
                LOG_WARN("[CallScenarioManager] = ERROR = Unknown eEventType!! [" + eEventType + "]");
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] CallScenarioManager(eEventType, eCallType, strRemoteIP, strRemoteSIPID, strMessage)");
            e.printStackTrace();
        }
    }

    public void ChatScenarioManager(CHATEVENT eEventType, CALLTYPE eCallType, String strRemoteIP, String strRemoteSIPID, String strMessage) {
        try {
            LOG_INFO("[ChatScenarioManager] eEventType [" + eEventType + "], eCallType [" + eCallType + "], strRemoteIP [" + strRemoteIP + "], strRemoteSIPID [" + strRemoteSIPID + "], strMessage [" + strMessage + "]");

            if (eEventType == CHATEVENT.TRY) {
                // CHAT 통화 요청
                if (mCallInfo.getIDLECnt() < mCallInfo.IDLECNT_MAX) {

                    if (mCallEventListener != null) {
                        mCallEventListener.onChatEvent(eEventType, eCallType, strRemoteIP, strRemoteSIPID, strMessage);
                    } else {
                        LOG_WARN("[ChatScenarioManager] mCallEventListener is null!!");
                    }
                } else {
                    LOG_WARN("[CallScenarioManager] Undefined scenario!!");
                }
            } else {
                // 기타
                LOG_WARN("[CallScenarioManager] not acceptable eEventType!! [" + eEventType + "]");
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] ChatScenarioManager(CHATEVENT eEventType, CALLTYPE eCallType, String strRemoteIP, String strRemoteSIPID, String strMessage)");
            e.printStackTrace();
        }
    }

    @Override
    public void onSIPEvent(CALLEVENTTYPE eEventType, CALLTYPE eCallType, String strRemoteIP, String strRemoteSIPID, String strMessage) {
        try {
            LOG_DEBUG("[onSIPEvent] eEventType [" + eEventType + "], eCallType [" + eCallType +"], strRemoteIP [" + strRemoteIP + "], strRemoteSIPID [" + strRemoteSIPID + "], strMessage [" + strMessage + "]");
 //           LOG("[onSIPEvent] eEventType [" + eEventType + "]");

            if(eEventType == CALLEVENTTYPE.SIP_RECEIVE_CALL)
            {
                ui_callInvoke(eCallType, RemoteIDInfo.strDong, RemoteIDInfo.strHo);
            }
            else
            {
                CallScenarioManager(eEventType, eCallType, strRemoteIP, strRemoteSIPID, strMessage);
            }

        } catch (Exception e) {
            Log.e(TAG, "[Exception] onSIPEvent(eEventType, eCallType, strRemoteIP, strRemoteSIPID, strMessage)");
            e.printStackTrace();
        }
    }

    @Override
    public void onVideoSet(boolean bSet, String strRemoteSIPID) {
        try {
            LOG_INFO("[onVideoSet] bSet [" + bSet + "]");
        } catch (Exception e) {
            Log.e(TAG, "[Exception] onVideoSet(bSet)");
            e.printStackTrace();
        }
    }

    @Override
    public void onShowRemoteVideo(boolean bShow) {

    }

    @Override
    public void onChatEvent(CALLTYPE eCallType, String strRemoteIP, String strRemoteSIPID, CHATEVENT eChatEvent, CHATSTATUS eChatStatus, String strMessage) {
        try {
            LOG_INFO("[onChatEvent] eCallType [" + eCallType + "], strRemoteIP [" + strRemoteIP + "], strRemoteSIPID [" + strRemoteSIPID + "], eChatEvent [" + eChatEvent + "], eChatStatus [" + eChatStatus + "], strMessage [" + strMessage + "]");

            if (eChatEvent == CHATEVENT.TRY) {
                ChatScenarioManager(eChatEvent, eCallType, strRemoteIP, strRemoteSIPID, strMessage);
            } else {
                LOG_WARN("[onChatEvent] not supported eChatEvent!! [" + eChatEvent + "]");
            }

        } catch (Exception e) {
            Log.e(TAG, "[Exception] onChatEvent(CALLTYPE eCallType, String strRemoteIP, String strRemoteSIPID, String strSeq, String strStatus, String strMessage)");
            e.printStackTrace();
        }
    }

    @Override
    public void onChatMessage(String strMessage) {
        try {
            LOG_INFO("[onChatMessage] strMessage [" + strMessage + "]");
            if (mCallEventListener != null) {
                mCallEventListener.onChatMessage(strMessage);
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] onChatMessage(String strMessage)");
            e.printStackTrace();
        }
    }

    public boolean setRemoteInfo(String strSIPID, String strRemoteIP) {
        try {
            LOG("[setRemoteInfo] strSIPID = [" + strSIPID + "]");
            if (strSIPID == null) {
                LOG("[setRemoteInfo] strSIPID is null");
                RemoteIDInfo.InitVariables();
                return false;
            }
            if (strSIPID.equals("null")) {
                LOG("[setRemoteInfo] strSIPID = [" + strSIPID + "] (String)");
                RemoteIDInfo.InitVariables();
                return false;
            }
            RemoteIDInfo.strSIPID = strSIPID;
            RemoteIDInfo.strIP = strRemoteIP;

            String[] strParse = RemoteIDInfo.strSIPID.split("_");
            String strDeviceType = strParse[1];
            RemoteIDInfo.nDong = Integer.parseInt(strParse[2]);
            RemoteIDInfo.nHo = Integer.parseInt(strParse[3]);
            RemoteIDInfo.strDong = Integer.toString(RemoteIDInfo.nDong);
            RemoteIDInfo.strHo = Integer.toString(RemoteIDInfo.nHo);
            RemoteIDInfo.strName = "NONE";

            if (strDeviceType.equalsIgnoreCase(DeviceString.strType_Resi)) {
                RemoteIDInfo.strName = RemoteIDInfo.strDong + "동 " + RemoteIDInfo.strHo + "호";
            } else if (strDeviceType.equalsIgnoreCase(DeviceString.strType_RentResi)) {
                RemoteIDInfo.strName = RemoteIDInfo.strDong + "동 " + RemoteIDInfo.strHo + "-" + RemoteIDInfo.nHo_Extension + "호";
            } else if (strDeviceType.equalsIgnoreCase(DeviceString.strType_Guard)) {
                RemoteIDInfo.strName = RemoteIDInfo.strDong + "동 " + RemoteIDInfo.strHo + "번 경비";
            } else if (strDeviceType.equalsIgnoreCase(DeviceString.strType_Lobby)) {
                RemoteIDInfo.strName = RemoteIDInfo.strDong + "동 " + RemoteIDInfo.strHo + "번 로비";
            }
            return true;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] setRemoteInfo(strSIPID)");
            e.printStackTrace();
            RemoteIDInfo.InitVariables();
            return false;
        }
    }

    private final static int AUDIO_MODE_NORMAL = AudioManager.MODE_NORMAL;              // 0, NORMAL
    private final static int AUDIO_MODE_RINGTONE = AudioManager.MODE_RINGTONE;          // 1, 사용안함
    private final static int AUDIO_MODE_MOIP_GUARD = 12;
    private final static int AUDIO_MODE_MOIP_RESIDENCE = 1;
    private final static int AUDIO_MODE_IN_CALL_PSTN = 4;

    public void setTalkPath(CALLPATH eCallPath) {
        try {
            LOG("[setTalkPath] eCallPath [" + eCallPath + "]");
            if (eCallPath == CALLPATH.MOIP_GUARD) {
                MainActivity.mAudioManager.setMode(AUDIO_MODE_MOIP_GUARD);
            } else if (eCallPath == CALLPATH.MOIP_RESIDENCE) {
                MainActivity.mAudioManager.setMode(AUDIO_MODE_MOIP_RESIDENCE);
            } else if (eCallPath == CALLPATH.PSTN) {
                MainActivity.mAudioManager.setMode(AUDIO_MODE_IN_CALL_PSTN);
            } else {
                MainActivity.mAudioManager.setMode(AUDIO_MODE_RINGTONE);
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] setTalkPath(eCallPath)");
            e.printStackTrace();
        }
    }

    public CALLPATH getTalkPath() {
        try {
            int nMode = MainActivity.mAudioManager.getMode();
            LOG("[getTalkPath] nMode [" + nMode + "]");
            if (nMode == AUDIO_MODE_NORMAL) {
                return CALLPATH.NORMAL;
            } else if (nMode == AUDIO_MODE_MOIP_GUARD) { // 12
                return CALLPATH.MOIP_GUARD;
            } else if (nMode == AUDIO_MODE_MOIP_RESIDENCE) {
                return CALLPATH.MOIP_RESIDENCE;
            } else if (nMode == AUDIO_MODE_IN_CALL_PSTN) {
                return CALLPATH.PSTN;
            }
            return CALLPATH.NONE;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] getTalkPath()");
            e.printStackTrace();
            return CALLPATH.ERROR;
        }
    }

    public boolean setDelayQuitMoIPCall(int nDelaySec) {
        try {
            LOG("[setDelayQuitMoIPCall] nDelaySec [" + nDelaySec + "]");
            if (nDelayQuitMoIPCallSec > 0) {
                // 타이머가 이미 동작중이므로, 시간을 새로 설정한다.
                nDelayQuitMoIPCallSec = nDelaySec;
            } else {
                // 타이머가 돌아가고 있지 않으므로, 새로 구동한다.
                if (DelayQuitMoIPCallTimer == null) {
                    LOG("[setAutoScreenChange] AutoScreenChangeTimer is null!!");
                    DelayQuitMoIPCallTimer = new Timer();
                    DelayQuitMoIPCallTimer.schedule(new DelayQuitMoIPCallCntDN(), 1000, 1000);
                }
                nDelayQuitMoIPCallSec = nDelaySec;
            }
            return true;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] setDelayQuitMoIPCall(nDelaySec) : " + e);
            e.printStackTrace();
            return false;
        }
    }

    public class DelayQuitMoIPCallCntDN extends TimerTask {
        @Override
        public void run() {
//            LOG_INFO("[DelayQuitMoIPCallCntDN().run()] Start!!");
            try {
                nDelayQuitMoIPCallSec--;
                LOG("[DelayQuitMoIPCallCntDN.run()] nDelayQuitMoIPCallSec = " + nDelayQuitMoIPCallSec);
                if (nDelayQuitMoIPCallSec <= 0) {
                    LOG("[DelayQuitMoIPCallCntDN.run()] QuitMoIPCall!!");
                    DelayQuitMoIPCallTimer.cancel();
                    DelayQuitMoIPCallTimer = null;
                    LOG("[DelayQuitMoIPCallCntDN.run()] mCallInfo.getIDLECnt() = " + mCallInfo.getIDLECnt());
                    LobbyAccessCtrl.strLobbyOpenRequestIP = null;
                    LOG("[DelayQuitMoIPCallCntDN.run()] LobbyAccessCtrl.strLobbyOpenRequestIP = " + LobbyAccessCtrl.strLobbyOpenRequestIP);
                    if (mCallInfo.getIDLECnt() != mCallInfo.IDLECNT_MAX) ui_callEnd();
                }
            } catch (Exception e) {
                Log.e(TAG, "[Exception] DelayQuitMoIPCallCntDN().run() : " + e);
                e.printStackTrace();
            }
        }
    }

    public boolean checkSIPActivation() {
        try {
            return SIPStack.bActive;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] checkSIPActivation()");
            e.printStackTrace();
            return false;
        }
    }

    public void makeResidenceCall(CALLTYPE eCallType, String dong, String ho) {
        Log.d(TAG, "[makeResidenceCall] eCallType [" + eCallType + "], dong [" + dong + "], ho [" + ho + "]");
        try {
            ui_callInvoke(eCallType, dong, ho);
        } catch (Exception e) {
            Log.e(TAG, "[Exception] makeResidenceCall(CALLTYPE eCallType, String dong, String ho)");
            e.printStackTrace();
        }
    }

    public void makeGuardCall(String dong, String id) {
        Log.d(TAG, "[makeGuardCall] dong [" + dong + "] , id [" + id + "]");
        try {
            ui_callInvoke(CALLTYPE.GUARD, dong, id);
        } catch (Exception e) {
            Log.e(TAG, "[Exception] makeGuardCall(String dong, String id)");
            e.printStackTrace();
        }
    }

    public void ui_callEnd() {
        try {
            Log.d(TAG, "[ui_callEnd] ========== START ==========");
            BSSVideo.bViewme = false;
            SIPStack.userDial.dial = "";
            SIPStack.userDial.dong = "";
            SIPStack.userDial.ho = "";

            if (SIPController.sipCall != null) {
                SIPController.sipCall.bCancelRequest = true;
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] ui_callEnd()");
            e.printStackTrace();
        }
        return;
    }

    public void ui_callInvoke(CALLTYPE eCallType, String Head, String Tail) {
        Log.d(TAG, "[ui_callInvoke] ========== START ==========");
        try {
            Log.d(TAG, "[ui_callInvoke] SIPController.sipCall.flag [" + SIPController.sipCall.flag + "]");
            Log.d(TAG, "[ui_callInvoke] eCallType [" + eCallType + "], Head [" + Head + "], Tail [" + Tail + "]");

            SIPStack.userDial.dong = Head;
            SIPStack.userDial.ho = Tail;
            SIPStack.userDial.dial = Tail;

            if (SIPStack.userDial.dial.length() == 0) return;

            if (SIPController.sipCall == null) Log.e(TAG, "SIPCALL is null");

            if (SIPController.sipCall != null && SIPController.sipCall.callDirection == SIPStack.SIP_CALLDIRECTION_IN && SIPController.sipCall.callState == SIPStack.SIP_CALLSTATE_OFFERRED) {
                // Incoming Call
                SIPController.sipCall.bDirectcall = SIPStack.bDirectCall;
                SIPController.sipCall.bNewcallRequest = true;
                SIPController.sipCall.number = new String(SIPStack.userDial.dial);
            } else {
                // Outgoing Call
                if (eCallType == CALLTYPE.RESIDENCE || eCallType == CALLTYPE.RENTRESIDENCE) {
                    BSSVideo.HNS_SERVICE_RECEIVER_SELECTED = BSSVideo.HNS_SERVICE_NEIGHBOR;
                } else if (eCallType == CALLTYPE.GUARD) {
                    BSSVideo.HNS_SERVICE_RECEIVER_SELECTED = BSSVideo.HNS_SERVICE_GUARD;
                } else {
                    BSSVideo.HNS_SERVICE_RECEIVER_SELECTED = BSSVideo.HNS_SERVICE_NEIGHBOR;
                }


                if (SIPStack.userDial.dial == null) SIPStack.userDial.dial = "";
                if (SIPStack.userDial.dial.length() == 0) {
                    if (SIPStack.userDial.latestDial == null || SIPStack.userDial.latestDial.length() == 0)
                        return;
                }

                SIPController.sipCall.number = MainActivity.mCallController.makeSIPID(eCallType, SIPStack.userDial.dong, SIPStack.userDial.ho);
                SIPController.sipCall.dong_number = SIPStack.userDial.dong;
                SIPController.sipCall.ho_number = SIPStack.userDial.ho;
                SIPController.sipCall.bDirectcall = false;

                if (eCallType == CALLTYPE.RESIDENCE) {
                    SIPController.sipCall.remoteIp = EthernetCtrl.makeIPAddress(Declare.DeviceType.RESIDENCE, SIPStack.userDial.dong, SIPStack.userDial.ho);
                } else if (eCallType == CALLTYPE.GUARD) {
                    SIPController.sipCall.remoteIp = EthernetCtrl.makeIPAddress(Declare.DeviceType.GUARD, SIPStack.userDial.dong, SIPStack.userDial.ho);
                } else if (eCallType == CALLTYPE.RENTRESIDENCE) {
                    SIPController.sipCall.remoteIp = EthernetCtrl.makeIPAddress(Declare.DeviceType.RENTRESIDENCE, SIPStack.userDial.dong, SIPStack.userDial.ho);
                } else {
                    SIPController.sipCall.remoteIp = EthernetCtrl.makeIPAddress(Declare.DeviceType.RESIDENCE, SIPStack.userDial.dong, SIPStack.userDial.ho);
                }

                SIPController.sipCall.serverIp = SIPController.sipCall.remoteIp;
                SIPController.sipCall.serverDomain = SIPController.sipCall.remoteIp;
                SIPController.sipCall.remoteContactIp = SIPController.sipCall.remoteIp;
                SIPController.sipCall.bDirectcall = true;
                SIPController.sipCall.bNewcallRequest = true;
                SIPStack.userDial.latestDial = new String(SIPController.sipCall.number);
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] ui_callInvoke(CALLTYPE eCallType, String Head, String Tail)");
            e.printStackTrace();
        }
        return;
    }

    public void setVoiceDisable(boolean bVoice) {
        try {
            SIPController.audioRTPManager.bDisableVoice = bVoice;
            Log.d(TAG, "[setVoiceDisable] SIPController.audioRTPManager.bDisableVoice [" + SIPController.audioRTPManager.bDisableVoice + "]");
        } catch (Exception e) {
            Log.e(TAG, "[Exception] setVoiceDisable(boolean bVoice) : " + e);
            e.printStackTrace();
        }
    }
    public void onCeresCallEvent(Intent mIntent) {
        try {
            String strCallEvent = mIntent.getStringExtra(Declare.CALLTRIGGER.CALLEVENTTYPE);
            String strCallType = mIntent.getStringExtra(Declare.CALLTRIGGER.CALLTYPE);
            String strRemoteNum =  mIntent.getStringExtra(Declare.CALLTRIGGER.REMOTEINFO);


            RemoteIDInfo.strSIPID = makeSIPID(strRemoteNum);
            Log.i(TAG, "[onCeresCallEvent] nDeviceType [" + strCallType + "], nEventType [" + strCallEvent + "], " + " strIP [" + strRemoteNum + "], " + "RemoteIDInfo.strSIPID [" + RemoteIDInfo.strSIPID + "]");
            if (strCallEvent.equals(CALLEVENTTYPE.SIP_RECEIVE_CALL.toString())) {
                Log.i(TAG, "[onCeresCallEvent] 1");
                if(strCallType.equals(CALLTYPE.GUARD.toString())) {
                    Log.i(TAG, "[onCeresCallEvent] 2");
                    CallScenarioManager(CALLEVENTTYPE.SIP_RECEIVE_CALL, CALLTYPE.GUARD, RemoteIDInfo.strIP, RemoteIDInfo.strSIPID, "null");
                }
                else if(strCallType.equals(CALLTYPE.RESIDENCE.toString())) {
                    Log.i(TAG, "[onCeresCallEvent] 3");
                    CallScenarioManager(CALLEVENTTYPE.SIP_RECEIVE_CALL, CALLTYPE.RESIDENCE, RemoteIDInfo.strIP, RemoteIDInfo.strSIPID, "null");
                }
            }
            else if (strCallEvent.equals(CALLEVENTTYPE.SIP_TERMINATE_CALL.toString())) {
                Log.i(TAG, "[onCeresCallEvent] 1");
                if(strCallType.equals(CALLTYPE.GUARD.toString())) {
                    Log.i(TAG, "[onCeresCallEvent] 2");
                    CallScenarioManager(CALLEVENTTYPE.SIP_TERMINATE_CALL, CALLTYPE.GUARD, RemoteIDInfo.strIP, RemoteIDInfo.strSIPID, "null");
                }
                else if(strCallType.equals(CALLTYPE.RESIDENCE.toString())) {
                    Log.i(TAG, "[onCeresCallEvent] 3");
                    CallScenarioManager(CALLEVENTTYPE.SIP_TERMINATE_CALL, CALLTYPE.RESIDENCE, RemoteIDInfo.strIP, RemoteIDInfo.strSIPID, "null");
                }
            }
            else if (strCallEvent.equals(CALLEVENTTYPE.SIP_REJECT_BUSY_CALL.toString())) {
                Log.i(TAG, "[onCeresCallEvent] 1");
                if(strCallType.equals(CALLTYPE.GUARD.toString())) {
                    Log.i(TAG, "[onCeresCallEvent] 2");
                    CallScenarioManager(CALLEVENTTYPE.SIP_REJECT_BUSY_CALL, CALLTYPE.GUARD, RemoteIDInfo.strIP, RemoteIDInfo.strSIPID, "null");
                }
                else if(strCallType.equals(CALLTYPE.RESIDENCE.toString())) {
                    Log.i(TAG, "[onCeresCallEvent] 3");
                    CallScenarioManager(CALLEVENTTYPE.SIP_REJECT_BUSY_CALL, CALLTYPE.RESIDENCE, RemoteIDInfo.strIP, RemoteIDInfo.strSIPID, "null");
                }
            }





//            else if (nEventType == HomeAutomation_Call.CALLTYPE_RECEIVE_CALL_END) {
//                CallScenarioManager(mCallInfo.getCallOwner(), CALLEVENTTYPE.TERMINATE_CALL, getAnalogEnumCallType(nDeviceType), RemoteIDInfo.strIP, RemoteIDInfo.strSIPID, "null");
//            }
//            else if (nEventType == HomeAutomation_Call.CALLTYPE_RECEIVE_CALL_ACK) {
//                CallScenarioManager(mCallInfo.getCallOwner(), CALLEVENTTYPE.RECEIVE_CALL_ACK, getAnalogEnumCallType(nDeviceType), RemoteIDInfo.strIP, RemoteIDInfo.strSIPID, "null");
//            }
//            else if (nEventType == HomeAutomation_Call.CALLTYPE_RECEIVE_CALL_ACK_FAIL) {
//                CallScenarioManager(mCallInfo.getCallOwner(), CALLEVENTTYPE.REJECT_BUSY_CALL, getAnalogEnumCallType(nDeviceType), RemoteIDInfo.strIP, RemoteIDInfo.strSIPID, "null");
//            }
//            else if (nEventType == HomeAutomation_Call.CALLTYPE_RECEIVE_CALL_START) {
//                CallScenarioManager(mCallInfo.getCallOwner(), CALLEVENTTYPE.CONNECT_CALL, getAnalogEnumCallType(nDeviceType), RemoteIDInfo.strIP, RemoteIDInfo.strSIPID, "null");
//            }
//            else if (nEventType == HomeAutomation_Call.CALLTYPE_RECEIVE_DOOR_OPEN_ACK) {
//                CallScenarioManager(mCallInfo.getCallOwner(), CALLEVENTTYPE.DOOR_OPEN, getAnalogEnumCallType(nDeviceType), RemoteIDInfo.strIP, RemoteIDInfo.strSIPID, "null");
//            }
            else {
                LOG_WARN("[onAnalogCallEvent] nEventType is unavailable!! nEventType [" + strCallEvent + "]");
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] onAnalogCallEvent(Intent mIntent)");
            e.printStackTrace();
        }
    }


}