package kr.co.icontrols.ilp300_700.rfreader;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import kr.co.icontrols.ilp300_700.MainActivity;
import kr.co.icontrols.ilp300_700.R;
import kr.co.icontrols.ilp300_700.global.Configure;
import kr.co.icontrols.ilp300_700.global.Configure.ConfigValue;
import kr.co.icontrols.ilp300_700.global.DataClasses.IPARKNFCInfo;
import kr.co.icontrols.ilp300_700.global.DataClasses.MultiReaderKeyInfo;
import kr.co.icontrols.ilp300_700.global.DataClasses.STDReaderKeyInfo;
import kr.co.icontrols.ilp300_700.global.Declare.MultiReaderPacket;
import kr.co.icontrols.ilp300_700.global.Global;
import kr.co.icontrols.ilp300_700.global.LobbyAccessCtrl;

public class HDCStandardManager {

    static String TAG = "HDCStandardManager";

    static boolean bLOG = true;   // true, false
    static boolean bLOG_DEBUG = false;   // true, false
    static boolean bLOG_INFO = true;   // true, false
    static MultiRFResultListener mMultiRFResultListener;
    static Handler RFTestHandler;

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

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

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

    public static void procRcvData(int nReaderType, int nMSGType, int nETC, byte[] hRcvRFData) {
        try {
            LOG("[procRcvData] ====== START =====");
            MultiReaderKeyInfo KeyInfo = new MultiReaderKeyInfo();
            KeyInfo.clear();

            String sUID = "";
            String sSN = "";
            String sSitecode = "";
            String sDong = "";
            String sHo = "";
            String sIDNo = "";
            String sIssueCnt = "0";
            byte hIDType = 0x00;
            byte hDirection = 0x00;   // 0x00: in -> out, 0x01: out -> in, 외부에서 내부로 들어올때만 문을 엽니다.

            LOG_DEBUG("[procRcvData] hRcvRFData.length = " + hRcvRFData.length);
            LOG_DEBUG("[procRcvData] hRcvRFData = " + Global.printHexs(hRcvRFData));

            switch (hRcvRFData[3]) {
                case MultiReaderPacket.CMD_STATUS_REPLY:
                    LOG("[procRcvData] CMD_STATUS_REPLY");
                    if (mMultiRFResultListener != null)
                        mMultiRFResultListener.onReplyResult("STATUS_OK");
                    break;

                case MultiReaderPacket.CMD_FW_VER_REPLY:
                    LOG("[procRcvData] CMD_FW_VER_REPLY");
                    String strModel = "";
                    String strVersion = "";
                    String strVersion_Over_Point = "";
                    String strVersion_Under_Point = "";
                    for (int i = 4; i < 8; i++) {
                        strModel += Global.HextoString(hRcvRFData[i]);
                    }
                    strVersion_Over_Point += Global.HextoString(hRcvRFData[8]) + Global.HextoString(hRcvRFData[9]);
                    strVersion_Under_Point += Global.HextoString(hRcvRFData[10]) + Global.HextoString(hRcvRFData[11]);
                    strVersion = strVersion_Over_Point + "." + strVersion_Under_Point;
                    String strResult = "FWVER_" + strModel + "_" + strVersion;
                    if (mMultiRFResultListener != null)
                        mMultiRFResultListener.onReplyResult(strResult);
                    break;

                case MultiReaderPacket.CMD_ZIGBEE_SENSITIVITY_REPLY:
//            	String strSensitivity = Global.HextoString(hRcvRFData[4]);
                    int strSensitivity = hRcvRFData[4];
                    LOG("[procRcvData] strSensitivity [" + strSensitivity + "]");
                    if (mMultiRFResultListener != null)
                        mMultiRFResultListener.onReplyResult(String.valueOf(strSensitivity));
                    break;

                case MultiReaderPacket.CMD_SMARTKEY:
                    LOG("[procRcvData] CMD_SMARTKEY");

                    for (int i = 0; i < 4; i++) {
                        sUID += String.format("%02X", hRcvRFData[i + 4]);
                    }

                    for (int i = 0; i < 4; i++) {
                        sSN += String.format("%02X", hRcvRFData[i + 16]);
                    }
                    sSN += String.format("%03X", hRcvRFData[20]);

                    sSitecode = String.format("%02X", hRcvRFData[12]) + String.format("%02X", hRcvRFData[13]) + String.format("%02X", hRcvRFData[14]) + String.format("%02X", hRcvRFData[15]);
                    sDong = Integer.toString(Integer.parseInt(String.format("%02X", hRcvRFData[16]) + String.format("%02X", hRcvRFData[17])));
                    sHo = Integer.toString(Integer.parseInt(String.format("%02X", hRcvRFData[18]) + String.format("%02X", hRcvRFData[19])));
                    sIDNo = Integer.toString(Integer.parseInt(String.format("%02X", hRcvRFData[20])));
                    hIDType = (byte) hRcvRFData[24];
                    hDirection = (byte) hRcvRFData[25];

                    KeyInfo.setKeyInfo(MultiReaderPacket.CMD_SMARTKEY, sUID, sSN, sSitecode, sDong, sHo, sIDNo, sIssueCnt, hIDType, hDirection);

                    decodeRFPassInfo(KeyInfo, null);

                    if (RFTestHandler != null)
                        sendHandlerMSG(RFTestHandler, RFReaderManager.HANDLE_RFREADER_STANDDARD, KeyInfo);
                    break;

                case MultiReaderPacket.CMD_IPARK:
                    LOG("[procRcvData] CMD_IPARK");

                    for (int i = 0; i < 4; i++) {
                        sUID += String.format("%02X", hRcvRFData[i + 4]);
                    }

                    sSitecode = String.format("%02X", hRcvRFData[12]) + String.format("%02X", hRcvRFData[13]) + String.format("%02X", hRcvRFData[14]) + String.format("%02X", hRcvRFData[15]);
                    sDong = Integer.toString(Integer.parseInt(String.format("%02X", hRcvRFData[16]) + String.format("%02X", hRcvRFData[17])));
                    sHo = Integer.toString(Integer.parseInt(String.format("%02X", hRcvRFData[18]) + String.format("%02X", hRcvRFData[19])));
                    sIDNo = Integer.toString(Integer.parseInt(String.format("%02X", hRcvRFData[21])));
                    sIssueCnt = Integer.toString(Integer.parseInt(String.format("%02X", hRcvRFData[22])));
                    hIDType = (byte) hRcvRFData[20];

                    KeyInfo.setKeyInfo(MultiReaderPacket.CMD_IPARK, sUID, sSN, sSitecode, sDong, sHo, sIDNo, sIssueCnt, hIDType, hDirection);

                    decodeRFPassInfo(KeyInfo, null);

                    if (RFTestHandler != null)
                        sendHandlerMSG(RFTestHandler, RFReaderManager.HANDLE_RFREADER_STANDDARD, KeyInfo);
                    break;

                case MultiReaderPacket.CMD_MIFARE:
                    LOG("[procRcvData] CMD_MIFARE");

                    for (int i = 0; i < 4; i++) {
                        sUID += String.format("%02X", hRcvRFData[i + 4]);
                    }

                    KeyInfo.setKeyInfo(MultiReaderPacket.CMD_MIFARE, sUID, sSN, sSitecode, sDong, sHo, sIDNo, sIssueCnt, hIDType, hDirection);

                    decodeRFPassInfo(KeyInfo, null);

                    if (RFTestHandler != null)
                        sendHandlerMSG(RFTestHandler, RFReaderManager.HANDLE_RFREADER_STANDDARD, KeyInfo);
                    break;

                case MultiReaderPacket.CMD_TMONEY:
                    LOG("[procRcvData] CMD_TMONEY");

                    for (int i = 0; i < 8; i++) {
                        sUID += String.format("%02X", hRcvRFData[i + 4]);
                        sSN += String.format("%02X", hRcvRFData[i + 12]);
                    }

                    KeyInfo.setKeyInfo(MultiReaderPacket.CMD_TMONEY, sUID, sSN, sSitecode, sDong, sHo, sIDNo, sIssueCnt, hIDType, hDirection);

                    decodeRFPassInfo(KeyInfo, null);

                    if (RFTestHandler != null)
                        sendHandlerMSG(RFTestHandler, RFReaderManager.HANDLE_RFREADER_STANDDARD, KeyInfo);
                    break;

                case MultiReaderPacket.CMD_IPARKNFC:
                    LOG("[procRcvData] CMD_IPARKNFC");

                    for (int i = 0; i < 4; i++) {
                        sUID += String.format("%02X", hRcvRFData[i + 4]);
                    }

                    sSitecode = String.format("%02X", hRcvRFData[12]) + String.format("%02X", hRcvRFData[13]) + String.format("%02X", hRcvRFData[14]) + String.format("%02X", hRcvRFData[15]);
                    sDong = String.format("%02X", hRcvRFData[16]) + String.format("%02X", hRcvRFData[17]);
                    sHo = String.format("%02X", hRcvRFData[18]) + String.format("%02X", hRcvRFData[19]);
                    sIDNo = String.format("%02X", hRcvRFData[21]);
                    sIssueCnt = String.format("%02X", hRcvRFData[22]);
                    hIDType = (byte) hRcvRFData[20];

                    byte[] hName = new byte[12];
                    byte[] hPhoneNum = new byte[6];
                    byte[] hPassWord = new byte[10];
                    String sName = "";
                    String sPhoneID = "";
                    String sPassword = "";
/*
                // 이름
                if (hRcvRFData[24] != 0x00) sName = Encoding.UTF8.GetString(hRcvRFData, 24, 12);
                else sName = "";

                // 전화번호
                for (int i = 0; i < 6; i++)
                {
                    sPhoneID += String.format("%02X", hRcvRFData[i + 36]);
                }

                // 비밀번호
                if (hRcvRFData[42] != 0x00) sPassword = Encoding.ASCII.GetString(hRcvRFData, 42, 10);
                else sPassword = "";
                */
                    IPARKNFCInfo NFCInfo = new IPARKNFCInfo();

                    NFCInfo.setIPARKNFCInfo(sName, sPhoneID, sPassword);

                    KeyInfo.setKeyInfo(MultiReaderPacket.CMD_IPARK, sUID, sSN, sSitecode, sDong, sHo, sIDNo, sIssueCnt, hIDType, hDirection);

                    decodeRFPassInfo(KeyInfo, NFCInfo);

                    break;

                case MultiReaderPacket.CMD_UNKNOWN:
                    LOG("[procRcvData] CMD_UNKNOWN");
                    break;
            }
        } catch (Exception e) {
            Log.e(TAG, "[Exception] procRcvData(nRFType, nMSGType, nETC, hRcvRFData) : " + e);
            e.printStackTrace();
        }
    }

