package kr.co.icontrols.ilp300_700.screen;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils.TruncateAt;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.RelativeLayout;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

import cm.sip.hns.SIPSound;
import kr.co.icontrols.ilp300_700.MainActivity;
import kr.co.icontrols.ilp300_700.MainActivity.HANDLERMSG;
import kr.co.icontrols.ilp300_700.MainActivity.TTSEventListener;
import kr.co.icontrols.ilp300_700.R;
import kr.co.icontrols.ilp300_700.call.CallController.CallEventListener;
import kr.co.icontrols.ilp300_700.call.CallManager.REMOTECALLOWNER;
import kr.co.icontrols.ilp300_700.call.CallManager.CALLPATH;
import kr.co.icontrols.ilp300_700.call.CallManager.CALLSTATUS;
import kr.co.icontrols.ilp300_700.call.CallManager.CALLTYPE;
import kr.co.icontrols.ilp300_700.call.CallManager.CHATEVENT;
import kr.co.icontrols.ilp300_700.ethernet.EthernetCtrl;
import kr.co.icontrols.ilp300_700.ethernet.iMAPCommon.iMAPResult;
import kr.co.icontrols.ilp300_700.global.Configure.ConfigValue;
import kr.co.icontrols.ilp300_700.global.DataClasses.POSITION;
import kr.co.icontrols.ilp300_700.global.DataClasses.RemoteIDInfo;
import kr.co.icontrols.ilp300_700.global.Declare;
import kr.co.icontrols.ilp300_700.global.Enumeration.TARGETINFOINPUTSTEP;
import kr.co.icontrols.ilp300_700.global.Enumeration.TTSEVENT;
import kr.co.icontrols.ilp300_700.global.Global;
import kr.co.icontrols.ilp300_700.global.ID;
import kr.co.icontrols.ilp300_700.imap.Request_chat_message;
import kr.co.icontrols.ilp300_700.imap.Request_check_sip_activation;
import kr.co.icontrols.ilp300_700.imap.iMAPResultCtrl;
import kr.co.icontrols.wallpadsupport.WpadImageView;
import kr.co.icontrols.wallpadsupport.WpadScreen;
import kr.co.icontrols.wallpadsupport.WpadTextView;

public class TalkGuard extends WpadScreen implements CallEventListener, TTSEventListener {

    String TAG = "TalkGuard";

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

    WpadImageView Image_Background;
    WpadImageView Image_Guard;
    WpadImageView Image_Call_Anim;
    WpadTextView Text_Instruction;
    WpadTextView Text_ChatMessage;   // 청각장애인 모드 통화 내용
    CountDownTimer InputDelayTimer;   // 메인화면에서 급격한 조작을 방지하기 위한 타이머 (통화 종료후, 통화상태 초기화를 위한 일정 시간후 입력 받음, X초)
    boolean bInputDelay = false;

    Animation mAnimation;

    Context mContext;

    int[] BGImages = {R.drawable.bg_black, R.drawable.bg_black_700};
    int[] GuardImages = {R.drawable.cir_guard, R.drawable.image_guard};
    int[] GuardCirImages = {R.drawable.cir_white_quarter, R.drawable.cir_white_quarter_700};
    int[] nFontSize = {26, 46};
    boolean bFUNCBlock = false;
    String strText_Instruction = "";
    String strText_ChatMessage = "";
    String strChatTargetIP = "";
    boolean bRcvCancel = false;
    boolean bRcvBusy = false;
    boolean bAutoCallRun = false;
    boolean bForwarding = false;
    CountDownTimer mCountDownTimer;
    private Handler TalkGuardHandler = new Handler(Looper.getMainLooper()) {
        public void handleMessage(Message msg) {
            LOG_INFO("[handleMessage] TalkGuardHandler : what [" + msg.what + "], arg1 [" + msg.arg1 + "], arg2 [" + msg.arg2 + "]");
            switch (msg.what) {
                case TALKGUARD_HD_MSG.DISPLAY_CHATMESSAGE:
                    strText_ChatMessage = (String) msg.obj;
                    displayChatMessage(strText_ChatMessage);
                    break;

                case TALKGUARD_HD_MSG.START_STT:
                    ((MainActivity) mContext).startSTT();
                    break;

                case TALKGUARD_HD_MSG.PLAYSOUND_STT_START:
                    MainActivity.mSound.Play_lobby(R.raw.callstart);
                    break;

                case TALKGUARD_HD_MSG.PLAYSOUND_STT_END:
                    MainActivity.mSound.Play_lobby(R.raw.callend);
                    break;

                default:
                    break;
            }
        }
    };

    public TalkGuard(Context context, RelativeLayout layout) {
        super(context, layout);
        try {
            LOG("------------------ [START - TalkGuard] -------------------");

            mContext = context;
            Initialize();

            super.addBrActionFilter(Declare.PrivateBR.UPDATE_KEYDATA_TALK);
            super.addBrActionFilter(Declare.PrivateBR.REDIRECT_CALL);
            Image_Background = new WpadImageView(context, 0, Declare.DeviceInfo.getScreenSizeFullW(ConfigValue.DEVICE_MODELTYPE), Declare.DeviceInfo.getScreenSizeFullH(ConfigValue.DEVICE_MODELTYPE), BGImages[ConfigValue.DEVICE_MODELTYPE], 0, ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.BACKGROUND);
            ViewRegistration(layout, Image_Background, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.BACKGROUND).X, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.BACKGROUND).Y);

