/**
 * Copyright (c) 2020
 *
 * CENTIRM HotelTV UI-WELCOME module javascript.
 *
 * @summary short description for the file
 * @author Joel <joel.kim@centirm.com>
 *
 * Created at     : 2020-11-26 02:21:56
 * Last modified  : 2020-11-26 15:31:40
 */
const gRmtKey = {
    left: 37,
    right: 39,
    up: 38,
    down: 40,
    enter: 13,
    back: 461,
    red: 403,
    green: 404,
    yellow: 405,
    blue: 406,
    stop: 413,
    play: 415,

    num0: 48,
    num1: 49,
    num2: 50,
    num3: 51,
    num4: 52,
    num5: 53,
    num6: 54,
    num7: 55,
    num8: 56,
    num9: 57,

    chup: 427,
    chdown: 428,
    chprev: 711,

    /** ENNPLE SPECIAL KEY */
    amenity: -2072433963,
    roomservice: -2072437788,
    flight: -2072437533,
    weather: -2072438298,
    tv: -2072443143,
}

const gRmKeyCode2Num = {
    "48" : 0,
    "49" : 1,
    "50" : 2,
    "51" : 3,
    "52" : 4,
    "53" : 5,
    "54" : 6,
    "55" : 7,
    "56" : 8,
    "57" : 9,
};


HotelTV.namespace('HotelTV.ui_appfull');
HotelTV.ui_appfull = (function() {
    //// 의존 관계 선언
    var _hndl_mmSel = null;
    var _hndl_mmBg = null;
    var _hndl_smSel = null;
    var _hndl_smBg = null;
    var _hndl_mpSel = null;
    var _hndl_mpBg = null;
    var _hndl_ctzGenBg = null;
    var _hndl_brochureBg = null;
    var _hndl_widget_topTime = null;
    var _hndl_tvCtgyFrm = null;
    var _hndl_tmrTvChnMngr = null;
    var _hndl_tmrTvShortcutMngr = null;
    var _hndl_tmrUgMngr = null;
    var _hndl_tmrCtzThumbAni = null;
    var _hndl_tmrCtzBgAni = null;
    var _hndl_tmrAmenityThumbAni = null;
    var _hndl_tmrRoomserviceThumbAni = null;
    const _tmrEvt = {
        'tvchannel_changed': null,
        'keyevt': {
            'tv_numBtn' :null,
            'tv_ctrl' :null,
            'last_uibar' :null,
        },
    };

    /***********************************************************************
     * 비공개 프로퍼티                                                      *
     ***********************************************************************/
    /**
     * _schedule오브젝트내의 시간범위 항목들을 검사하여 현재 시간이
     * _schedule에 기술된 범위 안에 있으면 true 그렇지 않으면 false를 출력
     * @param {object} _schedule
     * @returns {object} {"result": false or true, "avail_dtime": string}
     */
    function __uifxn_Utils_CheckAmItemAvailable(_schedule) {
        let _result = {"result": false, "avail_dtime": "unorderable"};
        let _curDtime = new Date(); // current time

        /**
         * Check validation week
         * @param {object} ___schedule_week_obj
         * @param {object} ___curDayTime
         * @returns true or false
         */
        const __ifxn_checkWeekValid = function(___schedule_week_obj, ___curDayTime) {
            if ( ___schedule_week_obj.week[Object.keys(___schedule_week_obj.week)[___curDayTime.getDay()]]==true ){
                return true;
            }
            return false;
        }

        const __ifxn_checkDatekValid = function(___schedule_day_obj, ___curDayTime) {
            if ( ___schedule_day_obj.date.mode=="always" ){
                return true;
            }else if ( ___schedule_day_obj.date.mode=="start" ){
                var _from = new Date(___schedule_day_obj.date.start).getTime();
                if(___curDayTime.getTime() >= _from ) {
                    return true;
                }
                _result.avail_dtime = ___schedule_day_obj.date.start;
            }else if ( ___schedule_day_obj.date.mode=="end" ){
                var _to = new Date(___schedule_day_obj.date.end).getTime();
                if(___curDayTime.getTime() <= _to ) {
                    return true;
                }
                _result.avail_dtime = ___schedule_day_obj.date.end;
            }else if ( ___schedule_day_obj.date.mode=="between" ){
                var _from = new Date(___schedule_day_obj.date.start).getTime();
                var _to = new Date(___schedule_day_obj.date.end).getTime();
                if(___curDayTime.getTime() >= _from && ___curDayTime.getTime() <= _to) {
                    return true;
                }
                _result.avail_dtime = `${___schedule_day_obj.date.start}~${___schedule_day_obj.date.end}`;
            }
            return false;
        }



        const __ifxn_checkTimekValid = function(___schedule_day_obj, ___curDayTime) {
            let __day = ___curDayTime.getDate();
            let __month = ___curDayTime.getMonth() + 1;
            let __year = ___curDayTime.getFullYear();

            let _str_datePrefix = [__year, '-', (__month>9 ? '' : '0') + __month, '-', (__day>9 ? '' : '0') + __day].join('');
            let _str_startTime = `${_str_datePrefix}T${___schedule_day_obj.time.start}`;
            let _str_endTime = `${_str_datePrefix}T${___schedule_day_obj.time.end}`;

            if ( ___schedule_day_obj.time.mode=="always" ){
                return true;
            }else if ( ___schedule_day_obj.time.mode=="between" ){
                var _from = new Date(_str_startTime).getTime();
                var _to = new Date(_str_endTime).getTime();
                if(___curDayTime.getTime() >= _from && ___curDayTime.getTime() <= _to) {
                    _result.result = true;
                    return true;
                }
                _result.avail_dtime = `${___schedule_day_obj.time.start}~${___schedule_day_obj.time.end}`;
            }
            return false;
        }

        try{
            if ( __ifxn_checkWeekValid(_schedule,_curDtime) == true ) {
                if ( __ifxn_checkDatekValid(_schedule,_curDtime) == true ){
                    if ( __ifxn_checkTimekValid(_schedule,_curDtime) == true ){
                        _result.result = true;
                        return _result;
                    }
                }
            }
            return _result;
        }catch(__err){
            return _result;
        }
    }

    /**
     * _schedule오브젝트내의 시간범위 항목들을 검사하여 현재 시간이
     * _schedule에 기술된 범위 안에 있으면 true 그렇지 않으면 false를 출력
     * @param {object} _schedule
     * @returns {object} {"result": false or true, "avail_dtime": string}
     */
    function __uifxn_Utils_CheckRsItemAvailable(_schedule) {
        let _result = {"result": false, "avail_dtime": "unorderable"};
        let _curDtime = new Date(); // current time

        /**
         * Check validation week
         * @param {object} ___schedule_week_obj
         * @param {object} ___curDayTime
         * @returns true or false
         */
        const __ifxn_checkWeekValid = function(___schedule_week_obj, ___curDayTime) {
            if ( ___schedule_week_obj.week[Object.keys(___schedule_week_obj.week)[___curDayTime.getDay()]]==true ){
                return true;
            }
            return false;
        }

        const __ifxn_checkDatekValid = function(___schedule_day_obj, ___curDayTime) {
            if ( ___schedule_day_obj.date.mode=="always" ){
                return true;
            }else if ( ___schedule_day_obj.date.mode=="start" ){
                var _from = new Date(___schedule_day_obj.date.start).getTime();
                if(___curDayTime.getTime() >= _from ) {
                    return true;
                }
                _result.avail_dtime = ___schedule_day_obj.date.start;
            }else if ( ___schedule_day_obj.date.mode=="end" ){
                var _to = new Date(___schedule_day_obj.date.end).getTime();
                if(___curDayTime.getTime() <= _to ) {
                    return true;
                }
                _result.avail_dtime = ___schedule_day_obj.date.end;
            }else if ( ___schedule_day_obj.date.mode=="between" ){
                var _from = new Date(___schedule_day_obj.date.start).getTime();
                var _to = new Date(___schedule_day_obj.date.end).getTime();
                if(___curDayTime.getTime() >= _from && ___curDayTime.getTime() <= _to) {
                    return true;
                }
                _result.avail_dtime = `${___schedule_day_obj.date.start}~${___schedule_day_obj.date.end}`;
            }
            return false;
        }



        const __ifxn_checkTimekValid = function(___schedule_day_obj, ___curDayTime) {
            let __day = ___curDayTime.getDate();
            let __month = ___curDayTime.getMonth() + 1;
            let __year = ___curDayTime.getFullYear();

            let _str_datePrefix = [__year, '-', (__month>9 ? '' : '0') + __month, '-', (__day>9 ? '' : '0') + __day].join('');
            let _str_startTime = `${_str_datePrefix}T${___schedule_day_obj.time.start}`;
            let _str_endTime = `${_str_datePrefix}T${___schedule_day_obj.time.end}`;

            if ( ___schedule_day_obj.time.mode=="always" ){
                return true;
            }else if ( ___schedule_day_obj.time.mode=="between" ){
                var _from = new Date(_str_startTime).getTime();
                var _to = new Date(_str_endTime).getTime();
                if(___curDayTime.getTime() >= _from && ___curDayTime.getTime() <= _to) {
                    _result.result = true;
                    return true;
                }
                _result.avail_dtime = `${___schedule_day_obj.time.start}~${___schedule_day_obj.time.end}`;
            }
            return false;
        }

        try{
            if ( __ifxn_checkWeekValid(_schedule,_curDtime) == true ) {
                if ( __ifxn_checkDatekValid(_schedule,_curDtime) == true ){
                    if ( __ifxn_checkTimekValid(_schedule,_curDtime) == true ){
                        _result.result = true;
                        return _result;
                    }
                }
            }
            return _result;
        }catch(__err){
            return _result;
        }
    }


    /**
     * HotelTV UI[AppFull] Wrapper Function::> 리모콘 키가 숫자키인지 검사
     * @param {dictionary} _evt event information
     */
    function __uifxn_Utils_CheckKeyisNumber(_evt_keyCode) {
        if ( _evt_keyCode == gRmtKey.num0 || _evt_keyCode == gRmtKey.num1 ||
            _evt_keyCode == gRmtKey.num2 || _evt_keyCode == gRmtKey.num3 ||
            _evt_keyCode == gRmtKey.num4 || _evt_keyCode == gRmtKey.num5 ||
            _evt_keyCode == gRmtKey.num6 || _evt_keyCode == gRmtKey.num7 ||
            _evt_keyCode == gRmtKey.num8 || _evt_keyCode == gRmtKey.num9 ){
            return true;
        }

        return false;
    }


    /**
     * HotelTV UI Wrapper Function::> Show Top Widjet Weather
     * @param {boolean} _show show/hide
     */
    function __uifxn_AppFull_TopWidjetShow(_show) {
        if (_show == true) {
            if ($('.widjet .top').css("display") == "none") {
                $('.widjet .top').fadeIn(300);
            }
        } else {
            if ($('.widjet .top').css("display") != "none") {
                $('.widjet .top').fadeOut(300);
            }
        }
    }


    /**
     * HotelTV UI[AppFull] Wrapper Function::> Keydown event time recorder
     * @param {dictionary} _evt event information
     */
    function __uifxn_AppFull_OnKeyDnEvtRec(_evt) {
        const _state = HotelTV.state;
        let _cur_date = new Date();
        let _valid_state_keyEvtOnTv = ["tvCtgShow", "tvCtgHide", "tvShortcut"];


        if ( __uifxn_Utils_CheckKeyisNumber(_evt.keyCode)==true ){
            if ( _valid_state_keyEvtOnTv.includes(_state.menu.stage.cur)==true ){
                _tmrEvt.keyevt.tv_numBtn = _cur_date;
            }
        } else if ( _evt.keyCode == gRmtKey.up || _evt.keyCode == gRmtKey.down ||
            _evt.keyCode == gRmtKey.left || _evt.keyCode == gRmtKey.right ||
            _evt.keyCode == gRmtKey.chup || _evt.keyCode == gRmtKey.chdown ) {
            _tmrEvt.keyevt.tv_ctrl = _cur_date;
        }
        _tmrEvt.keyevt.last_uibar = _cur_date;
    }




    /**
     * HotelTV UI Wrapper Function::> received event handling function
     * @param {dictionary} _evt event information
     */
    function __uifxn_AppFull_OnMediaEvt(_evt) {
        let _state = HotelTV.state;
        console.log("media_event_received = " + _evt.eventType);
        let _stateMedia = _evt.eventType;

        if (_state.menu.stage.cur == "ctzgen")
        {
            switch (_stateMedia) {
                case 'play_start':
                    _state.media.playing = true;
                    $('.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item').removeClass('movieplay');
                    $('.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item.active').addClass('movieplay');
                    $('.owl-theme .owl-nav.disabled+.owl-dots').fadeOut(500, function(){
                        __uifxn_AppFull_TopWidjetShow(false);
                    });
                    HotelTV.hal.VideoWinSize(null);
                    break;
                case 'play_end':
                    _state.media.playing = false;
                    HotelTV.hal.MediaStop(
                        function() {
                            $('.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item').removeClass('movieplay');
                            $('.owl-theme .owl-nav.disabled+.owl-dots').fadeIn(500, function() {
                                __uifxn_AppFull_TopWidjetShow(true);
                            });
                        },
                        function() {
                            $('.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item').removeClass('movieplay');
                            $('.owl-theme .owl-nav.disabled+.owl-dots').fadeIn(500, function() {
                                __uifxn_AppFull_TopWidjetShow(true);
                            });
                        });
                    break;
                case 'error_in_playing':
                    break;
                case 'buffer_full':
                    break;
                case 'file_not_found':
                    break;
                case 'network_disconnected':
                    break;
                case 'network_busy':
                    break;
                case 'seek_done':
                    break;
            }
        }
        else if (_state.menu.stage.cur == "mypage_select_menu" || _state.menu.stage.cur == "mypage_replay_welcome_vod" )
        {
            switch (_stateMedia) {
                case 'play_start':
                    _state.media.playing = true;
                    $('.main .mypage .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item').removeClass('movieplay');
                    $('.main .mypage .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item.active').addClass('movieplay');
                    HotelTV.hal.VideoWinSize(null);
                    $('.main .mypage .slider').animate({top:1080, left:0}, 1000, function(){
                        __uifxn_AppFull_TopWidjetShow(false);
                    })
                    break;
                case 'play_end':
                    _state.media.playing = false;
                    HotelTV.hal.MediaStop(
                        function() {
                            $('.main .mypage .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item').removeClass('movieplay');
                            $('.main .mypage .slider').animate({top:864, left:0}, 1000, function(){
                                __uifxn_AppFull_TopWidjetShow(true);
                            })
                            _state.menu.stage.cur = _state.menu.stage.prev;
                        },
                        function() {
                            $('.main .mypage .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item').removeClass('movieplay');
                            $('.main .mypage .slider').animate({top:864, left:0}, 1000, function(){
                                __uifxn_AppFull_TopWidjetShow(true);
                            })
                            _state.menu.stage.cur = _state.menu.stage.prev;
                        });
                    break;
                case 'error_in_playing':
                    break;
                case 'buffer_full':
                    break;
                case 'file_not_found':
                    break;
                case 'network_disconnected':
                    break;
                case 'network_busy':
                    break;
                case 'seek_done':
                    break;
            }
        }
    }

    /**
     * HotelTV UI Wrapper Function::> received event handling function
     * @param {dictionary} _evt event information
     */
    function __uifxn_AppFull_OnNetEvt(_evt) {
        let _state = HotelTV.state;
        console.log("network_event_received = " + _evt.eventType);
        let _typeNetEvt = _evt.eventType;

        switch (_typeNetEvt) {
            case 'play_start':
                break;
            case 'play_end':
                break;
            case 'error_in_playing':
                break;
            case 'buffer_full':
                break;
            case 'file_not_found':
                break;
            case 'network_disconnected':
                break;
            case 'network_busy':
                break;
            case 'seek_done':
                break;
        }
    }

    /**
     * HotelTV UI Wrapper Function::> received event handling function
     * @param {dictionary} _evt event information
     */
    function __uifxn_AppFull_OnAppFocusEvt(_evt) {
        let _state = HotelTV.state;
        console.log("hcap_application_focus_changed = " + _evt.eventType);
        let _typeAppFocusEvt = _evt.eventType;

        if (_typeAppFocusEvt == "focused") {
            // HotelTV.hal.SetSoftAp({
            //     "enable": false,
            // });
        }else if (_typeAppFocusEvt == "unfocused") {

        }
    }

    /**
     * HotelTV UI Wrapper Function::> received event handling function
     * @param {dictionary} _evt event information
     */
    function __uifxn_AppFull_OnHdmiConChangeEvt(_evt) {
        let _state = HotelTV.state;
        let _devinfo = HotelTV.devinfo;
        let _trTbl = HotelTV.translation;
        // {Number} param.index - index of the HDMI which was connected or disconnected.
        // {Boolean} param.connected - true if the HDMI is connected, else false.
        console.warn(
            "Event 'hdmi_connection_changed' is received.\n" +
            "HDMI-" + _evt.index + " : " + "connected = " + _evt.connected
        );

        let _valid_state_showsup_hdmi_unavailable = ["tvCtgShow", "tvCtgHide", "tvShortcut", "tvPreparing","language_selection"];
        if ( _valid_state_showsup_hdmi_unavailable.includes(_state.menu.stage.cur)==true ){
            console.warn("HDMI input doesn't work tv mode");
            //HDMI사용불가 말풍선 출력
            HotelTV.ui_utils.ShowNotificationMsgBalloon(_trTbl.system.notice.event.external_input.hdmi_unavailable[_state.lang], 5);
            return;
        }
        else
        {
            if ( _evt.connected==true ){
                _state.menu.stage.prev = _state.menu.stage.cur;
                _state.menu.stage.cur = "external_av_hdmi";
                _state.external_input.connected = true;
                // NOTE: US741H0ND모델에서 HDMI셋팅 인덱스는 0부터, 이 부분은 LG에 문의 필요
                if (_devinfo.model_name.includes("US761H0ND")) {
                    _state.external_input.last_input.index = Number(_evt.index);
                } else {
                    _state.external_input.last_input.index = Number(_evt.index)-1;
                }
                setTimeout(function(){
                    $('body,html').fadeOut(500, function(){
                        let __retSuccess = HotelTV.hal.SetExternalInput("HDMI", _state.external_input.last_input.index);
                        if ( __retSuccess==false ){
                            _state.external_input.connected = false;
                            _state.external_input.last_input.index = 0;
                            if ( $('body,html').css('display')=="none" ){
                                $('body,html').fadeIn(500, function(){
                                    __uifxn_AppFull_BuildNews();
                                    if ( _state.menu.stage.prev!=null ){
                                        _state.menu.stage.cur = _state.menu.stage.prev;
                                        _state.menu.stage.prev = null;
                                    }
                                    __uifxn_AppFull_RefreshNews(500);
                                });
                            }
                        }
                    });
                }, 1000);
                HotelTV.ui_utils.ShowNotificationMsgBalloon(_trTbl.system.notice.event.external_input.hdmi_connected[_state.lang], 5);
            }else{
                _state.external_input.connected = false;
                _state.external_input.last_input.index = 0;
                if ( $('body,html').css('display')=="none" ){
                    $('body,html').fadeIn(500, function(){
                        __uifxn_AppFull_BuildNews();
                        if ( _state.menu.stage.prev!=null ){
                            _state.menu.stage.cur = _state.menu.stage.prev;
                            _state.menu.stage.prev = null;
                        }
                        __uifxn_AppFull_RefreshNews(500);
                    });
                }
            }
        }
    }

    /**
     * HotelTV UI Wrapper Function::> received event handling function
     * @param {dictionary} _evt event information
     */
    function __uifxn_AppFull_OnTvChChgChangeEvt(_evt) {
        let _state = HotelTV.state;

        // Set tv playing flag
        // {Boolean} param.result - true if the current channel is changed successfully, else false.
        // {String} param.errorMessage - in case of failure, this message provides the details.
        if ( _evt.result==true ) {
            _state.tv.playing = true;
        } else {
            console.log("Event 'channel_changed' is failure::> " + _evt.errorMessage );
        }
    }

    /**
     * HotelTV UI Wrapper Function::> received event handling function
     */
    function __uifxn_AppFull_OnPwrModeChangeEvt() {
        let _state = HotelTV.state;
        let _tvMenu_stages = "tvCtgHide tvCtgShow tvShortcut tvPreparing";

        if ( _tvMenu_stages.includes(_state.menu.stage.cur)==true ){
            hcap.power.getPowerMode({
                "onSuccess" : function(s) {
                    console.log("onSuccess power mode " + s.mode);
                    if ( s.mode==hcap.power.PowerMode.NORMAL ){
                        console.log("Need to restart channel...");
                        __uifxn_AppFull_TVRequestChannel(null, null);
                    }
                },
                "onFailure" : function(f) {
                    console.log("onFailure : errorMessage = " + f.errorMessage);
                }
           });
        } else if ( _state.menu.stage.cur=="external_av_hdmi" ) {
            let __retSuccess = HotelTV.hal.SetExternalInput("HDMI", _state.external_input.last_input.index);
            if ( __retSuccess==false ){
                _state.external_input.connected = false;
                _state.external_input.last_input.index = 0;
                if ( $('body,html').css('display')=="none" ){
                    $('body,html').fadeIn(500);

                    if ( _state.menu.stage.prev!=null ){
                        _state.menu.stage.cur = _state.menu.stage.prev;
                        _state.menu.stage.prev = null;
                    }
                }
            }
        }
        console.log("Event 'power_mode_changed' is received. ");
    }


    /**
     * HotelTV UI[AppFull] Wrapper Function::> show/hide special hotkey(red/yellow/green/blue/etc...) btn
     * @param {boolean} _show flag for hotkey
     */
    function __uifxn_AppFull_HotKey_ShowBtnOnMM(_show) {
        let _state = HotelTV.state;
        let _opening = HotelTV.opening;
        let _brochure = _opening.brochures;

        // Draw Amenity & Room Service
        if (_opening.amenity) {
            let _amenityCtz = _opening.amenity;
            // TITLE
            $(`.control .mm .hotkey_${_amenityCtz.button}`).text(_amenityCtz.title[_state.lang]);
            // HOTKEY 버튼 Show/Hide
            $(`.control .mm .hotkey_${_amenityCtz.button}`).css({ "background-image": "url(" + _amenityCtz.buttonImage.file.download + ")" });
            $(`.control .mm .hotkey_${_amenityCtz.button}`).css({ "top": _amenityCtz.positionY + "%" });
            $(`.control .mm .hotkey_${_amenityCtz.button}`).css({ "left": _amenityCtz.positionX + "%" });
            if (_show == true) {
                if ($(`.control .mm .hotkey_${_amenityCtz.button}`).css("display") == "none") {
                    $(`.control .mm .hotkey_${_amenityCtz.button}`).fadeIn(300);
                }
            } else {
                if ($(`.control .mm .hotkey_${_amenityCtz.button}`).css("display") != "none") {
                    $(`.control .mm .hotkey_${_amenityCtz.button}`).fadeOut(300);
                }
            }
        }

        if (_opening.roomService) {
            let _roomserviceCtz = _opening.roomService;
            // TITLE
            $(`.control .mm .hotkey_${_roomserviceCtz.button}`).text(_roomserviceCtz.title[_state.lang]);
            // HOTKEY 버튼 Show/Hide
            $(`.control .mm .hotkey_${_roomserviceCtz.button}`).css({ "background-image": "url(" + _roomserviceCtz.buttonImage.file.download + ")" });
            $(`.control .mm .hotkey_${_roomserviceCtz.button}`).css({ "top": _roomserviceCtz.positionY + "%" });
            $(`.control .mm .hotkey_${_roomserviceCtz.button}`).css({ "left": _roomserviceCtz.positionX + "%" });
            if (_show == true) {
                if ($(`.control .mm .hotkey_${_roomserviceCtz.button}`).css("display") == "none") {
                    $(`.control .mm .hotkey_${_roomserviceCtz.button}`).fadeIn(300);
                }
            } else {
                if ($(`.control .mm .hotkey_${_roomserviceCtz.button}`).css("display") != "none") {
                    $(`.control .mm .hotkey_${_roomserviceCtz.button}`).fadeOut(300);
                }
            }
        }

        // Draw Brochure contents
        for (let _idx = 1; _idx <= _brochure.length; _idx++) {
            let _brcCtz = _brochure[_idx];
            // TITLE
            $(`.control .mm .hotkey_${_brcCtz.button}`).text(_brcCtz.title[_state.lang]);
            // HOTKEY 버튼 Show/Hide
            $(`.control .mm .hotkey_${_brcCtz.button}`).css({ "background-image": "url(" + _brcCtz.buttonImage.file.download + ")" });
            $(`.control .mm .hotkey_${_brcCtz.button}`).css({ "top": _brcCtz.positionY + "%" });
            $(`.control .mm .hotkey_${_brcCtz.button}`).css({ "left": _brcCtz.positionX + "%" });
            if (_show == true) {
                if ($(`.control .mm .hotkey_${_brcCtz.button}`).css("display") == "none") {
                    $(`.control .mm .hotkey_${_brcCtz.button}`).fadeIn(300);
                }
            } else {
                if ($(`.control .mm .hotkey_${_brcCtz.button}`).css("display") != "none") {
                    $(`.control .mm .hotkey_${_brcCtz.button}`).fadeOut(300);
                }
            }
        }
    }

    const __uifxn_AppFull_getOrderMenuName = function(_objCtgyInfo){
        let _state = HotelTV.state;
        for (__jj = 1; __jj <= _objCtgyInfo.length; __jj++) {
            if ( _objCtgyInfo[__jj].name=="ORDER" ) {
                return _objCtgyInfo[__jj].title[_state.lang];
            }
        }
        return "ORDER";
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> register hotkey for amenity service
     */
    function __uifxn_AppFull_HotKey_RegisterAmenityRoomservice() {
        let _state = HotelTV.state;
        let _opening = HotelTV.opening;
        let _amenity = null;
        let _roomservice = null;

        let _elAmPupOoderRoot = $('.popup .amenity').children('.order');
        if ( _elAmPupOoderRoot.css('display')!="none" ){
            _elAmPupOoderRoot.hide();
        }

        let _elRsPupOoderRoot = $('.popup .roomservice').children('.order');
        if ( _elRsPupOoderRoot.css('display')!="none" ){
            _elRsPupOoderRoot.hide();
        }


        if (!_opening.amenity) {
            return;
        }
        _amenity = _opening.amenity;
        // HOTKEY정보를 state에 기록
        if (!(_amenity.button in _state.hotkey.mm)) {
            _state.hotkey.mm[_amenity.button] = {
                'type': "amenity",
                'id': _amenity.id,
                "status": {
                    "focus": "category_sel",
                    "category_sel": {
                        'cnt': 0,
                        'cur': 1,
                        'prev': 1,
                    },
                    "items": {},
                    "stock": {},
                }
            };
        }





        if (!_opening.roomService) {
            return;
        }
        _roomservice = _opening.roomService;
        // HOTKEY정보를 state에 기록
        if (!(_roomservice.button in _state.hotkey.mm)) {
            _state.hotkey.mm[_roomservice.button] = {
                'type': "roomservice",
                'id': _roomservice.id,
                "status": {
                    "focus": "category_sel",
                    "category_sel": {
                        'cnt': 0,
                        'cur': 1,
                        'prev': 1,
                    },
                    "items": {},
                    "stock": {},
                }
            };
        }

        return;
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> build Brochure and In-room dining
     */
    function __uifxn_AppFull_BuildBrochure() {
        let _state = HotelTV.state;
        let _brochure = HotelTV.opening.brochures;

        for (let _idx = 1; _idx <= _brochure.length; _idx++) {
            let _brcCtz = _brochure[_idx];
            // BROCHURE 이미지 노드를 동적으로 구성
            let _div_popup_mm_brochure_bglist = document.querySelector(`#lst_hotkey_mm_${_brcCtz.button}`);
            for (let _page_idx = 1; _page_idx <= _brcCtz.page[_state.lang].length; _page_idx++) {
                let _div_popup_mm_brochure_item = document.createElement('div');
                let _sz_styleOpt = null;
                _div_popup_mm_brochure_item.className = 'item';
                _div_popup_mm_brochure_item.setAttribute(`popup_hotkey_mm_${_brcCtz.button}`, _page_idx);
                _sz_styleOpt = "background-image: url(" + _brcCtz.page[_state.lang][_page_idx].download + "); ";
                _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: 100% 100%; ";
                _div_popup_mm_brochure_item.setAttribute("style", _sz_styleOpt);

                _div_popup_mm_brochure_bglist.appendChild(_div_popup_mm_brochure_item);
            }
            _hndl_brochureBg = $(`#lst_hotkey_mm_${_brcCtz.button}`);
            _hndl_brochureBg.owlCarousel({
                center: false,
                items: 1, //Number of Items on Screen what you want
                nav: true,
                loop: false,
                margin: 0,
                smartSpeed: 1000,
                lazyLoad: true,
                mouseDrag: false,
                touchDrag: false,
                pullDrag: false,
                freeDrag: false,
                navText: ["<div class='nav-btn prev-slide'></div>", "<div class='nav-btn next-slide'></div>"],
                startPosition: 0,
            });

            // HOTKEY정보를 state에 기록
            if (!(_brcCtz.button in _state.hotkey.mm)) {
                _state.hotkey.mm[_brcCtz.button] = { 'type': "brochure" , 'id':_brcCtz.id};
            }
        }
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> Draw amenity feature user's guide
     * @param {string} _action
     */
    function __uifxn_AppFull_DrawAmUserGuide(_action) {
        let _state = HotelTV.state;
        let _trTbl = HotelTV.translation;
        let _opening = HotelTV.opening;
        let _aminfo_top = _opening.amenity;
        let _aminfo_ctgy = _aminfo_top.menu;
        let _elAmPupRoot = $('.popup .amenity');
        let _elAmUGRoot = _elAmPupRoot.children('.use_guide');
        let __status_am_specific = null;


        try{
            // 어메니티 정보 오브젝트
            _aminfo_top = _opening.amenity;
            _aminfo_ctgy = _aminfo_top.menu;
            __status_am_specific = _state.hotkey.mm[_aminfo_top.button].status;
            let __amctgyIdx = __status_am_specific.category_sel.cur;
            let __amctgyItemStatus = __status_am_specific.items[_aminfo_ctgy[__amctgyIdx].name];

            switch(_action)
            {
                case "destroy": {
                    _elAmUGRoot.fadeOut(200, function(){
                        _elAmUGRoot.html('');
                    });
                } break;

                case "amenity_ctgy_sel": {
                    if ( _elAmUGRoot.css('display')=="none" ) {
                        _elAmUGRoot.html(_trTbl.ui.amenity.usage.category_menus_nav[_state.lang]);
                        _elAmUGRoot.fadeIn(300);
                    } else {
                        _elAmUGRoot.fadeOut(200, function(){
                            _elAmUGRoot.html(_trTbl.ui.amenity.usage.category_menus_nav[_state.lang]);
                            _elAmUGRoot.fadeIn(300);
                        });
                    }
                } break;

                case "amenity_ctgy_item_sel": {
                    _elAmUGRoot.fadeOut(200, function(){
                        _elAmUGRoot.html(_trTbl.ui.amenity.usage.category_item_nav[_state.lang]);
                        _elAmUGRoot.fadeIn(300);
                    });
                } break;

                case "amenity_ctgy_item_cart": {
                    _elAmUGRoot.fadeOut(200, function(){
                        _elAmUGRoot.html(_trTbl.ui.amenity.usage.category_item_cart[_state.lang]);
                        _elAmUGRoot.fadeIn(300);
                    });
                } break;
            }
        }catch(_err){
            console.log(`Fail to draw::> ${_err}`);
        }
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> Draw amenity order history
     * @param {string} _action
     */
    function __uifxn_AppFull_DrawAmOrderList(_action) {
        let _state = HotelTV.state;
        let _trTbl = HotelTV.translation;
        let _opening = HotelTV.opening;
        let _order = HotelTV.orders.amenity;
        let _aminfo_top = _opening.amenity;
        let _aminfo_ctgy = _aminfo_top.menu;
        let _elAmPupRoot = $('.popup .amenity');
        let _elAmOrderRoot = _elAmPupRoot.children('.order');
        let _elAmOrderWinleft = _elAmOrderRoot.children('.winleft');
        let __status_am_specific = null;

        const __ifxn_removeOrderElements = function(){
            if ( _elAmOrderWinleft.children().length>0 ){
                _elAmOrderWinleft.children().remove();
            }
        }


        try{
            // 어메니티 정보 오브젝트
            _aminfo_top = _opening.amenity;
            _aminfo_ctgy = _aminfo_top.menu;
            __status_am_specific = _state.hotkey.mm[_aminfo_top.button].status;
            let __amctgyIdx = __status_am_specific.category_sel.cur;
            let __amctgyItemStatus = __status_am_specific.items[_aminfo_ctgy[__amctgyIdx].name];

            switch(_action)
            {
                case 'hide': {
                    if ( _elAmOrderRoot.css('display')!="none" ){
                        _elAmOrderRoot.fadeOut(100);
                    }
                } break;

                case 'build': {
                    __ifxn_removeOrderElements();

                    ////// ADD Table Header
                    var _elTbl_ItemsHdr = document.createElement('table');
                    _elTbl_ItemsHdr.className = "tbl_header";

                    let _elTBody_ItmesHdr = document.createElement('tbody');
                    {
                        _elTBody_ItmesHdr.setAttribute("id", "hdr");

                        var _elTr_ItmesHdr = document.createElement('tr');
                        var _elTh_ItmesHdr_Title = document.createElement('th');
                        _elTh_ItmesHdr_Title.setAttribute("id", "orderid");
                        _elTh_ItmesHdr_Title.textContent = _trTbl.ui.amenity.title.ordernum[_state.lang].toUpperCase();
                        _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Title);

                        var _elTh_ItmesHdr_Amount = document.createElement('th');
                        _elTh_ItmesHdr_Amount.setAttribute("id", "amount");
                        _elTh_ItmesHdr_Amount.textContent = _trTbl.ui.amenity.title.amount[_state.lang].toUpperCase();
                        _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Amount);

                        var _elTh_ItmesHdr_Status = document.createElement('th');
                        _elTh_ItmesHdr_Status.setAttribute("id", "date");
                        _elTh_ItmesHdr_Status.textContent = _trTbl.ui.amenity.title.orderdate[_state.lang].toUpperCase();
                        _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Status);

                        _elTBody_ItmesHdr.appendChild(_elTr_ItmesHdr);
                    }
                    _elTbl_ItemsHdr.appendChild(_elTBody_ItmesHdr);
                    _elAmOrderWinleft.append(_elTbl_ItemsHdr);

                    ////// Append item list record
                    var _elTbl_ItemsRec = document.createElement('table');
                    _elTbl_ItemsRec.className = "tbl_record";

                    let _elTBody_ItmesRec = document.createElement('tbody');
                    {
                        _elTBody_ItmesRec.setAttribute("id", "record");
                        for (let _j = 1; _j <= _order.orders.length; _j++) {
                            let _objChkAvail=null;
                            let _objItem = _order.orders[_j];

                            var _elTr_ItmesRec = document.createElement('tr');
                            var _elDiv_ItmesRec = document.createElement('div');
                            _elDiv_ItmesRec.className = "amOrderedItem";
                            var _elDiv_ItmesRecID = document.createElement('div');
                            _elDiv_ItmesRecID.setAttribute("id", "orderid");
                            _elDiv_ItmesRecID.textContent = _objItem.id.toUpperCase();
                            _elDiv_ItmesRec.appendChild(_elDiv_ItmesRecID);

                            var _elDiv_ItmesRecAmount = document.createElement('div');
                            _elDiv_ItmesRecAmount.setAttribute("id", "amount");
                            _elDiv_ItmesRecAmount.textContent = _aminfo_top.currency[_state.lang] + _objItem.amount[_state.lang].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
                            _elDiv_ItmesRec.appendChild(_elDiv_ItmesRecAmount);


                            var _elDiv_ItmesRecDate = document.createElement('div');
                            _elDiv_ItmesRecDate.setAttribute("id", "date");
                            _elDiv_ItmesRecDate.textContent = _objItem.createdAt;
                            _elDiv_ItmesRec.appendChild(_elDiv_ItmesRecDate);
                            _elTr_ItmesRec.appendChild(_elDiv_ItmesRec);
                            _elTBody_ItmesRec.appendChild(_elTr_ItmesRec);
                        }
                        _elTbl_ItemsRec.appendChild(_elTBody_ItmesRec);
                    }
                    _elAmOrderWinleft.append(_elTbl_ItemsRec);

                    var _elDiv_Summary = document.createElement('div');
                    _elDiv_Summary.className = "summary";
                    var _elDiv_Label = document.createElement('div');
                    _elDiv_Label.setAttribute("id", "label");
                    _elDiv_Label.textContent = _trTbl.ui.amenity.title.sum[_state.lang].toUpperCase();
                    _elDiv_Summary.appendChild(_elDiv_Label);
                    var _elDiv_Value = document.createElement('div');
                    _elDiv_Value.setAttribute("id", "value");
                    _elDiv_Value.textContent = _aminfo_top.currency[_state.lang] + _order.amount[_state.lang].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
                    _elDiv_Summary.appendChild(_elDiv_Value);
                    _elAmOrderWinleft.append(_elDiv_Summary);

                    if ( _elAmOrderRoot.css('display')=="none" ){
                        _elAmOrderRoot.fadeIn(100);
                    }
                } break;

                case "destroy": {
                    __ifxn_removeOrderElements();
                } break;
            }
        }catch(_err){
            console.log(`Fail to draw::> ${_err}`);
        }
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> Draw amenity item selection cart ui
     * @param {string} _action
     * @param {function} _cbFxnExitPre AM 아이탬선택 카트 팝업 종료 처리 전에 해야할 callback
     * @param {function} _cbFxnExitPost AM 아이탬선택 카트 팝업 종료 처리 후에 수행할 callback
     */
    function __uifxn_AppFull_DrawAmItemSeletionCart(_action, _cbFxnExitPre, _cbFxnExitPost) {
        let _state = HotelTV.state;
        let _trTbl = HotelTV.translation;
        let _opening = HotelTV.opening;
        let _carts = HotelTV.carts.amenity;
        let _order = HotelTV.orders.amenity;
        let _aminfo_top = _opening.amenity;
        let _aminfo_ctgy = _aminfo_top.menu;
        let _aminfo_item = null;
        let _elAmPupRoot = $('.popup .amenity');
        let _elAmCtgyBg = _elAmPupRoot.children('.bg').find('#lst_ctgbg');
        let _elAmCtgyBgFocus = _elAmCtgyBg.find('.owl-item.active.center');
        let _elAmCtgyBgMenuItemWin = _elAmCtgyBgFocus.find('.am_item_sel_win');
        let _elAmCtgyBgMenuItemCartWin = _elAmCtgyBgFocus.find('.am_item_sel_cart_win');
        let _elAmCtgyBgMenuItemCartWinLeft = _elAmCtgyBgMenuItemCartWin.children('.winleft');
        let _elAmCtgyBgMenuItemCartWinRight = _elAmCtgyBgMenuItemCartWin.children('.winright');
        let __status_am_specific = null;


        /**
         * CART에 _itemID에 해당하는 항목이 있는지 검사
         * @param {object} _objCart
         * @param {string} _itemID
         * @returns
         */
        const __ifxn_checkCartItemExist = function(_objCart, _itemID) {
            for (__j = 1; __j <= _objCart.length; __j++) {
                if ( _objCart[__j].id!=null && _objCart[__j].itemId == _itemID ) {
                    return true;
                }
            }
            return false;
        }

        const __ifxn_getCartIdbyItemID = function(_objCart, _itemID) {
            for (__j = 1; __j <= _objCart.length; __j++) {
                if ( _objCart[__j].id!=null && _objCart[__j].itemId == _itemID ) {
                    return _objCart[__j].id;
                }
            }
            return null;
        }

        /**
         * order/add to cart/back중 포커스 된 버턴의 ID를 반환
         */
        const __ifxn_getFocusedBtnID = function() {
            return _elAmCtgyBgMenuItemCartWinLeft.find('.buttons').find('.focus').attr('id');
        }


        const __ifxn_removeAmSelectedItemCartWinElement = function() {
            // Remove All element under winright div
            if ( _elAmCtgyBgMenuItemCartWinLeft.children().length ){
                _elAmCtgyBgMenuItemCartWinLeft.children().remove();
            }

            if ( _elAmCtgyBgMenuItemCartWinRight.children().length ){
                _elAmCtgyBgMenuItemCartWinRight.children().remove();
            }
        }

        /**
         * 어메니티 카트 테이블 갱신
         * @returns
         */
        const __ifxn_updateAmCartRecTable = function() {
            try{
                const __ifxn_getValidCartItemCount = function(_cartObj) {
                    let ___validCnt = 0;
                    for (let _j = 1; _j <= _cartObj.items.length; _j++) {
                        if ( _cartObj.items[_j].id ){
                            ___validCnt++;
                        }
                    }
                    return ___validCnt;
                }


                let _elAmCtgyBgMenuItemCartLstRecTbl = _elAmCtgyBgMenuItemCartWinRight.children('.cart_table').find('.tbl_record');

                if ( _elAmCtgyBgMenuItemCartLstRecTbl.length ){
                    // Remove all record under tbl_record
                    _elAmCtgyBgMenuItemCartLstRecTbl.children().remove();
                }

                if ( __ifxn_getValidCartItemCount(_carts)==0 ){
                    // 카트에 유효한 아이템이 없음. 테이블 그릴필요 없음.
                    return ;
                }

                // 카트 리스트 구성
                if ( _carts.items.length>0 )
                {
                    let _elTBody_ItmesRec = document.createElement('tbody');
                    _elTBody_ItmesRec.setAttribute("id", "record");
                    for (let _j = 1; _j <= _carts.items.length; _j++) {
                        let _objCartItem = _carts.items[_j];
                        if ( _objCartItem.id==null ){
                            continue;
                        }

                        var _elTr_CartItmesRec = document.createElement('tr');
                        var _elDiv_CartItmesRec = document.createElement('div');
                        _elDiv_CartItmesRec.className = "cartItem";
                        var _elDiv_CartItmesRecName = document.createElement('div');
                        _elDiv_CartItmesRecName.setAttribute("id", "title");
                        _elDiv_CartItmesRecName.textContent = _objCartItem.title[_state.lang];
                        _elDiv_CartItmesRec.appendChild(_elDiv_CartItmesRecName);

                        var _elDiv_CartItmesRecQuantity = document.createElement('div');
                        _elDiv_CartItmesRecQuantity.setAttribute("id", "quantity");
                        _elDiv_CartItmesRecQuantity.textContent = _objCartItem.quantity;
                        _elDiv_CartItmesRec.appendChild(_elDiv_CartItmesRecQuantity);

                        var _elDiv_CartItmesRecPrice = document.createElement('div');
                        _elDiv_CartItmesRecPrice.setAttribute("id", "amount");
                        _elDiv_CartItmesRecPrice.textContent = _aminfo_top.currency[_state.lang] + _objCartItem.amount[_state.lang].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
                        _elDiv_CartItmesRec.appendChild(_elDiv_CartItmesRecPrice);

                        _elTr_CartItmesRec.appendChild(_elDiv_CartItmesRec);
                        _elTBody_ItmesRec.appendChild(_elTr_CartItmesRec);
                    }
                    _elAmCtgyBgMenuItemCartLstRecTbl.append(_elTBody_ItmesRec);

                    // 전체 금액 갱신
                    let _elAmCtgyBgMenuItemCartTotalAmountValue = _elAmCtgyBgMenuItemCartWinRight.find('.summary').children('#value');
                    _elAmCtgyBgMenuItemCartTotalAmountValue.text( _aminfo_top.currency[_state.lang] + _carts.amount[_state.lang].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
                }
            } catch ( _err ){
                console.log(`Fail to update::> ${_err}`);
            }
        }

        /**
         * 주어진 _item_idx 아이탬의 수량 및 금액을 갱신
         * @param {string} _item_idx
         * @param {string} _action
         */
        const __ifxn_updateAmSelectedItemCartWin = async function(_item_idx, _action) {
            let __api_resp_stock = null;
            let __selected_item_amount_quantity = 0;
            let __selected_item_amount_subTotal = 0;

            let _elDiv_QuntCtrlFrmQuantityValue = _elAmCtgyBgMenuItemCartWinLeft.children('.control').children('.quantity').find('#value_quantity');
            let _elDiv_QuntCtrlFrmAmountValue = _elAmCtgyBgMenuItemCartWinLeft.children('.control').children('.quantity').find('#value_amount');

            /**
             * cart 오브젝트에서 해당 item id에 해당하는 수량을 반환.
             * 찾지 못하면 1개(디퐅트)를 반환
             * @param {object} _object
             * @param {string} _itemID
             * @returns
             */
            const ___ifxn_getCartItemQuantity = function(_object, _itemID) {
                for (__j = 1; __j <= _object.length; __j++) {
                    if ( _object[__j].id != null ){
                        if ( _object[__j].itemId == _itemID ) {
                            return _object[__j].quantity;
                        }
                    }
                }
                return 1;
            }

            const ___ifxn_updateSubTotalAmount = async function(_itemID, _quantityNum) {
                let __api_resp = await HotelTV.api.GetAmenityStocks(_itemID, _quantityNum);
                if ( __api_resp==null ){
                    console.log("error");
                    __selected_item_amount_subTotal = "Error";
                } else {
                    __selected_item_amount_subTotal = _aminfo_top.currency[_state.lang] + __api_resp['amount'][_state.lang].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
                }

                if ( _elDiv_QuntCtrlFrmAmountValue.length ){
                    _elDiv_QuntCtrlFrmAmountValue.text(__selected_item_amount_subTotal);
                }
            }

            // 개수 및 산정 로직
            // i) 현재 카트내에 해당 item id에 해당하는 개수르 구함.
            // ii) stock API로 총 비용을 산정
            if ( _action=="build" ){
                __selected_item_amount_quantity = ___ifxn_getCartItemQuantity(_carts.items, _aminfo_item.id);
                __status_am_specific.stock[_aminfo_item.id] = {"req_quantity": __selected_item_amount_quantity};
                ___ifxn_updateSubTotalAmount(_aminfo_item.id, __selected_item_amount_quantity);
            } else if ( _action=="plus" ){
                if ( __status_am_specific.stock[_aminfo_item.id].req_quantity<_aminfo_item.limitation.max ){
                    __status_am_specific.stock[_aminfo_item.id].req_quantity += 1;
                    ___ifxn_updateSubTotalAmount(_aminfo_item.id, __status_am_specific.stock[_aminfo_item.id].req_quantity);
                }
            } else if ( _action=="minus" ){
                if ( __status_am_specific.stock[_aminfo_item.id].req_quantity>1 ){
                    __status_am_specific.stock[_aminfo_item.id].req_quantity -= 1;
                    ___ifxn_updateSubTotalAmount(_aminfo_item.id, __status_am_specific.stock[_aminfo_item.id].req_quantity);
                }
            }

            // 개수 및 금액 출력
            if ( _elDiv_QuntCtrlFrmQuantityValue.length ){
                _elDiv_QuntCtrlFrmQuantityValue.text(__status_am_specific.stock[_aminfo_item.id].req_quantity);
            }
        }

        /**
         * 어메니티 수량 선택 및 카트 윈도우 빌드업
         * @param {number} _item_idx
         */
        const __ifxn_buildAmSelectedItemCartWin = function(_item_idx) {
            let _sz_styleOpt = null;

            const ___iCbfxn_buildAmSelectedItemWin = function() {
                // 상품 상세 설명페이지 구성
                __ifxn_removeAmSelectedItemCartWinElement();

                // Quantity Window
                {
                    //// Quantity Window Title
                    let _elDiv_QuntWinTitle = document.createElement('div');
                    _elDiv_QuntWinTitle.className = "title";
                    _elDiv_QuntWinTitle.textContent = _trTbl.ui.amenity.title.selected_menu_quantity[_state.lang].toUpperCase();
                    _elAmCtgyBgMenuItemCartWinLeft.append(_elDiv_QuntWinTitle);

                    //// Quantity control Frame
                    var _elDiv_QuntCtrlFrm = document.createElement('div');
                    _elDiv_QuntCtrlFrm.className = "control";
                    _elDiv_QuntCtrlFrm.innerHTML = `<div id="img_thumbnail" style="background-image: url(${_aminfo_item.thumbnail.files[_state.lang].download});"></div>`;
                    var _elDiv_QuntCtrlFrmQuantity = document.createElement('div');
                    _elDiv_QuntCtrlFrmQuantity.className = "quantity";
                    _elDiv_QuntCtrlFrmQuantity.innerHTML = `<div id="label_quantity">${_trTbl.ui.amenity.title.quantity[_state.lang].toUpperCase()}</div>`;
                    _elDiv_QuntCtrlFrmQuantity.innerHTML += `<div id="value_quantity"></div>`;
                    _elDiv_QuntCtrlFrmQuantity.innerHTML += `<div id="label_amount">${_trTbl.ui.amenity.title.amount[_state.lang].toUpperCase()}</div>`;
                    _elDiv_QuntCtrlFrmQuantity.innerHTML += `<div id="value_amount"></div>`;
                    _elDiv_QuntCtrlFrm.append(_elDiv_QuntCtrlFrmQuantity);
                    _elAmCtgyBgMenuItemCartWinLeft.append(_elDiv_QuntCtrlFrm);

                    //// Item description
                    var _elDiv_QuntItemDesc = document.createElement('div');
                    _elDiv_QuntItemDesc.className = "description";
                    _elDiv_QuntItemDesc.innerHTML = `<div id="title">${_aminfo_item.title[_state.lang]}</div><div id="details">${_aminfo_item.description[_state.lang]}</div>`;
                    _elAmCtgyBgMenuItemCartWinLeft.append(_elDiv_QuntItemDesc);

                    //// Buttons
                    var _elDiv_QuntBtnFrm = document.createElement('div');
                    _elDiv_QuntBtnFrm.className = "buttons";
                    _elDiv_QuntBtnFrm.innerHTML = `<div id="btn_ordernow">${_trTbl.ui.amenity.title.order_now[_state.lang].toUpperCase()}</div>`;
                    _elDiv_QuntBtnFrm.innerHTML += `<div id="btn_addtocart">${_trTbl.ui.amenity.title.add_to_cart[_state.lang].toUpperCase()}</div>`;
                    _elDiv_QuntBtnFrm.innerHTML += `<div id="btn_back">${_trTbl.ui.amenity.title.back[_state.lang].toUpperCase()}</div>`;
                    _elAmCtgyBgMenuItemCartWinLeft.append(_elDiv_QuntBtnFrm);
                }

                // CART Window
                {
                    //// Cart Window Title
                    let _elDiv_CartWinTitle = document.createElement('div');
                    _elDiv_CartWinTitle.className = "title";
                    _elDiv_CartWinTitle.textContent = _trTbl.ui.amenity.title.cartslist[_state.lang].toUpperCase();
                    _elAmCtgyBgMenuItemCartWinRight.append(_elDiv_CartWinTitle);

                    //// Cart item table
                    let _elDiv_CartWinTable = document.createElement('div');
                    _elDiv_CartWinTable.className = "cart_table";
                    {
                        ////// ADD Table Header
                        var _elTbl_ItemsHdr = document.createElement('table');
                        _elTbl_ItemsHdr.className = "tbl_header";

                        let _elTBody_ItmesHdr = document.createElement('tbody');
                        {
                            _elTBody_ItmesHdr.setAttribute("id", "hdr");

                            var _elTr_ItmesHdr = document.createElement('tr');
                            var _elTh_ItmesHdr_Title = document.createElement('th');
                            _elTh_ItmesHdr_Title.setAttribute("id", "title");
                            _elTh_ItmesHdr_Title.textContent = _trTbl.ui.amenity.title.item[_state.lang].toUpperCase();
                            _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Title);

                            var _elTh_ItmesHdr_Amount = document.createElement('th');
                            _elTh_ItmesHdr_Amount.setAttribute("id", "quantity");
                            _elTh_ItmesHdr_Amount.textContent = _trTbl.ui.amenity.title.quantity[_state.lang].toUpperCase();
                            _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Amount);

                            var _elTh_ItmesHdr_Status = document.createElement('th');
                            _elTh_ItmesHdr_Status.setAttribute("id", "amount");
                            //toUppderCase()
                            _elTh_ItmesHdr_Status.textContent = _trTbl.ui.amenity.title.amount[_state.lang].toUpperCase();
                            _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Status);

                            _elTBody_ItmesHdr.appendChild(_elTr_ItmesHdr);
                        }
                        _elTbl_ItemsHdr.appendChild(_elTBody_ItmesHdr);
                        _elDiv_CartWinTable.appendChild(_elTbl_ItemsHdr);

                        ////// Append item list record
                        var _elTbl_ItemsRec = document.createElement('table');
                        _elTbl_ItemsRec.className = "tbl_record";
                        _elDiv_CartWinTable.appendChild(_elTbl_ItemsRec);
                    }
                    _elAmCtgyBgMenuItemCartWinRight.append(_elDiv_CartWinTable);

                    //////// update cart table record
                    __ifxn_updateAmCartRecTable();



                    //// Quantity Window Title
                    let _elDiv_CartWinSummary = document.createElement('div');
                    _elDiv_CartWinSummary.className = "summary";
                    _elDiv_CartWinSummary.innerHTML = `<div id="label">${_trTbl.ui.amenity.title.sum[_state.lang].toUpperCase()}</div>`;
                    _elDiv_CartWinSummary.innerHTML += `<div id="value">${_aminfo_top.currency[_state.lang] + _carts.amount[_state.lang].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}</div>`;
                    _elAmCtgyBgMenuItemCartWinRight.append(_elDiv_CartWinSummary);
                }
            }

            // 카테고리매뉴윈도우 hide -> 아이템선택 윈도우 빌드 -> 아이탬선택 윈도우 show -> 버튼 포커스(back)
            _elAmCtgyBgMenuItemWin.fadeOut(200, function() {
                ___iCbfxn_buildAmSelectedItemWin();
                _elAmCtgyBgMenuItemCartWin.fadeIn(500, function() {
                    _elAmCtgyBgMenuItemCartWinLeft.find('#btn_back').addClass('focus');
                    __ifxn_updateAmSelectedItemCartWin(_item_idx, "build");

                    // 통계 이벤트 송출
                    HotelTV.api.ReportEvent([
                        {
                            'power': true,
                            'location':{
                                'conId':_aminfo_item.id
                            }
                        }], "indirect");
                });
            });
        }

        /**
         * 어메니티 카트 팝업 제거 함수
         * @param {function} __cbFxn_preForExit
         * @param {function} __cbFxn_postForExit
         */
        const __ifxn_removeAmSelectedItemCartWin = function(__cbFxn_preForExit, __cbFxn_postForExit) {
            if ( __cbFxn_preForExit ){
                __cbFxn_preForExit();
            }

            _elAmCtgyBgMenuItemCartWin.fadeOut(200, function() {
                // Remove All element under winleft&winright div
                __ifxn_removeAmSelectedItemCartWinElement();

                if ( __cbFxn_postForExit ){
                    __cbFxn_postForExit();
                }
            });
        }

        /**
         * 어메니티 상품을 쇼핑카트에 추가
         * @param {object} _am_itemInf
         * @param {number} _new_quantity
         * @param {callback} _cbFxn_Success
         * @param {callback} _cbFxn_Failure
         */
        const __ifxn_processAmAddtoCart = async function(_am_itemInf, _new_quantity, _cbFxn_Success, _cbFxn_Failure) {
            try {
                console.log("_new_quantity:" + _new_quantity);

                if ( __ifxn_checkCartItemExist(_carts.items, _am_itemInf.id)==true )
                {
                    // Modify API
                    let _result = await HotelTV.api.UpdateAmenityCarts(__ifxn_getCartIdbyItemID(_carts.items, _am_itemInf.id), _new_quantity);
                    if (_result) {
                        console.log(`Amenity Update cart successed::> ${_am_itemInf.id} ::> ${_am_itemInf.name}`);
                        if (_cbFxn_Success) {
                            HotelTV.carts.amenity = _carts = await HotelTV.api.GetAmenityCarts(null);
                            __ifxn_updateAmCartRecTable();
                            _cbFxn_Success();
                        }
                    } else {
                        console.log(`Amenity Update cart failed::> ${_am_itemInf.id} ::> ${_am_itemInf.name}`);
                        if (_cbFxn_Failure) {
                            _cbFxn_Failure();
                        }
                    }
                }
                else
                {
                    // Put API
                    let _result = await HotelTV.api.PutAmenityCarts(_am_itemInf.id, _new_quantity);
                    if (_result) {
                        console.log(`Amenity Add to cart successed::> ${_am_itemInf.id} ::> ${_am_itemInf.name}`);
                        if (_cbFxn_Success) {
                            HotelTV.carts.amenity = _carts = await HotelTV.api.GetAmenityCarts(null);
                            __ifxn_updateAmCartRecTable();
                            _cbFxn_Success();
                        }
                    } else {
                        console.log(`Amenity Add to cart failed::> ${_am_itemInf.id} ::> ${_am_itemInf.name}`);
                        if (_cbFxn_Failure) {
                            _cbFxn_Failure();
                        }
                    }
                }
            } catch ( _err ){
                console.log(`Fail to call API::> ${_err}`);
                if (_cbFxn_Failure) {
                    _cbFxn_Failure();
                }
            }
        }

        /**
         * 쇼핑카트에 담겨있는 어메니티 상품을 주문
         * @param {callback} _cbFxn_Success
         * @param {callback} _cbFxn_Failure
         */
        const __ifxn_processAmCartOrder = async function(_cbFxn_Success, _cbFxn_Failure) {
            let _elAmCtgyBgMenuItemCartWinOrderWin = $('.popup .amenity .owl-item.active.center .am_item_sel_order_win');

            try {
                _elAmCtgyBgMenuItemCartWin.fadeOut(200, async function() {
                    let _str_result_message = null;
                    // Remove All element under winleft&winright div
                    __ifxn_removeAmSelectedItemCartWinElement();

                    let _result = null;

                    try {
                        _result = await HotelTV.api.PutAmenityOrders();
                    } catch ( __err ){
                        console.log("CALL API::>" + __err);
                    } finally {
                        if ( _result !=null ) {
                            console.log(`Success to order Amenity cart::>`);
                            _str_result_message = _trTbl.ui.amenity.message.orderSuccess[_state.lang].replace('__MENU__', __uifxn_AppFull_getOrderMenuName(_aminfo_ctgy));
                            _elAmCtgyBgMenuItemCartWinOrderWin.children('#message').text(_str_result_message);
                            _elAmCtgyBgMenuItemCartWinOrderWin.fadeIn(500, async function() {
                                try{
                                    HotelTV.orders.amenity = await HotelTV.api.GetAmenityOrders(null);
                                    HotelTV.carts.amenity = await HotelTV.api.GetAmenityCarts(null);
                                } catch (___err) {
                                    console.log("CALL API::>" + ___err)
                                } finally {
                                    setTimeout(function() {
                                        _elAmCtgyBgMenuItemCartWinOrderWin.fadeOut(300);

                                        if ( _cbFxn_Success ){
                                            _cbFxn_Success();
                                        }
                                    }, 5000);
                                }
                            });
                        }else {
                            console.log(`Fail to order Amenity cart::>`);
                            _elAmCtgyBgMenuItemCartWinOrderWin.children('#message').text(_trTbl.ui.amenity.message.orderFailure[_state.lang]);
                            _elAmCtgyBgMenuItemCartWinOrderWin.fadeIn(500, async function() {
                                setTimeout(function() {
                                    _elAmCtgyBgMenuItemCartWinOrderWin.fadeOut(300);

                                    if ( _cbFxn_Failure ){
                                        _cbFxn_Failure();
                                    }
                                }, 5000);
                            });
                        }
                    }
                });
            } catch ( _err ){
                console.log(`Fail to call API::> ${_err}`);
                if ( _cbFxn_Failure ){
                    _cbFxn_Failure();
                }
            }
        }


        try{
            let _objChkAvail=null;
            let _str_curBtnID = null;
            // 어메니티 정보 오브젝트
            __status_am_specific = _state.hotkey.mm[_aminfo_top.button].status;
            let __amctgyIdx = __status_am_specific.category_sel.cur;
            let __amctgyItemStatus = __status_am_specific.items[_aminfo_ctgy[__amctgyIdx].name];

            // 선택된 어메니티 아이템 정보 매핑
            _aminfo_item = _aminfo_ctgy[__status_am_specific.category_sel.cur].items[__amctgyItemStatus.idx+1];

            _objChkAvail = __uifxn_Utils_CheckAmItemAvailable(_aminfo_item.schedule);
            if(_objChkAvail.result==false){
                return false;
            }

            if ( ["left","right","enter"].includes(_action) ){
                _str_curBtnID = __ifxn_getFocusedBtnID();
            }

            switch ( _action )
            {
                case "cart": {
                    __ifxn_buildAmSelectedItemCartWin(__amctgyItemStatus.idx);
                } break;

                case "left": {
                    if ( _str_curBtnID=='btn_back' ){
                        _elAmCtgyBgMenuItemCartWinLeft.find('.buttons').find('.focus').removeClass('focus');
                        _elAmCtgyBgMenuItemCartWinLeft.find('.buttons').find('#btn_addtocart').addClass('focus');
                    } else if ( _str_curBtnID=='btn_addtocart' ){
                        if ( _elAmCtgyBgMenuItemCartWinRight.find('.tbl_record').children().length>0 ){
                            _elAmCtgyBgMenuItemCartWinLeft.find('.buttons').find('.focus').removeClass('focus');
                            _elAmCtgyBgMenuItemCartWinLeft.find('.buttons').find('#btn_ordernow').addClass('focus');
                        }
                    }
                } break;

                case "right": {
                    if ( _str_curBtnID=='btn_ordernow' ){
                        _elAmCtgyBgMenuItemCartWinLeft.find('.buttons').find('.focus').removeClass('focus');
                        _elAmCtgyBgMenuItemCartWinLeft.find('.buttons').find('#btn_addtocart').addClass('focus');
                    } else if ( _str_curBtnID=='btn_addtocart' ){
                        _elAmCtgyBgMenuItemCartWinLeft.find('.buttons').find('.focus').removeClass('focus');
                        _elAmCtgyBgMenuItemCartWinLeft.find('.buttons').find('#btn_back').addClass('focus');
                    }
                } break;

                case "quantity_plus": {
                    __ifxn_updateAmSelectedItemCartWin(__amctgyItemStatus.idx, "plus");
                } break;

                case "quantity_minus": {
                    __ifxn_updateAmSelectedItemCartWin(__amctgyItemStatus.idx, "minus");
                } break;

                case "cart_scroll_up": {
                    let _elDiv_AmCtgyCartRecTable = _elAmCtgyBgMenuItemCartWinRight.find('.tbl_record').children('#record');
                    if ( _elDiv_AmCtgyCartRecTable.children().length>0 ){
                        let _heightTable = _elDiv_AmCtgyCartRecTable.outerHeight(true); // passing "true" will also include the top and bottom margin
                        let _numTrHeight = _elDiv_AmCtgyCartRecTable.find('tr').first().height(); //테이블 레코드 1줄 높이
                        let _posFirstTr = _elDiv_AmCtgyCartRecTable.find('tr').first().position();
                        let _posLastTr = _elDiv_AmCtgyCartRecTable.find('tr').last().position();

                        if ( _posFirstTr.top<0 ){
                            _elDiv_AmCtgyCartRecTable.animate({ scrollTop: _posFirstTr.top-_numTrHeight}, 200);
                        }
                    }
                } break;

                case "cart_scroll_down": {
                    let _elDiv_AmCtgyCartRecTable = _elAmCtgyBgMenuItemCartWinRight.find('.tbl_record').children('#record');
                    if ( _elDiv_AmCtgyCartRecTable.children().length>0 ){
                        const ___ifxn_calScrollTopOffset = function(){
                            let neededScrollRowCnt = 1;
                            for (__kk = 0; __kk < _elDiv_AmCtgyCartRecTable.children().length; __kk++) {
                                if ( _elDiv_AmCtgyCartRecTable.children().eq(__kk).position().top>_numTrHeight ){
                                    break;
                                }
                                neededScrollRowCnt ++;
                            }
                            return neededScrollRowCnt*_numTrHeight;
                        }
                        let _heightTable = _elDiv_AmCtgyCartRecTable.outerHeight(true); // passing "true" will also include the top and bottom margin
                        let _numTrHeight = _elDiv_AmCtgyCartRecTable.find('tr').first().height(); //테이블 레코드 1줄 높이
                        let _posFirstTr = _elDiv_AmCtgyCartRecTable.find('tr').first().position();
                        let _posLastTr = _elDiv_AmCtgyCartRecTable.find('tr').last().position();

                        if ( _posLastTr.top > _heightTable ){
                            _elDiv_AmCtgyCartRecTable.animate({ scrollTop: ___ifxn_calScrollTopOffset()}, 200);
                        }
                    }
                } break;

                case "enter": {
                    if ( _str_curBtnID=='btn_ordernow' ){
                        __ifxn_processAmCartOrder(
                            function() {
                                //Return to menu
                                if ( _cbFxnExitPost ){
                                    _cbFxnExitPost();
                                }
                            },
                            function() {
                                //Return to menu
                                if ( _cbFxnExitPost ){
                                    _cbFxnExitPost();
                                }
                            }
                        )
                    } else if ( _str_curBtnID=='btn_addtocart' ){
                        //console.log("SUCCESS::>> ADD TO CART");
                        __ifxn_processAmAddtoCart(
                            _aminfo_item,
                            __status_am_specific.stock[_aminfo_item.id].req_quantity,
                            function() {
                                //TODO: 카트 API호출 성공시 호출할 루틴
                            },
                            function() {
                                //TODO: 카트 API호출 실패시 호출할 루틴
                            }
                        );
                    } else if ( _str_curBtnID=='btn_back' ){
                        __ifxn_removeAmSelectedItemCartWin(_cbFxnExitPre, _cbFxnExitPost);
                    }
                } break;

                case "return": {
                    __ifxn_removeAmSelectedItemCartWin(_cbFxnExitPre, _cbFxnExitPost);
                } break;
            }

            return true;
        }catch(_err){
            console.log(`Fail to draw::> ${_err}`);
            return false;
        }
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> Draw amenity item selection ui
     */
    function __uifxn_AppFull_DrawAmItemSeletion(_action) {
        let _state = HotelTV.state;
        let _trTbl = HotelTV.translation;
        let _opening = HotelTV.opening;
        let _order = HotelTV.orders.amenity;
        let _aminfo_top = _opening.amenity;
        let _aminfo_ctgy = _aminfo_top.menu;
        let _elAmPupRoot = $('.popup .amenity');
        let _elAmCtgyBg = _elAmPupRoot.children('.bg').find('#lst_ctgbg');
        let _elAmCtgyBgFocus = _elAmCtgyBg.find('.owl-item.active.center');
        let _elAmCtgyBgMenuItemWin = _elAmCtgyBgFocus.find('.am_item_sel_win');
        let __status_am_specific = null;


        const __ifxn_updateAmItemDesc = function(_item_idx,_cbFxn) {
            let _sz_styleOpt = null;
            let __item_info = _aminfo_ctgy[__status_am_specific.category_sel.cur].items[_item_idx+1];
            // Remove All element under winright div
            let _elDivWinRight = _elAmCtgyBgMenuItemWin.find('.winright');

            const ___iCbfxn_updateAmItemDesc = function() {
                //상품 상세 설명페이지 구성
                ////썸네일
                let _elDiv_ItmesThumb = document.createElement('div');
                _elDiv_ItmesThumb.className = "amItemDescThumb";
                //let thuri = __item_info.thumbnail.files[_state.lang].download;
                _sz_styleOpt = "background-image: url(" + __item_info.thumbnail.files[_state.lang].download + "); ";
                _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: 100% 100%; ";
                _elDiv_ItmesThumb.setAttribute("style", _sz_styleOpt);

                ////상세설명
                let _elDiv_ItmesDetails = document.createElement('div');
                _elDiv_ItmesDetails.className = "amItemDescDetails";

                var _elDiv_ItmesTitle = document.createElement('div');
                _elDiv_ItmesTitle.setAttribute("id", "title");
                _elDiv_ItmesTitle.textContent = __item_info.title[_state.lang];

                var _elDiv_ItmesDescription = document.createElement('div');
                _elDiv_ItmesDescription.setAttribute("id", "description");
                _elDiv_ItmesDescription.textContent = __item_info.description[_state.lang];
                //_elDiv_ItmesDescription.textContent = __item_info.description[_state.lang].replace(/(?:\r\n|\r|\n)/g, '<br>');

                _elDiv_ItmesDetails.appendChild(_elDiv_ItmesTitle);
                _elDiv_ItmesDetails.appendChild(_elDiv_ItmesDescription);

                //winright에 썸네일과 상세설명 추가
                _elDivWinRight.append(_elDiv_ItmesThumb);
                _elDivWinRight.append(_elDiv_ItmesDetails);
            }

            if ( _elDivWinRight.css('display') != "none")  {
                _elDivWinRight.fadeOut(200, function() {
                    if ( _elDivWinRight.children().length ){
                        _elDivWinRight.children().remove();
                    }
                    ___iCbfxn_updateAmItemDesc();
                    _elDivWinRight.fadeIn(500, function() {
                        if ( _cbFxn ){ _cbFxn(); }
                    });
                });
            }else{
                if ( _elDivWinRight.children().length ){
                    _elDivWinRight.children().remove();
                }
                ___iCbfxn_updateAmItemDesc();

                _elDivWinRight.fadeIn(500, function() {
                    if ( _cbFxn ){ _cbFxn(); }
                });
            }
        }

        const __ifxn_removeAmItemDesc = function(_item_idx) {
            // Remove All element under winright div
            let _elDivWinRight = _elAmCtgyBgMenuItemWin.find('.winright');
            if ( _elDivWinRight.children().length ){
                _elDivWinRight.children().remove();
            }

            if ( _elDivWinRight.css('display') != "none")  {
                _elDivWinRight.fadeOut(300, function() {
                });
            }
        }

        try{
            // 어메니티 정보 오브젝트
            _aminfo_top = _opening.amenity;
            _aminfo_ctgy = _aminfo_top.menu;
            __status_am_specific = _state.hotkey.mm[_aminfo_top.button].status;
            let __amctgyIdx = __status_am_specific.category_sel.cur;
            let __amctgyItemStatus = __status_am_specific.items[_aminfo_ctgy[__amctgyIdx].name];

            switch ( _action )
            {
                case "enter": {
                    _elAmCtgyBgMenuItemWin.find('.amctgyItem').first().addClass("focus");
                    __amctgyItemStatus.idx = 0;
                    __amctgyItemStatus.scroll_TOfset = 0;
                    _elAmCtgyBgMenuItemWin.find('.tbl_record').children('#record').animate({ scrollTop: 0 }, 200);
                    __ifxn_updateAmItemDesc(__amctgyItemStatus.idx);
                } break;

                case "exit": {
                    _elAmCtgyBgMenuItemWin.find('.amctgyItem').removeClass("focus");
                    __ifxn_removeAmItemDesc();
                } break;

                case "up": {
                    let _isNeedSoldOutMask = false;
                    let _elTbl_AmItem = _elAmCtgyBgMenuItemWin.find('.tbl_record');
                    let _elTblTr_AmItemNext = _elTbl_AmItem.find('.focus').parent().prev('tr');

                    if (_elTblTr_AmItemNext.length) {
                        _elTbl_AmItem.find('.focus').removeClass("focus");
                        _elTblTr_AmItemNext.children('.amctgyItem').addClass('focus');

                        if ( _elTblTr_AmItemNext.children('.amctgyItem.unavailable').length ){
                            _isNeedSoldOutMask = true;
                        }

                        // 테이블 ROW인덱스와 스크롤 OFFSET계산
                        __amctgyItemStatus.idx = _elTblTr_AmItemNext.prop('rowIndex');

                        if ( _elTbl_AmItem.children('#record').find('tr').first().position().top<0 ){
                            __amctgyItemStatus.scroll_TOfset -= _elTblTr_AmItemNext.prop('scrollHeight');
                            //스크롤 에니메이션 수행
                            _elTbl_AmItem.children('#record').animate({ scrollTop: __amctgyItemStatus.scroll_TOfset }, 200);
                        }

                        __ifxn_updateAmItemDesc(__amctgyItemStatus.idx, function() {
                            if ( _isNeedSoldOutMask==true ){
                                _elAmCtgyBgMenuItemWin.find('.winright').find('.amItemDescThumb').addClass('unavailable');
                            }else {
                                _elAmCtgyBgMenuItemWin.find('.winright').find('.amItemDescThumb').removeClass('unavailable');
                            }
                        });
                    }
                } break;

                case "down": {
                    let _elTbl_AmItem = _elAmCtgyBgMenuItemWin.find('.tbl_record');
                    let _elTblTr_AmItemNext = _elTbl_AmItem.find('.focus').parent().next('tr');
                    let _isNeedSoldOutMask = false;

                    if (_elTblTr_AmItemNext.length) {
                        _elTbl_AmItem.find('.focus').removeClass("focus");
                        _elTblTr_AmItemNext.children('.amctgyItem').addClass('focus');

                        if ( _elTblTr_AmItemNext.children('.amctgyItem.unavailable').length ){
                            _isNeedSoldOutMask = true;
                        }

                        // 테이블 ROW인덱스와 스크롤 OFFSET계산
                        __amctgyItemStatus.idx = _elTblTr_AmItemNext.prop('rowIndex');
                        if ( __amctgyItemStatus.idx>=12 ){
                            __amctgyItemStatus.scroll_TOfset += _elTblTr_AmItemNext.prop('scrollHeight');
                            //스크롤 에니메이션 수행
                            _elTbl_AmItem.children('#record').animate({ scrollTop: __amctgyItemStatus.scroll_TOfset }, 200);
                        }

                        __ifxn_updateAmItemDesc(__amctgyItemStatus.idx, function() {
                            if ( _isNeedSoldOutMask==true ){
                                _elAmCtgyBgMenuItemWin.find('.winright').find('.amItemDescThumb').addClass('unavailable');
                            }else {
                                _elAmCtgyBgMenuItemWin.find('.winright').find('.amItemDescThumb').removeClass('unavailable');
                            }
                        });
                    }
                } break;
            }
        } catch (_err){
            console.log(`Fail to draw::> ${_err}`);
        }
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> build amenity service
     */
    function __uifxn_AppFull_BuildAmenity() {
        let _state = HotelTV.state;
        let __status_am_specific = null;
        let _trTbl = HotelTV.translation;
        let _opening = HotelTV.opening;
        let _order = HotelTV.orders.amenity;
        let _aminfo_top = null;
        let _aminfo_ctgy = null;
        let _elMainRoot = $('.main');
        let _elMainMenu = _elMainRoot.children('.mm');
        let _elAmPupRoot = $('.popup .amenity');
        let _elAmCtgyBg = _elAmPupRoot.children('.bg').find('#lst_ctgbg');
        let _elAmCtgySel = _elAmPupRoot.children('.slider').find('#lst_ctgsel');
        let _elAmUGRoot = _elAmPupRoot.children('.use_guide');

        const __ifxn_clrearAmCarts = async function() {
            try {
                _result = await HotelTV.api.DeleteAmenityCarts(null);
                HotelTV.carts.amenity = await HotelTV.api.GetAmenityCarts(null);
            } catch ( __err ){
                console.log("CALL API::>" + __err);
            }
        }


        // 어메니티 인포 Validation
        if (!_opening.amenity) {
            return;
        }

        // 어메니티 정보 오브젝트
        _aminfo_top = _opening.amenity;
        _aminfo_ctgy = _aminfo_top.menu;


        __status_am_specific = _state.hotkey.mm[_aminfo_top.button].status;



        // 초기 메인 메뉴 KEY설정
        _state.menu.stage.cur = "preparing_amenity";
        _elAmUGRoot.hide();

        // 어메니티 팝업 카테고리 셀렉터 노드를 동적으로 구성
        for (let _idx = 1; _idx <= _aminfo_ctgy.length; _idx++) {
            let _elDiv_Ctgy = document.createElement('div');
            _elDiv_Ctgy.className = 'item';
            _elDiv_Ctgy.id = _aminfo_ctgy[_idx].id;
            _elDiv_Ctgy.setAttribute("am_ctgy_id", _idx);

            // Append Category elements::title
            let _elDiv_CtgyTitle = document.createElement('div');
            _elDiv_CtgyTitle.setAttribute("id", "am_item_title");

            if (_aminfo_ctgy[_idx].showTitle && _aminfo_ctgy[_idx].showTitle == true) {
                _elDiv_CtgyTitle.textContent = _aminfo_ctgy[_idx].title[_state.lang];
            }

            // Append Category elements::btn
            let _elDiv_CtgyBtn = document.createElement('div');
            _elDiv_CtgyBtn.setAttribute("id", "ctgy_item_btn");
            let _sz_styleOpt = "--icon_unfocus: url(" + _aminfo_ctgy[_idx].unfocusIcon.file.download + "); ";
            _sz_styleOpt += "--icon_focus: url(" + _aminfo_ctgy[_idx].focusIcon.file.download + "); ";
            //_sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom; background-size: 100% 100%; ";
            _sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom;";
            _elDiv_CtgyBtn.setAttribute("style", _sz_styleOpt);

            _elDiv_Ctgy.appendChild(_elDiv_CtgyBtn);
            _elDiv_Ctgy.appendChild(_elDiv_CtgyTitle);

            _elAmCtgySel.append(_elDiv_Ctgy);

            // 각 카테고리별 아이템 스크롤위치등을 관리하기 위하여 status맴버 초기화 및 구성
            if ( !(_aminfo_ctgy[_idx].name in __status_am_specific.items)==true ){
                __status_am_specific.items[_aminfo_ctgy[_idx].name] = {
                    "idx": 0,
                    "scroll_TOfset": 0,
                    "carts": {
                        "idx": 0,
                        "scroll_TOfset": 0
                    }
                };
            }
        }

        // 어메니티 팝업 카테고리 백그라운드 이미지 노드를 동적으로 구성
        for (let _idx = 1; _idx <= _aminfo_ctgy.length; _idx++) {
            let _objAm_ctgyItem = _aminfo_ctgy[_idx].items;
            let _sz_styleOpt = null;
            let _elDiv_Ctgy = document.createElement('div');

            _elDiv_Ctgy.className = 'item';
            _elDiv_Ctgy.id = _aminfo_ctgy[_idx].id;
            _elDiv_Ctgy.setAttribute("am_ctgy_id", _idx);
            _sz_styleOpt = "background-image: url(" + _aminfo_ctgy[_idx].background.file.download + "); ";
            _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: 100% 100%; ";
            _elDiv_Ctgy.setAttribute("style", _sz_styleOpt);

            // TOP 그라데이션
            let _elDiv_CtgyGradientTop = document.createElement('div');
            _elDiv_CtgyGradientTop.className = 'top_gradient';

            _elDiv_Ctgy.appendChild(_elDiv_CtgyGradientTop);

            // BOTTOM 그라데이션
            let _elDiv_CtgyGradientBottom = document.createElement('div');
            _elDiv_CtgyGradientBottom.className = 'bottom_gradient';

            _elDiv_Ctgy.appendChild(_elDiv_CtgyGradientBottom);

            // ITEM LIST TOP-LEVEL ELEMENTS
            //// ITEM SELECTION WINDOW
            let _elDiv_ItemSelWin = document.createElement('div');
            _elDiv_ItemSelWin.className = 'am_item_sel_win';
            {
                ////// Window Left side
                let _elDiv_ItemWinLeft = document.createElement('div');
                _elDiv_ItemWinLeft.className = 'winleft';

                if ( ["ORDER", "CARTS"].includes(_aminfo_ctgy[_idx].name)==true )
                {
                    _elDiv_ItemWinLeft.classList.add(_aminfo_ctgy[_idx].name.toLowerCase());
                    _elDiv_ItemWinLeft.style.display = 'none';
                }
                else
                {
                    ////// ADD Table Header
                    var _elTbl_ItemsHdr = document.createElement('table');
                    _elTbl_ItemsHdr.className = "tbl_header";

                    let _elTBody_ItmesHdr = document.createElement('tbody');
                    {
                        _elTBody_ItmesHdr.setAttribute("id", "hdr");

                        var _elTr_ItmesHdr = document.createElement('tr');
                        var _elTh_ItmesHdr_Title = document.createElement('th');
                        _elTh_ItmesHdr_Title.setAttribute("id", "title");
                        _elTh_ItmesHdr_Title.textContent = _trTbl.ui.amenity.title.item[_state.lang].toUpperCase();
                        _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Title);

                        var _elTh_ItmesHdr_Amount = document.createElement('th');
                        _elTh_ItmesHdr_Amount.setAttribute("id", "price");
                        _elTh_ItmesHdr_Amount.textContent = _trTbl.ui.amenity.title.amount[_state.lang].toUpperCase();
                        _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Amount);

                        var _elTh_ItmesHdr_Status = document.createElement('th');
                        _elTh_ItmesHdr_Status.setAttribute("id", "status");
                        _elTh_ItmesHdr_Status.textContent = _trTbl.ui.amenity.title.orderability[_state.lang].toUpperCase();
                        _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Status);

                        _elTBody_ItmesHdr.appendChild(_elTr_ItmesHdr);
                    }
                    _elTbl_ItemsHdr.appendChild(_elTBody_ItmesHdr);
                    _elDiv_ItemWinLeft.appendChild(_elTbl_ItemsHdr);

                    ////// Append item list record
                    var _elTbl_ItemsRec = document.createElement('table');
                    _elTbl_ItemsRec.className = "tbl_record";

                    let _elTBody_ItmesRec = document.createElement('tbody');
                    {
                        _elTBody_ItmesRec.setAttribute("id", "record");
                        for (let _j = 1; _j <= _objAm_ctgyItem.length; _j++) {
                            let _objChkAvail=null;
                            let _objItem = _objAm_ctgyItem[_j];

                            var _elTr_ItmesRec = document.createElement('tr');
                            var _elDiv_ItmesRec = document.createElement('div');
                            _elDiv_ItmesRec.className = "amctgyItem";
                            var _elDiv_ItmesRecName = document.createElement('div');
                            _elDiv_ItmesRecName.setAttribute("id", "title");
                            _elDiv_ItmesRecName.textContent = _objItem.title[_state.lang];
                            _elDiv_ItmesRec.appendChild(_elDiv_ItmesRecName);

                            var _elDiv_ItmesRecPrice = document.createElement('div');
                            _elDiv_ItmesRecPrice.setAttribute("id", "price");
                            _elDiv_ItmesRecPrice.textContent = _aminfo_top.currency[_state.lang] + _objItem.price[_state.lang].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
                            _elDiv_ItmesRec.appendChild(_elDiv_ItmesRecPrice);


                            var _elDiv_ItmesRecStatus = document.createElement('div');
                            _elDiv_ItmesRecStatus.setAttribute("id", "status");

                            _objChkAvail = __uifxn_Utils_CheckAmItemAvailable(_objItem.schedule);
                            if(_objChkAvail.result==true){
                                _elDiv_ItmesRecStatus.textContent = _trTbl.ui.amenity.title.orderable[_state.lang];
                            }else{
                                _elDiv_ItmesRec.classList.add("unavailable");
                                if ( _objChkAvail.avail_dtime=="unorderable" ){
                                    _elDiv_ItmesRecStatus.textContent = _trTbl.ui.amenity.title.unorderable[_state.lang];
                                }else{
                                    _elDiv_ItmesRecStatus.textContent = _objChkAvail.avail_dtime;
                                }
                            }
                            _elDiv_ItmesRec.appendChild(_elDiv_ItmesRecStatus);
                            _elTr_ItmesRec.appendChild(_elDiv_ItmesRec);
                            _elTBody_ItmesRec.appendChild(_elTr_ItmesRec);
                        }
                        _elTbl_ItemsRec.appendChild(_elTBody_ItmesRec);
                    }
                    _elDiv_ItemWinLeft.appendChild(_elTbl_ItemsRec);
                }
                _elDiv_ItemSelWin.appendChild(_elDiv_ItemWinLeft);

                ////// Window Right side
                let _elDiv_ItemWinRight = document.createElement('div');
                _elDiv_ItemWinRight.className = 'winright';

                _elDiv_ItemSelWin.appendChild(_elDiv_ItemWinRight);
            }
            // _elDiv_Ctgy에 추가
            _elDiv_Ctgy.appendChild(_elDiv_ItemSelWin);

            // Selected Item Cart Window
            let _elDiv_SelectedItemCartWin = document.createElement('div');
            _elDiv_SelectedItemCartWin.className = 'am_item_sel_cart_win';
            _elDiv_SelectedItemCartWin.style.display = 'none';
            {
                if ( ["ORDER", "CARTS"].includes(_aminfo_ctgy[_idx].name)==false )
                {
                    ////// Window Left side
                    let _elDiv_ItemWinCartLeft = document.createElement('div');
                    _elDiv_ItemWinCartLeft.className = 'winleft';
                    _elDiv_SelectedItemCartWin.appendChild(_elDiv_ItemWinCartLeft);

                    ////// Window Right side
                    let _elDiv_ItemWinCartRight = document.createElement('div');
                    _elDiv_ItemWinCartRight.className = 'winright';

                    _elDiv_SelectedItemCartWin.appendChild(_elDiv_ItemWinCartRight);
                }
            }
            // _elDiv_Ctgy에 추가
            _elDiv_Ctgy.appendChild(_elDiv_SelectedItemCartWin);


            // Selected Item Cart Window
            let _elDiv_SelectedItemOrderWin = document.createElement('div');
            _elDiv_SelectedItemOrderWin.className = 'am_item_sel_order_win';
            _elDiv_SelectedItemOrderWin.innerHTML += `<div id="message"></div>`;
            _elDiv_SelectedItemOrderWin.style.display = 'none';
            // _elDiv_Ctgy에 추가
            _elDiv_Ctgy.appendChild(_elDiv_SelectedItemOrderWin);

            // _elAmCtgyBg에 추가
            _elAmCtgyBg.append(_elDiv_Ctgy);
        }

        // popup:amenity 프레임 활성화
        if ( _elAmPupRoot.css('display') == "none")  {
            _elAmPupRoot.show();
        }

        _elAmCtgyBg.owlCarousel({
            center: true,
            items: 1, //Number of Items on Screen what you want
            loop: true,
            rewind: false,
            checkVisible: false,
            animateOut: 'fadeOut',
            animateIn: 'fadeIn',
            margin: 0,
            smartSpeed: 1000,
            lazyLoad: true,
            mouseDrag: false,
            touchDrag: false,
            pullDrag: false,
            freeDrag: false,
            dots: false,
            startPosition: (Number(__status_am_specific.category_sel.cur) - 1),
        });
        // _elAmPupRoot.children('.bg').fadeIn(1000, function() {
        //     __uifxn_AppFull_HotKey_ShowBtnOnMM(false);
        //     __uifxn_AppFull_TopWidjetShow(false);
        // });

        _elAmCtgySel.owlCarousel({
            center: true,
            items: 5, //Number of Items on Screen what you want
            loop: true,
            rewind: false,
            checkVisible: false,
            margin: 0,
            smartSpeed: 0,
            autoWidth: false,
            mouseDrag: false,
            touchDrag: false,
            pullDrag: false,
            freeDrag: false,
            dots: true,
            startPosition: (Number(__status_am_specific.category_sel.cur) - 1),
        });

        //메인 페이지->어메니티 페이지 화면 전환
        _elMainRoot.fadeOut(500, function() {
            __uifxn_AppFull_HotKey_ShowBtnOnMM(false);
            __uifxn_AppFull_TopWidjetShow(false);
            _elAmPupRoot.children('.slider').fadeIn(300, function() {
                _elAmPupRoot.children('.bg').fadeIn(500, function() {
                    _elAmCtgySel.find('.owl-item').addClass('unfocus');
                    _elAmCtgySel.trigger("to.owl.carousel", [(Number(__status_am_specific.category_sel.cur) - 1), 10, true]);
                    _elAmCtgySel.trigger('translate.owl.carousel', [0, 500, true]);

                    $(document.activeElement).keydown(function(event) { //attach event listener
                        if (_state.menu.stage.cur == "amenity_ctgy_sel") {
                            if (event.keyCode == gRmtKey.left) {
                                _elAmCtgySel.trigger('prev.owl', [700]);
                            } else if (event.keyCode == gRmtKey.right) {
                                _elAmCtgySel.trigger('next.owl', [700]);
                            } else if (event.keyCode == gRmtKey.enter) {
                                // 카테고리 화면 빌드 및 화면 전환
                                if ( __status_am_specific.category_sel.cur in Object.keys(_aminfo_ctgy) ){
                                    if ( _aminfo_ctgy[__status_am_specific.category_sel.cur].name == "CARTS" ){
                                        console.log("TODO::> NOTIFY cannot enter item sel on CARTS");
                                    }else if ( _aminfo_ctgy[__status_am_specific.category_sel.cur].name == "ORDER" ){
                                        let __str_notify_msg = _trTbl.ui.amenity.message.invalidCategory[_state.lang].replace('__MENU__', __uifxn_AppFull_getOrderMenuName(_aminfo_ctgy));
                                        HotelTV.ui_utils.ShowNotificationMsgBalloon(__str_notify_msg, 5);
                                    }else{
                                        _state.menu.stage.cur = "amenity_ctgy_item_sel";
                                        __uifxn_AppFull_DrawAmUserGuide("amenity_ctgy_item_sel");
                                        __uifxn_AppFull_DrawAmItemSeletion("enter");
                                    }
                                }
                            } else if (event.keyCode == gRmtKey.back) {
                                __uifxn_AppFull_DrawAmOrderList('hide');
                                // 카테고리 폼의 썸네일 에니메이션용 타이머 제거
                                if (_hndl_tmrAmenityThumbAni != null) {
                                    clearInterval(_hndl_tmrAmenityThumbAni);
                                    _hndl_tmrAmenityThumbAni = null;
                                    console.log("TMR(AMENITY CATEGORY CTZ ANI For Thumbnail)::>Destoried...");
                                }

                                //카트 비움 및 사용자 가이드 지움.
                                __ifxn_clrearAmCarts();
                                __uifxn_AppFull_DrawAmUserGuide("destroy");

                                // 어메니티 -> 메인 메뉴로 귀환
                                $(document.activeElement).off('keydown');
                                _elMainMenu.show(function() {
                                    $('#lst_mmsel').trigger('translate.owl.carousel', [0]);
                                });

                                _elAmCtgySel.off('refresh.owl.carousel');
                                _elAmCtgySel.off('change.owl.carousel');
                                _elAmCtgySel.off('changed.owl.carousel');
                                _elAmCtgySel.off('translate.owl.carousel');

                                _elAmCtgyBg.owlCarousel('destroy');
                                _elAmCtgySel.owlCarousel('destroy');

                                _elAmCtgySel.children('div').remove();
                                _elAmCtgyBg.children('div').remove();
                                _elAmPupRoot.children('.bg').hide();
                                _elAmPupRoot.children('.slider').hide();

                                setTimeout(function() {
                                    $('.main').fadeIn(1000, () => {
                                        _state.menu.stage.cur = "main";
                                        __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
                                        __uifxn_AppFull_TopWidjetShow(true);
                                        _state.menu.stage.prev = null;
                                    });
                                }, 500);
                            }
                        } else if (_state.menu.stage.cur == "amenity_ctgy_orderlists") {
                            if (event.keyCode == gRmtKey.left) {
                                _elAmCtgySel.trigger('prev.owl', [700]);
                            } else if (event.keyCode == gRmtKey.right) {
                                _elAmCtgySel.trigger('next.owl', [700]);
                            } else if (event.keyCode == gRmtKey.enter) {
                                let __str_notify_msg = _trTbl.ui.amenity.message.invalidCategory[_state.lang].replace('__MENU__', __uifxn_AppFull_getOrderMenuName(_aminfo_ctgy));
                                HotelTV.ui_utils.ShowNotificationMsgBalloon(__str_notify_msg, 5);
                            } else if (event.keyCode == gRmtKey.back) {
                                __uifxn_AppFull_DrawAmOrderList('hide');

                                // 카테고리 폼의 썸네일 에니메이션용 타이머 제거
                                if (_hndl_tmrAmenityThumbAni != null) {
                                    clearInterval(_hndl_tmrAmenityThumbAni);
                                    _hndl_tmrAmenityThumbAni = null;
                                    console.log("TMR(AMENITY CATEGORY CTZ ANI For Thumbnail)::>Destoried...");
                                }

                                //카트 비움 및 사용자 가이드 지움.
                                __ifxn_clrearAmCarts();
                                __uifxn_AppFull_DrawAmUserGuide("destroy");

                                // 어메니티 -> 메인 메뉴로 귀환
                                $(document.activeElement).off('keydown');
                                _elMainMenu.show(function() {
                                    $('#lst_mmsel').trigger('translate.owl.carousel', [0]);
                                });

                                _elAmCtgySel.off('refresh.owl.carousel');
                                _elAmCtgySel.off('change.owl.carousel');
                                _elAmCtgySel.off('changed.owl.carousel');
                                _elAmCtgySel.off('translate.owl.carousel');

                                _elAmCtgyBg.owlCarousel('destroy');
                                _elAmCtgySel.owlCarousel('destroy');

                                _elAmCtgySel.children('div').remove();
                                _elAmCtgyBg.children('div').remove();
                                _elAmPupRoot.children('.bg').hide();
                                _elAmPupRoot.children('.slider').hide();

                                setTimeout(function() {
                                    $('.main').fadeIn(1000, () => {
                                        _state.menu.stage.cur = "main";
                                        __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
                                        __uifxn_AppFull_TopWidjetShow(true);
                                        _state.menu.stage.prev = null;
                                    });
                                }, 500);
                            }
                        } else if (_state.menu.stage.cur == "amenity_ctgy_item_sel") {
                            if (event.keyCode == gRmtKey.left) {
                                __uifxn_AppFull_DrawAmItemSeletion("plus");
                            } else if (event.keyCode == gRmtKey.right) {
                                __uifxn_AppFull_DrawAmItemSeletion("minus");
                            } else if (event.keyCode == gRmtKey.up) {
                                __uifxn_AppFull_DrawAmItemSeletion("up");
                            } else if (event.keyCode == gRmtKey.down) {
                                __uifxn_AppFull_DrawAmItemSeletion("down");
                            } else if (event.keyCode == gRmtKey.back) {
                                __uifxn_AppFull_DrawAmItemSeletion("exit");
                                _state.menu.stage.cur = "amenity_ctgy_sel";
                                __uifxn_AppFull_DrawAmUserGuide("amenity_ctgy_sel");
                            } else if (event.keyCode == gRmtKey.enter) {
                                console.log('AMENITY CATEGORY ITEM SEL: KEY::> ' + event.keyCode);
                                if ( __uifxn_AppFull_DrawAmItemSeletionCart("cart", null, null)==true ){
                                    _state.menu.stage.cur = "amenity_ctgy_item_cart";
                                    __uifxn_AppFull_DrawAmUserGuide("amenity_ctgy_item_cart");
                                } else {
                                    HotelTV.ui_utils.ShowNotificationMsgBalloon(_trTbl.ui.amenity.message.notinservice[_state.lang], 5);
                                }
                            }
                        } else if (_state.menu.stage.cur == "amenity_ctgy_item_cart") {
                            if (event.keyCode == gRmtKey.left) {
                                __uifxn_AppFull_DrawAmItemSeletionCart("left", null, null);
                            } else if (event.keyCode == gRmtKey.right) {
                                __uifxn_AppFull_DrawAmItemSeletionCart("right", null, null);
                            } else if (event.keyCode == gRmtKey.up) {
                                __uifxn_AppFull_DrawAmItemSeletionCart("quantity_plus", null, null);
                            } else if (event.keyCode == gRmtKey.down) {
                                __uifxn_AppFull_DrawAmItemSeletionCart("quantity_minus", null, null);
                            } else if (event.keyCode == gRmtKey.chup) {
                                __uifxn_AppFull_DrawAmItemSeletionCart("cart_scroll_up", null, null);
                            } else if (event.keyCode == gRmtKey.chdown) {
                                __uifxn_AppFull_DrawAmItemSeletionCart("cart_scroll_down", null, null);
                            } else if (event.keyCode == gRmtKey.back) {
                                __uifxn_AppFull_DrawAmItemSeletionCart(
                                    "return",
                                    null,
                                    function() {
                                        let _elAmCtgyBgFocusedItemSelWin = _elAmCtgyBg.find('.owl-item.active.center').find('.am_item_sel_win');
                                        if ( _elAmCtgyBgFocusedItemSelWin.css('display') == "none")  {
                                            _elAmCtgyBgFocusedItemSelWin.fadeIn(500, function() {
                                                _state.menu.stage.cur = "amenity_ctgy_item_sel";
                                                __uifxn_AppFull_DrawAmUserGuide("amenity_ctgy_item_sel");
                                            });
                                        }
                                    }
                                );
                            } else if (event.keyCode == gRmtKey.enter) {
                                __uifxn_AppFull_DrawAmItemSeletionCart(
                                    "enter",
                                    null,
                                    function() {
                                        let _elAmCtgyBgFocusedItemSelWin = _elAmCtgyBg.find('.owl-item.active.center').find('.am_item_sel_win');
                                        if ( _elAmCtgyBgFocusedItemSelWin.css('display') == "none")  {
                                            _elAmCtgyBgFocusedItemSelWin.fadeIn(500, function() {
                                                _state.menu.stage.cur = "amenity_ctgy_item_sel";
                                                __uifxn_AppFull_DrawAmUserGuide("amenity_ctgy_item_sel");
                                            });
                                        }
                                    }
                                );
                                console.log('AMENITY CATEGORY ITEM SEL: KEY::> ' + event.keyCode);
                            }
                        } else {
                            console.log("AMENITY SLIDER KEYEVT: Skip events");
                        }
                    });
                    //어메니티 카테고리 선택 모드(생성시, 메뉴모드)
                    _state.menu.stage.cur = "amenity_ctgy_sel";
                    __uifxn_AppFull_DrawAmUserGuide("amenity_ctgy_sel");
                });
            })
        });

        _elAmCtgySel.on('change.owl.carousel', function(event) {
            // Update HotelTV Amenity menu sel status
            __status_am_specific.category_sel.prev = Object.keys(_aminfo_ctgy)[event.page.index];
        });

        _elAmCtgySel.on('destroy.owl.carousel', function(event) {
            console.log("AMENITY MM SEL destroied::>" );
        });

        _elAmCtgySel.on('changed.owl.carousel', function(event) {
            // Update HotelTV Amenity menu sel status
            __status_am_specific.category_sel.cur = Object.keys(_aminfo_ctgy)[event.page.index];
            //console.log("AMENITY CATEGORY EVT IDX::>" + event.page.index);
            console.log("AMENITY CATEGORY SEL IDX::>" + __status_am_specific.category_sel.cur);
            if ( __status_am_specific.category_sel.cur in Object.keys(_aminfo_ctgy) ){
                if ( _aminfo_ctgy[__status_am_specific.category_sel.cur].name == "CARTS" ){
                    console.log("TODO::> Draw Carts");
                }else if ( _aminfo_ctgy[__status_am_specific.category_sel.cur].name == "ORDER" ){
                    __uifxn_AppFull_DrawAmOrderList('build');
                    _state.menu.stage.prev = _state.menu.stage.cur;
                    _state.menu.stage.cur = "amenity_ctgy_orderlists";
                }else{
                    __uifxn_AppFull_DrawAmOrderList('hide');
                    if ( _state.menu.stage.prev!=null ){
                        if ( _state.menu.stage.prev=="preparing_amenity" ){
                            _state.menu.stage.prev="amenity_ctgy_sel";
                        }
                        _state.menu.stage.cur = _state.menu.stage.prev;
                    }
                }
            }
            _elAmCtgyBg.trigger("to.owl.carousel", [event.page.index, 1000]);
        });

        _elAmCtgySel.on('translate.owl.carousel', function(event) {
            // 메뉴 셀렉터 좌/우 헨들링 및 이펙트
            let _uiCtrl_idx = 0;
            if (typeof event.item != 'undefined') {
                _uiCtrl_idx = event.item.index;
            } else {
                _uiCtrl_idx = _elAmCtgySel.find('.owl-item.active.center').index();
            }
            console.log("AMENITY CATEGORY CTRL IDX::>" + _uiCtrl_idx);
            _elAmCtgySel.find('.owl-item.focus').addClass('unfocus');
            _elAmCtgySel.find('.owl-item.focus').removeClass('focus');
            _elAmCtgySel.find('.owl-item').eq(_uiCtrl_idx).addClass('focus');
            _elAmCtgySel.find('.owl-item').eq(_uiCtrl_idx).removeClass('unfocus');
        });
        return;
    }


    /**
     * HotelTV UI[AppFull] Wrapper Function::> Draw room service feature user's guide
     * @param {string} _action
     */
    function __uifxn_AppFull_DrawRsUserGuide(_action) {
        let _state = HotelTV.state;
        let _trTbl = HotelTV.translation;
        let _opening = HotelTV.opening;
        let _rsinfo_top = _opening.roomService;
        let _rsinfo_ctgy = _rsinfo_top.menu;
        let _elRsPupRoot = $('.popup .roomservice');
        let _elRsUGRoot = _elRsPupRoot.children('.use_guide');
        let __status_rs_specific = null;


        try{
            // 룸서비스 정보 오브젝트
            _rsinfo_top = _opening.roomService;
            _rsinfo_ctgy = _rsinfo_top.menu;
            __status_rs_specific = _state.hotkey.mm[_rsinfo_top.button].status;
            let __rsctgyIdx = __status_rs_specific.category_sel.cur;
            let __rsctgyItemStatus = __status_rs_specific.items[_rsinfo_ctgy[__rsctgyIdx].name];

            switch(_action)
            {
                case "destroy": {
                    _elRsUGRoot.fadeOut(200, function(){
                        _elRsUGRoot.html('');
                    });
                } break;

                case "roomservice_ctgy_sel": {
                    if ( _elRsUGRoot.css('display')=="none" ) {
                        _elRsUGRoot.html(_trTbl.ui.roomservice.usage.category_menus_nav[_state.lang]);
                        _elRsUGRoot.fadeIn(300);
                    } else {
                        _elRsUGRoot.fadeOut(200, function(){
                            _elRsUGRoot.html(_trTbl.ui.roomservice.usage.category_menus_nav[_state.lang]);
                            _elRsUGRoot.fadeIn(300);
                        });
                    }
                } break;

                case "roomservice_ctgy_item_sel": {
                    _elRsUGRoot.fadeOut(200, function(){
                        _elRsUGRoot.html(_trTbl.ui.roomservice.usage.category_item_nav[_state.lang]);
                        _elRsUGRoot.fadeIn(300);
                    });
                } break;

                case "roomservice_ctgy_item_cart": {
                    _elRsUGRoot.fadeOut(200, function(){
                        _elRsUGRoot.html(_trTbl.ui.roomservice.usage.category_item_cart[_state.lang]);
                        _elRsUGRoot.fadeIn(300);
                    });
                } break;
            }
        }catch(_err){
            console.log(`Fail to draw::> ${_err}`);
        }
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> Draw room service order history
     * @param {string} _action
     */
    function __uifxn_AppFull_DrawRsOrderList(_action) {
        let _state = HotelTV.state;
        let _trTbl = HotelTV.translation;
        let _opening = HotelTV.opening;
        let _order = HotelTV.orders.roomservice;
        let _rsinfo_top = _opening.roomService;
        let _rsinfo_ctgy = _rsinfo_top.menu;
        let _elRsPupRoot = $('.popup .roomservice');
        let _elRsOrderRoot = _elRsPupRoot.children('.order');
        let _elRsOrderWinleft = _elRsOrderRoot.children('.winleft');
        let __status_rs_specific = null;

        const __ifxn_removeOrderElements = function(){
            if ( _elRsOrderWinleft.children().length>0 ){
                _elRsOrderWinleft.children().remove();
            }
        }


        try{
            // 룸서비스 정보 오브젝트
            _rsinfo_top = _opening.roomService;
            _rsinfo_ctgy = _rsinfo_top.menu;
            __status_rs_specific = _state.hotkey.mm[_rsinfo_top.button].status;
            let __rsctgyIdx = __status_rs_specific.category_sel.cur;
            let __rsctgyItemStatus = __status_rs_specific.items[_rsinfo_ctgy[__rsctgyIdx].name];

            switch(_action)
            {
                case 'hide': {
                    if ( _elRsOrderRoot.css('display')!="none" ){
                        _elRsOrderRoot.fadeOut(100);
                    }
                } break;

                case 'build': {
                    __ifxn_removeOrderElements();

                    ////// ADD Table Header
                    var _elTbl_ItemsHdr = document.createElement('table');
                    _elTbl_ItemsHdr.className = "tbl_header";

                    let _elTBody_ItmesHdr = document.createElement('tbody');
                    {
                        _elTBody_ItmesHdr.setAttribute("id", "hdr");

                        var _elTr_ItmesHdr = document.createElement('tr');
                        var _elTh_ItmesHdr_Title = document.createElement('th');
                        _elTh_ItmesHdr_Title.setAttribute("id", "orderid");
                        _elTh_ItmesHdr_Title.textContent = _trTbl.ui.roomservice.title.ordernum[_state.lang].toUpperCase();
                        _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Title);

                        var _elTh_ItmesHdr_Amount = document.createElement('th');
                        _elTh_ItmesHdr_Amount.setAttribute("id", "amount");
                        _elTh_ItmesHdr_Amount.textContent = _trTbl.ui.roomservice.title.amount[_state.lang].toUpperCase();
                        _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Amount);

                        var _elTh_ItmesHdr_Status = document.createElement('th');
                        _elTh_ItmesHdr_Status.setAttribute("id", "date");
                        _elTh_ItmesHdr_Status.textContent = _trTbl.ui.roomservice.title.orderdate[_state.lang].toUpperCase();
                        _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Status);

                        _elTBody_ItmesHdr.appendChild(_elTr_ItmesHdr);
                    }
                    _elTbl_ItemsHdr.appendChild(_elTBody_ItmesHdr);
                    _elRsOrderWinleft.append(_elTbl_ItemsHdr);

                    ////// Append item list record
                    var _elTbl_ItemsRec = document.createElement('table');
                    _elTbl_ItemsRec.className = "tbl_record";

                    let _elTBody_ItmesRec = document.createElement('tbody');
                    {
                        _elTBody_ItmesRec.setAttribute("id", "record");
                        for (let _j = 1; _j <= _order.orders.length; _j++) {
                            let _objChkAvail=null;
                            let _objItem = _order.orders[_j];

                            var _elTr_ItmesRec = document.createElement('tr');
                            var _elDiv_ItmesRec = document.createElement('div');
                            _elDiv_ItmesRec.className = "rsOrderedItem";
                            var _elDiv_ItmesRecID = document.createElement('div');
                            _elDiv_ItmesRecID.setAttribute("id", "orderid");
                            _elDiv_ItmesRecID.textContent = _objItem.id.toUpperCase();
                            _elDiv_ItmesRec.appendChild(_elDiv_ItmesRecID);

                            var _elDiv_ItmesRecAmount = document.createElement('div');
                            _elDiv_ItmesRecAmount.setAttribute("id", "amount");
                            _elDiv_ItmesRecAmount.textContent = _rsinfo_top.currency[_state.lang] + _objItem.amount[_state.lang].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
                            _elDiv_ItmesRec.appendChild(_elDiv_ItmesRecAmount);


                            var _elDiv_ItmesRecDate = document.createElement('div');
                            _elDiv_ItmesRecDate.setAttribute("id", "date");
                            _elDiv_ItmesRecDate.textContent = _objItem.createdAt;
                            _elDiv_ItmesRec.appendChild(_elDiv_ItmesRecDate);
                            _elTr_ItmesRec.appendChild(_elDiv_ItmesRec);
                            _elTBody_ItmesRec.appendChild(_elTr_ItmesRec);
                        }
                        _elTbl_ItemsRec.appendChild(_elTBody_ItmesRec);
                    }
                    _elRsOrderWinleft.append(_elTbl_ItemsRec);

                    var _elDiv_Summary = document.createElement('div');
                    _elDiv_Summary.className = "summary";
                    var _elDiv_Label = document.createElement('div');
                    _elDiv_Label.setAttribute("id", "label");
                    _elDiv_Label.textContent = _trTbl.ui.roomservice.title.sum[_state.lang].toUpperCase();
                    _elDiv_Summary.appendChild(_elDiv_Label);
                    var _elDiv_Value = document.createElement('div');
                    _elDiv_Value.setAttribute("id", "value");
                    _elDiv_Value.textContent = _rsinfo_top.currency[_state.lang] + _order.amount[_state.lang].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
                    _elDiv_Summary.appendChild(_elDiv_Value);
                    _elRsOrderWinleft.append(_elDiv_Summary);

                    if ( _elRsOrderRoot.css('display')=="none" ){
                        _elRsOrderRoot.fadeIn(100);
                    }
                } break;

                case "destroy": {
                    __ifxn_removeOrderElements();
                } break;
            }
        }catch(_err){
            console.log(`Fail to draw::> ${_err}`);
        }
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> Draw room service item selection cart ui
     * @param {string} _action
     * @param {function} _cbFxnExitPre RS 아이탬선택 카트 팝업 종료 처리 전에 해야할 callback
     * @param {function} _cbFxnExitPost RS 아이탬선택 카트 팝업 종료 처리 후에 수행할 callback
     */
    function __uifxn_AppFull_DrawRsItemSeletionCart(_action, _cbFxnExitPre, _cbFxnExitPost) {
        let _state = HotelTV.state;
        let _trTbl = HotelTV.translation;
        let _opening = HotelTV.opening;
        let _carts = HotelTV.carts.roomservice;
        let _order = HotelTV.orders.roomservice;
        let _rsinfo_top = _opening.roomService;
        let _rsinfo_ctgy = _rsinfo_top.menu;
        let _rsinfo_item = null;
        let _elRsPupRoot = $('.popup .roomservice');
        let _elRsCtgyBg = _elRsPupRoot.children('.bg').find('#lst_ctgbg');
        let _elRsCtgyBgFocus = _elRsCtgyBg.find('.owl-item.active.center');
        let _elRsCtgyBgMenuItemWin = _elRsCtgyBgFocus.find('.rs_item_sel_win');
        let _elRsCtgyBgMenuItemCartWin = _elRsCtgyBgFocus.find('.rs_item_sel_cart_win');
        let _elRsCtgyBgMenuItemCartWinLeft = _elRsCtgyBgMenuItemCartWin.children('.winleft');
        let _elRsCtgyBgMenuItemCartWinRight = _elRsCtgyBgMenuItemCartWin.children('.winright');
        let __status_rs_specific = null;


        /**
         * CART에 _itemID에 해당하는 항목이 있는지 검사
         * @param {object} _objCart
         * @param {string} _itemID
         * @returns
         */
        const __ifxn_checkCartItemExist = function(_objCart, _itemID) {
            for (__j = 1; __j <= _objCart.length; __j++) {
                if ( _objCart[__j].id!=null && _objCart[__j].itemId == _itemID ) {
                    return true;
                }
            }
            return false;
        }

        const __ifxn_getCartIdbyItemID = function(_objCart, _itemID) {
            for (__j = 1; __j <= _objCart.length; __j++) {
                if ( _objCart[__j].id!=null && _objCart[__j].itemId == _itemID ) {
                    return _objCart[__j].id;
                }
            }
            return null;
        }

        /**
         * order/add to cart/back중 포커스 된 버턴의 ID를 반환
         */
        const __ifxn_getFocusedBtnID = function() {
            return _elRsCtgyBgMenuItemCartWinLeft.find('.buttons').find('.focus').attr('id');
        }


        const __ifxn_removeRsSelectedItemCartWinElement = function() {
            // Remove All element under winright div
            if ( _elRsCtgyBgMenuItemCartWinLeft.children().length ){
                _elRsCtgyBgMenuItemCartWinLeft.children().remove();
            }

            if ( _elRsCtgyBgMenuItemCartWinRight.children().length ){
                _elRsCtgyBgMenuItemCartWinRight.children().remove();
            }
        }

        /**
         * 룸서비스 카트 테이블 갱신
         * @returns
         */
        const __ifxn_updateRsCartRecTable = function() {
            try{
                const __ifxn_getValidCartItemCount = function(_cartObj) {
                    let ___validCnt = 0;
                    for (let _j = 1; _j <= _cartObj.items.length; _j++) {
                        if ( _cartObj.items[_j].id ){
                            ___validCnt++;
                        }
                    }
                    return ___validCnt;
                }


                let _elRsCtgyBgMenuItemCartLstRecTbl = _elRsCtgyBgMenuItemCartWinRight.children('.cart_table').find('.tbl_record');

                if ( _elRsCtgyBgMenuItemCartLstRecTbl.length ){
                    // Remove all record under tbl_record
                    _elRsCtgyBgMenuItemCartLstRecTbl.children().remove();
                }

                if ( __ifxn_getValidCartItemCount(_carts)==0 ){
                    // 카트에 유효한 아이템이 없음. 테이블 그릴필요 없음.
                    return ;
                }

                // 카트 리스트 구성
                if ( _carts.items.length>0 )
                {
                    let _elTBody_ItmesRec = document.createElement('tbody');
                    _elTBody_ItmesRec.setAttribute("id", "record");
                    for (let _j = 1; _j <= _carts.items.length; _j++) {
                        let _objCartItem = _carts.items[_j];
                        if ( _objCartItem.id==null ){
                            continue;
                        }

                        var _elTr_CartItmesRec = document.createElement('tr');
                        var _elDiv_CartItmesRec = document.createElement('div');
                        _elDiv_CartItmesRec.className = "cartItem";
                        var _elDiv_CartItmesRecName = document.createElement('div');
                        _elDiv_CartItmesRecName.setAttribute("id", "title");
                        _elDiv_CartItmesRecName.textContent = _objCartItem.title[_state.lang];
                        _elDiv_CartItmesRec.appendChild(_elDiv_CartItmesRecName);

                        var _elDiv_CartItmesRecQuantity = document.createElement('div');
                        _elDiv_CartItmesRecQuantity.setAttribute("id", "quantity");
                        _elDiv_CartItmesRecQuantity.textContent = _objCartItem.quantity;
                        _elDiv_CartItmesRec.appendChild(_elDiv_CartItmesRecQuantity);

                        var _elDiv_CartItmesRecPrice = document.createElement('div');
                        _elDiv_CartItmesRecPrice.setAttribute("id", "amount");
                        _elDiv_CartItmesRecPrice.textContent = _rsinfo_top.currency[_state.lang] + _objCartItem.amount[_state.lang].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") ;
                        _elDiv_CartItmesRec.appendChild(_elDiv_CartItmesRecPrice);

                        _elTr_CartItmesRec.appendChild(_elDiv_CartItmesRec);
                        _elTBody_ItmesRec.appendChild(_elTr_CartItmesRec);
                    }
                    _elRsCtgyBgMenuItemCartLstRecTbl.append(_elTBody_ItmesRec);

                    // 전체 금액 갱신
                    let _elRsCtgyBgMenuItemCartTotalAmountValue = _elRsCtgyBgMenuItemCartWinRight.find('.summary').children('#value');
                    _elRsCtgyBgMenuItemCartTotalAmountValue.text(_rsinfo_top.currency[_state.lang] + _carts.amount[_state.lang].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
                }
            } catch ( _err ){
                console.log(`Fail to update::> ${_err}`);
            }
        }

        /**
         * 주어진 _item_idx 아이탬의 수량 및 금액을 갱신
         * @param {string} _item_idx
         * @param {string} _action
         */
        const __ifxn_updateRsSelectedItemCartWin = async function(_item_idx, _action) {
            let __api_resp_stock = null;
            let __selected_item_amount_quantity = 0;
            let __selected_item_amount_subTotal = 0;

            let _elDiv_QuntCtrlFrmQuantityValue = _elRsCtgyBgMenuItemCartWinLeft.children('.control').children('.quantity').find('#value_quantity');
            let _elDiv_QuntCtrlFrmAmountValue = _elRsCtgyBgMenuItemCartWinLeft.children('.control').children('.quantity').find('#value_amount');

            /**
             * cart 오브젝트에서 해당 item id에 해당하는 수량을 반환.
             * 찾지 못하면 1개(디퐅트)를 반환
             * @param {object} _object
             * @param {string} _itemID
             * @returns
             */
            const ___ifxn_getCartItemQuantity = function(_object, _itemID) {
                for (__j = 1; __j <= _object.length; __j++) {
                    if ( _object[__j].id != null ){
                        if ( _object[__j].itemId == _itemID ) {
                            return _object[__j].quantity;
                        }
                    }
                }
                return 1;
            }

            const ___ifxn_updateSubTotalAmount = async function(_itemID, _quantityNum) {
                let __api_resp = await HotelTV.api.GetRoomserviceStocks(_itemID, _quantityNum);
                if ( __api_resp==null ){
                    console.log("error");
                    __selected_item_amount_subTotal = "Error";
                } else {
                    __selected_item_amount_subTotal = _rsinfo_top.currency[_state.lang] + __api_resp['amount'][_state.lang].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
                }

                if ( _elDiv_QuntCtrlFrmAmountValue.length ){
                    _elDiv_QuntCtrlFrmAmountValue.text(__selected_item_amount_subTotal);
                }
            }

            // 개수 및 산정 로직
            // i) 현재 카트내에 해당 item id에 해당하는 개수르 구함.
            // ii) stock API로 총 비용을 산정
            if ( _action=="build" ){
                __selected_item_amount_quantity = ___ifxn_getCartItemQuantity(_carts.items, _rsinfo_item.id);
                __status_rs_specific.stock[_rsinfo_item.id] = {"req_quantity": __selected_item_amount_quantity};
                ___ifxn_updateSubTotalAmount(_rsinfo_item.id, __selected_item_amount_quantity);
            } else if ( _action=="plus" ){
                if ( __status_rs_specific.stock[_rsinfo_item.id].req_quantity<_rsinfo_item.limitation.max ){
                    __status_rs_specific.stock[_rsinfo_item.id].req_quantity += 1;
                    ___ifxn_updateSubTotalAmount(_rsinfo_item.id, __status_rs_specific.stock[_rsinfo_item.id].req_quantity);
                }
            } else if ( _action=="minus" ){
                if ( __status_rs_specific.stock[_rsinfo_item.id].req_quantity>1 ){
                    __status_rs_specific.stock[_rsinfo_item.id].req_quantity -= 1;
                    ___ifxn_updateSubTotalAmount(_rsinfo_item.id, __status_rs_specific.stock[_rsinfo_item.id].req_quantity);
                }
            }

            // 개수 및 금액 출력
            if ( _elDiv_QuntCtrlFrmQuantityValue.length ){
                _elDiv_QuntCtrlFrmQuantityValue.text(__status_rs_specific.stock[_rsinfo_item.id].req_quantity);
            }
        }

        /**
         * 룸서비스 수량 선택 및 카트 윈도우 빌드업
         * @param {number} _item_idx
         */
        const __ifxn_buildRsSelectedItemCartWin = function(_item_idx) {
            let _sz_styleOpt = null;

            const ___iCbfxn_buildRsSelectedItemWin = function() {
                // 상품 상세 설명페이지 구성
                __ifxn_removeRsSelectedItemCartWinElement();

                // Quantity Window
                {
                    //// Quantity Window Title
                    let _elDiv_QuntWinTitle = document.createElement('div');
                    _elDiv_QuntWinTitle.className = "title";
                    _elDiv_QuntWinTitle.textContent = _trTbl.ui.roomservice.title.selected_menu_quantity[_state.lang].toUpperCase();
                    _elRsCtgyBgMenuItemCartWinLeft.append(_elDiv_QuntWinTitle);

                    //// Quantity control Frame
                    var _elDiv_QuntCtrlFrm = document.createElement('div');
                    _elDiv_QuntCtrlFrm.className = "control";
                    _elDiv_QuntCtrlFrm.innerHTML = `<div id="img_thumbnail" style="background-image: url(${_rsinfo_item.thumbnail.files[_state.lang].download});"></div>`;
                    var _elDiv_QuntCtrlFrmQuantity = document.createElement('div');
                    _elDiv_QuntCtrlFrmQuantity.className = "quantity";
                    _elDiv_QuntCtrlFrmQuantity.innerHTML = `<div id="label_quantity">${_trTbl.ui.roomservice.title.quantity[_state.lang].toUpperCase()}</div>`;
                    _elDiv_QuntCtrlFrmQuantity.innerHTML += `<div id="value_quantity"></div>`;
                    _elDiv_QuntCtrlFrmQuantity.innerHTML += `<div id="label_amount">${_trTbl.ui.roomservice.title.amount[_state.lang].toUpperCase()}</div>`;
                    _elDiv_QuntCtrlFrmQuantity.innerHTML += `<div id="value_amount"></div>`;
                    _elDiv_QuntCtrlFrm.append(_elDiv_QuntCtrlFrmQuantity);
                    _elRsCtgyBgMenuItemCartWinLeft.append(_elDiv_QuntCtrlFrm);

                    //// Item description
                    var _elDiv_QuntItemDesc = document.createElement('div');
                    _elDiv_QuntItemDesc.className = "description";
                    _elDiv_QuntItemDesc.innerHTML = `<div id="title">${_rsinfo_item.title[_state.lang]}</div><div id="details">${_rsinfo_item.description[_state.lang]}</div>`;
                    _elRsCtgyBgMenuItemCartWinLeft.append(_elDiv_QuntItemDesc);

                    //// Buttons
                    var _elDiv_QuntBtnFrm = document.createElement('div');
                    _elDiv_QuntBtnFrm.className = "buttons";
                    _elDiv_QuntBtnFrm.innerHTML = `<div id="btn_ordernow">${_trTbl.ui.roomservice.title.order_now[_state.lang].toUpperCase()}</div>`;
                    _elDiv_QuntBtnFrm.innerHTML += `<div id="btn_addtocart">${_trTbl.ui.roomservice.title.add_to_cart[_state.lang].toUpperCase()}</div>`;
                    _elDiv_QuntBtnFrm.innerHTML += `<div id="btn_back">${_trTbl.ui.roomservice.title.back[_state.lang].toUpperCase()}</div>`;
                    _elRsCtgyBgMenuItemCartWinLeft.append(_elDiv_QuntBtnFrm);
                }

                // CART Window
                {
                    //// Cart Window Title
                    let _elDiv_CartWinTitle = document.createElement('div');
                    _elDiv_CartWinTitle.className = "title";
                    _elDiv_CartWinTitle.textContent = _trTbl.ui.roomservice.title.cartslist[_state.lang].toUpperCase();
                    _elRsCtgyBgMenuItemCartWinRight.append(_elDiv_CartWinTitle);

                    //// Cart item table
                    let _elDiv_CartWinTable = document.createElement('div');
                    _elDiv_CartWinTable.className = "cart_table";
                    {
                        ////// ADD Table Header
                        var _elTbl_ItemsHdr = document.createElement('table');
                        _elTbl_ItemsHdr.className = "tbl_header";

                        let _elTBody_ItmesHdr = document.createElement('tbody');
                        {
                            _elTBody_ItmesHdr.setAttribute("id", "hdr");

                            var _elTr_ItmesHdr = document.createElement('tr');
                            var _elTh_ItmesHdr_Title = document.createElement('th');
                            _elTh_ItmesHdr_Title.setAttribute("id", "title");
                            _elTh_ItmesHdr_Title.textContent = _trTbl.ui.roomservice.title.item[_state.lang].toUpperCase();
                            _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Title);

                            var _elTh_ItmesHdr_Amount = document.createElement('th');
                            _elTh_ItmesHdr_Amount.setAttribute("id", "quantity");
                            _elTh_ItmesHdr_Amount.textContent = _trTbl.ui.roomservice.title.quantity[_state.lang].toUpperCase();
                            _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Amount);

                            var _elTh_ItmesHdr_Status = document.createElement('th');
                            _elTh_ItmesHdr_Status.setAttribute("id", "amount");
                            //toUppderCase()
                            _elTh_ItmesHdr_Status.textContent = _trTbl.ui.roomservice.title.amount[_state.lang].toUpperCase();
                            _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Status);

                            _elTBody_ItmesHdr.appendChild(_elTr_ItmesHdr);
                        }
                        _elTbl_ItemsHdr.appendChild(_elTBody_ItmesHdr);
                        _elDiv_CartWinTable.appendChild(_elTbl_ItemsHdr);

                        ////// Append item list record
                        var _elTbl_ItemsRec = document.createElement('table');
                        _elTbl_ItemsRec.className = "tbl_record";
                        _elDiv_CartWinTable.appendChild(_elTbl_ItemsRec);
                    }
                    _elRsCtgyBgMenuItemCartWinRight.append(_elDiv_CartWinTable);

                    //////// update cart table record
                    __ifxn_updateRsCartRecTable();



                    //// Quantity Window Title
                    let _elDiv_CartWinSummary = document.createElement('div');
                    _elDiv_CartWinSummary.className = "summary";
                    _elDiv_CartWinSummary.innerHTML = `<div id="label">${_trTbl.ui.roomservice.title.sum[_state.lang].toUpperCase()}</div>`;
                    _elDiv_CartWinSummary.innerHTML += `<div id="value">${_rsinfo_top.currency[_state.lang] + _carts.amount[_state.lang].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}</div>`;
                    _elRsCtgyBgMenuItemCartWinRight.append(_elDiv_CartWinSummary);
                }
            }

            // 카테고리매뉴윈도우 hide -> 아이템선택 윈도우 빌드 -> 아이탬선택 윈도우 show -> 버튼 포커스(back)
            _elRsCtgyBgMenuItemWin.fadeOut(200, function() {
                ___iCbfxn_buildRsSelectedItemWin();
                _elRsCtgyBgMenuItemCartWin.fadeIn(500, function() {
                    _elRsCtgyBgMenuItemCartWinLeft.find('#btn_back').addClass('focus');
                    __ifxn_updateRsSelectedItemCartWin(_item_idx, "build");

                    // 통계 이벤트 송출
                    HotelTV.api.ReportEvent([
                        {
                            'power': true,
                            'location':{
                                'conId':_rsinfo_item.id
                            }
                        }], "indirect");
                });
            });
        }

        /**
         * 룸서비스 카트 팝업 제거 함수
         * @param {function} __cbFxn_preForExit
         * @param {function} __cbFxn_postForExit
         */
        const __ifxn_removeRsSelectedItemCartWin = function(__cbFxn_preForExit, __cbFxn_postForExit) {
            if ( __cbFxn_preForExit ){
                __cbFxn_preForExit();
            }

            _elRsCtgyBgMenuItemCartWin.fadeOut(200, function() {
                // Remove All element under winleft&winright div
                __ifxn_removeRsSelectedItemCartWinElement();

                if ( __cbFxn_postForExit ){
                    __cbFxn_postForExit();
                }
            });
        }

        /**
         * 룸서비스 상품을 쇼핑카트에 추가
         * @param {object} _rs_itemInf
         * @param {number} _new_quantity
         * @param {callback} _cbFxn_Success
         * @param {callback} _cbFxn_Failure
         */
        const __ifxn_processRsAddtoCart = async function(_rs_itemInf, _new_quantity, _cbFxn_Success, _cbFxn_Failure) {
            try {
                console.log("_new_quantity:" + _new_quantity);

                if ( __ifxn_checkCartItemExist(_carts.items, _rs_itemInf.id)==true )
                {
                    // Modify API
                    let _result = await HotelTV.api.UpdateRoomserviceCarts(__ifxn_getCartIdbyItemID(_carts.items, _rs_itemInf.id), _new_quantity);
                    if (_result) {
                        console.log(`Roomservice Update cart successed::> ${_rs_itemInf.id} ::> ${_rs_itemInf.name}`);
                        if (_cbFxn_Success) {
                            HotelTV.carts.roomservice = _carts = await HotelTV.api.GetRoomserviceCarts(null);
                            __ifxn_updateRsCartRecTable();
                            _cbFxn_Success();
                        }
                    } else {
                        console.log(`Roomservice Update cart failed::> ${_rs_itemInf.id} ::> ${_rs_itemInf.name}`);
                        if (_cbFxn_Failure) {
                            _cbFxn_Failure();
                        }
                    }
                }
                else
                {
                    // Put API
                    let _result = await HotelTV.api.PutRoomserviceCarts(_rs_itemInf.id, _new_quantity);
                    if (_result) {
                        console.log(`Roomservice Add to cart successed::> ${_rs_itemInf.id} ::> ${_rs_itemInf.name}`);
                        if (_cbFxn_Success) {
                            HotelTV.carts.roomservice = _carts = await HotelTV.api.GetRoomserviceCarts(null);
                            __ifxn_updateRsCartRecTable();
                            _cbFxn_Success();
                        }
                    } else {
                        console.log(`Roomservice Add to cart failed::> ${_rs_itemInf.id} ::> ${_rs_itemInf.name}`);
                        if (_cbFxn_Failure) {
                            _cbFxn_Failure();
                        }
                    }
                }
            } catch ( _err ){
                console.log(`Fail to call API::> ${_err}`);
                if (_cbFxn_Failure) {
                    _cbFxn_Failure();
                }
            }
        }

        /**
         * 쇼핑카트에 담겨있는 룸서비스 상품을 주문
         * @param {callback} _cbFxn_Success
         * @param {callback} _cbFxn_Failure
         */
        const __ifxn_processRsCartOrder = async function(_cbFxn_Success, _cbFxn_Failure) {
            let _elRsCtgyBgMenuItemCartWinOrderWin = $('.popup .roomservice .owl-item.active.center .rs_item_sel_order_win');

            try {
                _elRsCtgyBgMenuItemCartWin.fadeOut(200, async function() {
                    let _str_result_message = null;
                    // Remove All element under winleft&winright div
                    __ifxn_removeRsSelectedItemCartWinElement();

                    let _result = null;

                    try {
                        _result = await HotelTV.api.PutRoomserviceOrders();
                    } catch ( __err ){
                        console.log("CALL API::>" + __err);
                    } finally {
                        if ( _result !=null ) {
                            console.log(`Success to order Roomservice cart::>`);
                            _str_result_message = _trTbl.ui.roomservice.message.orderSuccess[_state.lang].replace('__MENU__', __uifxn_AppFull_getOrderMenuName(_rsinfo_ctgy));
                            _elRsCtgyBgMenuItemCartWinOrderWin.children('#message').text(_str_result_message);
                            _elRsCtgyBgMenuItemCartWinOrderWin.fadeIn(500, async function() {
                                try{
                                    HotelTV.orders.roomservice = await HotelTV.api.GetRoomserviceOrders(null);
                                    HotelTV.carts.roomservice = await HotelTV.api.GetRoomserviceCarts(null);
                                } catch (___err) {
                                    console.log("CALL API::>" + ___err)
                                } finally {
                                    setTimeout(function() {
                                        _elRsCtgyBgMenuItemCartWinOrderWin.fadeOut(300);

                                        if ( _cbFxn_Success ){
                                            _cbFxn_Success();
                                        }
                                    }, 5000);
                                }
                            });
                        }else {
                            console.log(`Fail to order Roomservice cart::>`);
                            _elRsCtgyBgMenuItemCartWinOrderWin.children('#message').text(_trTbl.ui.roomservice.message.orderFailure[_state.lang]);
                            _elRsCtgyBgMenuItemCartWinOrderWin.fadeIn(500, async function() {
                                setTimeout(function() {
                                    _elRsCtgyBgMenuItemCartWinOrderWin.fadeOut(300);

                                    if ( _cbFxn_Failure ){
                                        _cbFxn_Failure();
                                    }
                                }, 5000);
                            });
                        }
                    }
                });
            } catch ( _err ){
                console.log(`Fail to call API::> ${_err}`);
                if ( _cbFxn_Failure ){
                    _cbFxn_Failure();
                }
            }
        }


        try{
            let _objChkAvail=null;
            let _str_curBtnID = null;
            // 룸서비스 정보 오브젝트
            __status_rs_specific = _state.hotkey.mm[_rsinfo_top.button].status;
            let __rsctgyIdx = __status_rs_specific.category_sel.cur;
            let __rsctgyItemStatus = __status_rs_specific.items[_rsinfo_ctgy[__rsctgyIdx].name];

            // 선택된 룸서비스 아이템 정보 매핑
            _rsinfo_item = _rsinfo_ctgy[__status_rs_specific.category_sel.cur].items[__rsctgyItemStatus.idx+1];

            _objChkAvail = __uifxn_Utils_CheckRsItemAvailable(_rsinfo_item.schedule);
            if(_objChkAvail.result==false){
                return false;
            }

            if ( ["left","right","enter"].includes(_action) ){
                _str_curBtnID = __ifxn_getFocusedBtnID();
            }

            switch ( _action )
            {
                case "cart": {
                    __ifxn_buildRsSelectedItemCartWin(__rsctgyItemStatus.idx);
                } break;

                case "left": {
                    if ( _str_curBtnID=='btn_back' ){
                        _elRsCtgyBgMenuItemCartWinLeft.find('.buttons').find('.focus').removeClass('focus');
                        _elRsCtgyBgMenuItemCartWinLeft.find('.buttons').find('#btn_addtocart').addClass('focus');
                    } else if ( _str_curBtnID=='btn_addtocart' ){
                        if ( _elRsCtgyBgMenuItemCartWinRight.find('.tbl_record').children().length>0 ){
                            _elRsCtgyBgMenuItemCartWinLeft.find('.buttons').find('.focus').removeClass('focus');
                            _elRsCtgyBgMenuItemCartWinLeft.find('.buttons').find('#btn_ordernow').addClass('focus');
                        }
                    }
                } break;

                case "right": {
                    if ( _str_curBtnID=='btn_ordernow' ){
                        _elRsCtgyBgMenuItemCartWinLeft.find('.buttons').find('.focus').removeClass('focus');
                        _elRsCtgyBgMenuItemCartWinLeft.find('.buttons').find('#btn_addtocart').addClass('focus');
                    } else if ( _str_curBtnID=='btn_addtocart' ){
                        _elRsCtgyBgMenuItemCartWinLeft.find('.buttons').find('.focus').removeClass('focus');
                        _elRsCtgyBgMenuItemCartWinLeft.find('.buttons').find('#btn_back').addClass('focus');
                    }
                } break;

                case "quantity_plus": {
                    __ifxn_updateRsSelectedItemCartWin(__rsctgyItemStatus.idx, "plus");
                } break;

                case "quantity_minus": {
                    __ifxn_updateRsSelectedItemCartWin(__rsctgyItemStatus.idx, "minus");
                } break;

                case "cart_scroll_up": {
                    let _elDiv_RsCtgyCartRecTable = _elRsCtgyBgMenuItemCartWinRight.find('.tbl_record').children('#record');
                    if ( _elDiv_RsCtgyCartRecTable.children().length>0 ){
                        let _heightTable = _elDiv_RsCtgyCartRecTable.outerHeight(true); // passing "true" will also include the top and bottom margin
                        let _numTrHeight = _elDiv_RsCtgyCartRecTable.find('tr').first().height(); //테이블 레코드 1줄 높이
                        let _posFirstTr = _elDiv_RsCtgyCartRecTable.find('tr').first().position();
                        let _posLastTr = _elDiv_RsCtgyCartRecTable.find('tr').last().position();

                        if ( _posFirstTr.top<0 ){
                            _elDiv_RsCtgyCartRecTable.animate({ scrollTop: _posFirstTr.top-_numTrHeight}, 200);
                        }
                    }
                } break;

                case "cart_scroll_down": {
                    let _elDiv_RsCtgyCartRecTable = _elRsCtgyBgMenuItemCartWinRight.find('.tbl_record').children('#record');
                    if ( _elDiv_RsCtgyCartRecTable.children().length>0 ){
                        const ___ifxn_calScrollTopOffset = function(){
                            let neededScrollRowCnt = 1;
                            for (__kk = 0; __kk < _elDiv_RsCtgyCartRecTable.children().length; __kk++) {
                                if ( _elDiv_RsCtgyCartRecTable.children().eq(__kk).position().top>_numTrHeight ){
                                    break;
                                }
                                neededScrollRowCnt ++;
                            }
                            return neededScrollRowCnt*_numTrHeight;
                        }
                        let _heightTable = _elDiv_RsCtgyCartRecTable.outerHeight(true); // passing "true" will also include the top and bottom margin
                        let _numTrHeight = _elDiv_RsCtgyCartRecTable.find('tr').first().height(); //테이블 레코드 1줄 높이
                        let _posFirstTr = _elDiv_RsCtgyCartRecTable.find('tr').first().position();
                        let _posLastTr = _elDiv_RsCtgyCartRecTable.find('tr').last().position();

                        if ( _posLastTr.top > _heightTable ){
                            _elDiv_RsCtgyCartRecTable.animate({ scrollTop: ___ifxn_calScrollTopOffset()}, 200);
                        }
                    }
                } break;

                case "enter": {
                    if ( _str_curBtnID=='btn_ordernow' ){
                        __ifxn_processRsCartOrder(
                            function() {
                                //Return to menu
                                if ( _cbFxnExitPost ){
                                    _cbFxnExitPost();
                                }
                            },
                            function() {
                                //Return to menu
                                if ( _cbFxnExitPost ){
                                    _cbFxnExitPost();
                                }
                            }
                        )
                    } else if ( _str_curBtnID=='btn_addtocart' ){
                        //console.log("SUCCESS::>> ADD TO CART");
                        __ifxn_processRsAddtoCart(
                            _rsinfo_item,
                            __status_rs_specific.stock[_rsinfo_item.id].req_quantity,
                            function() {
                                //TODO: 카트 API호출 성공시 호출할 루틴
                            },
                            function() {
                                //TODO: 카트 API호출 실패시 호출할 루틴
                            }
                        );
                    } else if ( _str_curBtnID=='btn_back' ){
                        __ifxn_removeRsSelectedItemCartWin(_cbFxnExitPre, _cbFxnExitPost);
                    }
                } break;

                case "return": {
                    __ifxn_removeRsSelectedItemCartWin(_cbFxnExitPre, _cbFxnExitPost);
                } break;
            }

            return true;
        }catch(_err){
            console.log(`Fail to draw::> ${_err}`);
            return false;
        }
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> Draw room service item selection ui
     */
    function __uifxn_AppFull_DrawRsItemSeletion(_action) {
        let _state = HotelTV.state;
        let _trTbl = HotelTV.translation;
        let _opening = HotelTV.opening;
        let _order = HotelTV.orders.roomservice;
        let _rsinfo_top = _opening.roomService;
        let _rsinfo_ctgy = _rsinfo_top.menu;
        let _elRsPupRoot = $('.popup .roomservice');
        let _elRsCtgyBg = _elRsPupRoot.children('.bg').find('#lst_ctgbg');
        let _elRsCtgyBgFocus = _elRsCtgyBg.find('.owl-item.active.center');
        let _elRsCtgyBgMenuItemWin = _elRsCtgyBgFocus.find('.rs_item_sel_win');
        let __status_rs_specific = null;


        const __ifxn_updateRsItemDesc = function(_item_idx,_cbFxn) {
            let _sz_styleOpt = null;
            let __item_info = _rsinfo_ctgy[__status_rs_specific.category_sel.cur].items[_item_idx+1];
            // Remove All element under winright div
            let _elDivWinRight = _elRsCtgyBgMenuItemWin.find('.winright');

            const ___iCbfxn_updateRsItemDesc = function() {
                //상품 상세 설명페이지 구성
                ////썸네일
                let _elDiv_ItmesThumb = document.createElement('div');
                _elDiv_ItmesThumb.className = "rsItemDescThumb";
                //let thuri = __item_info.thumbnail.files[_state.lang].download;
                _sz_styleOpt = "background-image: url(" + __item_info.thumbnail.files[_state.lang].download + "); ";
                _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: 100% 100%; ";
                _elDiv_ItmesThumb.setAttribute("style", _sz_styleOpt);

                ////상세설명
                let _elDiv_ItmesDetails = document.createElement('div');
                _elDiv_ItmesDetails.className = "rsItemDescDetails";

                var _elDiv_ItmesTitle = document.createElement('div');
                _elDiv_ItmesTitle.setAttribute("id", "title");
                _elDiv_ItmesTitle.textContent = __item_info.title[_state.lang];

                var _elDiv_ItmesDescription = document.createElement('div');
                _elDiv_ItmesDescription.setAttribute("id", "description");
                _elDiv_ItmesDescription.textContent = __item_info.description[_state.lang];
                //_elDiv_ItmesDescription.textContent = __item_info.description[_state.lang].replace(/(?:\r\n|\r|\n)/g, '<br>');

                _elDiv_ItmesDetails.appendChild(_elDiv_ItmesTitle);
                _elDiv_ItmesDetails.appendChild(_elDiv_ItmesDescription);

                //winright에 썸네일과 상세설명 추가
                _elDivWinRight.append(_elDiv_ItmesThumb);
                _elDivWinRight.append(_elDiv_ItmesDetails);
            }

            if ( _elDivWinRight.css('display') != "none")  {
                _elDivWinRight.fadeOut(200, function() {
                    if ( _elDivWinRight.children().length ){
                        _elDivWinRight.children().remove();
                    }
                    ___iCbfxn_updateRsItemDesc();
                    _elDivWinRight.fadeIn(500, function() {
                        if ( _cbFxn ){ _cbFxn(); }
                    });
                });
            }else{
                if ( _elDivWinRight.children().length ){
                    _elDivWinRight.children().remove();
                }
                ___iCbfxn_updateRsItemDesc();

                _elDivWinRight.fadeIn(500, function() {
                    if ( _cbFxn ){ _cbFxn(); }
                });
            }
        }

        const __ifxn_removeRsItemDesc = function(_item_idx) {
            // Remove All element under winright div
            let _elDivWinRight = _elRsCtgyBgMenuItemWin.find('.winright');
            if ( _elDivWinRight.children().length ){
                _elDivWinRight.children().remove();
            }

            if ( _elDivWinRight.css('display') != "none")  {
                _elDivWinRight.fadeOut(300, function() {
                });
            }
        }

        try{
            // 룸서비스 정보 오브젝트
            _rsinfo_top = _opening.roomService;
            _rsinfo_ctgy = _rsinfo_top.menu;
            __status_rs_specific = _state.hotkey.mm[_rsinfo_top.button].status;
            let __rsctgyIdx = __status_rs_specific.category_sel.cur;
            let __rsctgyItemStatus = __status_rs_specific.items[_rsinfo_ctgy[__rsctgyIdx].name];

            switch ( _action )
            {
                case "enter": {
                    _elRsCtgyBgMenuItemWin.find('.rsctgyItem').first().addClass("focus");
                    //인덱스 및 스크롤 초기화
                    __rsctgyItemStatus.idx = 0;
                    __rsctgyItemStatus.scroll_TOfset = 0;
                    _elRsCtgyBgMenuItemWin.find('.tbl_record').children('#record').animate({ scrollTop: 0 }, 200);
                    __ifxn_updateRsItemDesc(__rsctgyItemStatus.idx);
                } break;

                case "exit": {
                    _elRsCtgyBgMenuItemWin.find('.rsctgyItem').removeClass("focus");
                    __ifxn_removeRsItemDesc();
                } break;

                case "up": {
                    let _isNeedSoldOutMask = false;
                    let _elTbl_RsItem = _elRsCtgyBgMenuItemWin.find('.tbl_record');
                    let _elTblTr_RsItemNext = _elTbl_RsItem.find('.focus').parent().prev('tr');

                    if (_elTblTr_RsItemNext.length) {
                        _elTbl_RsItem.find('.focus').removeClass("focus");
                        _elTblTr_RsItemNext.children('.rsctgyItem').addClass('focus');

                        if ( _elTblTr_RsItemNext.children('.rsctgyItem.unavailable').length ){
                            _isNeedSoldOutMask = true;
                        }

                        // 테이블 ROW인덱스와 스크롤 OFFSET계산
                        __rsctgyItemStatus.idx = _elTblTr_RsItemNext.prop('rowIndex');

                        if ( _elTbl_RsItem.children('#record').find('tr').first().position().top<0 ){
                            __rsctgyItemStatus.scroll_TOfset -= _elTblTr_RsItemNext.prop('scrollHeight');
                            //스크롤 에니메이션 수행
                            _elTbl_RsItem.children('#record').animate({ scrollTop: __rsctgyItemStatus.scroll_TOfset }, 200);
                        }

                        __ifxn_updateRsItemDesc(__rsctgyItemStatus.idx, function() {
                            if ( _isNeedSoldOutMask==true ){
                                _elRsCtgyBgMenuItemWin.find('.winright').find('.rsItemDescThumb').addClass('unavailable');
                            }else {
                                _elRsCtgyBgMenuItemWin.find('.winright').find('.rsItemDescThumb').removeClass('unavailable');
                            }
                        });
                    }
                } break;

                case "down": {
                    let _elTbl_RsItem = _elRsCtgyBgMenuItemWin.find('.tbl_record');
                    let _elTblTr_RsItemNext = _elTbl_RsItem.find('.focus').parent().next('tr');
                    let _isNeedSoldOutMask = false;

                    if (_elTblTr_RsItemNext.length) {
                        _elTbl_RsItem.find('.focus').removeClass("focus");
                        _elTblTr_RsItemNext.children('.rsctgyItem').addClass('focus');

                        if ( _elTblTr_RsItemNext.children('.rsctgyItem.unavailable').length ){
                            _isNeedSoldOutMask = true;
                        }

                        // 테이블 ROW인덱스와 스크롤 OFFSET계산
                        __rsctgyItemStatus.idx = _elTblTr_RsItemNext.prop('rowIndex');
                        if ( __rsctgyItemStatus.idx>=12 ){
                            __rsctgyItemStatus.scroll_TOfset += _elTblTr_RsItemNext.prop('scrollHeight');
                            //스크롤 에니메이션 수행
                            _elTbl_RsItem.children('#record').animate({ scrollTop: __rsctgyItemStatus.scroll_TOfset }, 200);
                        }

                        __ifxn_updateRsItemDesc(__rsctgyItemStatus.idx, function() {
                            if ( _isNeedSoldOutMask==true ){
                                _elRsCtgyBgMenuItemWin.find('.winright').find('.rsItemDescThumb').addClass('unavailable');
                            }else {
                                _elRsCtgyBgMenuItemWin.find('.winright').find('.rsItemDescThumb').removeClass('unavailable');
                            }
                        });
                    }
                } break;
            }
        } catch (_err){
            console.log(`Fail to draw::> ${_err}`);
        }
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> build room service service
     */
    function __uifxn_AppFull_BuildRoomservice() {
        let _state = HotelTV.state;
        let __status_rs_specific = null;
        let _trTbl = HotelTV.translation;
        let _opening = HotelTV.opening;
        let _order = HotelTV.orders.roomservice;
        let _rsinfo_top = null;
        let _rsinfo_ctgy = null;
        let _elMainRoot = $('.main');
        let _elMainMenu = _elMainRoot.children('.mm');
        let _elRsPupRoot = $('.popup .roomservice');
        let _elRsCtgyBg = _elRsPupRoot.children('.bg').find('#lst_ctgbg');
        let _elRsCtgySel = _elRsPupRoot.children('.slider').find('#lst_ctgsel');
        let _elRsUGRoot = _elRsPupRoot.children('.use_guide');


        const __ifxn_clrearRsCarts = async function() {
            try {
                await HotelTV.api.DeleteRoomserviceCarts(null);
                HotelTV.carts.roomservice = await HotelTV.api.GetRoomserviceCarts(null);
            } catch ( __err ){
                console.log("CALL API::>" + __err);
            }
        }


        // 룸서비스 인포 Validation
        if (!_opening.roomService) {
            return;
        }

        // 룸서비스 정보 오브젝트
        _rsinfo_top = _opening.roomService;
        _rsinfo_ctgy = _rsinfo_top.menu;


        __status_rs_specific = _state.hotkey.mm[_rsinfo_top.button].status;



        // 초기 메인 메뉴 KEY설정
        _state.menu.stage.cur = "preparing_roomservice";
        _elRsUGRoot.hide();

        // 룸서비스 팝업 카테고리 셀렉터 노드를 동적으로 구성
        for (let _idx = 1; _idx <= _rsinfo_ctgy.length; _idx++) {
            let _elDiv_Ctgy = document.createElement('div');
            _elDiv_Ctgy.className = 'item';
            _elDiv_Ctgy.id = _rsinfo_ctgy[_idx].id;
            _elDiv_Ctgy.setAttribute("rs_ctgy_id", _idx);

            // Append Category elements::title
            let _elDiv_CtgyTitle = document.createElement('div');
            _elDiv_CtgyTitle.setAttribute("id", "rs_item_title");

            if (_rsinfo_ctgy[_idx].showTitle && _rsinfo_ctgy[_idx].showTitle == true) {
                _elDiv_CtgyTitle.textContent = _rsinfo_ctgy[_idx].title[_state.lang];
            }

            // Append Category elements::btn
            let _elDiv_CtgyBtn = document.createElement('div');
            _elDiv_CtgyBtn.setAttribute("id", "ctgy_item_btn");
            let _sz_styleOpt = "--icon_unfocus: url(" + _rsinfo_ctgy[_idx].unfocusIcon.file.download + "); ";
            _sz_styleOpt += "--icon_focus: url(" + _rsinfo_ctgy[_idx].focusIcon.file.download + "); ";
            //_sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom; background-size: 100% 100%; ";
            _sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom;";
            _elDiv_CtgyBtn.setAttribute("style", _sz_styleOpt);

            _elDiv_Ctgy.appendChild(_elDiv_CtgyBtn);
            _elDiv_Ctgy.appendChild(_elDiv_CtgyTitle);

            _elRsCtgySel.append(_elDiv_Ctgy);

            // 각 카테고리별 아이템 스크롤위치등을 관리하기 위하여 status맴버 초기화 및 구성
            if ( !(_rsinfo_ctgy[_idx].name in __status_rs_specific.items)==true ){
                __status_rs_specific.items[_rsinfo_ctgy[_idx].name] = {
                    "idx": 0,
                    "scroll_TOfset": 0,
                    "carts": {
                        "idx": 0,
                        "scroll_TOfset": 0
                    }
                };
            }
        }

        // 룸서비스 팝업 카테고리 백그라운드 이미지 노드를 동적으로 구성
        for (let _idx = 1; _idx <= _rsinfo_ctgy.length; _idx++) {
            let _objRs_ctgyItem = _rsinfo_ctgy[_idx].items;
            let _sz_styleOpt = null;
            let _elDiv_Ctgy = document.createElement('div');

            _elDiv_Ctgy.className = 'item';
            _elDiv_Ctgy.id = _rsinfo_ctgy[_idx].id;
            _elDiv_Ctgy.setAttribute("rs_ctgy_id", _idx);
            _sz_styleOpt = "background-image: url(" + _rsinfo_ctgy[_idx].background.file.download + "); ";
            _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: 100% 100%; ";
            _elDiv_Ctgy.setAttribute("style", _sz_styleOpt);

            // TOP 그라데이션
            let _elDiv_CtgyGradientTop = document.createElement('div');
            _elDiv_CtgyGradientTop.className = 'top_gradient';

            _elDiv_Ctgy.appendChild(_elDiv_CtgyGradientTop);

            // BOTTOM 그라데이션
            let _elDiv_CtgyGradientBottom = document.createElement('div');
            _elDiv_CtgyGradientBottom.className = 'bottom_gradient';

            _elDiv_Ctgy.appendChild(_elDiv_CtgyGradientBottom);

            // ITEM LIST TOP-LEVEL ELEMENTS
            //// ITEM SELECTION WINDOW
            let _elDiv_ItemSelWin = document.createElement('div');
            _elDiv_ItemSelWin.className = 'rs_item_sel_win';
            {
                ////// Window Left side
                let _elDiv_ItemWinLeft = document.createElement('div');
                _elDiv_ItemWinLeft.className = 'winleft';

                if ( ["ORDER", "CARTS"].includes(_rsinfo_ctgy[_idx].name)==true )
                {
                    _elDiv_ItemWinLeft.classList.add(_rsinfo_ctgy[_idx].name.toLowerCase());
                    _elDiv_ItemWinLeft.style.display = 'none';
                }
                else
                {
                    ////// ADD Table Header
                    var _elTbl_ItemsHdr = document.createElement('table');
                    _elTbl_ItemsHdr.className = "tbl_header";

                    let _elTBody_ItmesHdr = document.createElement('tbody');
                    {
                        _elTBody_ItmesHdr.setAttribute("id", "hdr");

                        var _elTr_ItmesHdr = document.createElement('tr');
                        var _elTh_ItmesHdr_Title = document.createElement('th');
                        _elTh_ItmesHdr_Title.setAttribute("id", "title");
                        _elTh_ItmesHdr_Title.textContent = _trTbl.ui.roomservice.title.item[_state.lang].toUpperCase();
                        _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Title);

                        var _elTh_ItmesHdr_Amount = document.createElement('th');
                        _elTh_ItmesHdr_Amount.setAttribute("id", "price");
                        _elTh_ItmesHdr_Amount.textContent = _trTbl.ui.roomservice.title.amount[_state.lang].toUpperCase();
                        _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Amount);

                        var _elTh_ItmesHdr_Status = document.createElement('th');
                        _elTh_ItmesHdr_Status.setAttribute("id", "status");
                        _elTh_ItmesHdr_Status.textContent = _trTbl.ui.roomservice.title.orderability[_state.lang].toUpperCase();
                        _elTr_ItmesHdr.appendChild(_elTh_ItmesHdr_Status);

                        _elTBody_ItmesHdr.appendChild(_elTr_ItmesHdr);
                    }
                    _elTbl_ItemsHdr.appendChild(_elTBody_ItmesHdr);
                    _elDiv_ItemWinLeft.appendChild(_elTbl_ItemsHdr);

                    ////// Append item list record
                    var _elTbl_ItemsRec = document.createElement('table');
                    _elTbl_ItemsRec.className = "tbl_record";

                    let _elTBody_ItmesRec = document.createElement('tbody');
                    {
                        _elTBody_ItmesRec.setAttribute("id", "record");
                        for (let _j = 1; _j <= _objRs_ctgyItem.length; _j++) {
                            let _objChkAvail=null;
                            let _objItem = _objRs_ctgyItem[_j];

                            var _elTr_ItmesRec = document.createElement('tr');
                            var _elDiv_ItmesRec = document.createElement('div');
                            _elDiv_ItmesRec.className = "rsctgyItem";
                            var _elDiv_ItmesRecName = document.createElement('div');
                            _elDiv_ItmesRecName.setAttribute("id", "title");
                            _elDiv_ItmesRecName.textContent = _objItem.title[_state.lang];
                            _elDiv_ItmesRec.appendChild(_elDiv_ItmesRecName);

                            var _elDiv_ItmesRecPrice = document.createElement('div');
                            _elDiv_ItmesRecPrice.setAttribute("id", "price");
                            _elDiv_ItmesRecPrice.textContent = _rsinfo_top.currency[_state.lang] + _objItem.price[_state.lang].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
                            _elDiv_ItmesRec.appendChild(_elDiv_ItmesRecPrice);


                            var _elDiv_ItmesRecStatus = document.createElement('div');
                            _elDiv_ItmesRecStatus.setAttribute("id", "status");

                            _objChkAvail = __uifxn_Utils_CheckRsItemAvailable(_objItem.schedule);
                            if(_objChkAvail.result==true){
                                _elDiv_ItmesRecStatus.textContent = _trTbl.ui.roomservice.title.orderable[_state.lang];
                            }else{
                                _elDiv_ItmesRec.classList.add("unavailable");
                                if ( _objChkAvail.avail_dtime=="unorderable" ){
                                    _elDiv_ItmesRecStatus.textContent = _trTbl.ui.roomservice.title.unorderable[_state.lang];
                                }else{
                                    _elDiv_ItmesRecStatus.textContent = _objChkAvail.avail_dtime;
                                }
                            }
                            _elDiv_ItmesRec.appendChild(_elDiv_ItmesRecStatus);
                            _elTr_ItmesRec.appendChild(_elDiv_ItmesRec);
                            _elTBody_ItmesRec.appendChild(_elTr_ItmesRec);
                        }
                        _elTbl_ItemsRec.appendChild(_elTBody_ItmesRec);
                    }
                    _elDiv_ItemWinLeft.appendChild(_elTbl_ItemsRec);
                }
                _elDiv_ItemSelWin.appendChild(_elDiv_ItemWinLeft);

                ////// Window Right side
                let _elDiv_ItemWinRight = document.createElement('div');
                _elDiv_ItemWinRight.className = 'winright';

                _elDiv_ItemSelWin.appendChild(_elDiv_ItemWinRight);
            }
            // _elDiv_Ctgy에 추가
            _elDiv_Ctgy.appendChild(_elDiv_ItemSelWin);

            // Selected Item Cart Window
            let _elDiv_SelectedItemCartWin = document.createElement('div');
            _elDiv_SelectedItemCartWin.className = 'rs_item_sel_cart_win';
            _elDiv_SelectedItemCartWin.style.display = 'none';
            {
                if ( ["ORDER", "CARTS"].includes(_rsinfo_ctgy[_idx].name)==false )
                {
                    ////// Window Left side
                    let _elDiv_ItemWinCartLeft = document.createElement('div');
                    _elDiv_ItemWinCartLeft.className = 'winleft';
                    _elDiv_SelectedItemCartWin.appendChild(_elDiv_ItemWinCartLeft);

                    ////// Window Right side
                    let _elDiv_ItemWinCartRight = document.createElement('div');
                    _elDiv_ItemWinCartRight.className = 'winright';

                    _elDiv_SelectedItemCartWin.appendChild(_elDiv_ItemWinCartRight);
                }
            }
            // _elDiv_Ctgy에 추가
            _elDiv_Ctgy.appendChild(_elDiv_SelectedItemCartWin);


            // Selected Item Cart Window
            let _elDiv_SelectedItemOrderWin = document.createElement('div');
            _elDiv_SelectedItemOrderWin.className = 'rs_item_sel_order_win';
            _elDiv_SelectedItemOrderWin.innerHTML += `<div id="message"></div>`;
            _elDiv_SelectedItemOrderWin.style.display = 'none';
            // _elDiv_Ctgy에 추가
            _elDiv_Ctgy.appendChild(_elDiv_SelectedItemOrderWin);

            // _elRsCtgyBg에 추가
            _elRsCtgyBg.append(_elDiv_Ctgy);
        }

        // popup:roomservice 프레임 활성화
        if ( _elRsPupRoot.css('display') == "none")  {
            _elRsPupRoot.show();
        }

        _elRsCtgyBg.owlCarousel({
            center: true,
            items: 1, //Number of Items on Screen what you want
            loop: true,
            rewind: false,
            checkVisible: false,
            animateOut: 'fadeOut',
            animateIn: 'fadeIn',
            margin: 0,
            smartSpeed: 1000,
            lazyLoad: true,
            mouseDrag: false,
            touchDrag: false,
            pullDrag: false,
            freeDrag: false,
            dots: false,
            startPosition: (Number(__status_rs_specific.category_sel.cur) - 1),
        });
        // _elRsPupRoot.children('.bg').fadeIn(1000, function() {
        //     __uifxn_AppFull_HotKey_ShowBtnOnMM(false);
        //     __uifxn_AppFull_TopWidjetShow(false);
        // });

        _elRsCtgySel.owlCarousel({
            center: true,
            items: 5, //Number of Items on Screen what you want
            loop: true,
            rewind: false,
            checkVisible: false,
            margin: 0,
            smartSpeed: 0,
            autoWidth: false,
            mouseDrag: false,
            touchDrag: false,
            pullDrag: false,
            freeDrag: false,
            dots: true,
            startPosition: (Number(__status_rs_specific.category_sel.cur) - 1),
        });

        //메인 페이지->룸서비스 페이지 화면 전환
        _elMainRoot.fadeOut(500, function() {
            __uifxn_AppFull_HotKey_ShowBtnOnMM(false);
            __uifxn_AppFull_TopWidjetShow(false);
            _elRsPupRoot.children('.slider').fadeIn(300, function() {
                _elRsPupRoot.children('.bg').fadeIn(500, function() {
                    _elRsCtgySel.find('.owl-item').addClass('unfocus');
                    _elRsCtgySel.trigger("to.owl.carousel", [(Number(__status_rs_specific.category_sel.cur) - 1), 10, true]);
                    _elRsCtgySel.trigger('translate.owl.carousel', [0, 500, true]);

                    $(document.activeElement).keydown(function(event) { //attach event listener
                        if (_state.menu.stage.cur == "roomservice_ctgy_sel") {
                            if (event.keyCode == gRmtKey.left) {
                                _elRsCtgySel.trigger('prev.owl', [700]);
                            } else if (event.keyCode == gRmtKey.right) {
                                _elRsCtgySel.trigger('next.owl', [700]);
                            } else if (event.keyCode == gRmtKey.enter) {
                                // 카테고리 화면 빌드 및 화면 전환
                                if ( __status_rs_specific.category_sel.cur in Object.keys(_rsinfo_ctgy) ){
                                    if ( _rsinfo_ctgy[__status_rs_specific.category_sel.cur].name == "CARTS" ){
                                        console.log("TODO::> NOTIFY cannot enter item sel on CARTS");
                                    }else if ( _rsinfo_ctgy[__status_rs_specific.category_sel.cur].name == "ORDER" ){
                                        let __str_notify_msg = _trTbl.ui.roomservice.message.invalidCategory[_state.lang].replace('__MENU__', __uifxn_AppFull_getOrderMenuName(_rsinfo_ctgy));
                                        HotelTV.ui_utils.ShowNotificationMsgBalloon(__str_notify_msg, 5);
                                    }else{
                                        _state.menu.stage.cur = "roomservice_ctgy_item_sel";
                                        __uifxn_AppFull_DrawRsUserGuide("roomservice_ctgy_item_sel");
                                        __uifxn_AppFull_DrawRsItemSeletion("enter");
                                    }
                                }
                            } else if (event.keyCode == gRmtKey.back) {
                                __uifxn_AppFull_DrawRsOrderList('hide');

                                // 카테고리 폼의 썸네일 에니메이션용 타이머 제거
                                if (_hndl_tmrRoomserviceThumbAni != null) {
                                    clearInterval(_hndl_tmrRoomserviceThumbAni);
                                    _hndl_tmrRoomserviceThumbAni = null;
                                    console.log("TMR(ROOMSERVICE CATEGORY CTZ ANI For Thumbnail)::>Destoried...");
                                }
                                //카트 비움 및 사용자 가이드 지움.
                                __ifxn_clrearRsCarts();
                                __uifxn_AppFull_DrawRsUserGuide("destroy");

                                // 룸서비스 -> 메인 메뉴로 귀환
                                $(document.activeElement).off('keydown');
                                _elMainMenu.show(function() {
                                    $('#lst_mmsel').trigger('translate.owl.carousel', [0]);
                                });

                                _elRsCtgySel.off('refresh.owl.carousel');
                                _elRsCtgySel.off('change.owl.carousel');
                                _elRsCtgySel.off('changed.owl.carousel');
                                _elRsCtgySel.off('translate.owl.carousel');

                                _elRsCtgyBg.owlCarousel('destroy');
                                _elRsCtgySel.owlCarousel('destroy');

                                _elRsCtgySel.children('div').remove();
                                _elRsCtgyBg.children('div').remove();
                                _elRsPupRoot.children('.bg').hide();
                                _elRsPupRoot.children('.slider').hide();

                                setTimeout(function() {
                                    $('.main').fadeIn(1000, () => {
                                        _state.menu.stage.cur = "main";
                                        __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
                                        __uifxn_AppFull_TopWidjetShow(true);
                                        _state.menu.stage.prev = null;
                                    });
                                }, 500);
                            }
                        } else if (_state.menu.stage.cur == "roomservice_ctgy_orderlists") {
                            if (event.keyCode == gRmtKey.left) {
                                _elRsCtgySel.trigger('prev.owl', [700]);
                            } else if (event.keyCode == gRmtKey.right) {
                                _elRsCtgySel.trigger('next.owl', [700]);
                            } else if (event.keyCode == gRmtKey.enter) {
                                let __str_notify_msg = _trTbl.ui.roomservice.message.invalidCategory[_state.lang].replace('__MENU__', __uifxn_AppFull_getOrderMenuName(_rsinfo_ctgy));
                                HotelTV.ui_utils.ShowNotificationMsgBalloon(__str_notify_msg, 5);
                            } else if (event.keyCode == gRmtKey.back) {
                                __uifxn_AppFull_DrawRsOrderList('hide');

                                // 카테고리 폼의 썸네일 에니메이션용 타이머 제거
                                if (_hndl_tmrRoomserviceThumbAni != null) {
                                    clearInterval(_hndl_tmrRoomserviceThumbAni);
                                    _hndl_tmrRoomserviceThumbAni = null;
                                    console.log("TMR(ROOMSERVICE CATEGORY CTZ ANI For Thumbnail)::>Destoried...");
                                }
                                //카트 비움 및 사용자 가이드 지움.
                                __ifxn_clrearRsCarts();
                                __uifxn_AppFull_DrawRsUserGuide("destroy");

                                // 룸서비스 -> 메인 메뉴로 귀환
                                $(document.activeElement).off('keydown');
                                _elMainMenu.show(function() {
                                    $('#lst_mmsel').trigger('translate.owl.carousel', [0]);
                                });

                                _elRsCtgySel.off('refresh.owl.carousel');
                                _elRsCtgySel.off('change.owl.carousel');
                                _elRsCtgySel.off('changed.owl.carousel');
                                _elRsCtgySel.off('translate.owl.carousel');

                                _elRsCtgyBg.owlCarousel('destroy');
                                _elRsCtgySel.owlCarousel('destroy');

                                _elRsCtgySel.children('div').remove();
                                _elRsCtgyBg.children('div').remove();
                                _elRsPupRoot.children('.bg').hide();
                                _elRsPupRoot.children('.slider').hide();

                                setTimeout(function() {
                                    $('.main').fadeIn(1000, () => {
                                        _state.menu.stage.cur = "main";
                                        __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
                                        __uifxn_AppFull_TopWidjetShow(true);
                                        _state.menu.stage.prev = null;
                                    });
                                }, 500);
                            }
                        } else if (_state.menu.stage.cur == "roomservice_ctgy_item_sel") {
                            if (event.keyCode == gRmtKey.left) {
                                __uifxn_AppFull_DrawRsItemSeletion("plus");
                            } else if (event.keyCode == gRmtKey.right) {
                                __uifxn_AppFull_DrawRsItemSeletion("minus");
                            } else if (event.keyCode == gRmtKey.up) {
                                __uifxn_AppFull_DrawRsItemSeletion("up");
                            } else if (event.keyCode == gRmtKey.down) {
                                __uifxn_AppFull_DrawRsItemSeletion("down");
                            } else if (event.keyCode == gRmtKey.back) {
                                __uifxn_AppFull_DrawRsItemSeletion("exit");
                                _state.menu.stage.cur = "roomservice_ctgy_sel";
                                __uifxn_AppFull_DrawRsUserGuide("roomservice_ctgy_sel");
                            } else if (event.keyCode == gRmtKey.enter) {
                                console.log('ROOMSERVICE CATEGORY ITEM SEL: KEY::> ' + event.keyCode);
                                if ( __uifxn_AppFull_DrawRsItemSeletionCart("cart", null, null)==true ){
                                    _state.menu.stage.cur = "roomservice_ctgy_item_cart";
                                    __uifxn_AppFull_DrawRsUserGuide("roomservice_ctgy_item_cart");
                                } else {
                                    HotelTV.ui_utils.ShowNotificationMsgBalloon(_trTbl.ui.roomservice.message.notinservice[_state.lang], 5);
                                }
                            }
                        } else if (_state.menu.stage.cur == "roomservice_ctgy_item_cart") {
                            if (event.keyCode == gRmtKey.left) {
                                __uifxn_AppFull_DrawRsItemSeletionCart("left", null, null);
                            } else if (event.keyCode == gRmtKey.right) {
                                __uifxn_AppFull_DrawRsItemSeletionCart("right", null, null);
                            } else if (event.keyCode == gRmtKey.up) {
                                __uifxn_AppFull_DrawRsItemSeletionCart("quantity_plus", null, null);
                            } else if (event.keyCode == gRmtKey.down) {
                                __uifxn_AppFull_DrawRsItemSeletionCart("quantity_minus", null, null);
                            } else if (event.keyCode == gRmtKey.chup) {
                                __uifxn_AppFull_DrawRsItemSeletionCart("cart_scroll_up", null, null);
                            } else if (event.keyCode == gRmtKey.chdown) {
                                __uifxn_AppFull_DrawRsItemSeletionCart("cart_scroll_down", null, null);
                            } else if (event.keyCode == gRmtKey.back) {
                                __uifxn_AppFull_DrawRsItemSeletionCart(
                                    "return",
                                    null,
                                    function() {
                                        let _elRsCtgyBgFocusedItemSelWin = _elRsCtgyBg.find('.owl-item.active.center').find('.rs_item_sel_win');
                                        if ( _elRsCtgyBgFocusedItemSelWin.css('display') == "none")  {
                                            _elRsCtgyBgFocusedItemSelWin.fadeIn(500, function() {
                                                _state.menu.stage.cur = "roomservice_ctgy_item_sel";
                                                __uifxn_AppFull_DrawRsUserGuide("roomservice_ctgy_item_sel");
                                            });
                                        }
                                    }
                                );
                            } else if (event.keyCode == gRmtKey.enter) {
                                __uifxn_AppFull_DrawRsItemSeletionCart(
                                    "enter",
                                    null,
                                    function() {
                                        let _elRsCtgyBgFocusedItemSelWin = _elRsCtgyBg.find('.owl-item.active.center').find('.rs_item_sel_win');
                                        if ( _elRsCtgyBgFocusedItemSelWin.css('display') == "none")  {
                                            _elRsCtgyBgFocusedItemSelWin.fadeIn(500, function() {
                                                _state.menu.stage.cur = "roomservice_ctgy_item_sel";
                                                __uifxn_AppFull_DrawRsUserGuide("roomservice_ctgy_item_sel");
                                            });
                                        }
                                    }
                                );
                                console.log('ROOMSERVICE CATEGORY ITEM SEL: KEY::> ' + event.keyCode);
                            }
                        } else {
                            console.log("ROOMSERVICE SLIDER KEYEVT: Skip events");
                        }
                    });
                    //룸서비스 카테고리 선택 모드(생성시, 메뉴모드)
                    _state.menu.stage.cur = "roomservice_ctgy_sel";
                    __uifxn_AppFull_DrawRsUserGuide("roomservice_ctgy_sel");
                });
            })
        });

        _elRsCtgySel.on('change.owl.carousel', function(event) {
            // Update HotelTV Roomservice menu sel status
            __status_rs_specific.category_sel.prev = Object.keys(_rsinfo_ctgy)[event.page.index];
        });

        _elRsCtgySel.on('destroy.owl.carousel', function(event) {
            console.log("ROOMSERVICE MM SEL destroied::>" );
        });

        _elRsCtgySel.on('changed.owl.carousel', function(event) {
            // Update HotelTV Roomservice menu sel status
            __status_rs_specific.category_sel.cur = Object.keys(_rsinfo_ctgy)[event.page.index];
            //console.log("ROOMSERVICE CATEGORY EVT IDX::>" + event.page.index);
            console.log("ROOMSERVICE CATEGORY SEL IDX::>" + __status_rs_specific.category_sel.cur);
            if ( __status_rs_specific.category_sel.cur in Object.keys(_rsinfo_ctgy) ){
                if ( _rsinfo_ctgy[__status_rs_specific.category_sel.cur].name == "CARTS" ){
                    console.log("TODO::> Draw Carts");
                }else if ( _rsinfo_ctgy[__status_rs_specific.category_sel.cur].name == "ORDER" ){
                    __uifxn_AppFull_DrawRsOrderList('build');
                    _state.menu.stage.prev = _state.menu.stage.cur;
                    _state.menu.stage.cur = "roomservice_ctgy_orderlists";
                }else{
                    __uifxn_AppFull_DrawRsOrderList('hide');
                    if ( _state.menu.stage.prev!=null ){
                        if ( _state.menu.stage.prev=="preparing_roomservice" ){
                            _state.menu.stage.prev="roomservice_ctgy_sel";
                        }
                        _state.menu.stage.cur = _state.menu.stage.prev;
                    }
                }
            }
            _elRsCtgyBg.trigger("to.owl.carousel", [event.page.index, 1000]);
        });

        _elRsCtgySel.on('translate.owl.carousel', function(event) {
            // 메뉴 셀렉터 좌/우 헨들링 및 이펙트
            let _uiCtrl_idx = 0;
            if (typeof event.item != 'undefined') {
                _uiCtrl_idx = event.item.index;
            } else {
                _uiCtrl_idx = _elRsCtgySel.find('.owl-item.active.center').index();
            }
            console.log("ROOMSERVICE CATEGORY CTRL IDX::>" + _uiCtrl_idx);
            _elRsCtgySel.find('.owl-item.focus').addClass('unfocus');
            _elRsCtgySel.find('.owl-item.focus').removeClass('focus');
            _elRsCtgySel.find('.owl-item').eq(_uiCtrl_idx).addClass('focus');
            _elRsCtgySel.find('.owl-item').eq(_uiCtrl_idx).removeClass('unfocus');
        });
        return;
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> refresh news
     */
    function __uifxn_AppFull_RefreshNews(_tmDelay) {
        let _hndlNewsTicker = $('.news>.newsctz #hoteltv-news-ticker');

        const __ifxn_refreshNewsTicker = function(_timeDelay=2000){
            _hndlNewsTicker.webTicker('stop');
            _hndlNewsTicker.children().remove();
            setTimeout(__uifxn_AppFull_BuildNews, _timeDelay);
        }

        try {
            __ifxn_refreshNewsTicker( _tmDelay );
        } catch ( _err ){
            console.error(`Fail to update::> ${_err}`);
        }
    }


    /**
     * HotelTV UI[AppFull] Wrapper Function::> build news
     */
    function __uifxn_AppFull_BuildNews() {
        let _state = HotelTV.state;
        let _newsInfo = HotelTV.news;

        if (!(_newsInfo) || _newsInfo.length == 0) {
            $('.news').hide();
        } else {
            let _hndlNewsTicker = $('.news>.newsctz #hoteltv-news-ticker');
            if (_hndlNewsTicker.children().length == 0) {
                let sz_li_news = "";
                for (let _nwsIdx = 1; _nwsIdx <= _newsInfo.length; _nwsIdx++) {
                    if (_newsInfo[_nwsIdx].logo.download != "") {
                        if (_newsInfo[_nwsIdx].multilanguage == true) {
                            sz_li_news += `<li data-update=item${_nwsIdx}><img src=" ${_newsInfo[_nwsIdx].logo.download}"/>${_newsInfo[_nwsIdx].content[_state.lang]}</li>`;
                        } else {
                            sz_li_news += `<li data-update=item${_nwsIdx}><img src=" ${_newsInfo[_nwsIdx].logo.download}"/>${_newsInfo[_nwsIdx].content.default}</li>`;
                        }
                    } else {
                        if (_newsInfo[_nwsIdx].multilanguage == true) {
                            sz_li_news += `<li data-update=item${_nwsIdx}>${_newsInfo[_nwsIdx].content[_state.lang]}</li>`;
                        } else {
                            sz_li_news += `<li data-update=item${_nwsIdx}>${_newsInfo[_nwsIdx].content.default}</li>`;
                        }
                    }
                }
                _hndlNewsTicker.html(sz_li_news);
                _hndlNewsTicker.webTicker({
                    height: '26px',
                    speed: 100
                });
                _hndlNewsTicker.webTicker('update');
            } else {
                let sz_li_news = "";
                for (let _nwsIdx = 1; _nwsIdx <= _newsInfo.length; _nwsIdx++) {
                    if (_newsInfo[_nwsIdx].logo.download != "") {
                        if (_newsInfo[_nwsIdx].multilanguage == true) {
                            sz_li_news += `<li data-update=item${_nwsIdx}><img src=" ${_newsInfo[_nwsIdx].logo.download}"/>${_newsInfo[_nwsIdx].content[_state.lang]}</li>`;
                        } else {
                            sz_li_news += `<li data-update=item${_nwsIdx}><img src=" ${_newsInfo[_nwsIdx].logo.download}"/>${_newsInfo[_nwsIdx].content.default}</li>`;
                        }
                    } else {
                        if (_newsInfo[_nwsIdx].multilanguage == true) {
                            sz_li_news += `<li data-update=item${_nwsIdx}>${_newsInfo[_nwsIdx].content[_state.lang]}</li>`;
                        } else {
                            sz_li_news += `<li data-update=item${_nwsIdx}>${_newsInfo[_nwsIdx].content.default}</li>`;
                        }
                    }
                }
                $(".news>.newsctz #hoteltv-news-ticker").webTicker('update', sz_li_news,
                    'swap',
                    true,
                    false
                );
            }
        }
    }




    /**
     * HotelTV UI[AppFull] Wrapper Function::> received event handling function
     * @param {object} _evt event
     */
    function __uifxn_AppFull_OnKeyDnEvt_SmSel(_evt) {
        let _state = HotelTV.state;
        let _sminfo = HotelTV.tvguide.program[_state.menu.main.cur].children;
        //console.log(`Evnt: ${_evt.item.index} Of ${_evt.item.count} page::> ${_evt.page.index} of ${_evt.page.count}`);

        $('#lst_smbg').trigger("to.owl.carousel", [_evt.page.index, 1000, true]);
    }



    /**
     * Return tv cagegory id by name
     * @param {string} _ctgy_name
     * @returns
     */
    function __uifxn_AppFull_TVCtgyIdByName(_ctgy_name="all") {
        let _program = HotelTV.tvguide.program;
        let _tvCtgyInfoAll = null;

        for ( let _i=1; _i<=_program.length; _i++ ){
            if ( _program[_i].type=="tv" ){
                _tvCtgyInfoAll = _program[_i].categories;
                break;
            }
        }

        if ( _tvCtgyInfoAll==null ){
            // ALL채널의 디폴트 인덱스번호는 1이라고 간주
            return 1;
        }

        for (let _ctgyidx = 1; _ctgyidx <= _tvCtgyInfoAll.length; _ctgyidx++) {
            if ( _tvCtgyInfoAll[_ctgyidx].name==_ctgy_name ){
                return _ctgyidx;
            }
        }
        // ALL채널의 디폴트 인덱스번호는 1이라고 간주
        return 1;
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> Get EPG Info by channel name
     * @param {string} _ch_name channel name
     */
    function __uifxn_AppFull_TVEpgByChName(_ch_name) {
        let _tm_cur = new Date();
        try {
            //
            let _epgInfo = HotelTV.epg;

            if (_epgInfo == 'undefined' || _epgInfo == null) {
                return { "tm_cur": _tm_cur, "epg_info": null};
            }

            if (Object.keys(_epgInfo).includes('schedules') != true || Object.keys(_epgInfo).includes('channels') != true) {
                return { "tm_cur": _tm_cur, "epg_info": null};
            }

            //Find out epg schedule id
            let _epg_schId = null;
            for (let _j = 0; _j < _epgInfo.channels.length; _j++) {
                if (_epgInfo.channels[_j].name == _ch_name) {
                    _epg_schId = _epgInfo.channels[_j].id;
                    break;
                }
            }

            // EPG SHEDULE ID를 찾을 수 없으므로, null 반환.
            if (_epg_schId == null) { return { "tm_cur": _tm_cur, "epg_info": null}; }

            let _epg_prom_info = null;
            if (Object.keys(_epgInfo.schedules).includes(_epg_schId) != true) {
                return { "tm_cur": _tm_cur, "epg_info": null};
            }
            _epg_prom_info = _epgInfo.schedules[_epg_schId];

            let _rtn_epg = null;
            for (_j=0; _j<_epg_prom_info.length; _j++) {
                let _schTmNext = new Date();
                let _schTmCur = new Date();
                let _epgProgInf_Cur = _epg_prom_info[_j];
                let _epgProgInf_Next = null;

                if (_epgProgInf_Cur.time.length != 5) {
                    console.log("EPG Schedule org time is NULL");
                } else {
                    let __str_playingTime = null;

                    _schTmCur.setHours(Number(_epgProgInf_Cur.time.charAt(0) + _epgProgInf_Cur.time.charAt(1)));
                    _schTmCur.setMinutes(Number(_epgProgInf_Cur.time.charAt(3) + _epgProgInf_Cur.time.charAt(4)));

                    // EPG shedule정보는 인덱스 0부터 시작
                    if ( _j<(_epg_prom_info.length-1) ){
                        _epgProgInf_Next = _epg_prom_info[_j+1];
                        _schTmNext.setHours(Number(_epgProgInf_Next.time.charAt(0) + _epgProgInf_Next.time.charAt(1)));
                        _schTmNext.setMinutes(Number(_epgProgInf_Next.time.charAt(3) + _epgProgInf_Next.time.charAt(4)));

                        __str_playingTime = `${_epgProgInf_Cur.time}~${_epgProgInf_Next.time}`;
                    } else {
                        //
                        _schTmNext.setMinutes(Number(0));
                        _schTmNext.setHours(Number(24));

                        __str_playingTime = `${_epgProgInf_Cur.time}~`;
                    }

                    let _t_playTotal = Math.round((_schTmNext - _schTmCur) / 60000); //Total play time in minuate
                    let _t_playRemain = Math.round((_schTmNext - _tm_cur) / 60000); //Remain play time in minuate

                    _rtn_epg = _epgProgInf_Cur;
                    if (_t_playRemain >= 0) {
                        //console.log("CHNAME::>" + _ch_name + " Remaining::> " + _t_playRemain);
                        _rtn_epg["progress_pcent"] = parseInt(((_t_playTotal-_t_playRemain)*100)/_t_playTotal, 10);
                        _rtn_epg["playing_time"] = __str_playingTime;
                        break;
                    }
                }
            }
            return { "tm_cur": _tm_cur, "epg_info": _rtn_epg};
        } catch ( _err ) {
            console.error(`fail to get epg info ${_err}`);
            return { "tm_cur": _tm_cur, "epg_info": null};
        }
    }

    function __uifxn_AppFull_TVEpgFadeIn() {
        let _state = HotelTV.state;
        let _elDivTvChFrm = $('.main .tv .bg .chFrm');

        _state.menu.stage.cur = "tvCtgShow";

        if ( _elDivTvChFrm.css('display') == 'none') {
            _elDivTvChFrm.fadeIn(200);
        }
    }

    function __uifxn_AppFull_TVEpgFadeOut() {
        let _state = HotelTV.state;
        const ____ifxn_fadeout_epg_div = function() {
            _state.menu.stage.cur = "tvCtgHide";
        }
        setTimeout(____ifxn_fadeout_epg_div);
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> TV Channel ui show/hide manager
     */
    function __uifxn_AppFull_TVChMngrUi() {
        let _state = HotelTV.state;
        let _tm_diff_ms_tvctrl = 0;

        if (_tmrEvt.keyevt.tv_ctrl == null) {
            return;
        }

        let _tm_cur = new Date();
        _tm_diff_ms_tvctrl = Math.floor(_tm_cur.getTime() - _tmrEvt.keyevt.tv_ctrl.getTime());
        //마지막 KEY 이벤트 수신 시간 갱신
        //console.log(`KeyDn Event Recoreded::> ${_tmrEvt.keyevt.tv_ctrl} TMDiff::> ${_tm_diff_ms_tvctrl}`);

        // TV Channel UI 지속 시간 2초
        if ( _state.menu.stage.cur=="tvShortcut" )
        {

        }
        else
        {
            if ( _tm_diff_ms_tvctrl>=5000 )
            {
                if ( _state.menu.stage.cur=="tvCtgShow" || _state.menu.stage.cur=="tvCtgHide" )
                {
                    let _elDivTvChFrm = $('.main .tv .bg .chFrm');

                    const ___ifxn_showTvEpgFrm = function() {
                        if ( _elDivTvChFrm.css('display') == 'none') {
                            _elDivTvChFrm.fadeIn(200);
                        }
                    }

                    const ___ifxn_hideTvEpgFrm = function() {
                        if ( _elDivTvChFrm.css('display') != 'none') {
                            _elDivTvChFrm.fadeOut(500);
                        }
                    }

                    if ( _state.menu.stage.cur=="tvCtgShow" ){
                        //___ifxn_showTvEpgFrm();
                    }else if ( _state.menu.stage.cur=="tvCtgHide" ){
                        ___ifxn_hideTvEpgFrm();
                    }
                }
            }
        }
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> TV shortcut ui show/hide manager
     */
    function __uifxn_AppFull_TVShortcutUiMngr() {

        if (_hndl_tmrTvShortcutMngr == null) {
            return;
        }

        // try {
            let _state = HotelTV.state;
            let _mmIdx = _state.menu.main.cur;
            let _programTv = HotelTV.tvguide.program[_mmIdx];

            let _tm_cur = new Date();
            let _tm_diff_ms_tvNumBtn = Math.floor(_tm_cur.getTime() - _tmrEvt.keyevt.tv_numBtn.getTime());

            let _elTvScutRoot = $('.main .tv .shortcut_mode0');


            const ___ifxn_fadeout_shortcutFrm = function() {
                // TV바로가기 번호키 UI 드로잉
                if ( _elTvScutRoot.css('display') != 'none') {
                    _elTvScutRoot.fadeOut(500);
                }
            }

            if ( _tm_diff_ms_tvNumBtn > 4000 ) {

                clearInterval(_hndl_tmrTvShortcutMngr);
                _hndl_tmrTvShortcutMngr = null;

                ___ifxn_fadeout_shortcutFrm();

                if ( _programTv.shortcutkeyMode=="mode_0" ) {
                    if ( _state.tv.shortkey.ch_item_idx!=null ) {
                        const _mmIdx_tv = _state.menu.main.cur;
                        let _tvCtgAllIdx = _state.menu.main[_mmIdx].cur = __uifxn_AppFull_TVCtgyIdByName("all");
                        let _tvChIdx = _state.menu.main[_mmIdx][_tvCtgAllIdx].cur = _state.tv.shortkey.ch_item_idx;

                        _tmrEvt.keyevt.tv_ctrl = new Date();
                        __uifxn_AppFull_TVUpdateChannel("on_shortcut");
                        __uifxn_AppFull_TVRequestChannel(_tvCtgAllIdx, _tvChIdx, __uifxn_AppFull_TVEpgFadeIn);
                    } else {
                        __uifxn_AppFull_TVEpgFadeOut();
                    }
                }
            }
        // } catch ( _err ) {
        //     console.log(`Failure::> ${_err}`);
        // }
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> update message selection on mypage
     * @param {string} _action parameter
     */
    function __uifxn_AppFull_MyPageSelectMessage(_action) {
        const _state = HotelTV.state;

        if (!(HotelTV.message)) {
            console.log("INFO::> No messages");
            return;
        }

        const _msg = HotelTV.message;
        const _mmIdx = _state.menu.main.cur;
        const _mmInfo = HotelTV.tvguide.program[_mmIdx];
        let _state_mypage = _state.menu.main[_mmIdx];

        if (_mmInfo.children[_state_mypage.cur].type == 'message') {
            const _total_cnt = _state_mypage['message']['cnt'];
            let _cur_idx = _state_mypage['message']['cur'];
            //mp_msg_tblrec tr엘리멘트들을 Query
            let _el_target = $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tbody');
            if (_action == "up") {
                if ((_cur_idx - 1) < 0) {
                    _cur_idx = 0;
                } else {
                    _cur_idx -= 1;
                }

                $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').removeClass('focus');
                $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').filter("[msgidx='" + _cur_idx.toString() + "']").addClass('focus');
                _state.menu.main[_mmIdx]['message']['cur'] = _cur_idx;

                if ((_cur_idx >= 3) && (_cur_idx < (_total_cnt - 3))) {
                    _el_target.stop().animate({ scrollTop: ((_cur_idx - 3) * 52).toString() }, 500, function() {
                        console.log("SCROLL DONE>>>1");
                    });
                }
            } else if (_action == "down") {
                if ((_cur_idx + 1) >= (_total_cnt - 1)) {
                    _cur_idx = (_total_cnt - 1);
                } else {
                    _cur_idx += 1;
                }
                $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').removeClass('focus');
                $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').filter("[msgidx='" + _cur_idx.toString() + "']").addClass('focus');
                _state.menu.main[_mmIdx]['message']['cur'] = _cur_idx;

                //if ((_cur_idx > 3) && (_cur_idx < (_total_cnt - 2))) {
                if ( _cur_idx >= 3 ) {
                    _el_target.stop().animate({ scrollTop: ((_cur_idx - 1) * 52).toString() }, 500, function() {
                        console.log("SCROLL DONE>>>2");
                    });
                }
            }
        } else {
            console.log("ERROR::> No centered Item");
        }
    }


    /**
     * HotelTV UI[AppFull] Wrapper Function::> My Page
     */
    function __uifxn_AppFull_BuildMyPage() {
        const _trTbl = HotelTV.translation;
        const _state = HotelTV.state;
        const _msg = HotelTV.message;
        const _guest = HotelTV.guestinfo;
        const _hotel = HotelTV.hotelinfo;
        const _mmIdx = _state.menu.main.cur;
        const _mpinfo = HotelTV.tvguide.program[_mmIdx].children;

        if (!(_mmIdx in _state.menu.main)) {
            _state.menu.main[_mmIdx] = {
                'cnt': 0,
                'cur': null,
                'prev': null,
            };
            _state.menu.main[_mmIdx].cnt = _mpinfo.length;
        }

        // 초기 메인 메뉴 KEY설정
        _state.menu.stage.cur = "preparing_mypage";
        if (_state.menu.main[_mmIdx].cur == null) {
            _state.menu.main[_mmIdx].cur = Object.keys(_mpinfo)[0];
        }

        // MYPAGE 메뉴 셀렉터 노드를 동적으로 구성
        let _div_mp_slist = document.querySelector('#lst_mypagesel');
        for (let _i = 1; _i <= _mpinfo.length; _i++) {
            let _div_mpsel_item = document.createElement('div');
            _div_mpsel_item.className = 'item';
            _div_mpsel_item.id = 'mpsel_' + _mpinfo[_i].type;
            _div_mpsel_item.setAttribute("mpid", _mpinfo[_i].id);

            // Append Sub elements::title
            let _mp_item_title = document.createElement('div');
            _mp_item_title.setAttribute("id", "mp_item_title");
            if (_mpinfo.length > 1) {
                _mp_item_title.textContent = _mpinfo[_i].title[_state.lang];

                // Append Sub elements::icon
                let _mp_item_icon = document.createElement('div');
                _mp_item_icon.setAttribute("id", "mp_item_icon");
                let _sz_styleOpt = "--icon_unfocus: url(" + _mpinfo[_i].unfocusIcon.file.download + "); ";
                _sz_styleOpt += "--icon_focus: url(" + _mpinfo[_i].focusIcon.file.download + "); ";
                _sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom; background-size: 100% 100%; ";
                _mp_item_icon.setAttribute("style", _sz_styleOpt);

                _div_mpsel_item.appendChild(_mp_item_icon);
            } else {

            }
            _div_mpsel_item.appendChild(_mp_item_title);
            _div_mp_slist.appendChild(_div_mpsel_item);
        }

        // MYPAGE 메뉴 백그라운드 노드를 동적으로 구성
        let _div_mp_bglist = document.querySelector('#lst_mypagebg');
        for (let _i = 1; _i <= _mpinfo.length; _i++) {
            let _div_mpbg_item = document.createElement('div');
            _div_mpbg_item.className = 'item';
            _div_mpbg_item.id = 'mpbg_' + _mpinfo[_i].id;

            let _sz_styleOpt = "--bg_noplay: url(" + _mpinfo[_i].background.file.download + "); ";
            _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: contain ";
            _div_mpbg_item.setAttribute("style", _sz_styleOpt);

            if (_mpinfo[_i].type == "accommodation") {
                let _accomo_title = document.createElement('div');
                _accomo_title.setAttribute("id", "mp_accomo_title");
                _accomo_title.textContent = _guest.name + _trTbl.ui.mypage.accmodation.title.title[_state.lang];
                _div_mpbg_item.appendChild(_accomo_title);

                let _accomo_info = document.createElement('div');
                _accomo_info.setAttribute("id", "mp_accomo_infowin");

                const _accmo_item_list = ["accmodation_gstname", "accmodation_rsvcode", "accmodation_hotel", "accmodation_bed_type", "accmodation_room_num", "accmodation_checkin", "accmodation_checkout"];
                for (let _j = 0; _j < _accmo_item_list.length; _j++) {
                    let __info_item = document.createElement('div');
                    __info_item.className = 'accmoinf_item';
                    switch (_accmo_item_list[_j]) {
                        case 'accmodation_gstname':
                            __info_item.innerHTML = `<span id="header">${_trTbl.ui.mypage.accmodation.title.gstname[_state.lang]}</span>`;
                            __info_item.innerHTML += `<span id="value">${_guest.name}</span>`;
                            break;
                        case 'accmodation_rsvcode':
                            __info_item.innerHTML = `<span id="header">${_trTbl.ui.mypage.accmodation.title.rsvcode[_state.lang]}</span>`;
                            __info_item.innerHTML += `<span id="value">${_guest.id}</span>`;
                            break;
                        case 'accmodation_hotel':
                            __info_item.innerHTML = `<span id="header">${_trTbl.ui.mypage.accmodation.title.hotel[_state.lang]}</span>`;
                            __info_item.innerHTML += `<span id="value">${_hotel.name}</span>`;
                            break;
                        case 'accmodation_bed_type':
                            __info_item.innerHTML = `<span id="header">${_trTbl.ui.mypage.accmodation.title.bed_type[_state.lang]}</span>`;
                            __info_item.innerHTML += `<span id="value">${_guest.roomtype[_state.lang]}</span>`;
                            break;
                        case 'accmodation_room_num':
                            __info_item.innerHTML = `<span id="header">${_trTbl.ui.mypage.accmodation.title.room_num[_state.lang]}</span>`;
                            __info_item.innerHTML += `<span id="value">${_guest.room}</span>`;
                            break;
                        case 'accmodation_checkin':
                            __info_item.innerHTML = `<span id="header">${_trTbl.ui.mypage.accmodation.title.checkin[_state.lang]}</span>`;
                            __info_item.innerHTML += `<span id="value">${_guest.checkIn}</span>`;
                            break;
                        case 'accmodation_checkout':
                            __info_item.innerHTML = `<span id="header">${_trTbl.ui.mypage.accmodation.title.checkout[_state.lang]}</span>`;
                            __info_item.innerHTML += `<span id="value">${_guest.checkOut}</span>`;
                            break;
                    }
                    _accomo_info.appendChild(__info_item);
                }
                _div_mpbg_item.appendChild(_accomo_info);

                //Hotel info win
                let _hotel_info = document.createElement('div');
                _hotel_info.setAttribute("id", "mp_hotel_infowin");

                const _hotelinfo_item_list = ["address", "custominquiry", "resvinquiry"];
                for (let _j = 0; _j < _hotelinfo_item_list.length; _j++) {
                    let __info_item = document.createElement('div');
                    __info_item.className = 'hotelinfo_item';
                    switch (_hotelinfo_item_list[_j]) {
                        case 'address':
                            __info_item.innerHTML = `<span id="title">${_trTbl.ui.mypage.accmodation.title.address[_state.lang]}</span>`;
                            __info_item.innerHTML += `<span id="address">${_hotel.address[_state.lang]}</span>`;
                            break;
                        case 'custominquiry':
                            __info_item.innerHTML = `<span id="title">${_trTbl.ui.mypage.accmodation.title.custominquiry[_state.lang]}</span>`;
                            __info_item.innerHTML += `<span id="email">${_hotel.inquiry.custom.email}</span>`;
                            __info_item.innerHTML += `<span id="phone">${_hotel.inquiry.custom.phone[_state.lang]}</span>`;
                            break;
                        case 'resvinquiry':
                            __info_item.innerHTML = `<span id="title">${_trTbl.ui.mypage.accmodation.title.resvinquiry[_state.lang]}</span>`;
                            __info_item.innerHTML += `<span id="email">${_hotel.inquiry.reservation.email}</span>`;
                            __info_item.innerHTML += `<span id="phone">${_hotel.inquiry.reservation.phone[_state.lang]}</span>`;
                            break;
                    }
                    _hotel_info.appendChild(__info_item);
                }
                _div_mpbg_item.appendChild(_hotel_info);

            } else if (_mpinfo[_i].type == "message") {
                // 메시지 상태 오브젝트 초기화
                if (!("message" in _state.menu.main[_mmIdx])) {
                    _state.menu.main[_mmIdx]['message'] = {
                        'cnt': 0,
                        'cur': null,
                        'prev': null,
                    };
                    _state.menu.main[_mmIdx]['message'].cnt = _msg.length;
                }


                let _msg_title = document.createElement('div');
                _msg_title.setAttribute("id", "mp_message_title");
                let _msg_unread_cnt = 0;
                for (let _j = 1; _j <= _msg.length; _j++) {
                    if (_msg[_j].read == false) {
                        _msg_unread_cnt++;
                    }
                }
                _msg_title.textContent = _guest.name + _trTbl.ui.mypage.message.title.title[_state.lang].replace("_XX", _msg_unread_cnt.toString());
                _div_mpbg_item.appendChild(_msg_title);

                let _msg_table = document.createElement('div');
                _msg_table.setAttribute("id", "mp_message_table");

                let _msg_tblhdr = document.createElement('table');
                _msg_tblhdr.setAttribute("id", "mp_msg_tblhdr");
                _msg_tblhdr.innerHTML = '<tbody><tr>' +
                    '<th id="num">' + _trTbl.ui.mypage.message.title.table.num[_state.lang] + '</th>' +
                    '<th id="title">' + _trTbl.ui.mypage.message.title.table.title[_state.lang] + '</th>' +
                    '<th id="from">' + _trTbl.ui.mypage.message.title.table.from[_state.lang] + '</th>' +
                    '<th id="date">' + _trTbl.ui.mypage.message.title.table.date[_state.lang] + '</th>' +
                    '</tr></tbody>';
                _msg_table.appendChild(_msg_tblhdr);

                let _msg_tblrec = document.createElement('table');
                _msg_tblrec.setAttribute("id", "mp_msg_tblrec");
                let _sz_innerHTML = '<tbody>';
                let _num_msgIdx = 0;
                for (let _j = _msg.length; _j > 0; _j--) {
                    _sz_innerHTML += '<tr msgnum=' + _j + ' msgidx=' + _num_msgIdx.toString() + ' >';
                    if (_msg[_j].read == false) {
                        _sz_innerHTML += '<td id="num">' + _j.toString() + '</td>';
                    } else {
                        _sz_innerHTML += '<td id="num" class="read">' + _j.toString() + '</td>';
                    }
                    if (_msg[_j].multilanguage == false) {
                        _sz_innerHTML += '<td id="title">' + _msg[_j].title.default+'</td>';
                    } else {
                        _sz_innerHTML += '<td id="title">' + _msg[_j].title[_state.lang] + '</td>';
                    }
                    _sz_innerHTML += '<td id="from">' + _msg[_j].from + '</td>';
                    _sz_innerHTML += '<td id="date">' + _msg[_j].createdAt + '</td>';
                    _sz_innerHTML += '</tr>';
                    _num_msgIdx++;
                }
                _sz_innerHTML += '</tbody>';
                _msg_tblrec.innerHTML = _sz_innerHTML;
                _msg_table.appendChild(_msg_tblrec);
                _div_mpbg_item.appendChild(_msg_table);
            } else if (_mpinfo[_i].type == "replaywelcome") {
                // 동영상이 있는 경우, PLAY안내 버튼 노출
                if ( _mpinfo[_i].videos[_state.lang] ) {
                    let _div_mypage_mvctrl = document.createElement('div');
                    _div_mypage_mvctrl.setAttribute("class", "ctz_mv_ctrl");
                    _div_mypage_mvctrl.setAttribute("video_url", _mpinfo[_i].videos[_state.lang].download);
                    _sz_styleOpt = '--playmsg: "' + _trTbl.ui.player.watch_movie[_state.lang] + '";';
                    _sz_styleOpt += '--stopmsg: "' + _trTbl.ui.player.stop_movie[_state.lang] + '";';
                    _div_mypage_mvctrl.setAttribute("style", _sz_styleOpt);
                    _div_mpbg_item.appendChild(_div_mypage_mvctrl);
                }
            }

            _div_mp_bglist.appendChild(_div_mpbg_item);
        }

        _hndl_mpBg = $('#lst_mypagebg');
        _hndl_mpBg.owlCarousel({
            center: true,
            items: 1, //Number of Items on Screen what you want
            loop: true,
            nav: false,
            dots: false,
            margin: 0,
            smartSpeed: 700,
            autoWidth: false,
            mouseDrag: false,
            touchDrag: false,
            pullDrag: false,
            freeDrag: false,
            //MYPAGE는 항상 accommodation부터 시작
            startPosition: 0,
        });


        _hndl_mpSel = $('#lst_mypagesel');
        _hndl_mpSel.owlCarousel({
            center: true,
            items: 3, //Number of Items on Screen what you want
            loop: true,
            nav: false,
            dots: true,
            margin: 0,
            smartSpeed: 700,
            autoWidth: false,
            mouseDrag: false,
            touchDrag: false,
            pullDrag: false,
            freeDrag: false,
            //MYPAGE는 항상 accommodation부터 시작
            startPosition: 0,
        });

        $('.main .mypage').show();
        $('.main .mypage .bg').show();

        //메인 페이지->MyPage 페이지 화면 전환
        $('.main .mypage .slider').show(function() {
            $('.main').animate({ top: -1080, left: 0 }, 1000, function() {
                $('.main .mm').fadeOut(1000);
                $('#lst_mypagesel').trigger('translate.owl.carousel', [0]);

                $(document.activeElement).keydown(function(event) { //attach event listener
                    if (_state.menu.stage.cur == "mypage_select_menu") {
                        if (event.keyCode == gRmtKey.left) {
                            $('#lst_mypagesel').trigger('prev.owl')
                            $('#lst_mypagebg').trigger('prev.owl')
                        } else if (event.keyCode == gRmtKey.right) {
                            $('#lst_mypagesel').trigger('next.owl')
                            $('#lst_mypagebg').trigger('next.owl')
                        } else if (event.keyCode == gRmtKey.up) {
                            //UP
                            __uifxn_AppFull_MyPageSelectMessage("up");
                        } else if (event.keyCode == gRmtKey.down) {
                            //DOWN
                            __uifxn_AppFull_MyPageSelectMessage("down");
                        } else if (event.keyCode == gRmtKey.enter) {
                            // 메시지 팝업 빌드 및 화면 전환
                            if (HotelTV.tvguide.program[_mmIdx].children[_state.menu.main[_mmIdx].cur].type == 'message')
                            {
                                let _msginf = HotelTV.message;
                                let _cur_msglst_idx = _state.menu.main[_mmIdx]['message']['cur'];
                                // 현재 선택된 메시지의 디테일 정보 가져오기
                                let _cur_msgnum = $($('.main>.mypage>.bg>.owl-carousel .owl-item.center #mp_msg_tblrec tbody .focus')[0]).attr('msgnum');
                                // 마이페이지 메뉴에서 메시지를 선택하지 않고 엔터키를 누른경우
                                if (!(_cur_msgnum)) {
                                    return;
                                }


                                let _cur_msgdesc = _msginf[_cur_msgnum];

                                if ( _cur_msgdesc.format==="text" )
                                {
                                    // TEXT타입 메시지
                                    $('.popup>.mypage>.message').css({ 'background-size' : '', 'background-repeat' : '' });
                                    $('.popup>.mypage>.message').css({"background-image":"url(./images/bg_message_cream-paper.png)"});

                                    // Message card 구성
                                    $('.popup>.mypage>.message>#msg_ctz').css('font-size', '34px');
                                    $('.popup>.mypage>.message>#title').css('font-size', '50px');
                                    // switch (_state.lang) {
                                    //     case 'ko-KR':
                                    //         $('.popup>.mypage>.message').css('font-family', 'Nanum Pen Script');
                                    //         $('.popup>.mypage>.message>#msg_ctz').css('font-size', '34px');
                                    //         $('.popup>.mypage>.message>#title').css('font-size', '50px');
                                    //         break;
                                    //     case 'zh-CN':
                                    //         $('.popup>.mypage>.message').css('font-family', 'Ma Shan Zheng');
                                    //         $('.popup>.mypage>.message>#msg_ctz').css('font-size', '34px');
                                    //         $('.popup>.mypage>.message>#title').css('font-size', '50px');
                                    //         break;
                                    //     case 'zh-TW':
                                    //         $('.popup>.mypage>.message').css('font-family', 'Ma Shan Zheng');
                                    //         $('.popup>.mypage>.message>#msg_ctz').css('font-size', '34px');
                                    //         $('.popup>.mypage>.message>#title').css('font-size', '50px');
                                    //         break;
                                    //     default:
                                    //         $('.popup>.mypage>.message').css('font-family', 'Parisienne');
                                    //         $('.popup>.mypage>.message>#msg_ctz').css('font-size', '32px');
                                    //         break;
                                    // }

                                    if (_cur_msgdesc.multilanguage == true) {
                                        $('.popup>.mypage>.message>#title').text(_cur_msgdesc.title[_state.lang]);
                                        $('.popup>.mypage>.message>#msg_ctz').html(_cur_msgdesc.content[_state.lang].replace(/(?:\r\n|\r|\n)/g, '<br>'));
                                    } else {
                                        $('.popup>.mypage>.message>#title').text(_cur_msgdesc.title.default);
                                        $('.popup>.mypage>.message>#msg_ctz').html(_cur_msgdesc.content.default.replace(/(?:\r\n|\r|\n)/g, '<br>'));
                                    }
                                }
                                else
                                {
                                    let _imgmsg_url = null;
                                    // 혹시 모를 타이틀 제거
                                    $('.popup>.mypage>.message>#title').empty();

                                    // 혹시 모를 html콘텐츠 제거
                                    $('.popup>.mypage>.message>#msg_ctz').empty();


                                    // Image 타입 메시지
                                    if (_cur_msgdesc.multilanguage == false)
                                    {
                                        _imgmsg_url = _cur_msgdesc.imageContent.default.download;
                                    }
                                    else
                                    {
                                        _imgmsg_url = _cur_msgdesc.imageContent[_state.lang].download;
                                    }
                                    $('.popup>.mypage>.message').css({"background-image":"url("+ _imgmsg_url +")"});
                                    $('.popup>.mypage>.message').css({"background-size":"cover"});
                                }

                                //Back button
                                $('.popup>.mypage>.message>#btn_back').text(_trTbl.system.btn.back[_state.lang]);

                                //SHOW ANIMATION
                                if ($('.popup>.mypage>.message').css('display') == "none") {
                                    _state.menu.stage.cur = "mypage_popup_message_card";
                                    $('.popup>.mypage').addClass('fade');
                                    $('.main>.mypage>.slider').animate({ top: 1080, left: 0 }, 1000, function() {
                                        $('.popup>.mypage>.message').fadeIn(500);

                                        //메시지 읽음 처리
                                        HotelTV.api.SetMessageStatus(_cur_msgdesc._id);
                                        _cur_msgdesc.read = true;
                                        $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').filter("[msgidx='" + _cur_msglst_idx.toString() + "']").children('td#num').addClass('read');
                                        __uifxn_AppFull_TopWidjet_BuildMsgCnt();
                                    });
                                }
                            }
                        } else if (event.keyCode == gRmtKey.back) {
                            // 메인 메뉴로 귀환
                            $(document.activeElement).off('keydown');
                            $('.main .mm').show(function() {
                                $('#lst_mmsel').trigger('refresh.owl.carousel', [0]);
                            });

                            $('.main').animate({ top: 0, left: 0 }, 1000, () => {
                                $('#lst_mypagesel').off('translate.owl.carousel');

                                $('#lst_mypagebg').owlCarousel('destroy');
                                $('#lst_mypagesel').owlCarousel('destroy');

                                $('.main .mypage .slider #lst_mypagesel div').remove();
                                $('.main .mypage .bg #lst_mypagebg div').remove();
                                $('.main .mypage').hide();
                                _hndl_mpSel = null;
                                _hndl_mpBg = null;
                                _state.menu.stage.cur = "main"
                                setTimeout(function() {
                                    __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
                                }, 500);
                            });
                        } else if (event.keyCode == gRmtKey.play) {
                            if (HotelTV.tvguide.program[_mmIdx].children[_state.menu.main[_mmIdx].cur].type == 'replaywelcome')
                            {
                                let uri_video = $($('.main .mypage .bg .owl-carousel .owl-item.active .ctz_mv_ctrl')[0]).attr('video_url');
                                if (uri_video != null) {
                                    _state.menu.stage.prev = _state.menu.stage.cur;
                                    _state.menu.stage.cur = "mypage_replay_welcome_vod";
                                    HotelTV.hal.MediaPlay(
                                        uri_video,
                                        "",
                                        "video/mp4",
                                        1,
                                        () => {
                                            console.log("STARTUP Done CB.");
                                        },
                                        () => {
                                            _state.menu.stage.cur = _state.menu.stage.prev;
                                            console.log("STARTUP Fail CB.");
                                        }
                                    );
                                }
                            }
                        } else {
                            console.log("MYPAGE KEYEVT: Skip events::>" + event.keyCode);
                        }
                    } else if (_state.menu.stage.cur == "mypage_replay_welcome_vod") {
                        if (event.keyCode == gRmtKey.stop)
                        {
                            if (_state.media.playing == true) {
                                _state.media.playing = false;
                                HotelTV.hal.MediaStop(
                                    function() {
                                        $('.main .mypage .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item').removeClass('movieplay');
                                        $('.main .mypage .slider').animate({top:864, left:0}, 1000, function(){
                                            __uifxn_AppFull_TopWidjetShow(true);
                                        })
                                        _state.menu.stage.cur = _state.menu.stage.prev;
                                    },
                                    function() {
                                        $('.main .mypage .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item').removeClass('movieplay');
                                        $('.main .mypage .slider').animate({top:864, left:0}, 1000, function(){
                                            __uifxn_AppFull_TopWidjetShow(true);
                                        })
                                        _state.menu.stage.cur = _state.menu.stage.prev;
                                    });
                            }
                        }
                    } else if (_state.menu.stage.cur == "mypage_popup_message_card") {
                        if (event.keyCode == gRmtKey.back) {
                            if ($('.popup>.mypage>.message').css('display') != "none") {
                                $('.popup>.mypage').removeClass('fade');
                                $('.popup>.mypage>.message').fadeOut(500, function() {
                                    _state.menu.stage.cur = "mypage_select_menu";
                                    $('.main>.mypage>.slider').animate({ top: 864, left: 0 }, 1000)
                                });
                            }
                        } else {
                            console.log("POPUP MESSAGE CARD KEYEVT: Skip events::>" + event.keyCode);
                        }
                    } else {
                        console.log("INVALID MYPAGE SUBMENU STAGE::>" + _state.menu.stage.cur);
                    }
                });
                _state.menu.stage.cur = "mypage_select_menu";
            });

            $('#lst_mypagesel').on('translate.owl.carousel', function(event) {
                const __ifxn_getMyPaggeItemIndex = function(_object, _type) {
                    for (__j = 1; __j <= _object.length; __j++) {
                        if (_object[__j].type == _type) {
                            return __j;
                        }
                    }
                }

                // 메뉴 셀렉터 좌/우 헨들링 및 이펙트
                let uiCtrl_idx = 0;
                if (typeof event.item != 'undefined') {
                    uiCtrl_idx = event.item.index;
                } else {
                    uiCtrl_idx = $('.main .mypage .slider .owl-item.active.center').index();
                }
                //console.log("MYPAGE EVT(TRANSLATED) IDX::>" + uiCtrl_idx);
                if ($('.main .mypage .slider .owl-item').eq(uiCtrl_idx).children('.item').length == 1) {
                    let _mp_sm = $('.main .mypage .slider .owl-item').eq(uiCtrl_idx).children('.item')[0].id;

                    // MYPAGE서브 메뉴 인덱스 갱신
                    if (_mp_sm == "mpsel_accommodation") {
                        _state.menu.main[_mmIdx].cur = __ifxn_getMyPaggeItemIndex(_mpinfo,'accommodation');
                    } else if (_mp_sm == "mpsel_message") {
                        let __curMsgDspIdx = 0;
                        _state.menu.main[_mmIdx].cur = __ifxn_getMyPaggeItemIndex(_mpinfo,'message');

                        // 메시지 포커싱
                        if ('message' in Object.keys(_state.menu.main[_mmIdx])) {
                            __curMsgDspIdx = _state.menu.main[_mmIdx].message.cur;
                        } else {
                            _state.menu.main[_mmIdx]['message'] = {
                                "cnt": _msg.length,
                                "cur": __curMsgDspIdx,
                                "prev": null,
                            }
                        }
                        $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').removeClass('focus');
                        $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').filter("[msgidx='" + __curMsgDspIdx + "']").addClass('focus');
                        HotelTV.ui_utils.ShowNotificationMsgBalloon(_trTbl.ui.guide.navi_mypageMsgSel[_state.lang], 5);
                    } else if (_mp_sm == "mpsel_replaywelcome") {
                        _state.menu.main[_mmIdx].cur = __ifxn_getMyPaggeItemIndex(_mpinfo,'replaywelcome');
                    }
                    console.log("MYPAGE EVT(TRANSLATED) MYPAGE MENU::>" + _state.menu.main[_mmIdx].cur);

                    HotelTV.api.ReportEvent([
                        {
                            'power': true,
                            'location':
                            {
                                'conId': _mpinfo[_state.menu.main[_mmIdx].cur].id
                            }
                        }]);
                }

                $('.main .mypage .slider .owl-item.focus').removeClass('focus');
                $('.main .mypage .slider .owl-item.unfocus').removeClass('unfocus');
                $('.main .mypage .slider .owl-item').eq(uiCtrl_idx).addClass('focus');
                $('.main .mypage .slider .owl-item').eq(uiCtrl_idx - 1).addClass('unfocus');
                $('.main .mypage .slider .owl-item').eq(uiCtrl_idx + 1).addClass('unfocus');
            });
        });


    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> request tv channel function
     * @param {Number} _force_ctg_item_idx
     * @param {Number} _force_ch_item_idx
     * @param {function} _cbfxn_success
     * @param {function} _cbfxn_failure
     */
    function __uifxn_AppFull_TVRequestChannel(_force_ctg_item_idx, _force_ch_item_idx, _cbfxn_success=null, _cbfxn_failure=null) {
        const _state = HotelTV.state;
        const _trTbl = HotelTV.translation;
        const _mmIdx_tv = _state.menu.main.cur;
        let _tvCtgIdx = _state.menu.main[_mmIdx_tv].cur;
        let _tvChIdx = _state.menu.main[_mmIdx_tv][_tvCtgIdx].cur;
        const _program = HotelTV.tvguide.program;
        const _tvCtgyInfoAll = _program[_mmIdx_tv].categories;
        let _tvChInfo = _tvCtgyInfoAll[_tvCtgIdx].channels[_tvChIdx];
        let _tm_diff_ms_TvRqt = 0;


        if (_tmrEvt.tvchannel_changed == null) {
            _tmrEvt.tvchannel_changed = new Date();
        } else {
            let _tm_cur = new Date();
            _tm_diff_ms_TvRqt = Math.floor(_tm_cur.getTime() - _tmrEvt.tvchannel_changed.getTime());
            //마지막 TV채널 변경 시간 갱신
            _tmrEvt.tvchannel_changed = _tm_cur;
        }

        // 번호키로 채널 변경시 카테고리와 채널 아이탬의 인덱스
        if ( _force_ctg_item_idx!=null && _force_ch_item_idx!=null ){
            //console.log(`Override channel category(${_force_ctg_item_idx}) and channel index(${_force_ch_item_idx})`);
            _tvCtgIdx = _force_ctg_item_idx;
            _tvChIdx = _force_ch_item_idx;
            _tvChInfo = _tvCtgyInfoAll[_tvCtgIdx].channels[_tvChIdx];
        }

        if ( _tm_diff_ms_TvRqt!=0 && _tm_diff_ms_TvRqt <= 200) {
            console.log(`SKIPPED::TVCTG[${_tvCtgyInfoAll[_tvCtgIdx].name}]` +
                ` CUR CH IDX::>${_tvChIdx} EPGID: ${_tvChInfo.epg_id} URL::>${_tvChInfo.url} TMDIFF::>${_tm_diff_ms_TvRqt}`);
            return;
        }


        let _chReqParam = {};
        console.log(`CHANGE::TVCTG[${_tvCtgyInfoAll[_tvCtgIdx].name}]` +
            ` CUR CH IDX::>${_tvChIdx} CHNAME:${_tvChInfo.name}  EPGID: ${_tvChInfo.epg_id} URL::>${_tvChInfo.url} TMDIFF::>${_tm_diff_ms_TvRqt}`);

        if (_tvChInfo.type == "ptcrf") {
            // RF
            _chReqParam['rf'] = {
                "type": _tvChInfo.RFType,
                "major": _tvChInfo.majorNo,
                "minor": _tvChInfo.minorNo,
                "program": _tvChInfo.programNo,
                "frequency": 0
            };

            // CBFXN
            _chReqParam['cbfxn'] = {
                "success": _cbfxn_success,
                "failure": _cbfxn_failure
            };
        } else if (_tvChInfo.type == "ipstream") {
            // IP STREAM URL
        } else if (_tvChInfo.type == "encoder") {
            // ENCODER
        }
        HotelTV.hal.ChannelSetup(_tvChInfo.type, _chReqParam);

        //TODO: 아래 실제 채널 셋업 부분 주석처리 되어 있는데, IP와 RF모두 처리 할 수 있도록 구현할것
        //let _uri_stream = _tvChInfo.url.split('://@')[1];
        //let _typ_proto = _tvChInfo.url.split('://@')[0];
        //let _uri_ip = _uri_stream.split(':')[0];
        //let _uri_port = _uri_stream.split(':')[1];
        //console.log(`ip = ${_uri_ip} port=${_uri_port} protocol=${_typ_proto}`);
        //HotelTV.hal.ChannelSetup("ip", { "ip": _uri_ip, "port": Number(_uri_port), "ptype": _typ_proto });


        // {
        //     let min = Math.ceil(0);
        //     let max = Math.floor(16);
        //     let _major = Math.floor(Math.random() * (max - min + 1)) + min;
        //     console.log("Major=5 minor=" + _major);
        //     HotelTV.hal.ChannelSetup("rf_analog_ntsc", { "major": _major, "minor": 0 });
        // }

        HotelTV.api.ReportEvent([{
            'power': true,
            'location':{
                'catId':_tvCtgyInfoAll[_tvCtgIdx].id,
                'chId': _tvChInfo.id,
            }
        }])
    }

    function __uifxn_AppFull_TVDrawShortcutKey_Mode0(_keyCode) {
        let _state = HotelTV.state;
        let _mmIdx = _state.menu.main.cur;
        let _trTbl = HotelTV.translation;
        let _program = HotelTV.tvguide.program;
        let _tvCtgyInfoAll = _program[_mmIdx].categories;
        let _tvCtgyAllChannels = null;

        const __ifxn_getChItemValue = function(_object, _key) {
            return _object[_key];
        }

        const __ifxn_getChItemIdxByNumber = function(_chNum) {
            for (let _kk = 1; _kk <= _tvCtgyAllChannels.length; _kk++) {
                if ( _tvCtgyAllChannels[_kk].number==_chNum ){
                    return _kk;
                }
            }
        }


        try {
            let _strReqNumCur = "";
            let _strReqNumNext = "";
            let _elTvScutRoot = $('.main .tv .shortcut_mode0');

            // ALL 카테고리 TV채널 정보 가져오기
            _tvCtgyAllChannels = _tvCtgyInfoAll[__uifxn_AppFull_TVCtgyIdByName("all")].channels;

            if ( _elTvScutRoot.css('display') == 'none') {
                _elTvScutRoot.text("");
                _elTvScutRoot.fadeIn(200);

                if (_hndl_tmrTvShortcutMngr == null) {
                    _hndl_tmrTvShortcutMngr = setInterval(__uifxn_AppFull_TVShortcutUiMngr, 500);
                    console.log("TMR(TVChMngrShortcutUiMngr)::>Created...");
                }
            } else {
                //_strReqNumCur = Array.from(_elTvScutRoot.text());
                _strReqNumCur = _elTvScutRoot.text();
            }

            if ( _strReqNumCur.length<3 ){
                _state.tv.shortkey.ch_item_idx = null;

                _strReqNumNext = _strReqNumCur + gRmKeyCode2Num[_keyCode];
                _elTvScutRoot.text(_strReqNumNext);

                for (let _idx = 1; _idx <= _tvCtgyAllChannels.length; _idx++)
                {
                    let _ChItem = _tvCtgyAllChannels[_idx];
                    // _chNumber는 -기준으로 잘라낸 앞숫자, 예를들면 16-1이라면 _chNumber는 16이 됨.
                    let _ChNumStr = __ifxn_getChItemValue(_ChItem, "number").toString();
                    let _ChNumber = Number(_ChNumStr.split('-')[0]);

                    // Find out matched channel
                    if ( _ChNumber==Number(_strReqNumNext) ){
                        // Find out
                        _state.tv.shortkey.ch_item_idx = Number(__ifxn_getChItemIdxByNumber(_ChNumStr));
                        console.log("Find out matched channel index(of ALL category)::> " + _state.tv.shortkey.ch_item_idx);
                        break;
                    }
                }
            } else {
                //
            }

        } catch ( _err ) {
            console.log(`Failure::> ${_err}`);
        }
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> build tv channel shortcut list(MODE1)
     * @param {boolean} _show flag for show/hide shortcut mode1 popup
     * @param {string} _action actions; build, move, exitWidthoutChchange, exitWidthChchage
     * @param {Number} _keyCode key event key code
     */
    function __uifxn_AppFull_TVDrawShortcutKey_Mode1(_show, _action, _keyCode) {
        let _state = HotelTV.state;
        let _mmIdx = _state.menu.main.cur;
        let _trTbl = HotelTV.translation;
        let _program = HotelTV.tvguide.program;
        let _tvCtgyInfoAll = _program[_mmIdx].categories;
        let _tvCtgyAllChannels = null;

        const __ifxn_getChItemValue = function(_object, _key) {
            return _object[_key];
        }

        const __ifxn_updateLastChIdxState = function(_ch_number) {
            let _state = HotelTV.state;
            let _mmIdx = _state.menu.main.cur;

            for (let _ctgidx = 1; _ctgidx <= _tvCtgyInfoAll.length; _ctgidx++) {
                let _matched_ch_idx=null;
                let _ch_info =  _tvCtgyInfoAll[_ctgidx].channels;
                // 해당 카테고리의 채널 인덱스 찾기
                for (let _chidx = 1; _chidx <= _ch_info.length; _chidx++) {
                    if ( _ch_info[_chidx].number.toString()==_ch_number ){
                        //_state.menu.main[_mmIdx][_ctgidx].cur = _chidx.toString();
                    }
                }
            }
        }



        let _elTvScutRoot = $('.main .tv .shortcut_mode1');
        let _elTvScutSugesstion = _elTvScutRoot.children('#suggestion');
        let _elTvScutChlistTbl = _elTvScutSugesstion.children('.ch_list');
        let _elTvScutChlistRecord = _elTvScutChlistTbl.children('tbody');

        // TV바로가기 번호키 UI 드로잉
        if ( _action=="build" )
        {
            // ALL 카테고리 TV채널 정보 가져오기
            _tvCtgyAllChannels = _tvCtgyInfoAll[__uifxn_AppFull_TVCtgyIdByName("all")].channels;

            try {
                let first_item = true;
                // 기존 레코드 제거
                if (_elTvScutChlistRecord.children('tr').length) {
                    _elTvScutChlistRecord.children('tr').remove();
                }

                _state.tv.shortkey = {
                    "idx": "1",
                    "scroll_offset": 0,
                    "ch_item_idx": 1,
                };

                for (let _idx = 1; _idx <= _tvCtgyAllChannels.length; _idx++)
                {
                    let _ChItem = _tvCtgyAllChannels[_idx];

                    if ( __ifxn_getChItemValue(_ChItem, "number").toString().includes( gRmKeyCode2Num[_keyCode].toString())==true )
                    {
                        var _elTr_ChtmesRec = document.createElement('tr');
                        var _elDiv_ChItmesRec = document.createElement('div');
                        _elDiv_ChItmesRec.className = "scitem";
                        // all카테고리의 channels의 해당 채널의 아이탬 인덱스
                        _elDiv_ChItmesRec.setAttribute("item_idx", _idx);
                        if ( first_item==true ){
                            _state.tv.shortkey.ch_item_idx = _idx;
                            __ifxn_updateLastChIdxState(__ifxn_getChItemValue(_ChItem, "number"));
                            first_item = false;
                        }

                        var _elDiv_ChItmesRecChIcon = document.createElement('div');
                        _elDiv_ChItmesRecChIcon.setAttribute("id", "logo");
                        _elDiv_ChItmesRecChIcon.style.backgroundImage = "url('" + __ifxn_getChItemValue(_ChItem, "logo").file.download + "')";
                        _elDiv_ChItmesRec.appendChild(_elDiv_ChItmesRecChIcon);

                        // 채널 번호
                        var _elDiv_ChItmesRecChNum = document.createElement('div');
                        _elDiv_ChItmesRecChNum.setAttribute("id", "num");
                        _elDiv_ChItmesRecChNum.textContent = __ifxn_getChItemValue(_ChItem, "number");
                        _elDiv_ChItmesRec.appendChild(_elDiv_ChItmesRecChNum);

                        var _elDiv_ChItmesRecName = document.createElement('div');
                        _elDiv_ChItmesRecName.setAttribute("id", "title");
                        _elDiv_ChItmesRecName.textContent = __ifxn_getChItemValue(_ChItem, "title")[_state.lang];
                        _elDiv_ChItmesRec.appendChild(_elDiv_ChItmesRecName);

                        _elTr_ChtmesRec.appendChild(_elDiv_ChItmesRec);
                        _elTvScutChlistRecord.append(_elTr_ChtmesRec);
                    }
                }
                // Activate first order lists
                _elTvScutChlistRecord.children('tr').first().addClass('active');

                // 화면 출력
                if ( _elTvScutRoot.css('display') == 'none') {
                    _elTvScutRoot.fadeIn(500);
                }

                return 0;
            } catch (_error) {
                console.log(`Fail to call API::> ${_error}`);
                return -1;
            }
        }
        else if ( _action=="exitWithoutChchange")
        {
            // 기존 레코드 제거
            if (_elTvScutChlistRecord.children('tr').length) {
                _elTvScutChlistRecord.children('tr').remove();
            }

            if ( _elTvScutRoot.css('display') != 'none') {
                _elTvScutRoot.fadeOut(500);
            }

            return 0;
        }
        else if ( _action=="exitWithChchange")
        {
            // 기존 레코드 제거
            if (_elTvScutChlistRecord.children('tr').length) {
                _elTvScutChlistRecord.children('tr').remove();
            }

            // 채널 요청
            __uifxn_AppFull_TVRequestChannel(__uifxn_AppFull_TVCtgyIdByName("all"), _state.tv.shortkey.ch_item_idx);

            if ( _elTvScutRoot.css('display') != 'none') {
                _elTvScutRoot.fadeOut(500);
            }

            return 0;
        }
        else if ( _action=="move" )
        {
            if ( _keyCode == gRmtKey.up || _keyCode==gRmtKey.chup ) {
                let selectedTblItem = _elTvScutChlistRecord.children('tr.active').prev("#record tr");

                if (selectedTblItem.length) {
                    _elTvScutChlistRecord.children('tr.active').removeClass("active");
                    selectedTblItem.addClass('active');
                    _state.tv.shortkey.idx = selectedTblItem.prop('rowIndex');
                    _state.tv.shortkey.ch_item_idx = Number(selectedTblItem.children(".scitem").attr("item_idx"));

                    __ifxn_updateLastChIdxState(selectedTblItem.children(".scitem").children("#num").text());

                    // 스크롤이 필요한 경우 스크롤링 하기
                    let _scrollTopVal = _state.tv.shortkey.scroll_offset;
                    _scrollTopVal -= selectedTblItem.prop('scrollHeight');
                    _elTvScutChlistRecord.animate({ scrollTop: _scrollTopVal }, selectedTblItem.height());
                    _state.tv.shortkey.scroll_offset = _scrollTopVal;
                }
            } else if ( _keyCode == gRmtKey.down || _keyCode==gRmtKey.chdown ) {
                let selectedTblItem = _elTvScutChlistRecord.children('tr.active').next("#record tr");

                if (selectedTblItem.length) {
                    _elTvScutChlistRecord.children('tr.active').removeClass("active");
                    selectedTblItem.addClass('active');
                    _state.tv.shortkey.idx = selectedTblItem.prop('rowIndex');
                    _state.tv.shortkey.ch_item_idx = Number(selectedTblItem.children(".scitem").attr("item_idx"));

                    __ifxn_updateLastChIdxState(selectedTblItem.children(".scitem").children("#num").text());

                    // 스크롤이 필요한 경우 스크롤링 하기
                    let _scrollTopVal = _state.tv.shortkey.scroll_offset;
                    _scrollTopVal += selectedTblItem.prop('scrollHeight');
                    _elTvScutChlistRecord.animate({ scrollTop: _scrollTopVal }, selectedTblItem.height());
                    _state.tv.shortkey.scroll_offset = _scrollTopVal;
                }
            }

            return 0;
        }
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> update tv channel list within selected tv category
     * @param {string} _action parameter
     */
    function __uifxn_AppFull_TVUpdateChannel(_action) {
        const _state = HotelTV.state;
        const _mmIdx_tv = _state.menu.main.cur;
        const _tvCtgIdx = _state.menu.main[_mmIdx_tv].cur;
        const _tvChIdx = _state.menu.main[_mmIdx_tv][_tvCtgIdx].cur; //프로파일 상의 채널 인덱스(문자열)
        const _tvChInfo = HotelTV.tvguide.program[_mmIdx_tv].categories[_tvCtgIdx].channels[_tvChIdx];

        let _trTbl = HotelTV.translation;
        let _elDivTvChFrm = $('.main .tv .bg .chFrm');
        let _elDivTvChLogo = _elDivTvChFrm.find('.chLogo').children('#icon');
        let _elDivTvChNum = _elDivTvChFrm.find('.chNum').children('#number');
        let _elDivTvChDesc = _elDivTvChFrm.find('.chDesc');
        let _elDivTvChEpgName = _elDivTvChDesc.find('#epg_chname');
        let _elDivTvChEpgTitle = _elDivTvChDesc.find('#epg_title');
        let _elDivTvChEpgDetails = _elDivTvChDesc.find('#epg_details');
        let _egp_prog_inf = null;


        //Update channel logo image
        _elDivTvChLogo.css({ "background-image": "url(" + _tvChInfo.logo.file.download + ")" });

        //Update channel number
        _elDivTvChNum.text(_tvChInfo.number);

        //Update channel description
        _elDivTvChEpgName.text(_tvChInfo.name);
        _egp_prog_inf = __uifxn_AppFull_TVEpgByChName(_tvChInfo.epg);
        _elDivTvChEpgDetails.find('#tm_current').text(_trTbl.ui.tv.epg.datetime[_state.lang] + _egp_prog_inf.tm_cur.getHours() + ":" + _egp_prog_inf.tm_cur.getMinutes() );
        if (_egp_prog_inf.epg_info != null) {
            _elDivTvChEpgTitle.text(_egp_prog_inf.epg_info.name);
            _elDivTvChEpgDetails.find('#tm_playing').text(_trTbl.ui.tv.epg.progamtime[_state.lang] + _egp_prog_inf.epg_info.playing_time);

            //let _new_progress_bar_width = parseInt(_elDivTvChEpgDetails.find("#tm_chart").width()*_egp_prog_inf.epg_info.progress_pcent/100);
            let _new_progress_bar_width = parseInt(835*_egp_prog_inf.epg_info.progress_pcent/100);
            _elDivTvChEpgDetails.find('.progress').width(_new_progress_bar_width);
        } else {
            _elDivTvChEpgTitle.text("");
            _elDivTvChEpgDetails.find('#tm_playing').text("");

            //let _new_progress_bar_width = parseInt(_elDivTvChEpgDetails.find("#tm_chart").width()*_egp_prog_inf.epg_info.progress_pcent/100);
            let _new_progress_bar_width = 0;
            _elDivTvChEpgDetails.find('.progress').width(_new_progress_bar_width);
        }

        // Fade in epg
        __uifxn_AppFull_TVEpgFadeIn();

        if (_action == "on_load") {
            //_state.menu.stage.cur = "tvCtgShow";
            // TODO: Request Channel
        } else if (_action == "ch_up") {
            // TODO: Request Channel
        } else if (_action == "ch_down") {
            // TODO: Request Channel
        } else if ( _action=="on_shortcut" ) {
            //
        }

        __uifxn_AppFull_TVRequestChannel(null, null, __uifxn_AppFull_TVEpgFadeOut, __uifxn_AppFull_TVEpgFadeOut);
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> Buildup sub menu and main bg
     */
    function __uifxn_AppFull_Update_CtzThumbnail() {
        let _state = HotelTV.state;
        let _mmIdx = _state.menu.main.cur;
        let _smIdx = _state.menu.main[_mmIdx].cur;
        if (_state.menu.main[_mmIdx][_smIdx] && _state.menu.main[_mmIdx][_smIdx].cur) {
            let _ctzidx = _state.menu.main[_mmIdx][_smIdx].cur;
            let _program = HotelTV.tvguide.program;
            let _ctzinfo = _program[_mmIdx].children[_smIdx].children;

            if (_state.menu.main[_mmIdx][_smIdx].thumbimg[_ctzidx].idx < _state.menu.main[_mmIdx][_smIdx].thumbimg[_ctzidx].cnt) {
                _state.menu.main[_mmIdx][_smIdx].thumbimg[_ctzidx].idx++;
            } else {
                _state.menu.main[_mmIdx][_smIdx].thumbimg[_ctzidx].idx = 1;
            }
            let _img_ctz_thumbnail = $('.main .ctzgen .bg .owl-carousel .owl-item.active .ctz_desc_frame #ctz_thumbnail img');

            _img_ctz_thumbnail.fadeOut(1000, function() {
                _img_ctz_thumbnail.attr({
                    src: _ctzinfo[_ctzidx].thumbnails.files[_state.lang][_state.menu.main[_mmIdx][_smIdx].thumbimg[_ctzidx].idx].download
                });
            }).fadeIn(1000);
            //console.log("CTZ(THUMBNAIL) UPDATED::> " + _state.menu.main[_mmIdx][_smIdx].thumbimg[_ctzidx].idx);
        }
    }


    /**
     * HotelTV UI[AppFull] Wrapper Function::> Buildup sub menu and main bg
     */
    function __uifxn_AppFull_Build_CtzGeneral() {
        let _trTbl = HotelTV.translation;
        let _state = HotelTV.state;
        let _mmIdx = _state.menu.main.cur;
        let _smIdx = _state.menu.main[_mmIdx].cur;
        let _program = HotelTV.tvguide.program;
        let _ctzinfo = _program[_mmIdx].children[_smIdx].children;


        if (!(_smIdx in _state.menu.main[_mmIdx])) {
            _state.menu.main[_mmIdx][_smIdx] = {
                'cnt': 0,
                'cur': null,
                'prev': null,
                'thumbimg': {}
            };
            _state.menu.main[_mmIdx][_smIdx].cnt = _ctzinfo.length;
        }

        // UI State Flag 설정
        _state.menu.stage.cur = "preparing_ctz_general";
        if (_state.menu.main[_mmIdx][_smIdx].cur == null) {
            _state.menu.main[_mmIdx][_smIdx].cur = Object.keys(_ctzinfo)[0];
        }

        // 컨텐트 매뉴 백그라운드 이미지 노드를 동적으로 구성
        let _div_ctzgen_bglist = document.querySelector('#lst_ctzgenbg');
        for (let _ctzidx = 1; _ctzidx <= _ctzinfo.length; _ctzidx++) {
            let _div_ctz_item = document.createElement('div');
            let _sz_styleOpt = null;

            _div_ctz_item.className = 'item';
            _div_ctz_item.id = _ctzinfo[_ctzidx].id;
            _div_ctz_item.setAttribute("cgzgenid", _ctzidx);
            _sz_styleOpt = "--bg_noplay: url(" + _ctzinfo[_ctzidx].background.file.download + "); ";
            _sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom; background-size: 100% 100%; ";
            _div_ctz_item.setAttribute("style", _sz_styleOpt);


            // 컨텐트 DESCRIPTION용 DIV 삽입
            let _div_ctz_frame = document.createElement('div');
            _div_ctz_frame.setAttribute("class", "ctz_desc_frame");

            // 컨텐트 타이틀 삽입
            let _div_ctz_title = document.createElement('div');
            _div_ctz_title.setAttribute("id", "ctz_title");
            _div_ctz_title.textContent = _ctzinfo[_ctzidx].title[_state.lang];
            _div_ctz_frame.appendChild(_div_ctz_title);

            // 컨텐트 썸네일 삽입
            let _div_ctz_thumbnail = document.createElement('div');
            _div_ctz_thumbnail.setAttribute("id", "ctz_thumbnail");

            let _img_ctz_thumbnail = document.createElement('img');
            _img_ctz_thumbnail.src = _ctzinfo[_ctzidx].thumbnails.files[_state.lang][1].download;
            _div_ctz_thumbnail.appendChild(_img_ctz_thumbnail);
            _div_ctz_frame.appendChild(_div_ctz_thumbnail);

            // 썸네일 에니메이션 관리용 맴버 추가 및 초기화
            _state.menu.main[_mmIdx][_smIdx].thumbimg[_ctzidx] = { "cnt": _ctzinfo[_ctzidx].thumbnails.files[_state.lang].length, "idx": 1 };

            // 컨텐트 설명 삽입
            let _div_ctz_desc = document.createElement('div');
            _div_ctz_desc.setAttribute("id", "ctz_description");
            _div_ctz_desc.innerHTML = "<p>" + _ctzinfo[_ctzidx].description[_state.lang].replace(/(?:\r\n|\r|\n)/g, '<br>') + "</p>";
            _div_ctz_frame.appendChild(_div_ctz_desc);

            _div_ctz_item.appendChild(_div_ctz_frame);


            // 나중에 구현하기로 하고 조선프로젝트에서 우선 스킵
            // // 컨텐트 IMAGE VIEWER DIV 삽입
            // let _div_ctz_imgvwr = document.createElement('div');
            // _div_ctz_imgvwr.setAttribute("class", "ctz_imgvwr_frame");
            // _div_ctz_item.appendChild(_div_ctz_imgvwr);

            // // 이미지 뷰어를 사용하는 경우 경우, PLAY안내 버튼 노출
            // if (_ctzinfo[_ctzidx].images.enable == true && _ctzinfo[_ctzidx].images.files[_state.lang]) {
            //     let _div_ctz_vwrctrl = document.createElement('div');
            //     _div_ctz_vwrctrl.setAttribute("class", "ctz_mv_ctrl");
            //     // _div_ctz_vwrctrl.setAttribute("video_url", _ctzinfo[_ctzidx].video.files[_state.lang].download);
            //     _sz_styleOpt = '--playmsg: "' + _trTbl.ui.player.watch_imgshow[_state.lang] + '";';
            //     _sz_styleOpt += '--stopmsg: "' + _trTbl.ui.player.stop_imgshow[_state.lang] + '";';
            //     _div_ctz_vwrctrl.setAttribute("style", _sz_styleOpt);
            //     _div_ctz_item.appendChild(_div_ctz_vwrctrl);
            // }

            // 동영상이 있는 경우, PLAY안내 버튼 노출
            if (_ctzinfo[_ctzidx].video.enable == true && _ctzinfo[_ctzidx].video.files[_state.lang]) {
                let _div_ctz_mvctrl = document.createElement('div');
                _div_ctz_mvctrl.setAttribute("class", "ctz_mv_ctrl");
                _div_ctz_mvctrl.setAttribute("video_url", _ctzinfo[_ctzidx].video.files[_state.lang].download);
                _sz_styleOpt = '--playmsg: "' + _trTbl.ui.player.watch_movie[_state.lang] + '";';
                _sz_styleOpt += '--stopmsg: "' + _trTbl.ui.player.stop_movie[_state.lang] + '";';
                _div_ctz_mvctrl.setAttribute("style", _sz_styleOpt);
                _div_ctz_item.appendChild(_div_ctz_mvctrl);
            }

            _div_ctzgen_bglist.appendChild(_div_ctz_item);
        }

        _hndl_ctzGenBg = $('#lst_ctzgenbg');
        _hndl_ctzGenBg.owlCarousel({
            center: false,
            items: 1, //Number of Items on Screen what you want
            loop: true,
            margin: 0,
            smartSpeed: 0,
            lazyLoad: true,
            mouseDrag: false,
            touchDrag: false,
            pullDrag: false,
            freeDrag: false,
            startPosition: Number(_state.menu.main[_mmIdx][_smIdx].cur) - 1,
        });

        //서브 페이지->콘텐트 페이지 화면 전환
        $('.main .ctzgen').show(function() {
            $('.main .ctzgen .bg').show(function() {
                $('.main').animate({ top: -2160, left: 0 }, 1000, function() {
                    $('.main .sub').fadeOut(600);
                    //$('#lst_ctzgenbg').trigger('translate.owl.carousel', [0]);
                    $('#lst_ctzgenbg').trigger('translate.owl.carousel', [0, 500, true]);
                });
            });
        });


        $('#lst_ctzgenbg').on('change.owl.carousel', function(event) {
            // Update HotelTV sub menu status
            let _state = HotelTV.state;
            let _mmIdx = _state.menu.main.cur;
            let _smIdx = _state.menu.main[_mmIdx].cur;
            let _program = HotelTV.tvguide.program;
            let _ctzinfo = _program[_mmIdx].children[_smIdx].children;
            _state.menu.main[_mmIdx][_smIdx].prev = Object.keys(_ctzinfo)[event.page.index];
        });

        $('#lst_ctzgenbg').on('changed.owl.carousel', function(event) {
            // Update HotelTV sub menu status
            let _state = HotelTV.state;
            let _mmIdx = _state.menu.main.cur;
            let _smIdx = _state.menu.main[_mmIdx].cur;
            let _program = HotelTV.tvguide.program;
            let _ctzinfo = _program[_mmIdx].children[_smIdx].children;
            _state.menu.main[_mmIdx][_smIdx].cur = Object.keys(_ctzinfo)[event.page.index];

            //if (_ctzinfo[_state.menu.main[_mmIdx][_smIdx].cur].thumbnails.autoplay == true )
            {
                if (_ctzinfo[_state.menu.main[_mmIdx][_smIdx].cur].thumbnails.interval > 0 && _ctzinfo[_state.menu.main[_mmIdx][_smIdx].cur].thumbnails.files[_state.lang].length > 1) {
                    if (_hndl_tmrCtzThumbAni != null) {
                        clearInterval(_hndl_tmrCtzThumbAni);
                        _hndl_tmrCtzThumbAni = null;
                        console.log("TMR(CTZ ANI)::>Destoried...");
                    }
                    _hndl_tmrCtzThumbAni = setInterval(__uifxn_AppFull_Update_CtzThumbnail, Number(_ctzinfo[_state.menu.main[_mmIdx][_smIdx].cur].thumbnails.interval) * 1000);
                    console.log("TMR::>Created...");
                } else {
                    if (_hndl_tmrCtzThumbAni != null) {
                        clearInterval(_hndl_tmrCtzThumbAni);
                        _hndl_tmrCtzThumbAni = null;
                        console.log("TMR(CTZ ANI)::>Destoried...");
                    }
                }
            }

            if (_ctzinfo[_state.menu.main[_mmIdx][_smIdx].cur].images.autoplay == true )
            {
                // if (_ctzinfo[_state.menu.main[_mmIdx][_smIdx].cur].thumbnails.interval > 0 && _ctzinfo[_state.menu.main[_mmIdx][_smIdx].cur].thumbnails.files[_state.lang].length > 1) {
                //     if (_hndl_tmrCtzThumbAni != null) {
                //         clearInterval(_hndl_tmrCtzThumbAni);
                //         _hndl_tmrCtzThumbAni = null;
                //         console.log("TMR(CTZ ANI)::>Destoried...");
                //     }
                //     _hndl_tmrCtzThumbAni = setInterval(__uifxn_AppFull_Update_CtzThumbnail, Number(_ctzinfo[_state.menu.main[_mmIdx][_smIdx].cur].thumbnails.interval) * 1000);
                //     console.log("TMR::>Created...");
                // } else {
                //     if (_hndl_tmrCtzThumbAni != null) {
                //         clearInterval(_hndl_tmrCtzThumbAni);
                //         _hndl_tmrCtzThumbAni = null;
                //         console.log("TMR(CTZ ANI)::>Destoried...");
                //     }
                // }
            }

            console.log("CTZ(GEN) IDX::>" + _state.menu.main[_mmIdx][_smIdx].cur);
            HotelTV.api.ReportEvent([{'power': true, 'location':{'conId':_ctzinfo[_state.menu.main[_mmIdx][_smIdx].cur].id}}])

            if ( _state.menu.stage.cur=="preparing_ctz_general" ){
                setTimeout(function() {
                    _state.menu.stage.cur = "ctzgen";
                }, 2000);
            }
        });

        $('#lst_ctzgenbg').on('translate.owl.carousel', function(event) {
            // 메뉴 셀렉터 좌/우 헨들링 및 이펙트
            let idx = 0;
            if (typeof event.item != 'undefined') {
                idx = event.item.index;
            } else {
                idx = $('.main .ctzgen .bg .owl-item.active').index();
            }

            if ($('.main .ctzgen .bg .owl-item').eq(idx).hasClass('movieplay') == true) {
                if ($('.owl-theme .owl-nav.disabled+.owl-dots').css('display') != 'none') {
                    $('.owl-theme .owl-nav.disabled+.owl-dots').fadeOut(500);
                }
            } else {
                if ($('.owl-theme .owl-nav.disabled+.owl-dots').css('display') == 'none') {
                    $('.owl-theme .owl-nav.disabled+.owl-dots').fadeIn(500);
                }
            }
        });
    }


    /**
     * HotelTV UI[AppFull] Wrapper Function::> Buildup sub menu and main bg
     */
    function __uifxn_AppFull_Build_SubGeneral() {
        let _trTbl = HotelTV.translation;
        let _state = HotelTV.state;
        let _mmIdx = _state.menu.main.cur;
        let _program = HotelTV.tvguide.program;
        let _sminfo = _program[_mmIdx].children;

        if (!(_mmIdx in _state.menu.main)) {
            _state.menu.main[_mmIdx] = {
                'cnt': 0,
                'cur': null,
                'prev': null,
            };
            _state.menu.main[_mmIdx].cnt = _sminfo.length;
        }

        // 초기 메인 메뉴 KEY설정
        _state.menu.stage.cur = "preparing_sub";
        if (_state.menu.main[_mmIdx].cur == null) {
            _state.menu.main[_mmIdx].cur = Object.keys(_sminfo)[0];
        }

        // 서브 메뉴 셀렉터 노드를 동적으로 구성
        let _div_sm_slist = document.querySelector('#lst_smsel');
        for (let _idx = 1; _idx <= _sminfo.length; _idx++) {
            let _div_sm_item = document.createElement('div');
            _div_sm_item.className = 'item';
            _div_sm_item.id = _sminfo[_idx].id;
            _div_sm_item.setAttribute("smid", _idx);

            // Append Sub elements::title
            let _sm_item_title = document.createElement('div');
            _sm_item_title.setAttribute("id", "sm_item_title");

            if (_sminfo[_idx].showTitle && _sminfo[_idx].showTitle == true) {
                _sm_item_title.textContent = _sminfo[_idx].title[_state.lang];
            }

            // Append Sub elements::icon
            let _sm_item_icon = document.createElement('div');
            _sm_item_icon.setAttribute("id", "sm_item_icon");
            let _sz_styleOpt = "--icon_unfocus: url(" + _sminfo[_idx].unfocusIcon.file.download + "); ";
            _sz_styleOpt += "--icon_focus: url(" + _sminfo[_idx].focusIcon.file.download + "); ";
            //_sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom; background-size: 100% 100%; ";
            _sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom;";
            _sm_item_icon.setAttribute("style", _sz_styleOpt);

            _div_sm_item.appendChild(_sm_item_icon);
            _div_sm_item.appendChild(_sm_item_title);

            _div_sm_slist.appendChild(_div_sm_item);
        }

        // 서브 메뉴 백그라운드 이미지 노드를 동적으로 구성
        let _div_sm_bglist = document.querySelector('#lst_smbg');
        for (let _idx = 1; _idx <= _sminfo.length; _idx++) {
            let _div_sm_item = document.createElement('div');
            let _sz_styleOpt = null;

            _div_sm_item.className = 'item';
            _div_sm_item.id = _sminfo[_idx].id;
            _div_sm_item.setAttribute("smid", _idx);
            _sz_styleOpt = "background-image: url(" + _sminfo[_idx].background.file.download + "); ";
            _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: 100% 100%; ";
            _div_sm_item.setAttribute("style", _sz_styleOpt);

            //해당 서버메뉴가 하위에 콘텐트를 가지고 있는 경우
            if (_sminfo[_idx].type.toLowerCase() == 'menu') {
                // 컨텐트 썸네일 베경 화면에 삽입
                let _div_sm_ctz_frame = document.createElement('div');
                _div_sm_ctz_frame.setAttribute("class", "bg_ctz_thumb_frame");

                // 컨텐트 썸네일 타이틀(신규 콘텐트)문구 삽입
                let _div_sm_ctz_title = document.createElement('div');
                _div_sm_ctz_title.setAttribute("id", "bg_ctz_thumb_title");
                _div_sm_ctz_title.textContent = _trTbl.ui.misc.title.new_ctz[_state.lang];
                _div_sm_ctz_frame.appendChild(_div_sm_ctz_title);


                let _ctz_info = _sminfo[_idx].children;
                for (let _ctzidx = 1; _ctzidx <= _sminfo[_idx].children.length; _ctzidx++) {
                    if (Number(_ctzidx) < 4) {
                        let _div_sm_ctz_item = document.createElement('div');
                        _div_sm_ctz_item.setAttribute("id", "bg_ctz_thumb_item");
                        // 해당 서브메뉴 아이탬의 하위 콘텐트들의 첫 썸네일 이미지
                        _sz_styleOpt = "background-image: url(" + _ctz_info[_ctzidx].thumbnails.files[_state.lang][1].download + "); ";
                        _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: 100% 100%; ";
                        _sz_styleOpt += "background-color: rgba(0,0,0,0.4)";
                        _div_sm_ctz_item.setAttribute("style", _sz_styleOpt);
                        _div_sm_ctz_item.textContent = _ctz_info[_ctzidx].title[_state.lang];
                        _div_sm_ctz_frame.appendChild(_div_sm_ctz_item);
                    }
                }

                // 추가 콘텐트 갯수 표시
                if (_ctz_info.length > 3) {
                    let _div_sm_ctz_notice = document.createElement('div');
                    _div_sm_ctz_notice.setAttribute("id", "bg_ctz_thumb_morenotice");
                    let _remain_ctz_cnt = _ctz_info.length - 3;
                    let _str_remain_ctz_cnt = _trTbl.ui.submenu.info.remain_ctz_cnt;
                    _div_sm_ctz_notice.textContent = _str_remain_ctz_cnt[_state.lang].replace('__CTZCNT', _remain_ctz_cnt);
                    _div_sm_ctz_frame.appendChild(_div_sm_ctz_notice);
                }
                _div_sm_item.appendChild(_div_sm_ctz_frame);

                //Set Attribute
                _div_sm_item.setAttribute("ctzUse", true);
            } else {
                _div_sm_item.setAttribute("ctzUse", false);
                //contents_use가 1이 아닌경우, 이에 대한 페이지 활용 아이디어 필요
            }
            _div_sm_bglist.appendChild(_div_sm_item);
        }

        _hndl_smBg = $('#lst_smbg');
        _hndl_smBg.owlCarousel({
            center: true,
            items: 1, //Number of Items on Screen what you want
            loop: true,
            margin: 0,
            smartSpeed: 1000,
            lazyLoad: true,
            mouseDrag: false,
            touchDrag: false,
            pullDrag: false,
            freeDrag: false,
            startPosition: (Number(_state.menu.main[_mmIdx].cur) - 1),
        });
        $('.main .sub').show(function() {
            $('.main .mm').fadeOut(800);
        });

        _hndl_smSel = $('#lst_smsel');
        _hndl_smSel.owlCarousel({
            center: true,
            items: 3, //Number of Items on Screen what you want
            loop: true,
            margin: 0,
            smartSpeed: 0,
            autoWidth: false,
            mouseDrag: false,
            touchDrag: false,
            pullDrag: false,
            freeDrag: false,
            startPosition: (Number(_state.menu.main[_mmIdx].cur) - 1),
        });

        //메인 페이지->서브 페이지 화면 전환
        $('.main .sub .slider').show(function() {
            $('.main').animate({ top: -1080, left: 0 }, 1000, function() {

                $('.main .sub .slider .owl-item').addClass('unfocus');
                $('#lst_smsel').trigger("to.owl.carousel", [(Number(_state.menu.main[_mmIdx].cur) - 1), 10, true]);
                $('#lst_smsel').trigger('translate.owl.carousel', [0, 500, true]);

                $(document.activeElement).keydown(function(event) { //attach event listener
                    if (_state.menu.stage.cur == "sub") {
                        if (event.keyCode == gRmtKey.left) {
                            $('#lst_smsel').trigger('prev.owl', 700);
                        } else if (event.keyCode == gRmtKey.right) {
                            $('#lst_smsel').trigger('next.owl', 700);
                        } else if (event.keyCode == gRmtKey.enter) {
                            // 콘텐트 리스트 화면 빌드 및 화면 전환
                            let _program = HotelTV.tvguide.program;
                            let _mmIdx = _state.menu.main.cur;
                            if (_program[_mmIdx].type.toLowerCase() == "normal") {
                                if (_program[_mmIdx].style.toLowerCase() == "none") {
                                    console.log("Invalid options");
                                } else if (_program[_mmIdx].style.toLowerCase() == "content") {
                                    console.log("Invalid options");
                                } else if (_program[_mmIdx].style.toLowerCase() == "submenu") {
                                    console.log('DDDBUG::> Go to CTZ>');
                                    __uifxn_AppFull_Build_CtzGeneral();
                                }
                            }
                        } else if (event.keyCode == gRmtKey.back) {
                            // 컨텐트 폼의 백그라운드 에니메이션용 타이머 제거
                            if (_hndl_tmrCtzBgAni != null) {
                                clearInterval(_hndl_tmrCtzBgAni);
                                _hndl_tmrCtzBgAni = null;
                                console.log("TMR(CTZ ANI For Background)::>Destoried...");
                            }

                            // 컨텐트 폼의 썸네일 에니메이션용 타이머 제거
                            if (_hndl_tmrCtzThumbAni != null) {
                                clearInterval(_hndl_tmrCtzThumbAni);
                                _hndl_tmrCtzThumbAni = null;
                                console.log("TMR(CTZ ANI For Thumbnail)::>Destoried...");
                            }

                            // 메인 메뉴로 귀환
                            $(document.activeElement).off('keydown');
                            $('.main .mm').show(function() {
                                $('#lst_mmsel').trigger('translate.owl.carousel', [0]);
                            });
                            $('.main').animate({ top: 0, left: 0 }, 1000, () => {
                                $('#lst_smsel').off('refresh.owl.carousel');
                                $('#lst_smsel').off('change.owl.carousel');
                                $('#lst_smsel').off('changed.owl.carousel');
                                $('#lst_smsel').off('translate.owl.carousel');

                                $('#lst_smbg').owlCarousel('destroy');
                                $('#lst_smsel').owlCarousel('destroy');

                                $('.main .sub .slider #lst_smsel div').remove();
                                $('.main .sub .bg #lst_smbg div').remove();
                                $('.main .sub').hide();
                                _hndl_smSel = null;
                                _hndl_smBg = null;
                                _state.menu.stage.cur = "main"
                                setTimeout(function() {
                                    __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
                                }, 500);
                            });
                        }
                    } else if (_state.menu.stage.cur == "ctzgen") {
                        if (event.keyCode == gRmtKey.left) {
                            $('#lst_ctzgenbg').trigger('prev.owl', 700);
                        } else if (event.keyCode == gRmtKey.right) {
                            $('#lst_ctzgenbg').trigger('next.owl', 700);
                        } else if (event.keyCode == gRmtKey.back) {
                            _state.menu.stage.cur = "preparing_sub";
                            $('.main .sub').show(0, function(){
                                $('.main').animate({ top: -1080, left: 0 }, 1000, () => {
                                    $('.main .ctzgen').hide();
                                    _state.media.playing = false;
                                    HotelTV.hal.MediaStop(null, null);

                                    $('#lst_ctzgenbg').off('refresh.owl.carousel');
                                    $('#lst_ctzgenbg').off('change.owl.carousel');
                                    $('#lst_ctzgenbg').off('changed.owl.carousel');
                                    $('#lst_ctzgenbg').off('translate.owl.carousel');
                                    $('#lst_ctzgenbg').owlCarousel('destroy');
                                    $('.main .ctzgen .bg #lst_ctzgenbg div').remove();
                                    _hndl_ctzGenBg = null;
                                    $('#lst_smsel').trigger('translate.owl.carousel', [0]);
                                    _state.menu.stage.cur = "sub";
                                    console.log('DDDBUG::> Return to SUB>');
                                });
                            });

                        } else if (event.keyCode == gRmtKey.play) {
                            if ($('.main .ctzgen .bg .owl-carousel .owl-item.active .ctz_mv_ctrl').length == 1) {
                                let uri_video = $($('.main .ctzgen .bg .owl-carousel .owl-item.active .ctz_mv_ctrl')[0]).attr('video_url');
                                if (uri_video != null) {
                                    HotelTV.hal.MediaPlay(
                                        uri_video,
                                        "",
                                        "video/mp4",
                                        1,
                                        () => {
                                            console.log("STARTUP Done CB.");
                                        },
                                        () => {
                                            console.log("STARTUP Fail CB.");
                                        }
                                    );
                                }
                            }
                        } else if (event.keyCode == gRmtKey.stop) {
                            if (_state.media.playing == true) {
                                _state.media.playing = false;
                                HotelTV.hal.MediaStop(
                                    function() {
                                        $('.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item').removeClass('movieplay');
                                        $('.owl-theme .owl-nav.disabled+.owl-dots').fadeIn(1000);
                                    },
                                    function() {
                                        $('.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item').removeClass('movieplay');
                                        $('.owl-theme .owl-nav.disabled+.owl-dots').fadeIn(1000);
                                    });
                            }
                        } else {
                            console.log('CTZ MENU: KEY::> ' + event.keyCode);
                        }
                    } else {
                        console.log("SUBMENU KEYEVT: Skip events");
                    }
                });
                _state.menu.stage.cur = "sub";
            });
        });

        $('#lst_smsel').on('change.owl.carousel', function(event) {
            // Update HotelTV sub menu status
            let _state = HotelTV.state;
            let _mmIdx = _state.menu.main.cur;
            let _sminfo = HotelTV.tvguide.program[_mmIdx].children;
            _state.menu.main[_mmIdx].prev = Object.keys(_sminfo)[event.page.index];
        });

        $('#lst_smsel').on('changed.owl.carousel', function(event) {
            // Update HotelTV sub menu status
            let _state = HotelTV.state;
            let _mmIdx = _state.menu.main.cur;
            let _sminfo = HotelTV.tvguide.program[_mmIdx].children;
            _state.menu.main[_mmIdx].cur = Object.keys(_sminfo)[event.page.index];
            //console.log("SUB IDX::>" + _state.menu.main[_mmIdx].cur);
            __uifxn_AppFull_OnKeyDnEvt_SmSel(event);

            HotelTV.api.ReportEvent([{'power': true, 'location':{'conId':_sminfo[_state.menu.main[_mmIdx].cur].id}}])
        });

        $('#lst_smsel').on('translate.owl.carousel', function(event) {
            // 메뉴 셀렉터 좌/우 헨들링 및 이펙트
            let _uiCtrl_idx = 0;
            if (typeof event.item != 'undefined') {
                _uiCtrl_idx = event.item.index;
            } else {
                _uiCtrl_idx = $('.main .sub .slider .owl-item.active.center').index();
            }
            //console.log("SUB UI CTRL IDX::>" + _uiCtrl_idx);
            $('.main .sub .slider .owl-item.focus').addClass('unfocus');
            $('.main .sub .slider .owl-item.focus').removeClass('focus');
            $('.main .sub .slider .owl-item').eq(_uiCtrl_idx).addClass('focus');
            $('.main .sub .slider .owl-item').eq(_uiCtrl_idx).removeClass('unfocus');
        });
    }


    /**
     * HotelTV UI[AppFull] Wrapper Function::> Buildup sub menu and main bg
     */
    function __uifxn_AppFull_Build_SubTv() {
        let _state = HotelTV.state;
        let _mmIdx = _state.menu.main.cur;
        let _trTbl = HotelTV.translation;
        let _programTv = HotelTV.tvguide.program[_mmIdx];
        let _tvCtgyInfoAll = _programTv.categories;

        const __ifxn_exitTvMenu = function() {
            // 현재 재생중인 TV채널 종료
            HotelTV.hal.ChannelShutDown();

            if (_hndl_tmrTvChnMngr != null) {
                clearInterval(_hndl_tmrTvChnMngr);
                _hndl_tmrTvChnMngr = null;
                console.log("TMR::>Destoried...");
            }

            if (_hndl_tmrTvShortcutMngr != null) {
                clearInterval(_hndl_tmrTvShortcutMngr);
                _hndl_tmrTvShortcutMngr = null;
                console.log("TMR::>Destoried...");
            }

            // 메인 메뉴로 귀환
            $(document.activeElement).off('keydown');
            $('.main .mm').show(function() {
                $('#lst_mmsel').trigger('refresh.owl.carousel', [0]);
            });

            $('.main').animate({ top: 0, left: 0 }, 1000, () => {
                $('#lst_tvCtgyFrm').off('refresh.owl.carousel');
                $('#lst_tvCtgyFrm').off('change.owl.carousel');
                $('#lst_tvCtgyFrm').off('changed.owl.carousel');
                $('#lst_tvCtgyFrm').off('translated.owl.carousel');

                $('#lst_tvCtgyFrm').owlCarousel('destroy');

                $('.main .tv .bg #lst_tvCtgyFrm div').remove();
                _hndl_tvCtgyFrm = null;
                _state.menu.stage.cur = "main";

                setTimeout(function() {
                    __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
                    __uifxn_AppFull_TopWidjetShow(true);
                }, 500);
            });
        }

        const __ifxn_moveTvChannel = function(_tvCtgyDataAll, _action) {
            let _mmIdx = _state.menu.main.cur;
            let _curChCtg = _state.menu.main[_mmIdx].cur;
            let _curChCntInCtg = Number(_state.menu.main[_mmIdx][_curChCtg].cnt);
            let _curChIdx = Number(_state.menu.main[_mmIdx][_curChCtg].cur);

            if ( _action=="ch_up" ){
                if ((_curChIdx - 1) >= 1) {
                    _curChIdx -= 1;
                } else {
                    _curChIdx = _curChCntInCtg;
                }
                _state.menu.main[_mmIdx][_curChCtg].cur = _curChIdx.toString();
                console.log(`TVCTG[${_tvCtgyDataAll[_curChCtg].name}] CUR CH::>${_state.menu.main[_mmIdx][_curChCtg].cur}`);

                __uifxn_AppFull_TVUpdateChannel("ch_up");
            }else if ( _action=="ch_down" ) {
                if ((_curChIdx + 1) <= _curChCntInCtg) {
                    _curChIdx += 1;
                } else {
                    _curChIdx = 1;
                }
                _state.menu.main[_mmIdx][_curChCtg].cur = _curChIdx.toString();
                console.log(`TVCTG[${_tvCtgyDataAll[_curChCtg].name}] CUR CH::>${_state.menu.main[_mmIdx][_curChCtg].cur}`);

                __uifxn_AppFull_TVUpdateChannel("ch_down");
            }
        }

        // 초기 채널 카테고리 슬라이더 표시 시간 증가
        _tmrEvt.keyevt.tv_ctrl = new Date();
        _tmrEvt.keyevt.tv_ctrl.setSeconds(_tmrEvt.keyevt.tv_ctrl.getSeconds() + 3);

        if (!(_mmIdx in _state.menu.main)) {
            _state.menu.main[_mmIdx] = {
                'cnt': 0,
                'cur': null, //현재 TV카테고리
                'prev': null, //마지막 TV카테고리
            };
            // TV Program category 개수
            _state.menu.main[_mmIdx].cnt = _tvCtgyInfoAll.length;
        }

        // state내의 tv shortcut key관련 상태값 초기화및 화면 숨김
        // mode_0에서는 ch_item_idx를 null로하고, mode_1에서는 ch_item_idx를 1로 초기화함.
        _state.tv.shortkey = {
            "idx": "1",
            "scroll_offset": 0,
            "ch_item_idx": 1,
        };

        if ( _programTv.shortcutkeyMode=="mode_0" ) {
            _state.tv.shortkey.ch_item_idx = null;
        }

        // 초기 메인 메뉴 KEY설정
        _state.menu.stage.cur = "tvPreparing";
        if (_state.menu.main[_mmIdx].cur == null) {
            _state.menu.main[_mmIdx].cur = Object.keys(_tvCtgyInfoAll)[0];

            // 각 채널 카테고리별 채널 개수 및 이전 시청 채널 과 현재 시청 채널 정보 초기화
            for (let _i = 1; _i <= _tvCtgyInfoAll.length; _i++) {
                _state.menu.main[_mmIdx][_i] = {
                    'cnt': 0,
                    'cur': null,
                    'prev': null,
                };
                _state.menu.main[_mmIdx][_i].cnt = _tvCtgyInfoAll[_i].channels.length;
                _state.menu.main[_mmIdx][_i].cur = Object.keys(_tvCtgyInfoAll[_i].channels)[0];
            }
        }

        // TV 메뉴 카테고리 노드를 동적으로 구성
        let _div_tvCgh_bglist = document.querySelector('#lst_tvCtgyFrm');
        for (let _tvCtg_idx = 1; _tvCtg_idx <= _tvCtgyInfoAll.length; _tvCtg_idx++) {
            let _tvCtgItem = _tvCtgyInfoAll[_tvCtg_idx];
            let _div_tvCtg_frame = document.createElement('div');
            let _sz_styleOpt = null;

            // TV 메뉴 카테고리 노드를 동적으로 구성
            _div_tvCtg_frame.className = 'item';
            _div_tvCtg_frame.id = 'tvctgfrm_' + _tvCtgItem.name.replace(/\s/g, '').toLowerCase();
            _div_tvCtg_frame.setAttribute("tvctgidx", _tvCtg_idx);

            // TV 카테고리 타이틀
            let _div_tvCtg_title = document.createElement('div');
            _div_tvCtg_title.setAttribute("id", "tvctg_title");
            _div_tvCtg_title.textContent = _trTbl.ui.tv.title.category[_tvCtgItem.name][_state.lang];
            _div_tvCtg_frame.appendChild(_div_tvCtg_title);

            //TV 카테고리 프레임 엘리멘트에 Child엘레멘트 추가
            _div_tvCgh_bglist.appendChild(_div_tvCtg_frame);
        }

        _hndl_tvCtgyFrm = $('#lst_tvCtgyFrm');

        //owlCarousel을 초기화 하기 전에 등록해야할 callback 함수들
        //initialized.owl.carousel같은 이벤트는 생성하기 전에 등록해야함.
        //이벤트 발생 순서는 대략 아래와 같음.
        //[1]change
        //[2]changed
        //[3]prepared
        //[4]initialized
        //[5]refresh
        //[6]translate

        _hndl_tvCtgyFrm.owlCarousel({
            center: true,
            items: 1, //Number of Items on Screen what you want
            loop: true,
            margin: 0,
            nav: true,
            dots: false,
            autoWidth:false,
            smartSpeed: 100,
            lazyLoad: true,
            mouseDrag: false,
            touchDrag: false,
            pullDrag: false,
            freeDrag: false,
            startPosition: (Number(_state.menu.main[_mmIdx].cur) - 1),
        });
        $('.main .tv .bg').show(function() {
            $('.main .mm').fadeOut(1000);
            $('.main').animate({ top: -1080, left: 0 }, 1000, function() {
                // Create Timer handle for TV EPG OSD & Shortcut key popup show/hide
                if (_hndl_tmrTvChnMngr == null) {
                    _hndl_tmrTvChnMngr = setInterval(__uifxn_AppFull_TVChMngrUi, 500);
                    console.log("TMR(TVChMngrUi)::>Created...");
                }

                $('#lst_tvCtgyFrm').trigger('translated.owl.carousel', [0]);

                $(document.activeElement).keydown(function(event) { //attach event listener
                    if (_state.menu.stage.cur == "tvCtgShow") {
                        if (event.keyCode == gRmtKey.left) {
                            // TODO:: mode_0에서 카테고리 ALL만 사용, 향후 다른 카테고리도 사용할수 있는 방안 모색
                            //$('#lst_tvCtgyFrm').trigger('prev.owl', [1000])
                        } else if (event.keyCode == gRmtKey.right) {
                            // TODO:: mode_0에서 카테고리 ALL만 사용, 향후 다른 카테고리도 사용할수 있는 방안 모색
                            //$('#lst_tvCtgyFrm').trigger('next.owl', [1000])
                        } else if (event.keyCode == gRmtKey.up || event.keyCode == gRmtKey.chup) {
                            // 채널 리스트 아이탬 이동(UP)
                            __ifxn_moveTvChannel(_tvCtgyInfoAll, "ch_down");
                        } else if (event.keyCode == gRmtKey.down || event.keyCode == gRmtKey.chdown) {
                            // 채널 리스트 아이탬 이동(DOWN)
                            __ifxn_moveTvChannel(_tvCtgyInfoAll, "ch_up");
                        } else if (event.keyCode == gRmtKey.enter) {
                            // TV채널 플레이
                        } else if (event.keyCode == gRmtKey.back) {
                            // TV 메뉴를 종료하고 메인 메뉴로 이동
                            __ifxn_exitTvMenu();
                        } else if ( __uifxn_Utils_CheckKeyisNumber(event.keyCode)==true  ){
                            //Navigate TV shortcut lists
                            if ( _programTv.shortcutkeyMode=="mode_0" ) {
                                _state.menu.stage.cur = "tvShortcut";
                                __uifxn_AppFull_TVDrawShortcutKey_Mode0(event.keyCode);
                            } else if ( _programTv.shortcutkeyMode=="mode_1" ) {
                                if ( __uifxn_AppFull_TVDrawShortcutKey_Mode1(true, "build", event.keyCode)==0 ){
                                    _state.menu.stage.prev = _state.menu.stage.cur;
                                    _state.menu.stage.cur = "tvShortcut";
                                }
                            }
                        }
                    } else if (_state.menu.stage.cur == "tvCtgHide") {
                        if (event.keyCode == gRmtKey.left) {
                            //$('#lst_tvCtgyFrm').trigger('prev.owl', [1000])
                        } else if (event.keyCode == gRmtKey.right) {
                            //$('#lst_tvCtgyFrm').trigger('next.owl', [1000])
                        } else if (event.keyCode == gRmtKey.up || event.keyCode == gRmtKey.chup) {
                            // 채널 리스트 아이탬 이동(CHUP)
                            __ifxn_moveTvChannel(_tvCtgyInfoAll, "ch_down");
                        } else if (event.keyCode == gRmtKey.down || event.keyCode == gRmtKey.chdown) {
                            // 채널 리스트 아이탬 이동(CHDOWN)
                            __ifxn_moveTvChannel(_tvCtgyInfoAll, "ch_up");
                        } else if (event.keyCode == gRmtKey.back) {
                            // TV 메뉴를 종료하고 메인 메뉴로 이동
                            __ifxn_exitTvMenu();
                        } else if ( __uifxn_Utils_CheckKeyisNumber(event.keyCode)==true ) {
                            //Navigate TV shortcut lists
                            if ( _programTv.shortcutkeyMode=="mode_0" ) {
                                _state.menu.stage.cur = "tvShortcut";
                                __uifxn_AppFull_TVDrawShortcutKey_Mode0(event.keyCode);
                            } else if ( _programTv.shortcutkeyMode=="mode_1" ) {
                                if ( __uifxn_AppFull_TVDrawShortcutKey_Mode1(true, "build", event.keyCode)==0 ){
                                    _state.menu.stage.prev = _state.menu.stage.cur;
                                    _state.menu.stage.cur = "tvShortcut";
                                }
                            }
                        } else {
                            console.log("event.keyCode::>" + event.keyCode);
                        }
                    } else if (_state.menu.stage.cur == "tvShortcut") {
                        // console.log("TV shortcut routine: key:" + event.keyCode);
                        if (event.keyCode == gRmtKey.back) {
                            // TV메뉴로 복귀
                            if ( _programTv.shortcutkeyMode=="mode_0" ) {
                                //
                            } else if ( _programTv.shortcutkeyMode=="mode_1" ) {
                                __uifxn_AppFull_TVDrawShortcutKey_Mode1(false, "exitWithoutChchange", event.keyCode);
                            }
                            _state.menu.stage.cur = _state.menu.stage.prev;
                            _state.menu.stage.prev = null;
                        } else if (event.keyCode == gRmtKey.enter) {
                            // 번호키를 이용한 채널 선택 팝업 삭제
                            if ( _programTv.shortcutkeyMode=="mode_0" ) {
                                //
                            } else if ( _programTv.shortcutkeyMode=="mode_1" ) {
                                __uifxn_AppFull_TVDrawShortcutKey_Mode1(false, "exitWithChchange", event.keyCode);
                            }
                            _state.menu.stage.cur = _state.menu.stage.prev;
                            _state.menu.stage.prev = null;

                            _tmrEvt.keyevt.tv_ctrl = new Date();
                            _tmrEvt.keyevt.tv_ctrl.setSeconds(_tmrEvt.keyevt.tv_ctrl.getSeconds() - 3);
                        } else if ( __uifxn_Utils_CheckKeyisNumber(event.keyCode)==true ) {
                            if ( _programTv.shortcutkeyMode=="mode_0" ) {
                                __uifxn_AppFull_TVDrawShortcutKey_Mode0(event.keyCode);
                            }
                        } else {
                            if ( _programTv.shortcutkeyMode=="mode_0" ) {
                                //
                            } else if ( _programTv.shortcutkeyMode=="mode_1" ) {
                                __uifxn_AppFull_TVDrawShortcutKey_Mode1(true, "move", event.keyCode);
                            }
                            console.log("TVSHORTCUT CHNUM: " + _state.tv.shortkey.ch_item_idx);
                        }
                    } else {
                        console.log("TVMENU KEYEVT: Skip events::> Invalid menu stage:" + _state.menu.stage.cur);
                    }
                });
            });
        });

        $('#lst_tvCtgyFrm').on('translated.owl.carousel', function(event) {
            __uifxn_AppFull_TVUpdateChannel("on_load");
            // HotelTV.ui_utils.ShowNotificationMsgBalloon(_trTbl.ui.guide.navi_tvcategory[_state.lang], 10);
        });


        $('#lst_tvCtgyFrm').on('changed.owl.carousel', function(event) {
            // Update HotelTV sub menu status
            let _state = HotelTV.state;
            let _mmIdx = _state.menu.main.cur;
            let _hndlOwlEl = $('.main .tv .bg .owl-carousel#lst_tvCtgyFrm .owl-stage-outer .owl-item');
            let _acvatedEl = null;
            let _curChCtgyIdx = null;
            let _bHasValidData = false;

            if (_hndlOwlEl) {
                _acvatedEl = $(_hndlOwlEl.children()[event.item.index]);
                if (_acvatedEl) {
                    _curChCtgyIdx = _acvatedEl.attr('tvctgidx');
                }
            }

            // if (_bHasValidData != true) {
            //     return;
            // }

            // 현재 채널 카테고리 인덱스 갱신
            _state.menu.main[_mmIdx].prev = _state.menu.main[_mmIdx].cur;
            _state.menu.main[_mmIdx].cur = _curChCtgyIdx;
            console.log("CHANGED TV CATEGORY::> CURRENT TV CTG IDX::> " + _curChCtgyIdx);
        });
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> Buildup language selector popup menu
     */
    function __uifxn_AppFull_Build_LangSel() {
        let _state = HotelTV.state;
        let _trTbl = HotelTV.translation;
        let _langInf = HotelTV.opening.languages;
        let _elLangSelDiv = $('.popup>.lang_selection');
        let _elLangSelCtrlDiv = $('.popup>.lang_selection .selector');
        let _elLangSelTitleDiv = _elLangSelCtrlDiv.children('.title');
        let _elLangSelUsageDiv = _elLangSelCtrlDiv.children('.usage');
        let _elLangSelButtonsDiv = _elLangSelCtrlDiv.children('.buttons');

        // 초기 메인 메뉴 KEY설정
        _state.menu.stage.cur = "language_selection";

        // Reset language total count as 1
        _state["langTotalCnt"] = 1;
        // Remove all items unter _elLangSelButtonsDiv
        _elLangSelButtonsDiv.children().remove();

        const ___ifxn_drawLangButtons = function() {
            for (let __lang in _langInf) {
                console.log("Lang==>" + __lang);
                let _elDiv_LangBtn = document.createElement('div');
                if ( __lang===_state.lang ){
                    _elDiv_LangBtn.className = 'langBtn focus';
                } else {
                    _elDiv_LangBtn.className = 'langBtn';
                }
                _elDiv_LangBtn.id = __lang;
                _elDiv_LangBtn.setAttribute("lang_idx", _state["langTotalCnt"]);
                _elDiv_LangBtn.innerHTML = _langInf[__lang].name;
                _state["langTotalCnt"] += 1;
                _elLangSelButtonsDiv.append(_elDiv_LangBtn);
            }
        }

        // Title
        _elLangSelTitleDiv.text(_trTbl.system.szsellanguage[_state.lang]);

        // Usages
        _elLangSelUsageDiv.html(_trTbl.system.lang_sel_usage[_state.lang]);

        // Draw Lang Buttons
        ___ifxn_drawLangButtons();

        // Language selection 프레임 활성화
        if ( _elLangSelDiv.css('display') == "none")  {
            _elLangSelDiv.fadeIn(1000);
        }
    }

    function __uifxn_AppFull_HandleLangSelect(_action, _cbFxn=null) {
        let _state = HotelTV.state;
        let _trTbl = HotelTV.translation;
        let _langInf = HotelTV.opening.languages;
        let _elLangSelDiv = $('.popup>.lang_selection');
        let _elLangSelCtrlDiv = $('.popup>.lang_selection .selector');
        let _elLangSelTitleDiv = _elLangSelCtrlDiv.children('.title');
        let _elLangSelUsageDiv = _elLangSelCtrlDiv.children('.usage');
        let _elLangSelButtonsDiv = _elLangSelCtrlDiv.children('.buttons');

        const ___ifxn_updateLangSelTitleAndUsages = function() {
            let __focusedLang = "en-US";
            if ( _elLangSelButtonsDiv.find('.focus').length ) {
                __focusedLang = _elLangSelButtonsDiv.find('.focus').attr('id');
            }

            // Title
            _elLangSelTitleDiv.text(_trTbl.system.szsellanguage[__focusedLang]);

            // Usages
            _elLangSelUsageDiv.html(_trTbl.system.lang_sel_usage[__focusedLang]);
        }


        const ___ifxn_moveLangButton = function(_direction) {
            let selectedBtnItemCur = _elLangSelButtonsDiv.find('.focus');
            let selectedBtnItemNext = null;

            if ( _direction=="down" ){
                selectedBtnItemNext = selectedBtnItemCur.next(".langBtn");
            } else if ( _direction=="up" ) {
                selectedBtnItemNext = selectedBtnItemCur.prev(".langBtn");
            }

            selectedBtnItemCur.removeClass("focus");

            if (selectedBtnItemNext.length) {
                selectedBtnItemNext.addClass('focus');
            }else{
                if ( _direction=="down" ){
                    _elLangSelButtonsDiv.find('.langBtn').first().addClass("focus");
                } else if ( _direction=="up" ) {
                    _elLangSelButtonsDiv.find('.langBtn').last().addClass("focus");
                }
            }

            ___ifxn_updateLangSelTitleAndUsages();
        }

        const __ifxn_sendNextLangUsrData = async function(_nextLang, __cbFxnFailure=null, __cbFxn_Success=null) {
            try {
                let found_dev_locale = false;
                // SET PLATFORM LANGUAGE
                // HotelTV.hal.SetPlatformLanguage(_state.lang);
                if ( 'getLocaleList' in HotelTV.devinfo )
                {
                    for( let _localeIdx in HotelTV.devinfo.getLocaleList )
                    {
                        if ( HotelTV.devinfo.getLocaleList[_localeIdx].specifier== _nextLang ){
                            found_dev_locale = true;
                            break;
                        }
                    }
                }
                if ( found_dev_locale==true ){
                    HotelTV.hal.SetDeviceLocale(_nextLang);
                }else{
                    console.log("Set Default device locale set to en-US");
                    HotelTV.hal.SetDeviceLocale('en-US');
                }

                let _usrDataJson = {
                    'next_lang': _nextLang,
                };
                _result = await HotelTV.api.SetUsrDataset(_usrDataJson);
                console.log("The app main page will be reloaded");
                window.location.replace('./app_hoteltv_full.html');
            } catch ( __err ){
                console.log("CALL API::>" + __err);
                _elLangSelDiv.fadeOut(1000, function() {
                    if ( __cbFxnFailure ){ __cbFxnFailure(); }
                });
            }
        }


        if ( _action=="up" ) {
            ___ifxn_moveLangButton(_action);
        } else if ( _action=="down" ) {
            ___ifxn_moveLangButton(_action);
        } else if ( _action=="back") {
            _elLangSelDiv.fadeOut(1000, function() {
                if ( _cbFxn ){ _cbFxn(); }
            });
        } else if ( _action=="enter") {
            if ( _elLangSelButtonsDiv.find('.focus').length ) {
                __ifxn_sendNextLangUsrData(_elLangSelButtonsDiv.find('.focus').attr('id'), _cbFxn);
            } else {
                __ifxn_sendNextLangUsrData("en-US", _cbFxn);
            }
        }

    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> Bottom Guide Bar UI mngr
     */
    function __uifxn_AppFull_GuideBarUiMngr() {
        let _state = HotelTV.state;
        let _newsInfo = HotelTV.news;
        let _trTbl = HotelTV.translation;

        let _tm_diff_ms_guibar = 0;

        let _tm_cur = new Date();
        _tm_diff_ms_guibar = Math.floor(_tm_cur.getTime() - _tmrEvt.keyevt.last_uibar);
        //마지막 KEY 이벤트 수신 시간 갱신
        //console.log(`KeyDn Event Recoreded::> ${_tmrEvt.keyevt.last_uibar} TMDiff::> ${_tm_diff_ms_guibar}`);

        if (_state.menu.stage.cur == "mypage_popup_message_card") {
            //HIDE NEWS and USER GUIDE TIPS
            if (_newsInfo == null || _newsInfo.length == 0) {
                if ($('.news').css('display') != "none") {
                    $('.news').hide();
                }
            }

            if ($('.guide>.tips').css('display') != "none") {
                $('.guide>.tips').fadeOut(500);
            }
            return;
        }

        // 가이드 UI 지속 시간 8초
        if (_state.media.playing == false) {
            if (_tm_diff_ms_guibar < 8000)
            {
                //KEY이벤트 발생이 8초 이내인경우
                //SHOW USER GUIDE TIPS
                //let show_stages = ["hotkey_mm_red", "hotkey_mm_green", "hotkey_mm_yellow", "hotkey_mm_blue", "main", "sub", "ctzgen", "tvCtgShow", "tvCtgHide", "mypage_select_menu"];
                let show_stages = ["hotkey_mm_red", "hotkey_mm_green", "hotkey_mm_yellow", "hotkey_mm_blue", "main", "sub", "ctzgen", "mypage_select_menu"];
                // Check needed shows up bottom user guide, update user guide sentance.
                if (show_stages.includes(_state.menu.stage.cur) == true) {
                    const ___ifxn_updateGuideMsg = function(_szMsg) {
                        if ($('.guide>.tips').attr("value") != _szMsg) {
                            $('.guide>.tips').attr("value", _szMsg);
                            $('.guide>.tips').html(_szMsg);
                        }
                    }

                    switch (_state.menu.stage.cur) {
                        case "hotkey_mm_red":
                            ___ifxn_updateGuideMsg(_trTbl.ui.guide.navi_brochure[_state.lang]);
                            break;
                        case "hotkey_mm_green":
                            ___ifxn_updateGuideMsg(_trTbl.ui.guide.navi_brochure[_state.lang]);
                            break;
                        case "hotkey_mm_yellow":
                            ___ifxn_updateGuideMsg(_trTbl.ui.guide.navi_brochure[_state.lang]);
                            break;
                        case "hotkey_mm_blue":
                            ___ifxn_updateGuideMsg(_trTbl.ui.guide.navi_brochure[_state.lang]);
                            break;
                        case "main":
                            ___ifxn_updateGuideMsg(_trTbl.ui.guide.navi_menu[_state.lang]);
                            break;
                        case "sub":
                            ___ifxn_updateGuideMsg(_trTbl.ui.guide.navi_menu[_state.lang]);
                            break;
                        case "ctzgen":
                            ___ifxn_updateGuideMsg(_trTbl.ui.guide.navi_ctz[_state.lang]);
                            break;
                        case "tvCtgShow":
                        case "tvCtgHide":
                            ___ifxn_updateGuideMsg(_trTbl.ui.guide.navi_tvchannel[_state.lang]);
                            break;
                    }

                    if ($('.guide>.tips').css('display') == "none") {
                        $('.guide>.tips').fadeIn(500, function() {
                            //HIDE NEWS
                            if (_newsInfo == null || _newsInfo.length == 0) {
                                if ($('.news').css('display') != "none") {
                                    $('.news').hide();
                                }
                            } else {
                                if ($('.news').css('display') != "none") {
                                    if ($('.news>.newsctz #hoteltv-news-ticker').children().length > 0) {
                                        $('.news>.newsctz #hoteltv-news-ticker').webTicker('stop');
                                        $('.news').fadeOut(500);
                                    }
                                }
                            }
                        });
                    }
                } else {
                    if ($('.guide>.tips').css('display') == "block") {
                        $('.guide>.tips').fadeOut(500);
                    }

                    if ($('.news').css('display') != "none") {
                        if ($('.news>.newsctz #hoteltv-news-ticker').children().length > 0) {
                            $('.news>.newsctz #hoteltv-news-ticker').webTicker('stop');
                            $('.news').fadeOut(500);
                        }
                    }
                }
            }
            else
            {
                //KEY이벤트 발생이 8초가 초과한경우
                //HIDE TIPS and then SHOW NEWS
                if ($('.guide>.tips').css('display') == "block") {
                    $('.guide>.tips').fadeOut(500, function() {
                        if (_newsInfo == null || _newsInfo.length == 0) {
                            if ($('.news').css('display') != "none") {
                                $('.news').hide();
                            }
                        } else {
                            if ( _state.menu.stage.cur=="tvCtgShow" || _state.menu.stage.cur=="tvCtgHide" )
                            {

                            }
                            else
                            {
                                if ($('.news').css('display') != "block") {
                                    $('.news').fadeIn(500, function() {
                                        __uifxn_AppFull_BuildNews();
                                        $('.news>.newsctz #hoteltv-news-ticker').webTicker('cont');
                                    });
                                }
                            }
                        }
                    });
                } else {
                    if (_newsInfo == null || _newsInfo.length == 0) {
                        if ($('.news').css('display') != "none") {
                            $('.news').hide();
                        }
                    } else {
                        if ( _state.menu.stage.cur=="tvCtgShow" || _state.menu.stage.cur=="tvCtgHide" )
                        {
                            // if ($('.news').css('display') != "block") {
                            //     if ($('.news>.newsctz #hoteltv-news-ticker').children().length > 0) {
                            //         $('.news>.newsctz #hoteltv-news-ticker').webTicker('stop');
                            //         $('.news').fadeOut(500);
                            //     }
                            // }
                        }
                        else
                        {
                            if ($('.news').css('display') != "block") {
                                $('.news').fadeIn(500, function() {
                                    __uifxn_AppFull_BuildNews();
                                    $('.news>.newsctz #hoteltv-news-ticker').webTicker('cont');
                                });
                            }
                        }
                    }
                }
            }
        } else {
            //HIDE NEWS and USER GUIDE TIPS
            if (_newsInfo == null || _newsInfo.length == 0) {
                if ($('.news').css('display') != "none") {
                    $('.news').hide();
                }
            }


            if ($('.guide>.tips').css('display') != "none") {
                $('.guide>.tips').fadeOut(500, function() {
                    if (_newsInfo == null || _newsInfo.length == 0) {
                        if ($('.news').css('display') != "none") {
                            $('.news').hide();
                        }
                    } else {
                        if ($('.news').css('display') != "none") {
                            if ($('.news>.newsctz #hoteltv-news-ticker').children().length > 0) {
                                $('.news>.newsctz #hoteltv-news-ticker').webTicker('stop');
                                $('.news').fadeOut(500);
                            }
                        }
                    }
                });
            }
        }
    }


    /**
     * HotelTV UI Wrapper Function::> received event handling function
     * @param {boolean} _evt event
     */
    function __uifxn_AppFull_OnKeyDnEvt_MmSel(_evt) {
        let _program = HotelTV.tvguide.program;
        let _state = HotelTV.state;

        if ((_program[(_evt.page.index + 1)].type == "weather") || (_program[(_evt.page.index + 1)].type == "flight")) {
            __uifxn_AppFull_HotKey_ShowBtnOnMM(false);
        } else {
            __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
        }

        //console.log(`Evnt: ${_evt.item.index} Of ${_evt.item.count} page::> ${_evt.page.index} of ${_evt.page.count}`);
        //Shows Up Weather Contents
        if (_program[(_evt.page.index + 1)].type == "weather") {
            if ($('.main .mm .weather').css("display") == "none") {
                $('.main .mm .weather').fadeIn(1000);
            }
        } else {
            if ($('.main .mm .weather').css("display") != "none") {
                $('.main .mm .weather').fadeOut(300);
            }
        }

        //Shows Up Flight Contents
        if (_program[(_evt.page.index + 1)].type == "flight") {
            $('.main .mm .flight').each(function (index, docObjFlight) {
                //console.log(index);
                if ( $(docObjFlight).css("display")!="none" ){
                    if ( $(docObjFlight).find('#record').length>0 ){
                        $(docObjFlight).find('#record').scrollTop(0);
                    }
                    $(docObjFlight).fadeOut(300);
                }
            });

            if ($(`.main .mm #flight_${_program[(_evt.page.index + 1)].location}`).css("display") == "none") {
                $(`.main .mm #flight_${_program[(_evt.page.index + 1)].location}`).fadeIn(1000, () => {
                    $(document.activeElement).keydown(function(_evt) {
                        let _curPos = 0;
                        let _maxHeight = 0;

                        switch (_evt.keyCode) {
                            case gRmtKey.up:
                                _curPos = $(`.main .mm #flight_${_program[_state.menu.main.cur].location} .departure tbody#record`).scrollTop();
                                _maxHeight = $(`.main .mm #flight_${_program[_state.menu.main.cur].location} .departure tbody#record`)[0].scrollHeight;
                                _curPos = (_curPos - 50) < 0 ? 0 : (_curPos - 50);
                                $('.main .mm .flight tbody#record').scrollTop(_curPos);
                                break;

                            case gRmtKey.down:
                                _curPos = $(`.main .mm #flight_${_program[_state.menu.main.cur].location} .departure tbody#record`).scrollTop();
                                _maxHeight = $(`.main .mm #flight_${_program[_state.menu.main.cur].location} .departure tbody#record`)[0].scrollHeight;
                                _curPos = (_curPos + 50) > _maxHeight ? _maxHeight : (_curPos + 50);
                                $('.main .mm .flight tbody#record').scrollTop(_curPos);
                                break;
                        }
                    });
                });
            }
        } else {
            $('.main .mm .flight').each(function (index, docObjFlight) {
                //console.log(index);
                if ( $(docObjFlight).css("display")!="none" ){
                    if ( $(docObjFlight).find('#record').length>0 ){
                        $(docObjFlight).find('#record').scrollTop(0);
                    }
                    $(docObjFlight).fadeOut(300, () => {
                        $(document.activeElement).off('keydown');
                    });
                }
            });
        }
        $('#lst_mmbg').trigger("to.owl.carousel", [_evt.page.index, 1000, true]);
    }


    /**
     * HotelTV UI Wrapper Function::> Show Top Widjet Weather
     * @param {boolean} _en show/hide
     */
    function __uifxn_AppFull_TopWidjet_BuildWeather() {
        const _state = HotelTV.state;
        let _widget_weather = HotelTV.widget.weather;

        $('.widjet .top .weather #icon').css({ "background-image": "url(" + _widget_weather.smallicon_image[_widget_weather.item.condition.code] + ")" });
        $('.widjet .top .weather #temp').text(_widget_weather.item.condition.temp + "°C");
        $('.widjet .top .weather').show();
    }


    /**
     * HotelTV UI Wrapper Function::> Show Top Widjet Message Cnt(Unread)
     * @param {boolean} _en show/hide
     */
    function __uifxn_AppFull_TopWidjet_BuildMsgCnt(_en) {
        let _msgCnt = 0;
        const _state = HotelTV.state;
        const _guest = HotelTV.guestinfo;
        let _trTbl = HotelTV.translation;
        const __ifxn_get_unread_msgCnt = function(_object) {
            let _msg_unread_cnt = 0;
            for (__j = 1; __j <= _object.length; __j++) {
                if (_object[__j].read == false) {
                    _msg_unread_cnt++;
                }
            }
            return _msg_unread_cnt;
        }

        _tmrEvt.keyevt.last_uibar = new Date().getTime();

        _msgCnt = __ifxn_get_unread_msgCnt(HotelTV.message);
        if (_msgCnt > 0) {
            $('.widjet .top .message #unread_cnt').text(_msgCnt.toString());
            $('.widjet .top .message').show();
        } else {
            $('.widjet .top .message').hide();
        }

        if ( $('div#lst_mypagebg').find('div #mp_message_title').length>0 ){
            $('div#lst_mypagebg div #mp_message_title').text(_guest.name + _trTbl.ui.mypage.message.title.title[_state.lang].replace("_XX", _msgCnt.toString()));
        }
    }

    /**
     * HotelTV UI Wrapper Function::> Build Main Menu::> Flight
     */
    function __uifxn_AppFull_BuildFlight() {
        let _state = HotelTV.state;
        let _program = HotelTV.tvguide.program;
        let _trTbl = HotelTV.translation;
        let _curDaTm = new Date();
        const ar_tdItem = ['airline', 'flight', 'scheduled', 'origin', 'destination', 'type', 'gate', 'status'];

        let _elFlightRoot = document.querySelector('.main .mm');
        for (let _mm_idx = 1; _mm_idx <= _program.length; _mm_idx++) {
            if ( _program[_mm_idx].type=="flight" ){
                let _flight = HotelTV.flight[_program[_mm_idx].location];
                _hndl_flight_elm = $(`.main .mm #flight_${_program[_mm_idx].location}`);
                if ( _hndl_flight_elm.length==0 )
                {
                    let _div_flight_item = document.createElement('div');
                    _div_flight_item.setAttribute("id", "flight_" + _program[_mm_idx].location );
                    _div_flight_item.setAttribute("class", "flight");

                    // 1. Departure DIV  생성
                    let _div_departure_item = document.createElement('div');
                    _div_departure_item.setAttribute("class", "departure");
                    // 1.1 Departure TITLE DIV  생성
                    let _div_departure_title_item = document.createElement('div');
                    _div_departure_title_item.setAttribute("id", "title");
                    _div_departure_title_item.innerText = _trTbl.ui.flight.title.departure[_state.lang] + "["+_flight.location+"]";
                    _div_departure_item.appendChild(_div_departure_title_item);

                    // 1.2 Departure Table 생성
                    // 1.2.1. Table HDR 생성
                    let _departure_tblhdr = document.createElement('table');
                    _departure_tblhdr.setAttribute("class", "tbl_header");
                    _departure_tblhdr.innerHTML = '<tbody id="hdr"><tr>' +
                        '<th id="airline">' + _trTbl.ui.flight.title.airline[_state.lang] + '</th>' +
                        '<th id="flight">' + _trTbl.ui.flight.title.flight_no[_state.lang] + '</th>' +
                        '<th id="scheduled">' + _trTbl.ui.flight.title.scheduled[_state.lang] + '</th>' +
                        '<th id="origin">' + _trTbl.ui.flight.title.origin[_state.lang] + '</th>' +
                        '<th id="destination">' + _trTbl.ui.flight.title.destination[_state.lang] + '</th>' +
                        '<th id="type">' + _trTbl.ui.flight.title.destination[_state.lang] + '</th>' +
                        '<th id="gate">' + _trTbl.ui.flight.title.boarding_gate[_state.lang] + '</th>' +
                        '<th id="status">' + _trTbl.ui.flight.status[_state.lang] + '</th>' +
                        '</tr></tbody>';
                    _div_departure_item.appendChild(_departure_tblhdr);

                    // 1.2.2. Table REC 생성
                    let _departure_tblrec = document.createElement('table');
                    _departure_tblrec.setAttribute("class", "tbl_record");
                    _departure_tblrec.innerHTML = '<tbody id="record"></tbody>';
                    _div_departure_item.appendChild(_departure_tblrec);

                    // 1.3. Border Table Bottom DIV  생성
                    let _div_departure_border_item = document.createElement('div');
                    _div_departure_border_item.setAttribute("id", "border_table_bottom");
                    _div_departure_item.appendChild(_div_departure_border_item);

                    _div_flight_item.appendChild(_div_departure_item);


                    // 2. Arrive DIV  생성
                    let _div_arrival_item = document.createElement('div');
                    _div_arrival_item.setAttribute("class", "arrival");
                    // 2.1 Arrive TITLE DIV  생성
                    let _div_arrive_title_item = document.createElement('div');
                    _div_arrive_title_item.setAttribute("id", "title");
                    _div_arrive_title_item.innerText = _trTbl.ui.flight.title.arrival[_state.lang] + "["+_flight.location+"]";
                    _div_arrival_item.appendChild(_div_arrive_title_item);

                    // 2.2 Departure Table 생성
                    // 2.2.1. Table HDR 생성
                    let _arrival_tblhdr = document.createElement('table');
                    _arrival_tblhdr.setAttribute("class", "tbl_header");
                    _arrival_tblhdr.innerHTML = '<tbody id="hdr"><tr>' +
                        '<th id="airline">' + _trTbl.ui.flight.title.airline[_state.lang] + '</th>' +
                        '<th id="flight">' + _trTbl.ui.flight.title.flight_no[_state.lang] + '</th>' +
                        '<th id="scheduled">' + _trTbl.ui.flight.title.scheduled[_state.lang] + '</th>' +
                        '<th id="origin">' + _trTbl.ui.flight.title.origin[_state.lang] + '</th>' +
                        '<th id="destination">' + _trTbl.ui.flight.title.destination[_state.lang] + '</th>' +
                        '<th id="type">' + _trTbl.ui.flight.title.destination[_state.lang] + '</th>' +
                        '<th id="gate">' + _trTbl.ui.flight.title.boarding_gate[_state.lang] + '</th>' +
                        '<th id="status">' + _trTbl.ui.flight.status[_state.lang] + '</th>' +
                        '</tr></tbody>';
                    _div_arrival_item.appendChild(_arrival_tblhdr);

                    // 2.2.2. Table REC 생성
                    let _arrival_tblrec = document.createElement('table');
                    _arrival_tblrec.setAttribute("class", "tbl_record");
                    _arrival_tblrec.innerHTML = '<tbody id="record"></tbody>';
                    _div_arrival_item.appendChild(_arrival_tblrec);

                    // 2.3. Border Table Bottom DIV  생성
                    let _div_arrival_border_item = document.createElement('div');
                    _div_arrival_border_item.setAttribute("id", "border_table_bottom");
                    _div_arrival_item.appendChild(_div_arrival_border_item);

                    _div_flight_item.appendChild(_div_arrival_item);

                    //3 Caution 추가
                    let _div_caution_item = document.createElement('div');
                    _div_caution_item.setAttribute("id", "caution");
                    _div_flight_item.appendChild(_div_caution_item);

                    // 생성된 Flight를 .main .mm 아래애 추가
                    _elFlightRoot.appendChild(_div_flight_item);
                }


                //Delete all table record for departure & arrival
                if ( $(`.main .mm #flight_${_program[_mm_idx].location} .departure table #record tr`).children().length>0 ){
                    $(`.main .mm #flight_${_program[_mm_idx].location} .departure table #record tr`).remove();
                }
                if ( $(`.main .mm #flight_${_program[_mm_idx].location} .arrival table #record tr`).children().length>0 ){
                    $(`.main .mm #flight_${_program[_mm_idx].location} .arrival table #record tr`).remove();
                }

                let _el_departure_tbl_rec = $(`.main .mm #flight_${_program[_mm_idx].location} .departure table #record`);
                let _el_arrival_tbl_rec = $(`.main .mm #flight_${_program[_mm_idx].location} .arrival table #record`);

                for (let _i = 0; _i < _flight.count; _i++) {
                    let _schOrg = new Date();
                    let _schEdt = new Date();
                    let _flitem = _flight.items[_i];

                    //let _sTmOrg = _flitem.std.length != 4 ? null : ;
                    //let _sTmChanged = _flitem.etd;

                    if (_flitem.std.length != 4) {
                        console.log("Flight Schedule org time is NULL");
                    } else {
                        _schOrg.setHours(Number(_flitem.std.charAt(0) + _flitem.std.charAt(1)));
                        _schOrg.setMinutes(Number(_flitem.std.charAt(2) + _flitem.std.charAt(3)));
                    }

                    if (_flitem.std.length != 4) {
                        console.log("Flight Schedule edited time is NULL");
                    } else {
                        _schEdt.setHours(Number(_flitem.std.charAt(0) + _flitem.std.charAt(1)));
                        _schEdt.setMinutes(Number(_flitem.std.charAt(2) + _flitem.std.charAt(3)));
                    }



                    let diffMs = (_schOrg - _curDaTm); // milliseconds between now & Christmas
                    // let diffDays = Math.floor(diffMs / 86400000); // days
                    // let diffHrs = Math.floor((diffMs % 86400000) / 3600000); // hours
                    // let diffMins = Math.round(((diffMs % 86400000) % 3600000) / 60000); // minutes
                    // console.log(diffDays + " days, " + diffHrs + " hours, " + diffMins + " minutes");
                    let diffMins = Math.round(diffMs / 60000);
                    //console.log("TDiff::> " + diffMins);

                    if ((-30 < diffMins) && (diffMins < 360)) {
                        if (_flitem.io == "O") {
                            let _el_tr = document.createElement('tr');
                            _el_tr.setAttribute("id", "record");
                            ar_tdItem.forEach(_itm => {
                                let _el_td = document.createElement('td');
                                _el_td.setAttribute("id", _itm);
                                if (_itm == "airline") {
                                    _el_td.innerText = HotelTV.ui_utils.Get_Airline(_trTbl.ui.flight.airlines, _flitem.airline, _state.lang);
                                } else if (_itm == "flight") {
                                    _el_td.innerText = _flitem.airFln;
                                } else if (_itm == "scheduled") {
                                    _el_td.innerText = _flitem.std.charAt(0) + _flitem.std.charAt(1) + ":" + _flitem.std.charAt(2) + _flitem.std.charAt(3) + " - ";
                                    _el_td.innerText += _flitem.etd.charAt(0) + _flitem.etd.charAt(1) + ":" + _flitem.etd.charAt(2) + _flitem.etd.charAt(3);
                                } else if (_itm == "origin") {
                                    _el_td.innerText = HotelTV.ui_utils.Get_Airport(_trTbl.ui.flight.city, _flitem.boarding, _state.lang);
                                } else if (_itm == "destination") {
                                    _el_td.innerText = HotelTV.ui_utils.Get_Airport(_trTbl.ui.flight.city, _flitem.arrived, _state.lang);
                                } else if (_itm == "type") {
                                    _el_td.innerText = _trTbl.ui.flight.line[_flitem.line][_state.lang];
                                } else if (_itm == "gate") {
                                    _el_td.innerText = _flitem.gate;
                                } else if (_itm == "status") {
                                    _el_td.innerText = HotelTV.ui_utils.Get_FlightStatus(_trTbl.ui.flight.result, _flitem.rmk, _state.lang);
                                }
                                _el_tr.appendChild(_el_td);
                            });
                            _el_departure_tbl_rec.append(_el_tr);
                        } else {
                            let _el_tr = document.createElement('tr');
                            _el_tr.setAttribute("id", "record");
                            ar_tdItem.forEach(_itm => {
                                let _el_td = document.createElement('td');
                                _el_td.setAttribute("id", _itm);
                                if (_itm == "airline") {
                                    _el_td.innerText = HotelTV.ui_utils.Get_Airline(_trTbl.ui.flight.airlines, _flitem.airline, _state.lang);
                                } else if (_itm == "flight") {
                                    _el_td.innerText = _flitem.airFln;
                                } else if (_itm == "scheduled") {
                                    _el_td.innerText = _flitem.std.charAt(0) + _flitem.std.charAt(1) + ":" + _flitem.std.charAt(2) + _flitem.std.charAt(3) + " - ";
                                    _el_td.innerText += _flitem.etd.charAt(0) + _flitem.etd.charAt(1) + ":" + _flitem.etd.charAt(2) + _flitem.etd.charAt(3);
                                } else if (_itm == "origin") {
                                    _el_td.innerText = HotelTV.ui_utils.Get_Airport(_trTbl.ui.flight.city, _flitem.boarding, _state.lang);
                                } else if (_itm == "destination") {
                                    _el_td.innerText = HotelTV.ui_utils.Get_Airport(_trTbl.ui.flight.city, _flitem.arrived, _state.lang);
                                } else if (_itm == "type") {
                                    if (_trTbl.ui.flight.line[_flitem.line]) {
                                        _el_td.innerText = _trTbl.ui.flight.line[_flitem.line][_state.lang];
                                    }
                                } else if (_itm == "gate") {
                                    _el_td.innerText = _flitem.gate;
                                } else if (_itm == "status") {
                                    _el_td.innerText = HotelTV.ui_utils.Get_FlightStatus(_trTbl.ui.flight.result, _flitem.rmk, _state.lang);
                                }
                                _el_tr.appendChild(_el_td);
                            });
                            _el_arrival_tbl_rec.append(_el_tr);
                        }
                    }
                }
                $(`.main .mm #flight_${_program[_mm_idx].location} #caution`).text(_trTbl.ui.flight.caution.body[_state.lang]);
            }
        }
    }

    /**
     * HotelTV UI Wrapper Function::> Build Main Menu::> Weather
     */
    function __uifxn_AppFull_BuildWeather() {
        let _state = HotelTV.state;
        let _trTbl = HotelTV.translation;
        let _weather = HotelTV.weather[_state.weather.default_location];
        let _cur_cond = _weather.item.condition
        let _elWeatherRoot = $('.main .mm .weather');
        let _elWeatherToday = _elWeatherRoot.children('.today');
        let _elWeatherForcast = _elWeatherRoot.children('.forcast');
        let _elWeatherCation = _elWeatherRoot.children('#caution');

        _elWeatherRoot.children('.location').text(_trTbl.system.locale.city[_weather.location][_state.lang] || null);
        _elWeatherToday.children('#temp_cur').text(_weather.item.condition.temp + "°C");
        _elWeatherToday.children('#temp_minmax').text(_weather.item.forecast[0].low + "°C/" + _weather.item.forecast[0].high + " °C");
        _elWeatherToday.children('.detail').children('#discription').text(_trTbl.ui.weather.cond[_cur_cond.code][_state.lang]);
        _elWeatherToday.children('.detail').children('#img_status').css('background-image', 'url(' + _weather.icon_image[_cur_cond.code] + ')');
        _elWeatherToday.children('.detail').children('#humidity').children('#icon').css('background-image', 'url(./images/icons/icon_humidity.png)');
        _elWeatherToday.children('.detail').children('#humidity').children('#value').text(_weather.daily['1'].main.humidity + " %");
        _elWeatherToday.children('.detail').children('#wind').children('#icon').css('background-image', 'url(./images/icons/icon_wind.png)');
        _elWeatherToday.children('.detail').children('#wind').children('#value').text(HotelTV.ui_utils.Weather_GetWindReport(_trTbl.ui.weather.wind_dir, _weather.wind.speed, _weather.wind.direction, _state.lang));

        //Daily Summary
        _elWeatherForcast.children('.daily').children('#title').text(_trTbl.ui.weather.fc_today[_state.lang]);
        let _eltbl_fc_daily_items = _elWeatherForcast.children('.daily').children('ul').children('li');
        for (let _idx = 0; _idx < _eltbl_fc_daily_items.length; ++_idx) {
            let _wData = _weather.daily[Number(_idx) + 1];
            let _time = _wData.dt_txt.split(' ')[1];
            let _temp = _wData.main.temp;
            $(_eltbl_fc_daily_items[_idx]).css('background-image', 'url(' + _weather.icon_image[_wData.weather.code] + ')');
            $(_eltbl_fc_daily_items[_idx].children.time)[0].innerText = _time.split(":")[0] + ":" + _time.split(":")[1];
            $(_eltbl_fc_daily_items[_idx].children.temp)[0].innerText = _temp.toString() + " °C";
        }

        //Weekly Summary
        _elWeatherForcast.children('.weekly').children('#title').text(_trTbl.ui.weather.fc_weekly[_state.lang]);
        let _eltbl_fc_weekly_items = _elWeatherForcast.children('.weekly').children('ul').children('li');
        for (let _idx = 0; _idx < _eltbl_fc_weekly_items.length; ++_idx) {
            let _wData = _weather.item.forecast[Number(_idx)];
            $(_eltbl_fc_weekly_items[_idx]).css('background-image', 'url(' + _weather.icon_image[_wData.code] + ')');
            $(_eltbl_fc_weekly_items[_idx].children.date)[0].innerText = _trTbl.system.days[_wData.day][_state.lang];
            $(_eltbl_fc_weekly_items[_idx].children.temp)[0].innerText = _wData.low + " °C /" + _wData.high + " °C";
        }
        _elWeatherCation.text(_trTbl.ui.weather.caution.body[_state.lang]);
    }

    /**
     * HotelTV UI[AppFull] Wrapper Function::> Buildup main menu and main bg
     * @param {boolean} uri_img background image url
     */
    function __uifxn_AppFull_BuildMain() {
        let _program = HotelTV.tvguide.program;
        let _weather = null;
        let _state = HotelTV.state;
        let _mmcnt = 0;

        const __ifxn_get_weather_def_location = function() {
            let _found = false;
            for (__j = 1; __j <= _program.length; __j++) {
                if (_program[__j].type == "weather" || _program[__j].widget==true ) {
                    if ( _program[__j].widget==true ) {
                        _state.weather.default_location = _program[__j].location;
                        _found = true;
                        break;
                    }
                }
            }
            return _found;
        }

        _mmcnt = _program.length;
        //_mm_width = 1920 / (_mmcnt - 1);
        _mm_width = 266;

        // 초기 메인 메뉴 KEY설정
        _state.menu.stage.cur = "preparing_main";
        if (_state.menu.main.cur == null) {
            _state.menu.main.cur = Object.keys(_program)[0];
        }

        // 메인 메뉴 셀렉터 노드를 동적으로 구성
        let _div_mm_slist = document.querySelector('#lst_mmsel');
        for (let _mm_idx = 1; _mm_idx <= _program.length; _mm_idx++) {
            let _div_mm_item = document.createElement('div');
            _div_mm_item.className = 'item';
            _div_mm_item.id = _program[_mm_idx].id;
            _div_mm_item.setAttribute("mmid", _mm_idx);
            _div_mm_item.style.height = '92px';
            // _div_mm_item.style.width = _mm_width + 'px';

            // Append Sub elements::title
            let _mm_item_title = document.createElement('div');
            _mm_item_title.setAttribute("id", "mm_item_title");
            if (_program[_mm_idx].showTitle && _program[_mm_idx].showTitle == true) {
                _mm_item_title.textContent = _program[_mm_idx].title[_state.lang];
            } else {
                _mm_item_title.textContent = "";
            }

            // Append Sub elements::icon
            let _mm_item_icon = document.createElement('div');
            _mm_item_icon.setAttribute("id", "mm_item_icon");
            let _sz_styleOpt = "--icon_unfocus: url(" + _program[_mm_idx].unfocusIcon.file.download + "); ";
            _sz_styleOpt += "--icon_focus: url(" + _program[_mm_idx].focusIcon.file.download + "); ";
            //_sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom; background-size: 100% 100%; ";
            _sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom;";
            _mm_item_icon.setAttribute("style", _sz_styleOpt);

            _div_mm_item.appendChild(_mm_item_icon);
            _div_mm_item.appendChild(_mm_item_title);

            _div_mm_slist.appendChild(_div_mm_item);

            // Record Special key map info
            if (['flight', 'weather', 'tv'].includes(_program[_mm_idx].type)) {
                if (!('specialKey' in _state)) {
                    _state['specialKey'] = {};
                }

                if (!(_program[_mm_idx].type in _state['specialKey'])) {
                    _state['specialKey'][_program[_mm_idx].type] = { "mm_index": _mm_idx , "id": _program[_mm_idx].id};
                }
            }
        }

        // 디폴트 로케이션 설정
        if ( __ifxn_get_weather_def_location()==true ){
            _weather = HotelTV.weather[_state.weather.default_location];
        }

        // 메인 메뉴 백그라운드 이미지 노드를 동적으로 구성
        let _div_mm_bglist = document.querySelector('#lst_mmbg');
        for (let _mm_idx = 1; _mm_idx <= _program.length; _mm_idx++) {
            let _div_mm_item = document.createElement('div');
            let _sz_styleOpt = null;

            _div_mm_item.className = 'item';
            _div_mm_item.id = 'mmbg_' + _program[_mm_idx].name.replace(/\s/g, '').toLowerCase();
            _div_mm_item.setAttribute("mmid", _mm_idx);
            if (_program[_mm_idx].type.toLowerCase() == "weather") {
                if (_weather != null) {
                    _sz_styleOpt = "background-image: url(" + _weather.background_image[_weather.item.condition.code] + "); ";
                } else {
                    _sz_styleOpt = "background-image: url(" + _program[_mm_idx].background.file.download + "); ";
                }
            } else {
                _sz_styleOpt = "background-image: url(" + _program[_mm_idx].background.file.download + "); ";
            }
            _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: 100% 100%; ";
            _div_mm_item.setAttribute("style", _sz_styleOpt);

            _div_mm_bglist.appendChild(_div_mm_item);
        }
        _hndl_mmBg = $('#lst_mmbg');
        _hndl_mmBg.owlCarousel({
            center: true,
            items: 1, //Number of Items on Screen what you want
            loop: true,
            margin: 0,
            smartSpeed: 1000,
            lazyLoad: true,
            mouseDrag: false,
            touchDrag: false,
            pullDrag: false,
            freeDrag: false,
            startPosition: Number(_state.menu.cur) - 1,
        });
        $('.main .mm .bg').show(function() {
            //호텔 로고 출력
            $('.widjet .top .hotellogo').css({ "background-image": "url(" + HotelTV.hotelinfo.subLogo.download + ")" });

            //상단 메시지(unread)개수 표시
            __uifxn_AppFull_TopWidjet_BuildMsgCnt();

            // //상단 시계 표시
            _hndl_widget_topTime = setInterval(() => {
                let _szCurTm = HotelTV.ui_utils.GetCur_DateTime();
                //console.log("_szCurTm=>" + _szCurTm);
                $('.widjet .top .datetime .time').text(_szCurTm.time);
                $('.widjet .top .datetime .date').text(_szCurTm.date);
            }, 1000);

            __uifxn_AppFull_TopWidjetShow(true);

            //Weather Contents Buildup
            if ( __ifxn_get_weather_def_location()==true ){
                if ( Object.keys(_state.weather.default_location).length != 0 ){
                    __uifxn_AppFull_BuildWeather();
                }
            }

            //Buildup Widget: Weather
            __uifxn_AppFull_TopWidjet_BuildWeather();

            //Build Flight
            __uifxn_AppFull_BuildFlight();

            //Build Brochures
            __uifxn_AppFull_BuildBrochure();

            //Register Amenity&Room service hotkey
            __uifxn_AppFull_HotKey_RegisterAmenityRoomservice();

            //위젯 표시
            $('.widjet').show();
        });



        _hndl_mmSel = $('#lst_mmsel');
        _hndl_mmSel.owlCarousel({
            center: true,
            items: 5, //Number of Items on Screen what you want
            loop: true,
            margin: 0,
            smartSpeed: 10,
            autoWidth: false,
            mouseDrag: false,
            touchDrag: false,
            pullDrag: false,
            freeDrag: false,
            startPosition: Number(_state.menu.cur) - 1,
        });
        $('.main .mm .slider').fadeIn(500, function() {
            if (_hndl_tmrUgMngr == null) {
                _hndl_tmrUgMngr = setInterval(__uifxn_AppFull_GuideBarUiMngr, 1000);
                console.log("TMR(GuideBarUiMngr)::>Created...");
            }
            $('.main .mm .slider .owl-item').addClass('unfocus');
            $('#lst_mmsel').trigger("to.owl.carousel", [0, 10, true]);
            $('#lst_mmsel').trigger('translate.owl.carousel', [0, 500, true]);

            HotelTV.ui_utils.SetBusy(false);
            _state.menu.stage.cur = "main";
        });

        $(document).on('keydown', function(_evt) { //attach event listener
            let _opening = HotelTV.opening;
            let _trTbl = HotelTV.translation;

            if (_state.menu.stage.cur == "main") {
                console.log(`MM KEY EVENT::> ${_evt.keyCode}, UINT=>${parseInt(_evt.keyCode)}`);

                // 현재 재생중인 TV채널 종료
                if ( _state.tv.playing == true ){
                    console.warn("Try to channel shutdown..");
                    HotelTV.hal.ChannelShutDown();
                    _state.tv.playing = false;
                }

                if (_evt.keyCode == gRmtKey.left) {
                    $('#lst_mmsel').trigger('prev.owl', 700)
                    //console.log("   MM ID::> " + _state.menu.main.cur + _program[_state.menu.main.cur].name);
                    HotelTV.api.ReportEvent([{'power': true, 'location':{'conId':_program[_state.menu.main.cur].id}}])
                } else if (_evt.keyCode == gRmtKey.right) {
                    $('#lst_mmsel').trigger('next.owl', 700)
                    //console.log("   MM ID::> " + _state.menu.main.cur + _program[_state.menu.main.cur].name);
                    HotelTV.api.ReportEvent([{'power': true, 'location':{'conId':_program[_state.menu.main.cur].id}}])
                } else if (_evt.keyCode == gRmtKey.enter) {
                    // 서브 메뉴 빌드 및 화면 전환
                    __uifxn_AppFull_HotKey_ShowBtnOnMM(false);
                    if (_program[Number(_state.menu.main.cur)].type.toLowerCase() == "normal") {
                        if (_program[Number(_state.menu.main.cur)].style.toLowerCase() == "none") {
                            console.log("It's Top level contents...");
                        } else if (_program[Number(_state.menu.main.cur)].style.toLowerCase() == "content") {
                            console.log("Preparing General sub contents...");
                        } else if (_program[Number(_state.menu.main.cur)].style.toLowerCase() == "submenu") {
                            console.log("Preparing General sub menu...");
                            __uifxn_AppFull_Build_SubGeneral();
                        }
                    } else if (_program[Number(_state.menu.main.cur)].type.toLowerCase() == "mypage") {
                        console.log("Preparing Mypage sub menu...");
                        __uifxn_AppFull_BuildMyPage();
                    } else if (_program[Number(_state.menu.main.cur)].type.toLowerCase() == "tv") {
                        console.log("Preparing TV sub menu...");
                        __uifxn_AppFull_TopWidjetShow(false);
                        __uifxn_AppFull_Build_SubTv();
                    } else if (_program[Number(_state.menu.main.cur)].type.toLowerCase() == "application") {
                        console.log("Preparing TV APP::>" + _program[Number(_state.menu.main.cur)].service);
                        if (_program[Number(_state.menu.main.cur)].service == "youtube") {
                            // console.log(`Type:${_program[Number(_state.menu.main.cur)].type} preparing WIFI AP...`);
                            // HotelTV.hal.SetSoftAp({
                            //     "enable": true,
                            //     "ssid": "TVWIFI-" + HotelTV.guestinfo.room,
                            //     "password": "12345678",
                            // });
                            HotelTV.hal.LaunchPreApp(_program[Number(_state.menu.main.cur)].service, null);
                        } else if (_program[Number(_state.menu.main.cur)].service == "netflix") {
                            let _foundNetflix = false;
                            for (_i = 0; _i < _state['hcap_app'].length; _i++) {
                                if (_state['hcap_app'][_i].title == 'Netflix') {
                                    _foundNetflix = true;
                                }
                            }

                            if (_foundNetflix == true) {
                                HotelTV.hal.LaunchPreApp(_program[Number(_state.menu.main.cur)].service, { "hotel_name": HotelTV.hotelinfo.name });
                            } else {
                                HotelTV.ui_utils.ShowNotificationMsgBalloon(_trTbl.system.ott_service_not_ready[_state.lang], 5);
                            }
                        } else if (_program[Number(_state.menu.main.cur)].service == "screenmirroring") {
                            HotelTV.hal.LaunchPreApp(_program[Number(_state.menu.main.cur)].service, null);
                        }
                    } else if (_program[Number(_state.menu.main.cur)].type.toLowerCase() == "language") {
                        console.log("Preparing language select sub menu...");
                        __uifxn_AppFull_Build_LangSel();
                    } else {
                        console.log(`Type:${_program[Number(_state.menu.main.cur)].type} doen's have sub menu...`);
                    }
                } else if (_evt.keyCode == gRmtKey.red) {
                    // RED BUTTON
                    if ("red" in _state.hotkey.mm) {
                        $('.guide>.tips').stop().animate({ backgroundColor: "rgba(0,0,0,0.8)" }, 500, function() {
                            if (_state.hotkey.mm.red.type == "brochure") {
                                $('.popup .hotkey_mm_red').fadeIn(1000, function() {
                                    _state.menu.stage.cur = "hotkey_mm_red";
                                    __uifxn_AppFull_HotKey_ShowBtnOnMM(false);
                                    __uifxn_AppFull_TopWidjetShow(false);
                                });
                            } else if (_state.hotkey.mm.red.type == "amenity") {
                                if (_opening.amenity) {
                                    __uifxn_AppFull_BuildAmenity();
                                }
                            } else if (_state.hotkey.mm.red.type == "roomservice") {
                                if (_opening.roomService) {
                                    __uifxn_AppFull_BuildRoomservice();
                                }
                            }
                        });
                        HotelTV.api.ReportEvent([{'power': true, 'location':{'conId':_state.hotkey.mm['red'].id}}])
                    }
                } else if (_evt.keyCode == gRmtKey.green) {
                    // GREEN BUTTON
                    if ("green" in _state.hotkey.mm) {
                        $('.guide>.tips').stop().animate({ backgroundColor: "rgba(0,0,0,0.8)" }, 500, function() {
                            if (_state.hotkey.mm.green.type == "brochure") {
                                $('.popup .hotkey_mm_green').fadeIn(1000, function() {
                                    _state.menu.stage.cur = "hotkey_mm_green";
                                    __uifxn_AppFull_HotKey_ShowBtnOnMM(false);
                                    __uifxn_AppFull_TopWidjetShow(false);
                                });
                            } else if (_state.hotkey.mm.green.type == "amenity") {
                                if (_opening.amenity) {
                                    __uifxn_AppFull_BuildAmenity();
                                }
                            } else if (_state.hotkey.mm.green.type == "roomservice") {
                                if (_opening.roomService) {
                                    __uifxn_AppFull_BuildRoomservice();
                                }
                            }
                        });
                        HotelTV.api.ReportEvent([{'power': true, 'location':{'conId':_state.hotkey.mm['green'].id}}])
                    }
                } else if (_evt.keyCode == gRmtKey.yellow) {
                    // YELLOW BUTTON
                    console.log("YELLOW::>");
                    if ("yellow" in _state.hotkey.mm) {
                        $('.guide>.tips').stop().animate({ backgroundColor: "rgba(0,0,0,0.8)" }, 500, function() {
                            if (_state.hotkey.mm.yellow.type == "brochure") {
                                $('.popup .hotkey_mm_yellow').fadeIn(1000, function() {
                                    _state.menu.stage.cur = "hotkey_mm_yellow";
                                    __uifxn_AppFull_HotKey_ShowBtnOnMM(false);
                                    __uifxn_AppFull_TopWidjetShow(false);
                                });
                            } else if (_state.hotkey.mm.yellow.type == "amenity") {
                                if (_opening.amenity) {
                                    console.log("YELLOW::>AMENITY");
                                    __uifxn_AppFull_BuildAmenity();
                                }
                            } else if (_state.hotkey.mm.yellow.type == "roomservice") {
                                if (_opening.roomService) {
                                    console.log("YELLOW::>ROOMSERVICEC");
                                    __uifxn_AppFull_BuildRoomservice();
                                }
                            }
                        });
                        HotelTV.api.ReportEvent([{'power': true, 'location':{'conId':_state.hotkey.mm['yellow'].id}}])
                    }
                } else if (_evt.keyCode == gRmtKey.blue) {
                    console.log("BLUE::>");
                    // BLUE BUTTON
                    if ("blue" in _state.hotkey.mm) {
                        $('.guide>.tips').stop().animate({ backgroundColor: "rgba(0,0,0,0.8)" }, 500, function() {
                            if (_state.hotkey.mm.blue.type == "brochure") {
                                $('.popup .hotkey_mm_blue').fadeIn(1000, function() {
                                    _state.menu.stage.cur = "hotkey_mm_blue";
                                    __uifxn_AppFull_HotKey_ShowBtnOnMM(false);
                                    __uifxn_AppFull_TopWidjetShow(false);
                                });
                            } else if (_state.hotkey.mm.blue.type == "amenity") {
                                if (_opening.amenity) {
                                    console.log("BLUE::>AMENITY");
                                    __uifxn_AppFull_BuildAmenity();
                                }
                            } else if (_state.hotkey.mm.blue.type == "roomservice") {
                                if (_opening.roomService) {
                                    console.log("BLUE::>ROOMSERVICE");
                                    __uifxn_AppFull_BuildRoomservice();
                                }
                            }
                        });
                        HotelTV.api.ReportEvent([{'power': true, 'location':{'conId':_state.hotkey.mm['blue'].id}}])
                    }
                } else if (_evt.keyCode == gRmtKey.amenity) {
                    // DEDICATED HOT KEY: Amenity
                    // Check amenity menu enabled
                    if (_opening.amenity) {
                        __uifxn_AppFull_BuildAmenity();
                    }
                } else if (_evt.keyCode == gRmtKey.roomservice) {
                    // DEDICATED HOT KEY: Room service
                    // Check room service menu enabled
                    if (_opening.roomService) {
                        __uifxn_AppFull_BuildRoomservice();
                    }
                } else if (_evt.keyCode == gRmtKey.flight) {
                    // DEDICATED HOT KEY: Flight
                    // Check flight main menu index and go
                    if (('flight' in _state['specialKey'])) {
                        $('#lst_mmsel').trigger("to.owl.carousel", [Number(_state['specialKey']['flight'].mm_index) - 1, 10, true]);
                        HotelTV.api.ReportEvent([{'power': true, 'location':{'conId':_state['specialKey']['flight'].id}}])
                    }
                } else if (_evt.keyCode == gRmtKey.weather) {
                    // DEDICATED HOT KEY: Weather
                    // Check flight main menu index and go
                    if (('weather' in _state['specialKey'])) {
                        $('#lst_mmsel').trigger("to.owl.carousel", [Number(_state['specialKey']['weather'].mm_index) - 1, 10, true]);
                        HotelTV.api.ReportEvent([{'power': true, 'location':{'conId':_state['specialKey']['weather'].id}}])
                    }
                } else if (_evt.keyCode == gRmtKey.tv) {
                    // DEDICATED HOT KEY: TV
                    // Check flight main menu index and go
                    if (('tv' in _state['specialKey'])) {
                        $('#lst_mmsel').trigger("to.owl.carousel", [Number(_state['specialKey']['tv'].mm_index) - 1, 10, true]);
                        HotelTV.api.ReportEvent([{'power': true, 'location':{'conId':_state['specialKey']['tv'].id}}])
                    }
                }
            } else if (_state.menu.stage.cur == "hotkey_mm_red") {
                console.log("HOTKEY(MM:RED) KEY EVENT::> " + _evt.keyCode);
                if (_evt.keyCode == gRmtKey.left) {
                    $('#lst_hotkey_mm_red').trigger('prev.owl')
                } else if (_evt.keyCode == gRmtKey.right) {
                    $('#lst_hotkey_mm_red').trigger('next.owl')
                } else if (_evt.keyCode == gRmtKey.back) {
                    $('.popup .hotkey_mm_red').fadeOut(1000, function() {
                        $('.popup .hotkey_mm_red').stop().animate({ backgroundColor: "rgba(0,0,0,0.0)" }, 500, function() {
                            $('.popup .hotkey_mm_red').css({ "background-color": "" });
                            _state.menu.stage.cur = "main";
                            __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
                            __uifxn_AppFull_TopWidjetShow(true);
                        });
                    });
                }
            } else if (_state.menu.stage.cur == "hotkey_mm_green") {
                console.log("HOTKEY(MM:GREEN) KEY EVENT::> " + _evt.keyCode);
                if (_evt.keyCode == gRmtKey.left) {
                    $('#lst_hotkey_mm_green').trigger('prev.owl')
                } else if (_evt.keyCode == gRmtKey.right) {
                    $('#lst_hotkey_mm_green').trigger('next.owl')
                } else if (_evt.keyCode == gRmtKey.back) {
                    $('.popup .hotkey_mm_green').fadeOut(1000, function() {
                        $('.popup .hotkey_mm_green').stop().animate({ backgroundColor: "rgba(0,0,0,0.0)" }, 500, function() {
                            $('.popup .hotkey_mm_green').css({ "background-color": "" });
                            _state.menu.stage.cur = "main";
                            __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
                            __uifxn_AppFull_TopWidjetShow(true);
                        });
                    });
                }
            } else if (_state.menu.stage.cur == "hotkey_mm_yellow") {
                console.log("HOTKEY(MM:YELLOW) KEY EVENT::> " + _evt.keyCode);
                if (_evt.keyCode == gRmtKey.left) {
                    $('#lst_hotkey_mm_yellow').trigger('prev.owl')
                } else if (_evt.keyCode == gRmtKey.up) {
                    console.log("UP");
                } else if (_evt.keyCode == gRmtKey.right) {
                    $('#lst_hotkey_mm_yellow').trigger('next.owl')
                } else if (_evt.keyCode == gRmtKey.down) {
                    console.log("DOWN");
                } else if (_evt.keyCode == gRmtKey.back) {
                    $('.popup .hotkey_mm_yellow').fadeOut(1000, function() {
                        $('.popup .hotkey_mm_yellow').stop().animate({ backgroundColor: "rgba(0,0,0,0.0)" }, 500, function() {
                            $('.popup .hotkey_mm_yellow').css({ "background-color": "" });
                            _state.menu.stage.cur = "main";
                            __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
                            __uifxn_AppFull_TopWidjetShow(true);
                        });
                    });
                }
            } else if (_state.menu.stage.cur == "hotkey_mm_blue") {
                console.log("HOTKEY(MM:BLUE) KEY EVENT::> " + _evt.keyCode);
                if (_evt.keyCode == gRmtKey.left) {
                    $('#lst_hotkey_mm_blue').trigger('prev.owl')
                } else if (_evt.keyCode == gRmtKey.up) {
                    console.log("UP");
                } else if (_evt.keyCode == gRmtKey.right) {
                    $('#lst_hotkey_mm_blue').trigger('next.owl')
                } else if (_evt.keyCode == gRmtKey.down) {
                    console.log("DOWN");
                } else if (_evt.keyCode == gRmtKey.back) {
                    $('.popup .hotkey_mm_blue').fadeOut(1000, function() {
                        $('.popup .hotkey_mm_blue').stop().animate({ backgroundColor: "rgba(0,0,0,0.0)" }, 500, function() {
                            $('.popup .hotkey_mm_blue').css({ "background-color": "" });
                            _state.menu.stage.cur = "main";
                            __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
                            __uifxn_AppFull_TopWidjetShow(true);
                        });
                    });
                }
            } else if (_state.menu.stage.cur == "hotkey_mm_roomservice") {
                console.log("HOTKEY(MM:ROOMSERVICE: MENU) KEY EVENT::> " + _evt.keyCode);
                if (_evt.keyCode == gRmtKey.left) {
                    console.log("ROOMSERVICE::>LEFT");
                    __uifxn_AppFull_HandleRoomservice("left", false, false, null);
                } else if (_evt.keyCode == gRmtKey.up) {
                    console.log("ROOMSERVICE::>UP");
                    __uifxn_AppFull_HandleRoomservice("up", false, false, null);
                } else if (_evt.keyCode == gRmtKey.right) {
                    console.log("ROOMSERVICE::>RIGHT");
                    __uifxn_AppFull_HandleRoomservice("right", false, false, null);
                } else if (_evt.keyCode == gRmtKey.down) {
                    console.log("ROOMSERVICE::>DOWN");
                    __uifxn_AppFull_HandleRoomservice("down", false, false, null);
                } else if (_evt.keyCode == gRmtKey.enter) {
                    console.log("ROOMSERVICE::>ENTER");
                    __uifxn_AppFull_HandleRoomservice("enter", false, false, function() {
                        _state.menu.stage.cur = "main";
                        __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
                    });
                } else if (_evt.keyCode == gRmtKey.back) {
                    __uifxn_AppFull_HandleRoomservice("back", true, false, function() {
                        _state.menu.stage.cur = "main";
                        __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
                    });
                }
            } else if ( _state.menu.stage.cur == "language_selection" ) {
                console.log("HOTKEY(MM:LANGUAGE SELECTION: MENU) KEY EVENT::> " + _evt.keyCode);
                if (_evt.keyCode == gRmtKey.left) {
                    console.log("LANGUAGE SELECTION::>LEFT");
                } else if (_evt.keyCode == gRmtKey.up) {
                    console.log("LANGUAGE SELECTION::>UP");
                    __uifxn_AppFull_HandleLangSelect("up");
                } else if (_evt.keyCode == gRmtKey.right) {
                    console.log("LANGUAGE SELECTION::>RIGHT");
                } else if (_evt.keyCode == gRmtKey.down) {
                    console.log("LANGUAGE SELECTION::>DOWN");
                    __uifxn_AppFull_HandleLangSelect("down");
                } else if (_evt.keyCode == gRmtKey.enter) {
                    console.log("LANGUAGE SELECTION::>ENTER");
                    __uifxn_AppFull_HandleLangSelect("enter", function() {
                        _state.menu.stage.cur = "main";
                        __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
                    });
                } else if (_evt.keyCode == gRmtKey.back) {
                    console.log("LANGUAGE SELECTION::>BACK");
                    __uifxn_AppFull_HandleLangSelect("back", function() {
                        _state.menu.stage.cur = "main";
                        __uifxn_AppFull_HotKey_ShowBtnOnMM(true);
                    });
                }
            }
        });

        _hndl_mmSel.on('change.owl.carousel', function(event) {
            // Update HotelTV menu status
            let _state = HotelTV.state;
            _state.menu.main.prev = Object.keys(_program)[event.page.index];
        });

        _hndl_mmSel.on('changed.owl.carousel', function(event) {
            // Update HotelTV menu status
            let _state = HotelTV.state;
            _state.menu.main.cur = Object.keys(_program)[event.page.index];
            __uifxn_AppFull_OnKeyDnEvt_MmSel(event);
            //console.log("MAIN IDX::>" + _state.menu.main.cur);
        });

        _hndl_mmSel.on('translate.owl.carousel', function(event) {
            /** 메뉴 셀렉터 좌/우 헨들링 및 이펙트 */
            //console.log("MM::> Translaged Event");
            let idx = 0;
            if (typeof event.item != 'undefined') {
                idx = event.item.index;
            } else {
                idx = $('.main .mm .slider .owl-item.active.center').index();
            }
            //console.log("Get Translate Event::>" + idx);
            $('.main .mm .slider .owl-item.focus').addClass('unfocus');
            $('.main .mm .slider .owl-item.focus').removeClass('focus');
            $('.main .mm .slider .owl-item').eq(idx).addClass('focus');
            $('.main .mm .slider .owl-item').eq(idx).removeClass('unfocus');
        });
    }

    /// 초기화 루틴

    //// 공개 API
    return {
        Init: function(width, height) {
            //ADD Media related event haldner
            document.addEventListener("media_event_received", __uifxn_AppFull_OnMediaEvt, false);
            //ADD Key(remote control) event handler
            document.addEventListener("keydown", __uifxn_AppFull_OnKeyDnEvtRec, false);
            //ADD Network related event handler
            document.addEventListener("network_event_received", __uifxn_AppFull_OnNetEvt, false);
            //ADD Event for the focus change of HCAP application
            document.addEventListener("hcap_application_focus_changed", __uifxn_AppFull_OnAppFocusEvt, false);
            //ADD Event for the result of HDMI connection change
            document.addEventListener("hdmi_connection_changed", __uifxn_AppFull_OnHdmiConChangeEvt, false);
            //ADD Event for the result of channel changed
            document.addEventListener("channel_changed", __uifxn_AppFull_OnTvChChgChangeEvt, false);
            //ADD power mode changed
            document.addEventListener("power_mode_changed", __uifxn_AppFull_OnPwrModeChangeEvt, false);
        },

        Show: function() {
            let _ctzWc = HotelTV.welcome;
            let _ctzGst = HotelTV.guestinfo;
            let _ctzHotel = HotelTV.hotelinfo;

            console.log("Preparing APP[FULL] Page");
            __uifxn_AppFull_BuildMain();
        },

        BGServiceEvent: function(_evt) {
            let _state = HotelTV.state;
            let _program = HotelTV.tvguide.program;

            if ( _evt == "update_flight" ){
                _state.schedule.flight_reflash = true;
            }else if ( _evt == "update_weather" ){
                _state.schedule.weather_reflash = true;
            }else if ( _evt == "update_widget" ){
                _state.schedule.widget_reflash = true;
            }

            // Update flight schedule table if user doesn't watch flight schedule screen
            if ( _state.schedule.flight_reflash == true) {
                //if (_program[Number(_state.menu.main.cur)].type.toLowerCase() != "flight")
                {
                    _state.schedule.flight_reflash = false;
                    console.warn("Updated flight scheudle UI table.");

                    //Flight Contents Buildup
                    __uifxn_AppFull_BuildFlight();
                }
            }

            // Update weather schedule table if user doesn't watch weather screen
            if ( _state.schedule.weather_reflash == true) {
                if (_program[Number(_state.menu.main.cur)].type.toLowerCase() != "weather"){
                    _state.schedule.weather_reflash = false;
                    console.log("Updated Weather UI table.");

                    //Weather Contents Buildup
                    if ( _state.weather.default_location!=null )
                    {
                        if ( Object.keys(_state.weather.default_location).length != 0 ){
                            //날씨 콘텐트 업데이트
                            __uifxn_AppFull_BuildWeather();
                        }
                    }
                }
            }

            // Update weather schedule table if user doesn't watch weather screen
            if ( _state.schedule.widget_reflash == true) {
                _state.schedule.widget_reflash = false;
                console.log("Updated Widget UI");

                //Widget:Weather Contents Buildup
                if ( _state.weather!=null )
                {
                    if ( Object.keys(_state.weather.default_location).length != 0 ){
                        //상단 날씨 아이콘 및 온도 표시
                        __uifxn_AppFull_TopWidjet_BuildWeather();
                    }
                }
            }
        },

        MqttEvent: function(_evt) {
            let _state = HotelTV.state;

            console.log("MQTT RECEVED MESSAGE::> " + _evt);
            if (_evt == "EVENT-MESSAGE-CREATE" || _evt == "EVENT-MESSAGE-UPDATE" || _evt == "EVENT-MESSAGE-DELETE") {
                //DO NEW GUEST MESSAGE&DO CHANGE GUEST MESSAGE
                HotelTV.api.GetMessage().then(_ret => {
                    HotelTV.message = _ret;
                    console.log("Get New Message contents");

                    let _el_tbls = $('div#lst_mypagebg div #mp_message_table #mp_msg_tblrec');
                    let _msg = HotelTV.message;
                    let _msg_unread_cnt = 0;
                    //기존 메시지 테이블 레코드 삭제
                    _el_tbls.children('tbody').remove();
                    _el_tbls.each(function(_idx, _item) {
                        let _sz_innerHTML = '<tbody>';
                        let _num_msgIdx = 0;
                        for (let _j = _msg.length; _j > 0; _j--) {
                            _sz_innerHTML += '<tr msgnum=' + _j + ' msgidx=' + _num_msgIdx.toString() + ' >';
                            if (_msg[_j].read == false) {
                                _sz_innerHTML += '<td id="num">' + _j.toString() + '</td>';
                            } else {
                                _sz_innerHTML += '<td id="num" class="read">' + _j.toString() + '</td>';
                            }

                            if (_msg[_j].multilanguage == false) {
                                _sz_innerHTML += '<td id="title">' + _msg[_j].title.default+'</td>';
                            } else {
                                _sz_innerHTML += '<td id="title">' + _msg[_j].title[_state.lang] + '</td>';
                            }
                            _sz_innerHTML += '<td id="from">' + _msg[_j].from + '</td>';
                            _sz_innerHTML += '<td id="date">' + _msg[_j].createdAt + '</td>';
                            _sz_innerHTML += '</tr>';
                            _num_msgIdx++;
                        }
                        _sz_innerHTML += '</tbody>';
                        $(_item).html(_sz_innerHTML);
                    });

                    // 사용자가 메시지 메뉴를 사용중인경우에 대한 처리
                    if (_state.menu.stage.cur == "mypage_popup_message_card" || _state.menu.stage.cur == "mypage_select_menu") {
                        const _mmIdx = _state.menu.main.cur;
                        // 메시지 상태 오브젝트 초기화
                        if ("message" in _state.menu.main[_mmIdx]) {
                            _state.menu.main[_mmIdx]['message'] = {
                                'cnt': _msg.length,
                                'cur': 0,
                                'prev': null,
                            };
                        }
                        $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').removeClass('focus');
                        $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').filter("[msgidx='" + _state.menu.main[_mmIdx]['message']['cur'] + "']").addClass('focus');
                    }

                    //메시지 개수 표시
                    const _guest = HotelTV.guestinfo;
                    let _trTbl = HotelTV.translation;
                    for (let _j = _msg.length; _j > 0; _j--) {
                        if (_msg[_j].read == false) {
                            _msg_unread_cnt++;
                        }
                    }
                    $('div#lst_mypagebg div #mp_message_title').text(_guest.name + _trTbl.ui.mypage.message.title.title[_state.lang].replace("_XX", _msg_unread_cnt.toString()));

                    //widjet 상단 메시지(unread)개수 표시
                    __uifxn_AppFull_TopWidjet_BuildMsgCnt();

                    //신규 메시지 볼룬팝업
                    HotelTV.ui_utils.ShowNotificationMsgBalloon(_guest.name + _trTbl.ui.mypage.message.title.title_widget[_state.lang].replace("_XX", _msg_unread_cnt.toString()), 10);
                }).catch(_error => {
                    console.log("Fail to get Message info");
                });
            } else if (_evt == "EVENT-NEWS-UPDATE") {
                //DO NEW NEWS
                HotelTV.api.GetNews().then(_ret => {
                    HotelTV.news = _ret;
                    console.log("Get New News contents");
                    __uifxn_AppFull_BuildNews();
                }).catch(_error => {
                    console.log("Fail to get news info");
                });
            } else if (_evt == "EVENT-EMERGENCY-START") {

            } else if (_evt == "EVENT-EMERGENCY-STOT") {

            } else if (_evt == "COMMAND-SYSTEM-RESTART") {
                let _tmval = 10;
                let _state = HotelTV.state;
                let _trTbl = HotelTV.translation;

                setTimeout(HotelTV.hal.Reboot, 12000);
                HotelTV.ui_utils.ShowSysNoticeMsg(true,
                    "notice",
                    "SYSTEM NOTICE",
                    _trTbl.system.notice.event.mqtt.system_reboot[_state.lang], {
                        "timeout": _tmval,
                        "cb_disp": function() {
                            _tmval -= 1;
                            console.log("time..." + _tmval);
                            if ($('.error #countdown').css("display") == "none") {
                                $('.error #countdown').fadeIn(1000);
                            }
                            $('.error #countdown #message').text(`System will be shutdown in ${_tmval} second...`);
                        },
                        "cb_eoe": function() {
                            HotelTV.api.ReportEvent([{'power': false, 'location':null}])
                        }
                    });
            } else if (_evt == "COMMAND-GUEST-CHECKIN") {
                let _tmval = 10;
                let _state = HotelTV.state;
                let _trTbl = HotelTV.translation;

                setTimeout(HotelTV.hal.Reboot, 12000);
                HotelTV.ui_utils.ShowSysNoticeMsg(true,
                    "notice",
                    "SYSTEM NOTICE",
                    _trTbl.system.notice.event.mqtt.system_reboot[_state.lang], {
                        "timeout": _tmval,
                        "cb_disp": function() {
                            _tmval -= 1;
                            console.log("time..." + _tmval);
                            if ($('.error #countdown').css("display") == "none") {
                                $('.error #countdown').fadeIn(1000);
                            }
                            $('.error #countdown #message').text(`System will be restart in ${_tmval} second...`);
                        },
                        "cb_eoe": function() {
                            HotelTV.api.ReportEvent([{'power': false, 'location':null}])
                        }
                    });
            } else if (_evt == "COMMAND-GUEST-CHECKOUT" || _evt == "COMMAND-SYSTEM-STOP") {
                let _tmval = 30;
                let _state = HotelTV.state;
                let _trTbl = HotelTV.translation;

                setTimeout(HotelTV.hal.Reboot, 32000);

                HotelTV.ui_utils.ShowSysNoticeMsg(true,
                    "notice",
                    "SYSTEM NOTICE",
                    _trTbl.system.notice.event.mqtt.checkout[_state.lang], {
                        "timeout": _tmval,
                        "cb_disp": function() {
                            _tmval -= 1;
                            console.log("time..." + _tmval);
                            if ($('.error #countdown').css("display") == "none") {
                                $('.error #countdown').fadeIn(1000);
                            }
                            $('.error #countdown #message').text(`System will be shutdown in ${_tmval} second...`);
                        },
                        "cb_eoe": function() {
                            HotelTV.api.ReportEvent([{'power': false, 'location':null}])
                        }
                    });
            } else if (_evt == "COMMAND-GUEST-UPDATE") {

            } else if (_evt == "COMMAND-GUEST-ROOMCHANGE") {
                let _tmval = 30;
                let _state = HotelTV.state;
                let _trTbl = HotelTV.translation;
                setTimeout(HotelTV.hal.Reboot, 32000);
                HotelTV.ui_utils.ShowSysNoticeMsg(true,
                    "notice",
                    "SYSTEM NOTICE",
                    _trTbl.system.notice.event.mqtt.room_change[_state.lang], {
                        "timeout": _tmval,
                        "cb_disp": function() {
                            _tmval -= 1;
                            console.log("time..." + _tmval);
                            if ($('.error #countdown').css("display") == "none") {
                                $('.error #countdown').fadeIn(1000);
                            }
                            $('.error #countdown #message').text(`System will be restart in ${_tmval} second...`);
                        },
                        "cb_eoe": function() {
                            HotelTV.api.ReportEvent([{'power': false, 'location':null}])
                        }
                    });
            }
        },

        UpdateEpg: function() {
            let _state = HotelTV.state;
            let _trTbl = HotelTV.translation;

            if (_state.menu.stage.cur != 'tvCtgHide') {
                return;
            }

            let _el_tvctglst = $('.main .tv .bg .owl-item>.item');
            if (_el_tvctglst.length > 0) {
                _el_tvctglst.each(function(_idx, _item) {
                    let _el_epg_items = $(_item[_idx]).find('span#tvch_epg_info')
                    _el_epg_items.each(function(_j, _ch) {
                        let _epg_id = _ch.attr('epg_id');
                        let _epg_inf = __uifxn_AppFull_TVEpgByChName(_epg_id);
                        if (_epg_inf != null) {
                            _ch.text(_egp_prog_inf.name);
                        } else {
                            _ch.text(_trTbl.ui.tv.epg.msg.none_epg_info[_state.lang]);
                        }
                    });
                });
            }
        },

        Close: function() {
            SpatialNavigation.clear();
        },
    }
})();
