package kr.co.icontrols.ilp300_700.screen;

import android.content.Context;
import android.graphics.Color;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.RelativeLayout;

import kr.co.icontrols.ilp300_700.MainActivity;
import kr.co.icontrols.ilp300_700.R;
import kr.co.icontrols.ilp300_700.call.CallManager.CALLTYPE;
import kr.co.icontrols.ilp300_700.ethernet.iMAPCommon.iMAPResult;
import kr.co.icontrols.ilp300_700.global.Configure;
import kr.co.icontrols.ilp300_700.global.Configure.ConfigValKey;
import kr.co.icontrols.ilp300_700.global.Configure.ConfigValue;
import kr.co.icontrols.ilp300_700.global.Configure.DefaultConfigValue;
import kr.co.icontrols.ilp300_700.global.Configure.SetValue;
import kr.co.icontrols.ilp300_700.global.DataClasses.POSITION;
import kr.co.icontrols.ilp300_700.global.Declare;
import kr.co.icontrols.ilp300_700.global.Global;
import kr.co.icontrols.ilp300_700.global.ID;
import kr.co.icontrols.ilp300_700.imap.Request_device_bootup;
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 Init extends WpadScreen {

    String TAG = "Init";

    boolean bLOG = true;
    boolean bLOG_DEBUG = true;
    boolean bLOG_INFO = true;

    WpadImageView Image_Background;
    WpadImageView Image_Load;
    WpadImageView Image_Load_anim;
    WpadTextView Text_Instruction;
    Animation mAnimation;

    Context mContext;

    int[] BGImages = {R.drawable.bg_black, R.drawable.bg_black_700};
    int[] CirYellowImages = {R.drawable.cir_yellow, R.drawable.cir_yellow_700};
    int[] CirWhiteImages = {R.drawable.cir_white_quarter, R.drawable.cir_white_quarter_700};
    int nTotalInitStep = 10;
    int[] nFontSize_Instruction = {24, 46};
    String strText_Instruction = "";
    DeviceInitManager mDeviceInitManager;

    private Handler MainHandler = new Handler(Looper.getMainLooper()) {
        public void handleMessage(Message msg) {
            LOG("[MainHandler] what [" + msg.what + "], arg1 [" + msg.arg1 + "], arg2 [" + msg.arg2 + "]");
            switch (msg.what) {
                case HANDLERMSG.INITSTEPCNT:
                    displayInitStep(msg.arg1);
                    break;

                case HANDLERMSG.INIT_SIPMODULE:
                    boolean bResult = ((MainActivity) mContext).initSIPModule();
                    LOG_INFO("[MainHandler] initSIPModule [" + bResult + "]");
                    break;

                case HANDLERMSG.INIT_ONSCREEN_MAIN:
                    ((MainActivity) mContext).setChangeScreen(ID.SCREENS.Main, false);
                    break;

                case HANDLERMSG.INIT_ONSCREEN_BASICSETTING:
                    ((MainActivity) mContext).setChangeScreen(ID.SCREENS.AdminSet_Setting_BasicInfo, false);
                    break;

                case HANDLERMSG.CLEAR_ANIMATION:
                    LOG_INFO("[MainHandler] CLEAR_ANIMATION");
                    Image_Load_anim.clearAnimation();
                    Image_Load_anim.setVisibility(View.GONE);
                    break;

                default:
                    LOG("MainHandler : " + msg.what);
                    break;
            }
        }
    };

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

            mContext = context;
            Initialize();

            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.INIT.ELEMENTS.IMAGES.BACKGROUND);
            ViewRegistration(layout, Image_Background, getPosition(ID.SCREENS.INIT.ELEMENTS.IMAGES.BACKGROUND).X, getPosition(ID.SCREENS.INIT.ELEMENTS.IMAGES.BACKGROUND).Y);

            Image_Load = new WpadImageView(context, 0, getPosition(ID.SCREENS.INIT.ELEMENTS.IMAGES.LOAD).W, getPosition(ID.SCREENS.INIT.ELEMENTS.IMAGES.LOAD).H, CirYellowImages[ConfigValue.DEVICE_MODELTYPE], 0, ID.SCREENS.INIT.ELEMENTS.IMAGES.LOAD);
            ViewRegistration(layout, Image_Load, getPosition(ID.SCREENS.INIT.ELEMENTS.IMAGES.LOAD).X, getPosition(ID.SCREENS.INIT.ELEMENTS.IMAGES.LOAD).Y);

            Image_Load_anim = new WpadImageView(context, 0, getPosition(ID.SCREENS.INIT.ELEMENTS.IMAGES.LOAD_ANIM).W, getPosition(ID.SCREENS.INIT.ELEMENTS.IMAGES.LOAD_ANIM).H, CirWhiteImages[ConfigValue.DEVICE_MODELTYPE], 0, ID.SCREENS.INIT.ELEMENTS.IMAGES.LOAD_ANIM);
            ViewRegistration(layout, Image_Load_anim, getPosition(ID.SCREENS.INIT.ELEMENTS.IMAGES.LOAD_ANIM).X, getPosition(ID.SCREENS.INIT.ELEMENTS.IMAGES.LOAD_ANIM).Y);

            mAnimation = AnimationUtils.loadAnimation(mContext, R.anim.rotate_init);
            mAnimation.setInterpolator(AnimationUtils.loadInterpolator(mContext, android.R.anim.accelerate_decelerate_interpolator));

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

            startDeviceInitThread();
        } catch (Exception e) {
            Log.e(TAG, "[Exception] Init(...) : " + 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 Initialize() {
        try {
            LOG("[Initialize] ===== START =====");
//            displayInitStep(0);
        } catch (Exception e) {
            Log.e(TAG, "[Exception] Initialize() : " + e);
            e.printStackTrace();
        }
    }

    @Override
    protected void onClose() {
        try {
            LOG("------------------ [onClose - Init] -------------------");
            Image_Load_anim.clearAnimation();
            Image_Load_anim.setVisibility(View.GONE);
        } catch (Exception e) {
            Log.e(TAG, "[Exception] onClose(...) : " + e);
            e.printStackTrace();
        }
        super.onClose();
    }

    public void UpdateScreen() {
        try {
            LOG("[updateScreen] ========== START ==========");
        } catch (Exception e) {
            Log.e(TAG, "[Exception] updateScreen() : " + e);
            e.printStackTrace();
        }
    }

    public POSITION getPosition(int nID) {
        POSITION position = new POSITION();
        position.SetPosition(0, 0, 480, 272);

        try {
            switch (nID) {
                case ID.SCREENS.INIT.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.INIT.ELEMENTS.IMAGES.LOAD:
                    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.INIT.ELEMENTS.IMAGES.LOAD_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.INIT.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;

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

    private String getInitStep(int step) {
        try {
            return TextResources.strInitStep + " (" + step + "/" + nTotalInitStep + ")";
        } catch (Exception e) {
            Log.e(TAG, "[Exception] getInitStep()");
            e.printStackTrace();
            return TextResources.strInitStep;
        }
    }

    private boolean send_device_bootup_request() {
        try {
            final Request_device_bootup device_bootup = new Request_device_bootup(mContext);
            if (device_bootup.send_device_bootup_request()) {
                device_bootup.setResultCtrl(new iMAPResultCtrl() {

                    @Override
                    public void onResult(iMAPResult eResult) {
                        LOG_INFO("[send_device_bootup_request] (onResult) eResult =" + eResult);
                        if (eResult == iMAPResult.OK) {
                            int nYear = 0, nMonth = 0, nDate = 0, nHour = 0, nMin = 0;
                            String strLocationName = "";
                            int nLocationCode = 0;
                            String strServerVer = "1.0";
                            device_bootup.setItem("date");
                            nYear = Integer.parseInt(device_bootup.getAttributeValue(0, "year"));
                            nMonth = Integer.parseInt(device_bootup.getAttributeValue(0, "month"));
                            nDate = Integer.parseInt(device_bootup.getAttributeValue(0, "date"));
                            device_bootup.setItem("time");
                            nHour = Integer.parseInt(device_bootup.getAttributeValue(0, "hour"));
                            nMin = Integer.parseInt(device_bootup.getAttributeValue(0, "min"));
                            device_bootup.setItem("location");
                            strLocationName = device_bootup.getAttributeValue(0, "name");
                            nLocationCode = Integer.parseInt(device_bootup.getAttributeValue(0, "code"));
                            strServerVer = device_bootup.getItemValue("ver_server");

                            LOG_INFO("[send_device_bootup] Calendar [" + nYear + "/" + nMonth + "/" + nDate + " " + nHour + ":" + nMin + "]");
                            LOG_INFO("[send_device_bootup] strLocationName [" + strLocationName + "], nLocationCode [" + nLocationCode + "]");
                            LOG_INFO("[send_device_bootup] strServerVer [" + strServerVer + "]");

                            Global.bDevicebootup = Global.setSystemTime(nYear, nMonth, nDate, nHour, nMin);
                            Global.setMainServerType(strServerVer);
                            LOG_INFO("[send_device_bootup] Global.bDevicebootup [" + Global.bDevicebootup + "]");
                        }
                    }
                });
                return true;
            }
            return false;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] send_device_bootup_request()");
            e.printStackTrace();
            return false;
        }
    }

    private void startDeviceInitThread() {
        try {
            Log.e(TAG, "[startDeviceInitThread] ===== START =====");
//            iMAPServer.resetRFKeyDB();   // DB 오류 복구용 코드 (2015.12.04, JEFF)
//            Thread.sleep(3000);
            mDeviceInitManager = new DeviceInitManager(nTotalInitStep);
            mDeviceInitManager.start();

            // 애니메이션 시작
            mAnimation.setDuration(10 * 1000);
            mAnimation.setFillAfter(false);
            Image_Load_anim.startAnimation(mAnimation);
        } catch (Exception e) {
            Log.e(TAG, "[Exception] startDeviceInitThread()");
            e.printStackTrace();
        }
    }

    private void destroyDeviceInitThread() {
        try {
            mDeviceInitManager.interrupt();
            mDeviceInitManager = null;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] destroyDeviceInitThread()");
            e.printStackTrace();
        }
    }

    private void displayInitStep(int nStep) {
        try {
            LOG("[displayInitStep] nStep [" + nStep + "]");
            strText_Instruction = getInitStep(nStep);
            Text_Instruction.setText(strText_Instruction);
        } catch (Exception e) {
            Log.e(TAG, "[Exception] displayInitStep(int nStep)");
            e.printStackTrace();
        }
    }

    public void sendHandlerMsg(int what, int arg1, int arg2) {
        try {
            LOG("[sendHandlerMsg] what [" + what + "], arg1 [" + arg1 + "], arg2 [" + arg2 + "]");
            Message HandleMsg = MainHandler.obtainMessage();
            HandleMsg.what = what;
            HandleMsg.arg1 = arg1;
            HandleMsg.arg2 = arg2;
            MainHandler.sendMessage(HandleMsg);
        } catch (Exception e) {
            Log.e(TAG, "[Exception] sendHandlerMsg(msg)");
            e.printStackTrace();
        }
    }

    private void setDNSIPAddress() {
        try {
            Log.w(TAG, "[setDNSIPAddress] ===== Before changing ===== ConfigValue.strDNSIPAddress [" + ConfigValue.strDNSIPAddress + "], DefaultConfigValue.strDNSIPAddress [" + DefaultConfigValue.strDNSIPAddress + "]");
            if (!ConfigValue.strDNSIPAddress.equals(DefaultConfigValue.strDNSIPAddress)) {
                ConfigValue.strDNSIPAddress = DefaultConfigValue.strDNSIPAddress;
                Log.w(TAG, "[setDNSIPAddress] ===== After changing ===== ConfigValue.strDNSIPAddress [" + ConfigValue.strDNSIPAddress + "], DefaultConfigValue.strDNSIPAddress [" + DefaultConfigValue.strDNSIPAddress + "]");
                MainActivity.ConfigDBManager.setData(Declare.DBInfo.TABLE_NAME_CONFIG, ConfigValKey.DNSIPAddress, ConfigValue.strDNSIPAddress);
            } else {
                Log.w(TAG, "[setDNSIPAddress] ===== not need changing ===== ConfigValue.strDNSIPAddress [" + ConfigValue.strDNSIPAddress + "], DefaultConfigValue.strDNSIPAddress [" + DefaultConfigValue.strDNSIPAddress + "]");
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] setDNSIPAddress()");
            e.printStackTrace();
        }
    }

    class TextResources {
        static final String strInitStep = "초기화중입니다.";
    }

    private class DeviceInitManager extends Thread {

        int nInitCnt = 0;
        boolean bResult = false;

        public DeviceInitManager(int nTotalInitCnt) {
            nInitCnt = nTotalInitCnt;
        }

        public void run() {
            try {
                LOG_INFO("[DeviceInitManager().run()] nInitCnt [" + nInitCnt + "] ========== START ==========");
                for (int i = 0; i <= nInitCnt; i++) {
                    try {
                        LOG_INFO("[DeviceInitManager().run()] ========== Device Init Step [" + i + "] ==========");
                        sendHandlerMsg(HANDLERMSG.INITSTEPCNT, i, 0);

                        switch (i) {
                            case 1:
                                bResult = ((MainActivity) mContext).initJNI();
                                LOG_INFO("[DeviceInitManager().run()] initJNI [" + bResult + "]");
                                ((MainActivity) mContext).startAppLiveSignalSender();
                                break;

                            case 2:
                                bResult = ((MainActivity) mContext).initBestinDirectory();
                                LOG_INFO("[DeviceInitManager().run()] initBestinDirectory [" + bResult + "]");
                                bResult = ((MainActivity) mContext).initConfigDB();
                                LOG_INFO("[DeviceInitManager().run()] initConfigDB [" + bResult + "]");
                                Configure.printConfigValues();
                                setDNSIPAddress();
                                break;

                            case 3:
                                bResult = ((MainActivity) mContext).initLCD();
                                LOG_INFO("[DeviceInitManager().run()] initLCD [" + bResult + "]");
                                bResult = ((MainActivity) mContext).initSystemVolume();
                                LOG_INFO("[DeviceInitManager().run()] initSystemVolume [" + bResult + "]");
                                break;

                            case 4:
                                bResult = ((MainActivity) mContext).initNetworkInterface();
                                LOG_INFO("[DeviceInitManager().run()] initNetworkInterface [" + bResult + "]");
                                break;

                            case 5:
                                sendHandlerMsg(HANDLERMSG.INIT_SIPMODULE, 0, 0);
                                break;

                            case 6:
                                bResult = ((MainActivity) mContext).initiMAPServer();
                                LOG_INFO("[DeviceInitManager().run()] initiMAPServer [" + bResult + "]");
                                break;

                            case 7:
                                bResult = ((MainActivity) mContext).initRFPassModule();
                                LOG_INFO("[DeviceInitManager().run()] initRFPassModule [" + bResult + "]");

                                if (ConfigValue.eSmartAutodoorLink == SetValue.TRUE) {
                                    bResult = ((MainActivity) mContext).initIFConverter();
                                    MainActivity.startRFReaderChecker();
                                    LOG_INFO("[DeviceInitManager().run()] initIFConverter [" + bResult + "]");
                                }
                                else {
                                    Log.w(TAG, "[DeviceInitManager().run()] SmartAutodoorLink disabled!!");
                                }

                                if (ConfigValue.eFingerPrintLink == SetValue.TRUE) {
                                    bResult = ((MainActivity) mContext).initFingerprintService();
                                }
                                else {
                                    Log.w(TAG, "[DeviceInitManager().run()] FingerPrintLink disabled!!");
                                }
                                break;

                            case 8:
                                ((MainActivity) mContext).setVersions();
                                bResult = send_device_bootup_request();
                                LOG_INFO("[DeviceInitManager().run()] send_device_bootup_request [" + bResult + "]");
                                break;

                            case 9:
                                bResult = Global.startHeartbeatSender();
                                LOG_INFO("[DeviceInitManager().run()] startHeartbeatSender [" + bResult + "]");
                                ((MainActivity) mContext).startOnePassProc();
                                break;

                            case 10:
                                // 초기화 마지막 단계시 애니메이션 해제
                                sendHandlerMsg(HANDLERMSG.CLEAR_ANIMATION, 0, 0);

                                Global.changeVolumeMoIPMode(CALLTYPE.NONE);
                                if (ConfigValue.eFirstBoot != SetValue.FALSE) {
                                    LOG_INFO("[DeviceInitManager().run()] ========== FIRST BOOT ==========");
                                    sendHandlerMsg(HANDLERMSG.INIT_ONSCREEN_BASICSETTING, 0, 0);
                                } else {
                                    LOG_INFO("[DeviceInitManager().run()] ========== NORMAL BOOT ==========");
                                    sendHandlerMsg(HANDLERMSG.INIT_ONSCREEN_MAIN, 0, 0);
                                }
                                Global.setEnableDeviceInput(true);
                                LOG_INFO("[DeviceInitManager().run()] Global.getEnableDeviceInput() = " + Global.getEnableDeviceInput());
                                LOG_INFO("[DeviceInitManager().run()] ========== DONE BOOT SEQUENCE ==========");
                                break;
                        }
                    } catch (Exception e) {
                        Log.e(TAG, "[Exception] DeviceInitManager().run().for");
                        e.printStackTrace();
                    }
                    Thread.sleep(1000);
                }
            } catch (Exception e) {
                Log.e(TAG, "[Exception] DeviceInitManager().run()");
                e.printStackTrace();
            }
//            destroyDeviceInitThread();
            LOG_INFO("[DeviceInitManager().run()] ========== END ==========");
        }
    }

    // Init Class Handler
    private final class HANDLERMSG {
        private final static int INITSTEPCNT = 100;
        private final static int INIT_SIPMODULE = 200;
        private final static int INIT_ONSCREEN_MAIN = 300;
        private final static int INIT_ONSCREEN_BASICSETTING = 400;
        private final static int CLEAR_ANIMATION = 500;
    }
}