            Image_Guard = new WpadImageView(context, 0, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.GUARD).W, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.GUARD).H, GuardImages[ConfigValue.DEVICE_MODELTYPE], 0, ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.GUARD);
            ViewRegistration(layout, Image_Guard, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.GUARD).X, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.GUARD).Y);

            Image_Call_Anim = new WpadImageView(context, 0, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.GUARD_ANIM).W, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.GUARD_ANIM).H, GuardCirImages[ConfigValue.DEVICE_MODELTYPE], 0, ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.GUARD_ANIM);
            ViewRegistration(layout, Image_Call_Anim, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.GUARD_ANIM).X, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.GUARD_ANIM).Y);
            Image_Call_Anim.setVisibility(View.INVISIBLE);

            mAnimation = AnimationUtils.loadAnimation(mContext, R.anim.rotate_call);
            mAnimation.setInterpolator(AnimationUtils.loadInterpolator(mContext, android.R.anim.linear_interpolator));

            Text_Instruction = new WpadTextView(context, false, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.TEXTS.INSTRUCTION).W, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.TEXTS.INSTRUCTION).H, Gravity.CENTER, Color.WHITE, nFontSize[ConfigValue.DEVICE_MODELTYPE], false, ID.SCREENS.TALKGUARD.ELEMENTS.TEXTS.INSTRUCTION);
            ViewRegistration(layout, Text_Instruction, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.TEXTS.INSTRUCTION).X, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.TEXTS.INSTRUCTION).Y);
            Text_Instruction.setText(strText_Instruction);

            Text_ChatMessage = new WpadTextView(context, false, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.TEXTS.CHATMESSAGE).W, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.TEXTS.CHATMESSAGE).H, Gravity.CENTER, Color.YELLOW, nFontSize[ConfigValue.DEVICE_MODELTYPE], false, ID.SCREENS.TALKGUARD.ELEMENTS.TEXTS.CHATMESSAGE);
            ViewRegistration(layout, Text_ChatMessage, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.TEXTS.CHATMESSAGE).X, getPosition(ID.SCREENS.TALKGUARD.ELEMENTS.TEXTS.CHATMESSAGE).Y);
            Text_ChatMessage.setText(strText_ChatMessage);
            Text_ChatMessage.setSingleLine();
            Text_ChatMessage.setEllipsize(TruncateAt.MARQUEE);
            Text_ChatMessage.setMarqueeRepeatLimit(-1);