    private static void decodeRFPassInfo(MultiReaderKeyInfo KeyInfo, IPARKNFCInfo NFCInfo) {
        try {
            LOG_INFO("[decodeRFPassInfo] ====== decodeRFPassInfo =====");
            LOG_INFO("[decodeRFPassInfo] CMD [" + String.format("%02X", KeyInfo.getCMD()) + "]");
            LOG_DEBUG("[decodeRFPassInfo] UID [" + KeyInfo.getUID() + "], SN [" + KeyInfo.getSN() + "]");
            String strCryptedData = "";
            LOG_INFO("[decodeRFPassInfo] ConfigValue.eCardReaderType [" + ConfigValue.eCardReaderType + "]");
            strCryptedData = Global.encryptHDCAccessKeyInfo(KeyInfo.getUID());
            LOG_INFO("[decodeRFPassInfo] Crypted UID [" + strCryptedData + "], SN [" + KeyInfo.getSN() + "]");
            LOG_INFO("[decodeRFPassInfo] Sitecode [" + KeyInfo.getSitecode() + "], Dong [" + KeyInfo.getDong() + "], Ho [" + KeyInfo.getHo() + "]");
            LOG_INFO("[decodeRFPassInfo] KeyNo [" + KeyInfo.getKeyNo() + "], IssueCnt [" + KeyInfo.getIssueCnt() + "], IDType [" + String.format("%02X", KeyInfo.getIDType()) + "]");

            if (NFCInfo != null) {
                LOG_INFO("[decodeRFPassInfo] Name [" + NFCInfo.getNFCInfo_Name() + "], PhoneID [" + NFCInfo.getNFCInfo_PhoneID() + "], PW [" + NFCInfo.getNFCInfo_Password() + "]");
            }
            LOG_INFO("[decodeRFPassInfo] ====== decodeRFPassInfo =====");

            switch (KeyInfo.getCMD()) {
                case MultiReaderPacket.CMD_STATUS_REPLY:
                    LOG_INFO("[decodeRFPassInfo] CMD_STATUS_REPLY");
                    break;

                case MultiReaderPacket.CMD_FW_VER_REPLY:
                    LOG_INFO("[decodeRFPassInfo] CMD_FW_VER_REPLY");
                    break;


                case MultiReaderPacket.CMD_ZIGBEE_SENSITIVITY_REPLY:
                    LOG_INFO("[decodeRFPassInfo] CMD_ZIGBEE_SENSITIVITY_REPLY");
                    break;

                case MultiReaderPacket.CMD_SMARTKEY:
                    LOG_INFO("[decodeRFPassInfo] CMD_SMARTKEY");
                    if (Global.bSmartKeyTestMode) MainActivity.mSound.Play_lobby(R.raw.onepass);
                    MultiReaderKeyInfo SmartKeyInfo = new MultiReaderKeyInfo();
                    SmartKeyInfo.setKeyInfo(KeyInfo.getCMD(), strCryptedData, KeyInfo.getSN(), KeyInfo.getSitecode(), KeyInfo.getDong(), KeyInfo.getHo(), KeyInfo.getKeyNo(), KeyInfo.getIssueCnt(), KeyInfo.getIDType(), KeyInfo.getDirection());
                    LobbyAccessCtrl.ctrlAccessSmartKey(SmartKeyInfo);
                    break;

                case MultiReaderPacket.CMD_IPARK:
                    LOG_INFO("[decodeRFPassInfo] CMD_IPARK");
                    STDReaderKeyInfo STDKeyInfo = new STDReaderKeyInfo();
                    STDKeyInfo.setInfo(KeyInfo.getSitecode(), KeyInfo.getDong(), KeyInfo.getHo(), KeyInfo.getKeyNo(), KeyInfo.getIssueCnt(), KeyInfo.getIDType());
                    LobbyAccessCtrl.ctrlAccessSTDRFKey(STDKeyInfo);
                    break;

                case MultiReaderPacket.CMD_MIFARE:
                    LOG_INFO("[decodeRFPassInfo] CMD_MIFARE");
                    MultiReaderKeyInfo MifareKeyInfo = new MultiReaderKeyInfo();
                    MifareKeyInfo.setKeyInfo(KeyInfo.getCMD(), strCryptedData, KeyInfo.getSN(), KeyInfo.getSitecode(), KeyInfo.getDong(), KeyInfo.getHo(), KeyInfo.getKeyNo(), KeyInfo.getIssueCnt(), KeyInfo.getIDType(), KeyInfo.getDirection());
                    if (ConfigValue.eExternalOnePassLink == Configure.SetValue.TRUE) LobbyAccessCtrl.ctrlAccessExternalMifareKey(MifareKeyInfo);
                    else LobbyAccessCtrl.ctrlAccessMifareKey(MifareKeyInfo);
                    break;

                case MultiReaderPacket.CMD_TMONEY:
                    LOG("[decodeRFPassInfo] CMD_TMONEY");
                    MultiReaderKeyInfo TMoneyKeyInfo = new MultiReaderKeyInfo();
                    TMoneyKeyInfo.setKeyInfo(KeyInfo.getCMD(), strCryptedData, KeyInfo.getSN(), KeyInfo.getSitecode(), KeyInfo.getDong(), KeyInfo.getHo(), KeyInfo.getKeyNo(), KeyInfo.getIssueCnt(), KeyInfo.getIDType(), KeyInfo.getDirection());
                    LobbyAccessCtrl.ctrlAccessTMoneyKey(TMoneyKeyInfo);
                    break;

                case MultiReaderPacket.CMD_IPARKNFC:
                    LOG_INFO("[decodeRFPassInfo] CMD_IPARKNFC");
                    break;

                case MultiReaderPacket.CMD_UNKNOWN:
                    LOG_INFO("[decodeRFPassInfo] CMD_UNKNOWN");
                    break;
            }

        } catch (Exception e) {
            Log.e(TAG, "[Exception] decodeRFPassInfo(PassInfo) : " + e);
            e.printStackTrace();
        }
    }

    public static void setMultiRFResultListener(MultiRFResultListener RFResult) {
        mMultiRFResultListener = RFResult;
    }

    public static void releaseMultiRFResultListener() {
        mMultiRFResultListener = null;
    }

    public static void setHandler(Handler Handle) {
        try {
            RFTestHandler = Handle;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] setHandler(Handle)");
            e.printStackTrace();
        }
    }

    public static void releaseHandler() {
        try {
            RFTestHandler = null;
        } catch (Exception e) {
            Log.e(TAG, "[Exception] releaseHandler()");
            e.printStackTrace();
        }
    }

    private static void sendHandlerMSG(Handler Handle, int nReaderType, Object Msg) {
        try {
            LOG_INFO("[sendHandlerMSG] nReaderType [" + nReaderType + "]");
            Message Serialmsg = Handle.obtainMessage();
            Serialmsg.what = nReaderType;
            Serialmsg.obj = Msg;

            Handle.sendMessage(Serialmsg);

        } catch (Exception e) {
            Log.e(TAG, "[Exception] sendHandlerMSG()");
            e.printStackTrace();
        }
    }

    public interface MultiRFResultListener {
        public void onReplyResult(String strResult);
    }


}