//          Text_ChatMessage.setFocusable(true);

            UpdateScreen();
            checkTalkTestMode();
            ((MainActivity) mContext).setAutoScreenChange(ID.SCREENS.Main, MainActivity.nDefaultScreenTimeout);
            doTactGuardCall();
            doAutoCall();
        } catch (Exception e) {
            Log.e(TAG, "[Exception] TalkGuard(Context context, RelativeLayout layout) : " + e);
            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_WARN) Log.w(TAG, log);
    }

    protected void Initialize() {
        try {
            LOG("[Initialize] ===== START =====");
            MainActivity.mCallController.setCallEventListener(this);
            if (!RemoteIDInfo.bAutoCall) RemoteIDInfo.InitVariables();
        } catch (Exception e) {
            Log.e(TAG, "[Exception] Initialize() : " + e);
            e.printStackTrace();
        }
    }

    private void checkTalkTestMode() {
        try {
            LOG("[checkTalkTestMode] ===== START =====");
            if (MainActivity.mCallController.bTalkTestModeEnable) {
                Text_Instruction.setTextColor(Color.GREEN);
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] Initialize() : " + e);
            e.printStackTrace();
        }
    }

    @Override
    protected void onClose() {
        try {
            LOG("------------------ [onClose - TalkGuard] -------------------");
            Image_Call_Anim.clearAnimation();
            Image_Call_Anim.setVisibility(View.GONE);

            if (mPathCheckHandler != null) {
                mPathCheckHandler.removeMessages(0);
                mPathCheckHandler.removeMessages(1);
            }
            if (mVolumeCheckHandler != null) {
                mVolumeCheckHandler.removeMessages(0);
                mVolumeCheckHandler.removeMessages(1);
            }

            if (SIPSound.mHandler != null) {
                SIPSound.mHandler.removeMessages(0);
                SIPSound.mHandler.removeMessages(1);
            }

            ((MainActivity) mContext).sendHandlerMsg(HANDLERMSG.STOP_CHATMODE, 0, 0);
            ((MainActivity) mContext).releaseTTSEventListener();
            MainActivity.mCallController.releaseCallEventListener();
            MainActivity.mIOInterface.setAnalogCameraPower(false);
            Global.changeVolumeMoIPMode(CALLTYPE.NONE);
            MainActivity.mCallController.mCallInfo.setRemoteCallOwner(REMOTECALLOWNER.NONE);
            MainActivity.m_bCallType = 0;
            ((MainActivity) mContext).ctrlVideoSurface(false);
            if (!RemoteIDInfo.bAutoCall) RemoteIDInfo.InitVariables();
        } catch (Exception e) {
            Log.e(TAG, "[Exception] onClose(...) : " + e);
            e.printStackTrace();
        }
        super.onClose();
    }

    @Override
    protected void onBrReceive(Intent intent) {
        try {
            LOG("[onBrReceive] Intent : " + intent);

            if (intent.getAction().equals(Declare.PrivateBR.UPDATE_KEYDATA_TALK))
            {
                int keyCode = intent.getIntExtra("data", -1);
                LOG("[onBrReceive] Intent : " + keyCode);
                if (keyCode == Declare.Button.CALL) {
                    startInputDelayTimer();
                    if (bFUNCBlock) return;

                    ((MainActivity) mContext).cancelAutoScreenChange();
                    if (MainActivity.mCallController.mCallInfo.getIDLECnt() != MainActivity.mCallController.mCallInfo.IDLECNT_MAX) {
                        MainActivity.mSound.PlayMent_lobby(R.raw.inputfail);
                        MainActivity.mCallController.mCallInfo.printCallStatus();
                        LOG("[onKeyDown] CallStatus is not idle!!");
                        return;
                    }
                    LOG("[onKeyDown] strGuard_Dong [" + ConfigValue.strGuard_Dong + "], strGuard_ID [" + ConfigValue.strGuard_ID + "]");
                    RemoteIDInfo.strDong = ConfigValue.strGuard_Dong;
                    RemoteIDInfo.strHo = ConfigValue.strGuard_ID;
                    RemoteIDInfo.strIP = EthernetCtrl.makeIPAddress(Declare.DeviceType.GUARD, RemoteIDInfo.strDong, RemoteIDInfo.strHo);
                    if (!send_check_sip_activation_request(EthernetCtrl.makeIPAddress(Declare.DeviceType.GUARD, RemoteIDInfo.strDong, RemoteIDInfo.strHo))) {
                        MainActivity.mSound.PlayMent_lobby(R.raw.trylater);
                        return;
                    }
                    MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.GUARD, CALLSTATUS.TRYING_CALL);
                } else if (keyCode == Declare.Button.CANCEL || keyCode == Declare.Button.TACT_CANCEL) {
                    if (!bForwarding) {
                        if (MainActivity.mCallController.mCallInfo.getIDLECnt() != MainActivity.mCallController.mCallInfo.IDLECNT_MAX) {
                            MainActivity.mCallController.ui_callEnd();
                            mySocket s = new mySocket(RemoteIDInfo.strIP, "BYE");
                            s.start();
                            super.setChangeScreen(ID.SCREENS.Main);
                        } else {
                            // 애니메이션 해제
                            Image_Call_Anim.clearAnimation();
                            Image_Call_Anim.setVisibility(View.GONE);
                            mySocket s = new mySocket(RemoteIDInfo.strIP, "BYE");
                            s.start();
                            super.setChangeScreen(ID.SCREENS.Main);
                        }
                    } else {
                        mySocket s = new mySocket(RemoteIDInfo.strIP, "BYE");
                        s.start();
                        LOG_WARN("[onKeyDown] bForwarding [" + bForwarding + "], Disabled canceling!!");
                    }
                } else if (keyCode == Declare.Button.STAR) {
                    if (!MainActivity.mCallController.bTalkTestModeEnable) {
                        if (Global.TargetInputStep == TARGETINFOINPUTSTEP.DONG) {
                            Global.TargetInputStep = TARGETINFOINPUTSTEP.HO;
                        }
                    } else {
                        if (MainActivity.mCallController.mCallInfo.getGUARD() != CALLSTATUS.TALKING)
                            return;
                        changeTalkVol(true);
                    }
                } else if (keyCode == Declare.Button.SHARP) {
                    if (!MainActivity.mCallController.bTalkTestModeEnable) return;
                    if (MainActivity.mCallController.mCallInfo.getGUARD() != CALLSTATUS.TALKING) return;
                    changeTalkVol(false);
                }
                UpdateScreen();
            }
            else if(intent.getAction().equals(Declare.PrivateBR.REDIRECT_CALL))
            {
                String strRedirectIP = intent.getStringExtra(Declare.CALLTRIGGER.REMOTEINFO);

                String[] aDeviceName = Global.makeDeviceName(strRedirectIP);
                LOG("[onKeyDown] strRedirectIP [" + strRedirectIP + "] strGuard_Dong [" + aDeviceName[1] + "], strGuard_ID [" + aDeviceName[2] + "]");
                RemoteIDInfo.strDong = aDeviceName[1];
                RemoteIDInfo.strHo = aDeviceName[2];
                RemoteIDInfo.strIP = EthernetCtrl.makeIPAddress(Declare.DeviceType.GUARD, RemoteIDInfo.strDong, RemoteIDInfo.strHo);
                if (!send_check_sip_activation_request(EthernetCtrl.makeIPAddress(Declare.DeviceType.GUARD, RemoteIDInfo.strDong, RemoteIDInfo.strHo))) {
                    MainActivity.mSound.PlayMent_lobby(R.raw.trylater);
                    return;
                }
                MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.GUARD, CALLSTATUS.TRYING_CALL);
                LOG("[onBrReceive] Intent : " + strRedirectIP);
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] onBrReceive(...) : " + e);
            e.printStackTrace();
        }
        super.onBrReceive(intent);
    }

    @Override
    protected void onKeyDown(int keyCode, KeyEvent event) {
        try {

            if (bInputDelay) {
                LOG("[onKeyDown] bInputDelay [" + bInputDelay + "], Ignore Key Input");
                return;
            }

            if (keyCode == Declare.Button.CALL) {
                startInputDelayTimer();
                if (bFUNCBlock) return;

                ((MainActivity) mContext).cancelAutoScreenChange();
                if (MainActivity.mCallController.mCallInfo.getIDLECnt() != MainActivity.mCallController.mCallInfo.IDLECNT_MAX) {
                    MainActivity.mSound.PlayMent_lobby(R.raw.inputfail);
                    MainActivity.mCallController.mCallInfo.printCallStatus();
                    LOG("[onKeyDown] CallStatus is not idle!!");
                    return;
                }
                LOG("[onKeyDown] strGuard_Dong [" + ConfigValue.strGuard_Dong + "], strGuard_ID [" + ConfigValue.strGuard_ID + "]");
                RemoteIDInfo.strDong = ConfigValue.strGuard_Dong;
                RemoteIDInfo.strHo = ConfigValue.strGuard_ID;
                RemoteIDInfo.strIP = EthernetCtrl.makeIPAddress(Declare.DeviceType.GUARD, RemoteIDInfo.strDong, RemoteIDInfo.strHo);
                if (!send_check_sip_activation_request(EthernetCtrl.makeIPAddress(Declare.DeviceType.GUARD, RemoteIDInfo.strDong, RemoteIDInfo.strHo))) {
                    MainActivity.mSound.PlayMent_lobby(R.raw.trylater);
                    return;
                }
                MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.GUARD, CALLSTATUS.TRYING_CALL);
            } else if (keyCode == Declare.Button.CANCEL || keyCode == Declare.Button.TACT_CANCEL) {
                if (!bForwarding) {
                    if (MainActivity.mCallController.mCallInfo.getIDLECnt() != MainActivity.mCallController.mCallInfo.IDLECNT_MAX) {
                        MainActivity.mCallController.ui_callEnd();
                        mySocket s = new mySocket(RemoteIDInfo.strIP, "BYE");
                        s.start();
                        super.setChangeScreen(ID.SCREENS.Main);
                    } else {
                        // 애니메이션 해제
                        Image_Call_Anim.clearAnimation();
                        Image_Call_Anim.setVisibility(View.GONE);
                        mySocket s = new mySocket(RemoteIDInfo.strIP, "BYE");
                        s.start();
                        super.setChangeScreen(ID.SCREENS.Main);
                    }
                } else {
                    mySocket s = new mySocket(RemoteIDInfo.strIP, "BYE");
                    s.start();
                    LOG_WARN("[onKeyDown] bForwarding [" + bForwarding + "], Disabled canceling!!");
                }
            } else if (keyCode == Declare.Button.STAR) {
                if (!MainActivity.mCallController.bTalkTestModeEnable) {
                    if (Global.TargetInputStep == TARGETINFOINPUTSTEP.DONG) {
                        Global.TargetInputStep = TARGETINFOINPUTSTEP.HO;
                    }
                } else {
                    if (MainActivity.mCallController.mCallInfo.getGUARD() != CALLSTATUS.TALKING)
                        return;
                    changeTalkVol(true);
                }
            } else if (keyCode == Declare.Button.SHARP) {
                if (!MainActivity.mCallController.bTalkTestModeEnable) return;
                if (MainActivity.mCallController.mCallInfo.getGUARD() != CALLSTATUS.TALKING) return;
                changeTalkVol(false);
            }
            UpdateScreen();
        } catch (Exception e) {
            Log.e(TAG, "[Exception] onKeyDown(...) : " + e);
            e.printStackTrace();
        }
        super.onKeyDown(keyCode, event);
    }

    public void UpdateScreen() {
        try {
            LOG("[updateScreen] MainActivity.mCallController.mCallInfo.getGUARD() =" + MainActivity.mCallController.mCallInfo.getGUARD());
            if (MainActivity.mCallController.mCallInfo.getGUARD() == CALLSTATUS.IDLE) {
                strText_Instruction = TextResources.strPressCallButton;
            } else if (MainActivity.mCallController.mCallInfo.getGUARD() == CALLSTATUS.TRYING_CALL) {
                strText_Instruction = TextResources.strTryingGuard;
            } else if (MainActivity.mCallController.mCallInfo.getGUARD() == CALLSTATUS.WAITNG_INVITE_ACK) {
                strText_Instruction = TextResources.strTryingGuard;
            } else if (MainActivity.mCallController.mCallInfo.getGUARD() == CALLSTATUS.CALLING || MainActivity.mCallController.mCallInfo.getGUARD() == CALLSTATUS.CALLED) {
                strText_Instruction = TextResources.strCallingGuard;

                // 애니메이션 시작
                mAnimation.setDuration(MainActivity.mCallController.mCTT.CALLED * 1000);
                mAnimation.setFillAfter(false);
                Image_Call_Anim.setVisibility(View.VISIBLE);
                Image_Call_Anim.startAnimation(mAnimation);
            } else if (MainActivity.mCallController.mCallInfo.getGUARD() == CALLSTATUS.TALKING) {
                strText_Instruction = TextResources.strTalkingGuard;

                // 애니메이션 해제
                Image_Call_Anim.clearAnimation();
                Image_Call_Anim.setVisibility(View.GONE);
                displayTalkVolume();
            } else {
                strText_Instruction = "";

                // 애니메이션 해제
                Image_Call_Anim.clearAnimation();
                Image_Call_Anim.setVisibility(View.GONE);
            }
            Text_Instruction.setText(strText_Instruction);
        } catch (Exception e) {
            Log.e(TAG, "[Exception] updateScreen() : " + e);
            e.printStackTrace();
        }
    }

    private void displayTalkVolume() {
        try {
            if (!MainActivity.mCallController.bTalkTestModeEnable) return;
            strText_Instruction = strText_Instruction + " [음량 " + nTalkVolume + "]";
        } catch (Exception e) {
            Log.e(TAG, "[Exception] displayTalkVolume() : " + e);
            e.printStackTrace();
        }
    }

    public POSITION getPosition(int nID) {
        POSITION position = new POSITION();
        position.SetPosition(0, 0, 480, 272);
        try {
            switch (nID) {
                case ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.BACKGROUND:
                    if (ConfigValue.DEVICE_MODELTYPE == Global.MODEL_ILP_700) position.SetPosition(0, 0, 800, 480);
                    else position.SetPosition(0, 0, 480, 272);
                    return position;

                case ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.GUARD:
                    if (ConfigValue.DEVICE_MODELTYPE == Global.MODEL_ILP_700) position.SetPosition(280, 89, 240, 240);
                    else position.SetPosition(150, 21, 180, 180);
                    return position;

                case ID.SCREENS.TALKGUARD.ELEMENTS.IMAGES.GUARD_ANIM:
                    if (ConfigValue.DEVICE_MODELTYPE == Global.MODEL_ILP_700) position.SetPosition(280, 88, 240, 240);
                    else position.SetPosition(150, 21, 180, 180);
                    return position;

                case ID.SCREENS.TALKGUARD.ELEMENTS.TEXTS.INSTRUCTION:
                    if (ConfigValue.DEVICE_MODELTYPE == Global.MODEL_ILP_700) position.SetPosition(0, 381, 800, 99);
                    else position.SetPosition(0, 216, 480, 56);
                    return position;

                case ID.SCREENS.TALKGUARD.ELEMENTS.TEXTS.CHATMESSAGE:
                    if (ConfigValue.DEVICE_MODELTYPE == Global.MODEL_ILP_700) position.SetPosition(80, 420, 600, 80);
                    else position.SetPosition(47, 170, 386, 50);
                    return position;

                default:
                    return position;
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] getPosition() : " + e);
            e.printStackTrace();
            return position;
        }
    }
    public class mySocket extends Thread {

        Socket s;
        String toCall;
        BufferedWriter output;
        BufferedReader input;
        String message;


        public mySocket (String toCall, String msg) {
            this.toCall = toCall;
            this.message = msg;

        }

        @Override
        public void run() {
            try {
                s = new Socket(toCall, 4001);
                s.setTcpNoDelay(true);
                output = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
                input = new BufferedReader(new InputStreamReader(s.getInputStream()));

                int what = -1;
                output.write(message);
                output.flush();
                while (true) {

                    String msg = input.readLine();
                    if (msg != null) {
                        LOG_INFO("[TCPServer11] " + msg);
                        if (msg.equals("ACK")) {
                            if(message.equals("BYE"))
                            {
                                Global.stopMelodyRepeat();
                                Global.changeVolumeMoIPMode(CALLTYPE.NONE);
//                                if (strMessage.contains("전화를 받지 않습니다."))
//                                    MainActivity.mSound.PlayMent_lobby(R.raw.trylater);
                                MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.GUARD, CALLSTATUS.IDLE);
                                MainActivity.mCallController.setCallTimer(MainActivity.mCallController.mCTT.KILLTIMER);
                                //Image_Call_Anim.clearAnimation();
                                //Image_Call_Anim.setVisibility(View.GONE);
                            }
                            s.close();
                            break;
                        }


                    }
                }
                if (s != null)
                    s.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private boolean send_check_sip_activation_request(String strTargetIP) {
        try {
            bFUNCBlock = true;

            Log.d(TAG, "[send_check_sip_activation_request] strTargetIP " + RemoteIDInfo.strIP);
            mySocket s = new mySocket(strTargetIP, "HEY");
            s.start();


            return true;
//            Request_check_sip_activation check_sip_activation = new Request_check_sip_activation(mContext);
//            bFUNCBlock = true;
//            if (check_sip_activation.send_check_sip_activation_request(strTargetIP)) {
//                check_sip_activation.setResultCtrl(new iMAPResultCtrl() {
//
//                    @Override
//                    public void onResult(iMAPResult eResult) {
//                        LOG_INFO("[send_check_sip_activation_request] (onResult) eResult =" + eResult);
//                        ((MainActivity) mContext).checkMemoryUsage();
//                        if (eResult == iMAPResult.OK) {
//                            if (RemoteIDInfo.bAutoCall)
//                                MainActivity.mCallController.tryMoIPCall(CALLTYPE.GUARD, RemoteIDInfo.strDong, RemoteIDInfo.strHo);
//                            else
//                                MainActivity.mCallController.tryMoIPCall(CALLTYPE.GUARD, ConfigValue.strGuard_Dong, ConfigValue.strGuard_ID);
//                            ((MainActivity) mContext).ctrlVideoSurface(true);
//                        } else {
//                            bFUNCBlock = false;
//                            MainActivity.mSound.Play_lobby(R.raw.trylater);
//                            MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.GUARD, CALLSTATUS.IDLE);
//                            Image_Call_Anim.clearAnimation();
//                            Image_Call_Anim.setVisibility(View.GONE);
//                            ((MainActivity) mContext).setChangeScreen(ID.SCREENS.Main, false);
//                        }
//                    }
//                });
//                return true;
//            }
//            bFUNCBlock = false;
//            return false;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] send_check_sip_activation_request(strTargetIP)");
            e.printStackTrace();
            bFUNCBlock = false;
            return false;
        }
    }

    private boolean send_chat_message_request(String strTargetIP, String strMessage) {
        try {
            Request_chat_message chat_message = new Request_chat_message(mContext);
            if (chat_message.send_chat_message_request(strTargetIP, strMessage)) {
                chat_message.setResultCtrl(new iMAPResultCtrl() {

                    @Override
                    public void onResult(iMAPResult eResult) {
                        LOG_INFO("[send_chat_message_request] (onResult) eResult =" + eResult);
                    }
                });
                return true;
            }
            return false;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] send_check_sip_activation_request(strTargetIP)");
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public void onCallEvent(CALLSTATUS eCallStatus, CALLTYPE eCallType, String strRemoteIP, String strRemoteSIPID, String strMessage) {
        try {
            LOG_INFO("[onCallEvent] eCallStatus [" + eCallStatus + "], eCallType [" + eCallType + "], strRemoteIP [" + strRemoteIP + "], strRemoteSIPID [" + strRemoteSIPID + "], strMessage [" + strMessage + "]");

            if (eCallType == CALLTYPE.GUARD || eCallType == CALLTYPE.NONE) {
                MainActivity.mCallController.setRemoteInfo(strRemoteSIPID, strRemoteIP);
                if (eCallStatus == CALLSTATUS.TRYING_CALL) {
                    ((MainActivity) mContext).cancelAutoScreenChange();
                    MainActivity.mCallController.setCallTimer(MainActivity.mCallController.mCTT.WAITNG_INVITE_ACK);
                    UpdateScreen();
                } else if (eCallStatus == CALLSTATUS.CALLING) {
                    bRcvCancel = false;
                    Global.playMelodyRepeat(ConfigValue.eCallMelody_Guard);
                    ((MainActivity) mContext).cancelAutoScreenChange();
                    MainActivity.mCallController.setCallTimer(MainActivity.mCallController.mCTT.CALLING);
                    UpdateScreen();
                } else if (eCallStatus == CALLSTATUS.CALLED) {
                    bRcvCancel = false;
                    Global.playMelodyRepeat(ConfigValue.eCallMelody_Guard);
                    ((MainActivity) mContext).cancelAutoScreenChange();
                    MainActivity.mCallController.setCallTimer(MainActivity.mCallController.mCTT.CALLED);
                    UpdateScreen();
                    MainActivity.m_bCallType = 1;

                    //MainActivity.mIOInterface.setAnalogCameraPower(true);

                    ((MainActivity) mContext).ctrlVideoSurface(true);
                } else if (eCallStatus == CALLSTATUS.TALKING) {
                    MainActivity.mCallController.mCallInfo.setRemoteCallOwner(REMOTECALLOWNER.GUARD);
                    Global.stopMelodyRepeat();
                    MainActivity.mCallController.setCallTimer(MainActivity.mCallController.mCTT.LOBBYnGUARD);
                    UpdateScreen();
                    Thread.sleep(500);
//                    Global.changeVolumeMoIPMode(CALLTYPE.GUARD); // Handler로 코드 수정!!!
                    mPathCheckHandler.sendEmptyMessage(0);
                } else if (eCallStatus == CALLSTATUS.END) {
//                    stopVideo();
                    Global.stopMelodyRepeat();
                    Global.changeVolumeMoIPMode(CALLTYPE.NONE);
                    if (strMessage.contains("전화를 받지 않습니다."))
                        MainActivity.mSound.PlayMent_lobby(R.raw.trylater);
                    MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.GUARD, CALLSTATUS.IDLE);
                    MainActivity.mCallController.setCallTimer(MainActivity.mCallController.mCTT.KILLTIMER);
                    Image_Call_Anim.clearAnimation();
                    Image_Call_Anim.setVisibility(View.GONE);
                    super.setChangeScreen(ID.SCREENS.Main);
                } else if (eCallStatus == CALLSTATUS.REJECT) {
                    Global.changeVolumeMoIPMode(CALLTYPE.NONE);
                    if (bRcvCancel || bRcvBusy) {
                        MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.GUARD, CALLSTATUS.IDLE);
                        return;
                    }
                    Global.stopMelodyRepeat();
//                    stopVideo();
                    MainActivity.mSound.PlayMent_lobby(R.raw.trylater);
                    MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.GUARD, CALLSTATUS.IDLE);
                    MainActivity.mCallController.setCallTimer(MainActivity.mCallController.mCTT.KILLTIMER);
                    Image_Call_Anim.clearAnimation();
                    Image_Call_Anim.setVisibility(View.GONE);
                    super.setChangeScreen(ID.SCREENS.Main);
                } else if (eCallStatus == CALLSTATUS.BUSY) {
                    bRcvBusy = true;
                    Global.stopMelodyRepeat();
//                    stopVideo();
                    Global.changeVolumeMoIPMode(CALLTYPE.NONE);
                    MainActivity.mSound.PlayMent_lobby(R.raw.busytrylater);
                    MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.GUARD, CALLSTATUS.IDLE);
                    MainActivity.mCallController.setCallTimer(MainActivity.mCallController.mCTT.KILLTIMER);
                    Image_Call_Anim.clearAnimation();
                    Image_Call_Anim.setVisibility(View.GONE);
                    super.setChangeScreen(ID.SCREENS.Main);
                } else if (eCallStatus == CALLSTATUS.CANCEL) {
                    bRcvCancel = true;
                    Global.stopMelodyRepeat();
//                    stopVideo();
                    Global.changeVolumeMoIPMode(CALLTYPE.NONE);
                    MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.GUARD, CALLSTATUS.IDLE);
                    MainActivity.mCallController.setCallTimer(MainActivity.mCallController.mCTT.KILLTIMER);
                    Image_Call_Anim.clearAnimation();
                    Image_Call_Anim.setVisibility(View.GONE);
                    super.setChangeScreen(ID.SCREENS.Main);
                } else if (eCallStatus == CALLSTATUS.FORWARD) {
                    startForwardTimer();
                    Global.stopMelodyRepeat();
//                    stopVideo();
                    Global.changeVolumeMoIPMode(CALLTYPE.NONE);
                    MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.GUARD, CALLSTATUS.IDLE);
                    MainActivity.mCallController.setCallTimer(MainActivity.mCallController.mCTT.KILLTIMER);
                    if (!tryAutoCall(strMessage)) {
                        Image_Call_Anim.clearAnimation();
                        Image_Call_Anim.setVisibility(View.GONE);
                        super.setChangeScreen(ID.SCREENS.Main);
                    }
                } else {
                    Log.w(TAG, "[onCallEvent] Incorrect eCallStatus!!! eCallStatus = " + eCallStatus);
                }
            } else {
                Log.w(TAG, "[onCallEvent] Incorrect eCallType!!! eCallType = " + eCallType);
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] onCallEvent(CALLSTATUS eCallStatus, CALLTYPE eCallType, String strRemoteIP, String strRemoteSIPID, String strMessage) : " + e);
            e.printStackTrace();
        }
    }

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

    @Override
    public void onChatEvent(CHATEVENT eEventType, CALLTYPE eCallType, String strRemoteIP, String strRemoteSIPID, String strMessage) {
        try {
            LOG("[onChatEvent] eEventType [" + eEventType + "], eCallType [" + eCallType + "], strRemoteIP [" + strRemoteIP + "], strRemoteSIPID [" + strRemoteSIPID + "], strMessage [" + strMessage + "]");

            if (eEventType == CHATEVENT.TRY) {
                ((MainActivity) mContext).sendHandlerMsg(HANDLERMSG.START_CHATMODE, 0, 0);
                ((MainActivity) mContext).setTTSEventListener(this);
                strChatTargetIP = strRemoteIP;
            } else {
                // 기타
                LOG_WARN("[CallScenarioManager] not acceptable eEventType!! [" + eEventType + "]");
            }

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

    @Override
    public void onChatMessage(String strMessage) {
        try {
            LOG_INFO("[onChatMessage] strMessage [" + strMessage + "]");
            if (MainActivity.mCallController.mCallInfo.getGUARD() == CALLSTATUS.TALKING) {
                strText_ChatMessage = strMessage;
                ((MainActivity) mContext).playTTS(strMessage);
                sendHandlerMsg(TALKGUARD_HD_MSG.DISPLAY_CHATMESSAGE, 0, 0, strMessage);
            } else {
                Log.w(TAG, "[onChatMessage] CallStatus is not talking!! [" + MainActivity.mCallController.mCallInfo.getGUARD() + "]");
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] onChatMessage(String strMessage) : " + e);
            e.printStackTrace();
        }
    }

    @Override
    public void onTTSEvent(TTSEVENT eTTSEvent, String strMessage) {
        try {
            LOG("[onTTSEvent] eTTSEvent [" + eTTSEvent + "], strMessage [" + strMessage + "]");
            if (eTTSEvent == TTSEVENT.TTS_SPEECH_END) {
                startSTT();
            } else if (eTTSEvent == TTSEVENT.TTS_ERROR) {

            } else if (eTTSEvent == TTSEVENT.STT_READY) {
                strText_ChatMessage = "말씀하세요.";
                sendHandlerMsg(TALKGUARD_HD_MSG.DISPLAY_CHATMESSAGE, 0, 0, strText_ChatMessage);
            } else if (eTTSEvent == TTSEVENT.STT_SUCCESS) {
                strText_ChatMessage = strMessage;
                send_chat_message_request(strChatTargetIP, strText_ChatMessage);
                sendHandlerMsg(TALKGUARD_HD_MSG.DISPLAY_CHATMESSAGE, 0, 0, strText_ChatMessage);
            } else if (eTTSEvent == TTSEVENT.STT_ERROR) {

            } else {
                LOG_INFO("[onTTSEvent] eTTSEvent is not acceptable!! [" + eTTSEvent + "]");
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] onChatMessage(String strMessage) : " + e);
            e.printStackTrace();
        }
    }

    private void startSTT() {
        try {
            ((MainActivity) mContext).startSTT();
        } catch (Exception e) {
            Log.e(TAG, "[Exception] startSTT()");
            e.printStackTrace();
        }
    }

    private void displayChatMessage(String strMessage) {
        try {
            Text_ChatMessage.setText(strMessage);
            Text_ChatMessage.setFocusable(true);
        } catch (Exception e) {
            Log.e(TAG, "[Exception] displayChatMessage(String strMessage) : " + e);
            e.printStackTrace();
        }
    }

//    private void playVideo() {
//        try {
//            LOG_INFO("[playVideo] ===== START =====");
//            ((MainActivity) mContext).ctrlVideoSurface(true);
//        } catch (Exception e) {
//            Log.e(TAG, "[Exception] playVideo() : " + e);
//            e.printStackTrace();
//        }
//    }
//
//    private void stopVideo() {
//        try {
//            LOG_INFO("[stopVideo] ===== START =====");
//            ((MainActivity) mContext).ctrlVideoSurface(false);
//        } catch (Exception e) {
//            Log.e(TAG, "[Exception] stopVideo() : " + e);
//            e.printStackTrace();
//        }
//    }

    int nTalkVolume = Global.getMoIPoVolume();

    private void changeTalkVol(boolean bUp) {
        try {
            LOG("[changeTalkVol] bUp = " + bUp);
            if (bUp) {
                nTalkVolume++;
                if (nTalkVolume > 10) nTalkVolume = 10;
            } else {
                nTalkVolume--;
                if (nTalkVolume < 1) nTalkVolume = 1;
            }
            LOG("[changeTalkVol] nTalkVolume = " + nTalkVolume);
            Global.setMoIPVolume(Global.nMoIPVolumeTable_Guard[nTalkVolume]);
        } catch (Exception e) {
            Log.e(TAG, "[Exception] changeTalkVol(bUp) : " + e);
            e.printStackTrace();
        }
    }

    private void sendHandlerMsg(int what, int arg1, int arg2, String strMessage) {
        try {
            LOG("[sendHandlerMsg] what [" + what + "], arg1 [" + arg1 + "], arg2 [" + arg2 + "], strMessage [" + strMessage + "]");
            Message HandleMsg = TalkGuardHandler.obtainMessage();
            HandleMsg.what = what;
            HandleMsg.arg1 = arg1;
            HandleMsg.arg2 = arg2;
            HandleMsg.obj = strMessage;
            TalkGuardHandler.sendMessage(HandleMsg);
        } catch (Exception e) {
            Log.e(TAG, "[Exception] sendHandlerMsg(int what, int arg1, int arg2, String strMessage)");
            e.printStackTrace();
        }
    }

    private boolean tryAutoCall(String strAutoCallInfo) {
        try {
            if (bAutoCallRun) return false;
            bAutoCallRun = true;
            LOG("[tryAutoCall] strAutoCallInfo [" + strAutoCallInfo + "]");
            String[] strParse_01 = strAutoCallInfo.split(":");
            String[] strParse_02 = strParse_01[1].split("@");
            String[] strParse_03 = strParse_02[1].split(":");
            String strForwardTarget_SIPID = strParse_02[0];
            String strForwardTarget_IP = strParse_03[0];

            CALLTYPE eCallType = MainActivity.mCallController.tryAutoMoIPCall(strForwardTarget_IP, strForwardTarget_SIPID);
            LOG("[tryAutoCall] eCallType [" + eCallType + "]");
            if (eCallType == CALLTYPE.FRONT || eCallType == CALLTYPE.LOBBY || eCallType == CALLTYPE.PSTN || eCallType == CALLTYPE.NONE)
                return false;
            else if (eCallType == CALLTYPE.GUARD) {
                ((MainActivity) mContext).setChangeScreen(ID.SCREENS.Talk_Guard, false);
                return true;
            } else if (eCallType == CALLTYPE.RESIDENCE) {
                ((MainActivity) mContext).setChangeScreen(ID.SCREENS.Talk_Residence, false);
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] tryAutoCall(String strAutoCallInfo) : " + e);
            e.printStackTrace();
            return false;
        }
    }

    boolean bTactGuardCall = false;

    private void doTactGuardCall() {
        try {
            Intent intent = getScreenIntent();
            if (intent != null) {
                bTactGuardCall = (intent.getIntExtra("KEYCODE", -1) == Declare.Button.TACT_GUARD) ? true : false;
                Log.w(TAG, "[doTactGuardCall] bTactGuardCall [" + bTactGuardCall + "]");
                if (bTactGuardCall) {
                    ((MainActivity) mContext).cancelAutoScreenChange();
                    if (MainActivity.mCallController.mCallInfo.getIDLECnt() != MainActivity.mCallController.mCallInfo.IDLECNT_MAX) {
                        MainActivity.mSound.PlayMent_lobby(R.raw.inputfail);
                        MainActivity.mCallController.mCallInfo.printCallStatus();
                        LOG("[doTactGuardCall] CallStatus is not idle!!");
                        return;
                    }
                    LOG("[doTactGuardCall] strGuard_Dong [" + ConfigValue.strGuard_Dong + "], strGuard_ID [" + ConfigValue.strGuard_ID + "]");
                    RemoteIDInfo.strDong = ConfigValue.strGuard_Dong;
                    RemoteIDInfo.strHo = ConfigValue.strGuard_ID;
                    RemoteIDInfo.strIP = EthernetCtrl.makeIPAddress(Declare.DeviceType.GUARD, RemoteIDInfo.strDong, RemoteIDInfo.strHo);
                    if (!send_check_sip_activation_request(EthernetCtrl.makeIPAddress(Declare.DeviceType.GUARD, RemoteIDInfo.strDong, RemoteIDInfo.strHo))) {
                        MainActivity.mSound.PlayMent_lobby(R.raw.trylater);
                        return;
                    }
                    MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.GUARD, CALLSTATUS.TRYING_CALL);
                    UpdateScreen();
                } else {
                    Log.w(TAG, "[doTactGuardCall] bTactGuardCall [" + bTactGuardCall + "]");
                }
            }
            else {
                Log.w(TAG, "[doTactGuardCall] intent is null!!!");
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] doTactGuardCall()");
            e.printStackTrace();
        }
    }

    private void doAutoCall() {
        try {
            if (RemoteIDInfo.bAutoCall) {
                LOG("[doAutoCall] strDong [" + RemoteIDInfo.strDong + "], strHo [" + RemoteIDInfo.strHo + "], strIP [" + RemoteIDInfo.strIP + "]");
                if (!send_check_sip_activation_request(RemoteIDInfo.strIP)) {
                    initCallVariables();
                    MainActivity.mSound.PlayMent_lobby(R.raw.trylater);
                    UpdateScreen();
                    return;
                }
                MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.GUARD, CALLSTATUS.TRYING_CALL);
                UpdateScreen();
            } else {
                LOG("[doAutoCall] AutoCall is not activated!!");
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] doAutoCall() : " + e);
            e.printStackTrace();
        }
    }

    private void initCallVariables() {
        try {
            RemoteIDInfo.InitVariables();
            MainActivity.mCallController.mCallInfo.setCallStatus(CALLTYPE.GUARD, CALLSTATUS.IDLE);
            Global.TargetInputStep = TARGETINFOINPUTSTEP.DONG;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] initCallVariables()");
            e.printStackTrace();
        }
    }

    private void startForwardTimer() {
        try {
            LOG("[startForwardTimer] ===== START =====");
            cancelForwardTimer();
            if (mCountDownTimer == null) {
                mCountDownTimer = new ForwardTimer(3000, 3000);
                mCountDownTimer.start();
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] startForwardTimer() : " + e);
            e.printStackTrace();
        }
    }

    private void cancelForwardTimer() {
        try {
            LOG("[cancelForwardTimer] ===== START =====");
            if (mCountDownTimer != null) {
                mCountDownTimer.cancel();
                mCountDownTimer = null;
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] cancelForwardTimer() : " + e);
            e.printStackTrace();
        }
    }

    class TextResources {
        static final String strPressCallButton = "호출버튼을 누르세요.";
        static final String strTryingGuard = "경비실을 호출합니다.";
        static final String strCallingGuard = "경비실을 호출중입니다.";
        static final String strTalkingGuard = "경비실과 통화중입니다.";
    }

    private class TALKGUARD_HD_MSG {
        private static final int DISPLAY_CHATMESSAGE = 100;
        private static final int START_STT = 200;
        private static final int PLAYSOUND_STT_START = 300;
        private static final int PLAYSOUND_STT_END = 400;
    }

    class ForwardTimer extends CountDownTimer {

        public ForwardTimer(long millisInFuture, long countDownInterval) {
//            LOG("[ForwardTimer] millisInFuture [" + millisInFuture + "], countDownInterval [" + countDownInterval + "]");
            super(millisInFuture, countDownInterval);
            LOG("[ForwardTimer] millisInFuture [" + millisInFuture + "], countDownInterval [" + countDownInterval + "]");
        }

        @Override
        public void onTick(long millisUntilFinished) {
            LOG("[ForwardTimer] onTick!!");
        }

        @Override
        public void onFinish() {
            LOG("[ForwardTimer] onFinish!!");
            cancelForwardTimer();
            bForwarding = false;
        }
    }

    private Handler mPathCheckHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
//            Log.d(TAG, "[mPathCheckHandler.handleMessage]");
            if (msg.what == 0) {
                if (MainActivity.mCallController.getTalkPath() == CALLPATH.MOIP_GUARD)
                    mPathCheckHandler.sendEmptyMessageDelayed(1, 10);
                else mPathCheckHandler.sendEmptyMessageDelayed(0, 10);
            } else if (msg.what == 1) {
                Log.d(TAG, "[mPathCheckHandler.handleMessage] Handler finish!! CALLPATH [MOIP_GUARD] setMoIPVolume");
                Global.changeVolumeMoIPMode(CALLTYPE.GUARD);
                mVolumeCheckHandler.sendEmptyMessage(0);
            }
        }
    };

    private Handler mVolumeCheckHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 0) {
                if (Global.getCurrentGuardVolume(MainActivity.mIOInterface.getVolumeCtl()) != ConfigValue.nVolumeLevel_Talk) {
                    Global.changeVolumeMoIPMode(CALLTYPE.GUARD);
                    mVolumeCheckHandler.sendEmptyMessageDelayed(0, 500);
                } else {
                    mVolumeCheckHandler.sendEmptyMessageDelayed(1, 500);
                }
            } else if (msg.what == 1) {
                Log.d(TAG, "[mVolumeCheckHandler.handleMessage] Handler finish!!");
            }
        }
    };

    private void startInputDelayTimer() {
        try {
            LOG("[startInputDelayTimer] ========== START ==========");
            bInputDelay = true;
            if (InputDelayTimer != null) {
                InputDelayTimer.cancel();
                InputDelayTimer = null;
            }

            InputDelayTimer = new CountDownTimer(3000, 1000) {
                @Override
                public void onTick(long millisUntilFinished) {
                    LOG("[startInputDelayTimer] onTick!!");
                }

                @Override
                public void onFinish() {
                    LOG("[startInputDelayTimer] onFinish!!");
                    bInputDelay = false;
                    quitInputDelayTimer();
                }
            };
            InputDelayTimer.start();
        } catch (Exception e) {
            Log.e(TAG, "[Exception] startInputDelayTimer()");
            e.printStackTrace();
        }
    }

    private void quitInputDelayTimer() {
        try {
            LOG("[quitInputDelayTimer] ========== START ==========");
            if (InputDelayTimer != null) {
                InputDelayTimer.cancel();
            }
            InputDelayTimer = null;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] quitInputDelayTimer()");
            e.printStackTrace();
        }
    }

}