/**
 * Copyright (c) 2020
 *
 * CENTIRM HotelTV HCAP 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
 */
HotelTV.namespace('HotelTV.hcap');
HotelTV.hcap = (function() {
    //// 의존 관계 선언


    //// 비공개 프로퍼티
    // var hcap_property_key = ['hcap_js_extension_version', 'hcap_middleware_version', 'model_name', 'platform_version',
    //     'serial_number', 'number_of_tuner', 'support_language_list', 'osd_layer_id', 'room_number', 'single_decoding',
    //     'browser_network_error_handling', 'soft_ap_ui', 'clock_display', 'asl_mode', 'rms_trusted_ip',
    //     'input_splash_image', 'boot_sequence_option', 'tv_channel_attribute_floating_ui', 'browser_https_security_level',
    //     'dmr',
    //     'netinfo',
    //     'pro_centric_server_info',
    // ];
    let hcap_property_key = ['hcap_js_extension_version', 'hcap_middleware_version', 'model_name', 'platform_version',
        'micom_version', 'boot_version', 'platform_src_revision', 'ptc_version', 'serial_number', 'display_resolution',
        'number_of_tuner', 'support_language_list', 'language', 'country', 'gmt_offset_in_minute', 'daylight_saving', 'boot_sequence_option',
        'application_channel_control', 'application_update_on_startup', 'application_update_in_shutdown',
        'osd_layer_id', 'key_delivery_to_simplink',
        'wol_w', 'wol_m',
        'single_decoding',
        'inband_data_service_mhp', 'inband_data_service_mheg', 'inband_data_service_hbbtv',
        'security_level', 'tv_name', 'wifi_screen_share',
        'smart_share', 'smart_pairing', 'dmr', 'browser_https_security_level',
        'clock_display', 'teletext', 'secure_mmr_pairing', 'dial', 'alljoyn', 'clock_source', 'xait_version',
        'asl_mode', 'screensaver_control', 'rms_trusted_ip', 'lg_service_xml_version', 'cec_device_control',
        'input_splash_image', 'block_usb', 'tv_channel_attribute_floating_ui',
        'instant_power', 'hardware_version',
        'network_info',
        'tv_channel_ui', "mute_on_tv_input",
        'soft_ap_ui', "soft_ap", "soft_ap_password",
        'picture',
        'end_of_item'
    ];



    const g_media = {
        'hndl': null,
        'status': 'stop',
        'pipeline': false,
        'tm_lststat': null,
    };

    const g_nativApps_info = {
        'preapp': null,
    };


    /// 초기화 루틴




    //// 비공개 매써드
    /**
     * HCAP Wrapper Function::> Get ProCentric Server Info(Realted HCAP API:hcap.power.reboot)
     */
    function __hcapfxn_Reboot() {
        hcap.power.reboot({
            "onSuccess": function() {
                console.log("onSuccess");
            },
            "onFailure": function(f) {
                console.log("onFailure : errorMessage = " + f.errorMessage);
            }
        });
    };

    /**
     * HCAP Wrapper Function::> Get ProCentric Server Info(Realted HCAP API:hcap.system.setBrowserDebugMode)
     * @param {Boolean} enable enable/disable flag.
     */
    function __hcapfxn_setBrowserDebugMode(enable) {
        hcap.system.setBrowserDebugMode({
            "debugMode": enable == true ? true : false,
            "onSuccess": function() {
                console.log("onSuccess: browser debug mode enabled");
            },
            "onFailure": function(f) {
                console.log("onFailure : errorMessage = " + f.errorMessage);
            }
        });
    };

    /**
     * HCAP Wrapper Function::> Get Device Properties(Realted HCAP API:hcap.property.getProperty)
     * @param {string} sz_key property key name.
     */
    function __hcapfxn_get_property(sz_key) {
        return new Promise((resolve, reject) => {
            let param = {
                "key": sz_key,
                "onSuccess": function(s) { resolve({ "key": sz_key, "value": s.value }) },
                //"onFailure": function(f) { reject({ "key": sz_key, "value": "unknown" }) }
                "onFailure": function(f) { resolve({ "key": sz_key, "value": "unknown" }) }
            };
            hcap.property.getProperty(param);
        });
    };

    /**
     * HCAP Wrapper Function::> Get Device Properties(Realted HCAP API:hcap.property.setProperty)
     * @param {string} sz_key property key name.
     * @param {object} value is object to setting property
     */
    function __hcapfxn_set_property(sz_key, value) {
        return new Promise((resolve, reject) => {
            let param = {
                "key": sz_key,
                "value": value.toString(),
                "onSuccess": function(s) { resolve({ "key": sz_key, "value": value }) },
                "onFailure": function(f) { resolve({ "key": sz_key, "value": "unknown" }) }
            };
            hcap.property.setProperty(param);
        });
    };

    /**
     * IDCAP Wrapper Function::> Get Device Configuration(Properties)(Realted IDCAP API:idcap://configuration/property/get)
     * @param {string} sz_key property key name.
     */
    function __idcapfxn_get_property(sz_key) {
        return new Promise((resolve, reject) => {
            idcap.request( "idcap://configuration/property/get" , {
                "parameters": {
                    "key" : sz_key
                },
                "onSuccess": function (s) {
                    console.log("onSuccess cbObject = " + JSON.stringify(s));
                    resolve({ "key": sz_key, "value": s.value })
                },
                "onFailure": function (err) {
                    console.log("onFailure : errorMessage = " + err.errorMessage);
                    resolve({ "key": sz_key, "value": "unknown" })
                }
            });
        });
    };

    /**
     * IDCAP Wrapper Function::> Get Device Configuration(Properties)(Realted IDCAP API:idcap://configuration/property/set)
     * @param {string} sz_key property key name.
     * @param {object} value is object to setting property
     */
    function __idcapfxn_set_property(sz_key, value) {
        return new Promise((resolve, reject) => {
            // let param = {
            //     "key": sz_key,
            //     "value": value.toString(),
            //     "onSuccess": function(s) { resolve({ "key": sz_key, "value": value }) },
            //     "onFailure": function(f) { resolve({ "key": sz_key, "value": "unknown" }) }
            // };
            // hcap.property.setProperty(param);

            idcap.request( "idcap://configuration/property/set" , {
                    "parameters": {
                        "key" : sz_key,
                        "value" : value.toString()
                    },
                    "onSuccess": function () {
                        resolve({ "key": sz_key, "value": value });
                    },
                    "onFailure": function (err) {
                        resolve({ "key": sz_key, "value": "unknown" })
                        console.log("onFailure : errorMessage = " + err.errorMessage);
                    }
                });
        });
    };



    /**
     * HCAP Wrapper Function::> Get Device Networn Information(Realted HCAP API:hcap.network.getNetworkInformation)
     * @param {string} sz_key network property key name.
     * @param {callback} callback is callback object
     */
    function __hcapfxn_get_netinfo(sz_key, callback) {
        return new Promise((resolve, reject) => {
            let param = {
                "onSuccess": function(p) {
                    let _info = p;
                    _info['details'] = {};
                    hcap.network.getNumberOfNetworkDevices({
                        "onSuccess": function(s) {
                            //console.log("onSuccess : the number of network devices = " + s.count);
                            for (var i = 0; i < s.count; i++) {
                                (function(k) {
                                    hcap.network.getNetworkDevice({
                                        "index": k,
                                        "onSuccess": function(r) {
                                            console.log("onSuccess : networkMode = " + r.networkMode +
                                                "\n name = " + r.name +
                                                "\n mac = " + r.mac +
                                                "\n dhcp = " + r.dhcp +
                                                "\n ip = " + r.ip +
                                                "\n gateway = " + r.gateway +
                                                "\n netmask = " + r.netmask +
                                                "\n primary dns = " + r.primaryDns +
                                                "\n secondary dns = " + r.secondaryDns);
                                            delete r.command;
                                            delete r.command_id;
                                            _info['details'][k] = r;
                                            if ((k + 1) == s.count) {
                                                resolve({ "key": sz_key, "value": _info })
                                            }
                                        },
                                        "onFailure": function(r) {
                                            console.log("onFailure : errorMessage = " + r.errorMessage);
                                            resolve({ "key": sz_key, "value": null });
                                        }
                                    });
                                })(i);
                            }
                        },
                        "onFailure": function(f) {
                            console.log("onFailure : errorMessage = " + f.errorMessage);
                            resolve({ "key": sz_key, "value": null })
                        }
                    });

                    //resolve({ "key": sz_key, "value": p })
                },
                "onFailure": function(f) { resolve({ "key": sz_key, "value": null }) }
            };
            hcap.network.getNetworkInformation(param);
        });
    };

    /**
     * HCAP Wrapper Function::> Get Device Picture Property Information(Realted HCAP API:hcap.property.getPictureProperty)
     * @param {string} sz_key picture property key name.
     */
    function __hcapfxn_get_picproperty(sz_key, callback) {
        return new Promise((resolve, reject) => {
            let param = {
                "key": sz_key,
                "onSuccess": function(s) { resolve({ "key": sz_key, "value": s.value }) },
                //"onFailure": function(f) { reject({ "key": sz_key, "value": "unknown" }) }
                "onFailure": function(f) { resolve({ "key": sz_key, "value": "unknown" }) }
            };
            hcap.property.getProperty(param);
        });
    };


    /**
     * HCAP Wrapper Function::> Get Device Locale List
     * @param {string} sz_key locale key name.
     * @param {callback} callback is callback object
     */
    function __hcapfxn_get_dev_locale_info(sz_key, callback) {
        return new Promise((resolve, reject) => {
            let param = {
                "onSuccess": function(p) { resolve({ "key": sz_key, "info": p }) },
                "onFailure": function(f) { resolve({ "key": sz_key, "info": null }); }
            }
            hcap.system.getLocaleList(param);
        });
    };

    /**
     * HCAP Wrapper Function::> Get ProCentric Server Info(Realted HCAP API:hcap.system.getProcentricServer)
     * @param {string} sz_key procentric server property key name.
     * @param {callback} callback is callback object
     */
    function __hcapfxn_get_pctrsvrinfo(sz_key, callback) {
        return new Promise((resolve, reject) => {
            let param = {
                "onSuccess": function(p) { resolve({ "key": sz_key, "info": p }) },
                "onFailure": function(f) { resolve({ "key": sz_key, "info": null }); }
            }
            hcap.system.getProcentricServer(param);
        });
    };

    /**
     * HCAP Wrapper Function::> Get ProCentric Server Info(Realted HCAP API:hcap.system.getHotelMode)
     * @param {callback} callback is callback object
     */
    function __hcapfxn_get_pctrhotelmodeinfo(callback) {
        let param = {
            "onSuccess": function(p) { callback({ "info": p.hotelMode }); },
            "onFailure": function(f) { callback({ "info": null, errmsg: f.errorMessage }); }
        }
        hcap.property.getHotelMode(param);
    };

    /**
     * HCAP Wrapper Function::> Get Cpu TIme
     * @param {callback} callback is callback object
     */
    function __hcapfxn_get_cpuTime(callback) {
        let param = {
            "onSuccess": function(param) {
                //console.log("onSuccess : cpu time(milliseconds) = " + param.cpuTime);
                if (callback != null) {
                    callback(param.cpuTime);
                }
            },
            "onFailure": function(f) {
                console.log("onFailure : errorMessage = " + f.errorMessage);
            }
        }
        hcap.time.getCpuTime(param);
    };

    /**
     * HCAP Wrapper Function::> Set Video Window size(Realted HCAP API:hcap.video.setVideoSize)
     * @param {number} _sx start x position
     * @param {number} _sy start x position
     * @param {number} _width width
     * @param {number} _height height
     */
    function __hcapfxn_set_vidwinsize(_sx, _sy, _width, _height) {
        hcap.video.setVideoSize({
            "x": _sx,
            "y": _sy,
            "width": _width,
            "height": _height,
            "onSuccess": function() {
                console.log("onSuccess : setVideoSize");
            },
            "onFailure": function(f) {
                console.log("onFailure : errorMessage = " + f.errorMessage);
            }
        });
    };

    /**
     * HCAP Wrapper Function::> Get Device Resourcee status(CPU usage)
     */
    function __hcapfxn_get_cpuUsage() {
        return new Promise((resolve, reject) => {
            let param = {
                "onSuccess": function(s) { resolve({ "key": "cpu_usage", "value": s.percentage }) },
                "onFailure": function(f) { resolve({ "key": "cpu_usage", "value": -1 }) }
            };
            hcap.system.getCpuUsage(param);
        });
    };

    /**
     * HCAP Wrapper Function::> Get Device Resourcee status(MEM usage)
     */
    function __hcapfxn_get_memUsage() {
        return new Promise((resolve, reject) => {
            let param = {
                "onSuccess": function(s) { resolve({ "key": "mem_usage", "value": { "total": s.totalmemory, "free": s.freememory, "percent": s.percentage } }) },
                "onFailure": function(f) { resolve({ "key": "mem_usage", "value": -1 }) }
            };
            hcap.system.getMemoryUsage(param);
        });
    };

    /**
     * HCAP Wrapper Function::> Play channel
     * @param {string} _type channel type
     * @param {dictionary} _param channel parameter
     */
    function __hcapfxn_play_channel(_type, _param) {
        const _lutBCastType = {
                'TERRESTRIAL': hcap.channel.RfBroadcastType.TERRESTRIAL,
                'TERRESTRIAL_2': hcap.channel.RfBroadcastType.TERRESTRIAL_2,
                'SATELLITE': hcap.channel.RfBroadcastType.SATELLITE,
                'SATELLITE_2': hcap.channel.RfBroadcastType.SATELLITE_2,
                'CABLE': hcap.channel.RfBroadcastType.CABLE,
                'CABLE_STD': hcap.channel.RfBroadcastType.CABLE_STD,
                'CABLE_HRC': hcap.channel.RfBroadcastType.CABLE_HRC,
                'CABLE_IRC': hcap.channel.RfBroadcastType.CABLE_IRC,
                'ANALOG_PAL_BG': hcap.channel.RfBroadcastType.ANALOG_PAL_BG,
                'ANALOG_PAL_DK': hcap.channel.RfBroadcastType.ANALOG_PAL_DK,
                'ANALOG_PAL_I': hcap.channel.RfBroadcastType.ANALOG_PAL_I,
                'ANALOG_PAL_M': hcap.channel.RfBroadcastType.ANALOG_PAL_M,
                'ANALOG_PAL_N': hcap.channel.RfBroadcastType.ANALOG_PAL_N,
                'ANALOG_SECAM_BG': hcap.channel.RfBroadcastType.ANALOG_SECAM_BG,
                'ANALOG_SECAM_DK': hcap.channel.RfBroadcastType.ANALOG_SECAM_DK,
                'ANALOG_SECAM_L': hcap.channel.RfBroadcastType.ANALOG_SECAM_L,
                'ANALOG_NTSC': hcap.channel.RfBroadcastType.ANALOG_NTSC,
                'TERRESTRIAL_ATSC3': hcap.channel.RfBroadcastType.TERRESTRIAL_ATSC3,
                'CABLE_ATSC3': hcap.channel.RfBroadcastType.CABLE_ATSC3,
            }
            // IP channel class 2 change request
        if (_type === "ipstream" || _type === "encoder") {
            hcap.channel.requestChangeCurrentChannel({
                "channelType": hcap.channel.ChannelType.IP,
                "ip": _param.ip,
                "port": _param.port,
                "ipBroadcastType": _param.ptype == "rtp" ? hcap.channel.IpBroadcastType.RTP : hcap.channel.IpBroadcastType.UDP,
                "onSuccess": function() {
                    console.log("onSuccess");
                },
                "onFailure": function(f) {
                    console.log("onFailure : errorMessage = " + f.errorMessage);
                }
            });
        } else if (_type === "ptcrf") {
            if (_param.rf.type == "CABLE") {
                hcap.channel.requestChangeCurrentChannel({
                    "channelType": hcap.channel.ChannelType.RF,
                    "majorNumber": _param.rf.major,
                    "minorNumber": _param.rf.minor,
                    "plpId": 0,
                    "rfBroadcastType": _lutBCastType[_param.rf.type],
                    "onSuccess": function() {
                        console.log("onSuccess");
                    },
                    "onFailure": function(f) {
                        console.log("onFailure : errorMessage = " + f.errorMessage);
                    }
                });
            } else {
                console.log("Unsupported RF type:" + _param.rf.type);
            }
        } else {
            console.log("Unsupported type:" + _type);
        }
    }


    /**
     * HCAP Wrapper Function::> Play media
     * @param {string} _type channel type
     * @param {dictionary} _param channel parameter
     */
    function __hcapfxn_play_media(uri_media, uri_srt, mime_typ, repeat, cb_play_ok, cb_play_err) {
        if (g_media.pipeline == true) {
            g_media.hndl.stop({
                "onSuccess": function() {
                    g_media.hndl.destroy({
                        "onSuccess": function() {
                            g_media.hndl = hcap.Media.createMedia({
                                "url": uri_media,
                                "mimeType": mime_typ
                            });

                            console.log("Media.createMedia = " + g_media.hndl);
                            g_media.hndl.play({
                                "repeatCount": repeat,
                                "onSuccess": function() {
                                    console.log("onSuccess : playVOD -> " + uri_media);
                                    g_media.status = 'play';
                                    if (cb_play_ok != null) {
                                        cb_play_ok();
                                    }
                                },
                                "onFailure": function(f) {
                                    console.log("onFailure : errorMessage = " + f.errorMessage);
                                    if (cb_play_err != null) {
                                        cb_play_err();
                                    }
                                }
                            });
                        },
                        "onFailure": function(f) {
                            console.log("onFailure : errorMessage = " + f.errorMessage);
                            if (cb_play_err != null) {
                                cb_play_err();
                            }
                        }
                    });
                },
                "onFailure": function(f) {
                    console.log("onFailure : errorMessage = " + f.errorMessage);
                    if (f.errorMessage == 'already destroyed.') {
                        g_media.hndl = hcap.Media.createMedia({
                            "url": uri_media,
                            "mimeType": mime_typ
                        });

                        console.log("Media.createMedia = " + g_media.hndl);
                        g_media.hndl.play({
                            "repeatCount": repeat,
                            "onSuccess": function() {
                                console.log("onSuccess : playVOD -> " + uri_media);
                                g_media.status = 'play';
                                if (cb_play_ok != null) {
                                    cb_play_ok();
                                }
                            },
                            "onFailure": function(f) {
                                console.log("onFailure : errorMessage = " + f.errorMessage);
                                if (cb_play_err != null) {
                                    cb_play_err();
                                }
                            }
                        });
                    } else {
                        if (cb_play_err != null) {
                            cb_play_err();
                        }
                    }
                }
            });
        } else {
            g_media.pipeline = true;
            hcap.Media.startUp({
                "onSuccess": function() {
                    g_media.hndl = hcap.Media.createMedia({
                        "url": uri_media,
                        "mimeType": mime_typ
                    });

                    console.log("Media.createMedia = " + g_media.hndl);
                    g_media.hndl.play({
                        "repeatCount": repeat,
                        "onSuccess": function() {
                            console.log("onSuccess : playVOD -> " + uri_media);
                            g_media.status = 'play';
                            if (cb_play_ok != null) {
                                cb_play_ok();
                            }
                        },
                        "onFailure": function(f) {
                            console.log("onFailure : errorMessage = " + f.errorMessage);
                            if (cb_play_err != null) {
                                cb_play_err();
                            }
                        }
                    });
                },
                "onFailure": function(f) {
                    console.log("onFailure : errorMessage = " + f.errorMessage);
                    if (cb_play_err != null) {
                        cb_play_err();
                    }
                }
            });
        }
    }

    /**
     * HCAP Wrapper Function::> Media Shutdown
     */
    function __hcapfxn_media_shutdown() {
        return new Promise((resolve, reject) => {
            if (g_media.hndl != null) {
                g_media.hndl.stop({
                    "onSuccess": function() {
                        g_media.hndl.destroy({
                            "onSuccess": function() {
                                hcap.Media.shutDown({
                                    "onSuccess": function() {
                                        console.log("shutDown onSuccess");
                                        g_media.status = 'stop';
                                        resolve();
                                    },
                                    "onFailure": function(f) {
                                        console.log("onFailure : errorMessage = " + f.errorMessage);
                                        reject(f.errorMessage);
                                    }
                                });
                            },
                            "onFailure": function(f) {
                                console.log("onFailure : errorMessage = " + f.errorMessage);
                                reject(f.errorMessage);
                            }
                        });
                    },
                    "onFailure": function(f) {
                        console.log("onFailure : errorMessage = " + f.errorMessage);
                        reject(f.errorMessage);
                    }
                });
            } else {
                console.log("g_media.hndl is null");
                resolve("g_media.hndl is null");
            }
        });
    }


    //// 공개 API
    return {
        Init: function() {
            hcap.channel.stopCurrentChannel({
                "onSuccess": null,
                "onFailure": null
            });
        },

        SetBrowserDebug: function(__en_dbg_hcap, __en_dbg_brw) {
            /** Disable HCAP debug message turn off */
            if (__en_dbg_hcap == false) {
                extDisableHcapConsoleLog = true;
            }
            __hcapfxn_setBrowserDebugMode(__en_dbg_brw);
        },


        PwrOff: function() {
            hcap.power.powerOff({
                "onSuccess": function() {
                    console.log("onSuccess:: > Power OFF");
                },
                "onFailure": function(f) {
                    console.log("onFailure : errorMessage = " + f.errorMessage);
                }
            });
        },

        Reboot: function() {
            __hcapfxn_Reboot();
        },


        GetDevInfo: function() {
            return new Promise((resolve, reject) => {
                const _pmFxnArProperty = [];
                // __hcapfxn_get_property("display_resolution").then(result => {
                //     console.log("R::>" + result.key + ":" + result.value);
                // }).catch(err => {
                //     console.log("E::>" + err.key);
                // });

                // Device Information
                for (let i = 0; i < hcap_property_key.length; i++) {
                    if (hcap_property_key[i] != 'end_of_item') {
                        if (hcap_property_key[i] == 'network_info') {
                            _pmFxnArProperty.push(__hcapfxn_get_netinfo(hcap_property_key[i]));
                        } else if (hcap_property_key[i] == 'picture') {

                        } else if (hcap_property_key[i] == "wifi_screen_share"){
                            // HCAP대신 IDCAP API호출
                            _pmFxnArProperty.push(__idcapfxn_get_property(hcap_property_key[i]));
                        } else {
                            _pmFxnArProperty.push(__hcapfxn_get_property(hcap_property_key[i]));
                        }
                    }
                }
                Promise.all(_pmFxnArProperty)
                    .then(_ret => {
                        let _devinfo = HotelTV.devinfo;
                        for (let i = 0; i < _ret.length; i++) {
                            let _dic_item = _ret[i];
                            if (_dic_item.value != null) {
                                if (_dic_item.value != "unknown" && (
                                        _dic_item.key == 'hcap_js_extension_version' ||
                                        _dic_item.key == 'hcap_middleware_version' ||
                                        _dic_item.key == 'platform_version' ||
                                        _dic_item.key == 'boot_version' ||
                                        _dic_item.key == 'ptc_version' ||
                                        _dic_item.key == 'hardware_version'
                                    )) {
                                    let _verinfo = _dic_item.value.split(".");
                                    if (_verinfo.length == 1) {
                                        _devinfo[_dic_item.key] = { "major": _verinfo[0], "minor": "00" };
                                    } else if (_verinfo.length == 3) {
                                        _devinfo[_dic_item.key] = { "major": _verinfo[0], "minor": _verinfo[1], "revision": _verinfo[2] };
                                    } else if (_verinfo.length == 4) {
                                        _devinfo[_dic_item.key] = { "major": _verinfo[0], "minor": _verinfo[1], "revision": _verinfo[2] + _verinfo[3] };
                                    }
                                } else {
                                    _devinfo[_dic_item.key] = _dic_item.value;

                                    if (_dic_item.key == 'network_info') {
                                        delete _devinfo[_dic_item.key].command;
                                        delete _devinfo[_dic_item.key].command_id;
                                    }
                                }
                            } else {
                                console.log(`ERROR::>Item[${_dic_item.key}] is NULL::>`);
                            }
                            //console.log(`Item[${_dic_item.key}] ::> ${_dic_item.value}`);
                        };
                        //Locale Information
                        __hcapfxn_get_dev_locale_info("getLocaleList").then(result => {
                            _devinfo['getLocaleList'] = result.info.list;
                        });

                        //Server Information
                        __hcapfxn_get_pctrsvrinfo("pro_centric_server_info").then(result => {
                            let _svrinfo = HotelTV.svrinfo;
                            let _info = result.info;
                            if (_info.media === "rf") {
                                console.log(`PTC server type[${_info.rfServer.type}], data channel number = ${_info.rfServer.dataChannelNumber}`);
                                console.log(`PTC server type[${_info.rfServer.type}], frequency = ${_info.rfServer.freqeuncy}`);
                            } else if (_info.media === "ip") {
                                if (_info.ipServer.type === "ip") {
                                    console.log(`PTC server type[${_info.ipServer.type}], ip = ${_info.ipServer.ip} port=${_info.ipServer.port}`);
                                    _svrinfo['ipaddr'] = _info.ipServer.ip;
                                    _svrinfo['port'] = _info.ipServer.port;
                                } else if (p.ipServer.type === "domain_name") {
                                    console.log(`PTC server type[${_info.ipServer.type}], dns = ${_info.ipServer.domainName} port=${_info.ipServer.port}`);
                                }
                            }
                            _svrinfo['media'] = _info.media;
                            _svrinfo['typ_ipsvr'] = _info.ipServer.type;
                            resolve(0);
                        });
                    });
            });
        },

        ShowDevInfo: function() {
            return new Promise((resolve, reject) => {
                let _devinfo = HotelTV.devinfo;
                for (let key in _devinfo) {
                    console.log("Device Info::Key[" + key + "]: " + _devinfo[key]);
                }
                resolve(0);
            });
        },

        SetDevice: function(config) {
            return new Promise((resolve, reject) => {
                const _pmFxnArProperty = [];
                let _devinfo = HotelTV.devinfo;
                let _devconfig = config;
                let need_to_reboot = false;

                // STEP#001::> HOTEL MODE
                hcap.mode.getHcapMode({
                    "onSuccess": function(s) {
                        console.log("onSuccess : current hcap mode = " + s.mode);
                        if (s.mode != hcap.mode.HCAP_MODE_1) {
                            hcap.mode.setHcapMode({
                                "mode": hcap.mode.HCAP_MODE_1,
                                "onSuccess": function() {
                                    console.log("onSuccess");
                                },
                                "onFailure": function(f) {
                                    console.log("onFailure : errorMessage = " + f.errorMessage);
                                }
                            });
                        }
                    },
                    "onFailure": function(f) {
                        console.log("onFailure : errorMessage = " + f.errorMessage);
                    }
                });

                // STEP#002::> Start Channel
                hcap.channel.getStartChannel({
                    "onSuccess": function(s) {
                        console.log("onSuccess :" +
                            "\n channel type      : " + s.channelType +
                            "\n logical number    : " + s.logicalNumber +
                            "\n frequency         : " + s.frequency +
                            "\n program number    : " + s.programNumber +
                            "\n major number      : " + s.majorNumber +
                            "\n minor number      : " + s.minorNumber +
                            "\n satellite ID      : " + s.satelliteId +
                            "\n polarization      : " + s.polarization +
                            "\n rf broadcast type : " + s.rfBroadcastType +
                            "\n ip                : " + s.ip +
                            "\n port              : " + s.port +
                            "\n ip broadcast type : " + s.ipBroadcastType +
                            "\n symbol rate       : " + s.symbolRate +
                            "\n pcr pid           : " + s.pcrPid +
                            "\n video pid         : " + s.videoPid +
                            "\n video stream type : " + s.videoStreamType +
                            "\n audio pid         : " + s.audioPid +
                            "\n audio stream type : " + s.audioStreamType +
                            "\n signal strength   : " + s.signalStrength +
                            "\n source address    : " + s.sourceAddress);
                        if (s.channelType != hcap.channel.ChannelType.UNKNOWN) {
                            // set start channel with RF channel class 2
                            hcap.channel.setStartChannel({
                                "channelType": hcap.channel.ChannelType.UNKNOWN,
                                "onSuccess": function() {
                                    console.log("onSuccess::StartChanell Setting");
                                },
                                "onFailure": function(f) {
                                    console.log("onFailure : errorMessage = " + f.errorMessage);
                                }
                            });
                        }
                    },
                    "onFailure": function(f) {
                        console.log("onFailure : errorMessage = " + f.errorMessage);
                    }
                });

                // STEP#003::>  CENTIRM's Remote Controller Registr
                let _rmcTbl_CT_default = [
                    // INFO: KEYCODE Format
                    //       CCCCKKII
                    //       CCCC: Custom code
                    //       KK: Remote Key Value
                    //       II: Invertied remote Key Value
                    // PWR
                    { "_keyCode": 0x847912ed, "_virCode": hcap.key.Code.POWER }, //PWR -> PWR KEY
                    // NAVIGATION
                    { "_keyCode": 0x847907f8, "_virCode": hcap.key.Code.LEFT }, //LEFT -> LEFT KEY
                    { "_keyCode": 0x847909f6, "_virCode": hcap.key.Code.RIGHT }, //RIGHT -> RIGHT KEY
                    { "_keyCode": 0x847908f7, "_virCode": hcap.key.Code.ENTER }, //OK -> OK KEY
                    { "_keyCode": 0x847905fa, "_virCode": hcap.key.Code.UP }, //UP -> UP KEY
                    { "_keyCode": 0x847900ff, "_virCode": hcap.key.Code.DOWN }, //DOWN -> DOWN KEY
                    { "_keyCode": 0x84791ae5, "_virCode": hcap.key.Code.BACK }, //BACK -> BACK KEY
                    { "_keyCode": 0x8479EA15, "_virCode": hcap.key.Code.PORTAL }, //HOME -> PORTAL KEY
                    { "_keyCode": 0x84790FF0, "_virCode": hcap.key.Code.CH_UP }, //CHUP -> CH_UP KEY
                    { "_keyCode": 0x847928D7, "_virCode": hcap.key.Code.CH_DOWN }, //CHDN -> CH_DOWN KEY
                    { "_keyCode": 0x8479DA25, "_virCode": hcap.key.Code.Q_MENU }, //MENU -> CH_DOWN KEY
                    // VOLUME
                    { "_keyCode": 0x847910ef, "_virCode": hcap.key.Code.VOL_UP }, //VOL UP -> VOL UP KEY
                    { "_keyCode": 0x84790ff0, "_virCode": hcap.key.Code.VOL_DOWN }, //VOL DOWN -> VOL DOWN KEY
                    { "_keyCode": 0x847903fC, "_virCode": hcap.key.Code.MUTE }, //VOL DOWN -> MUTE KEY
                    // PLAYER
                    { "_keyCode": 0x84791fe0, "_virCode": hcap.key.Code.STOP }, //STOP -> STOP KEY
                    { "_keyCode": 0x84791EE1, "_virCode": hcap.key.Code.PLAY }, //PLAY -> PLAY KEY
                    { "_keyCode": 0x847921DE, "_virCode": hcap.key.Code.REWIND }, //REWIND -> REWIND KEY
                    { "_keyCode": 0x847922DD, "_virCode": hcap.key.Code.FORWARD }, //FORWARD -> FORWARD KEY
                    { "_keyCode": 0x847923DC, "_virCode": hcap.key.Code.GOTOPREV }, //GO PREV -> GOTOPREV KEY
                    { "_keyCode": 0x847924DB, "_virCode": hcap.key.Code.GOTONEXT }, //GO NEXT -> GOTONEXT KEY
                    // NUMBER
                    { "_keyCode": 0x84790BF4, "_virCode": hcap.key.Code.NUM_1 }, //1 -> NUM_1 KEY
                    { "_keyCode": 0x84790CF3, "_virCode": hcap.key.Code.NUM_2 }, //2 -> NUM_2 KEY
                    { "_keyCode": 0x84790DF2, "_virCode": hcap.key.Code.NUM_3 }, //3 -> NUM_3 KEY
                    { "_keyCode": 0x84790EF1, "_virCode": hcap.key.Code.NUM_4 }, //4 -> NUM_4 KEY
                    { "_keyCode": 0x847911EE, "_virCode": hcap.key.Code.NUM_5 }, //5 -> NUM_5 KEY
                    { "_keyCode": 0x847927D8, "_virCode": hcap.key.Code.NUM_6 }, //6 -> NUM_6 KEY
                    { "_keyCode": 0x847913EC, "_virCode": hcap.key.Code.NUM_7 }, //7 -> NUM_7 KEY
                    { "_keyCode": 0x847914EB, "_virCode": hcap.key.Code.NUM_8 }, //8 -> NUM_8 KEY
                    { "_keyCode": 0x847915EA, "_virCode": hcap.key.Code.NUM_9 }, //9 -> NUM_9 KEY
                    { "_keyCode": 0x847916E9, "_virCode": hcap.key.Code.NUM_11 }, //* -> NUM_11 KEY
                    { "_keyCode": 0x847917E8, "_virCode": hcap.key.Code.NUM_0 }, //0 -> NUM_0 KEY
                    { "_keyCode": 0x847918E7, "_virCode": hcap.key.Code.NUM_12 }, //# -> NUM_12 KEY
                    // SPECIAL KEY
                    { "_keyCode": 0x847925DA, "_virCode": hcap.key.Code.RED }, //RED -> RED KEY
                    { "_keyCode": 0x847926D9, "_virCode": hcap.key.Code.GREEN }, //GREEN -> GREEN KEY
                    { "_keyCode": 0x847902FD, "_virCode": hcap.key.Code.YELLOW }, //YELLOW -> YELLOW KEY
                    { "_keyCode": 0x847901FE, "_virCode": hcap.key.Code.BLUE }, //BLUE -> BLUE KEY

                    //{ "_keyCode": 0x84790af5, "_virCode": hcap.key.Code.PORTAL },   //HDMI RET -> ??? KEY
                    //{ "_keyCode": 0x84792AD5, "_virCode": hcap.key.Code.PORTAL },   //MYPAGE -> ??? KEY
                    //{ "_keyCode": 0x84791BE4, "_virCode": hcap.key.Code.PORTAL },   //ROOMSERVICE -> ??? KEY
                    //{ "_keyCode": 0x847920DF, "_virCode": hcap.key.Code.PORTAL },   //LANGAGUE -> ??? KEY
                    //{ "_keyCode": 0x84791CE3, "_virCode": hcap.key.Code.PORTAL },   //FLIGHT -> ??? KEY
                    //{ "_keyCode": 0x847910E6, "_virCode": hcap.key.Code.PORTAL },   //WEATHER -> ??? KEY
                    //{ "_keyCode": 0x847906F9, "_virCode": hcap.key.Code.PORTAL },   //EPG -> ??? KEY
                ];

                _rmcTbl_CT_default.forEach(function(_item) {
                    //console.log(`${_item._keyCode} map as ${_item._virCode}`);
                    hcap.key.addKeyItem({
                        "keycode": _item._keyCode,
                        "virtualKeycode": _item._virCode,
                        "attribute": 0,
                        "onSuccess": null,
                        "onFailure": function(f) {
                            console.log("onFailure : errorMessage = " + f.errorMessage);
                        }
                    });
                })

                // STEP#004::>  Power Mode
                if (_devinfo["instant_power"] !== undefined) {
                    if (_devinfo["instant_power"] != 0) {
                        console.log("INSTANT POWER MODE::> off");
                        __hcapfxn_set_property('instant_power', 0).then(_result => {
                            hcap.power.getPowerMode({
                                "onSuccess": function(s) {
                                    console.log("onSuccess power mode " + s.mode);
                                    if (s.mode != hcap.power.PowerMode.WARM) {
                                        hcap.power.setPowerMode({
                                            "mode": hcap.power.PowerMode.WARM,
                                            "onSuccess": null,
                                            "onFailure": function(f) {
                                                console.log("onFailure : errorMessage = " + f.errorMessage);
                                            }
                                        });
                                    }
                                },
                                "onFailure": function(f) {
                                    console.log("onFailure : errorMessage = " + f.errorMessage);
                                }
                            });
                        });
                    }
                }

                // STEP#00X::> SERVICE RELATED PARAMETERS
                for (let _cfg in _devconfig) {
                    if (_cfg == 'video') {
                        for (let _item in _devconfig.video) {
                            if (_item == "resolution") {
                                if (_devconfig.video.resolution != _devinfo.display_resolution) {
                                    console.log(`Try to set screen resolution ${_devinfo.display_resolution} to ${_devconfig.video.resolution}`);
                                    _pmFxnArProperty.push(__hcapfxn_set_property('display_resolution', _devconfig.video.resolution));
                                }
                            }
                        }
                    } else if (_cfg == 'networks') {
                        let _netCfg = _devconfig[_cfg];
                        /* Note:
                           동작 스킴
                           1. WLAN이 HOST모드이면 이 디바이스는 WIFI는 독립 AP로 활용
                           2. WLAN이 NAT나 BRIDGE모드이면 이 디바이스는 WIFI로 접속
                           2. 그외의 경우 ETH0를 통한 네트워크 접속 수행 */
                        /* Wireless Network Configuration */
                        if ('wlan0' in _netCfg) {
                            let _wlan_cfg = _netCfg['wlan0'];
                            if (_wlan_cfg.enable == true) {
                                // // Change TV Device Name(It will be used for SSID)
                                // if (_wlan_cfg.ssid && _devinfo['tv_name'] != _wlan_cfg.ssid) {
                                //     _pmFxnArProperty.push(__hcapfxn_set_property('tv_name', _wlan_cfg.ssid));
                                // } else {
                                //     _pmFxnArProperty.push(__hcapfxn_set_property('tv_name', "TV-" + HotelTV.guestinfo.room));
                                // }

                                console.log(`Net Cfg enabled: ${_wlan_cfg.name}`);
                                if (_wlan_cfg.apMode == 'nat') {
                                    // hcap.network.setSoftAP({
                                    //     "channel": Number(_wlan_cfg.channel),
                                    //     "signalStrength": Number(_wlan_cfg.signalStrength),
                                    //     "vlanId": 0,
                                    //     "vlanIp": _wlan_cfg.ipaddr,
                                    //     "vlanSubnet": _wlan_cfg.subnet,
                                    //     "vlanGateway": _wlan_cfg.gateway,
                                    //     "mode": "nat",
                                    //     "securityType": (_wlan_cfg.securityType == "open") ? "open" : "psk",
                                    //     "onSuccess": function(s) {
                                    //         console.log("onSuccess");
                                    //     },
                                    //     "onFailure": function(f) {
                                    //         console.log("onFailure : errorMessage = " + f.errorMessage);
                                    //     }
                                    // });
                                } else if (_wlan_cfg.apMode == 'bridge') {
                                    // mode : bridge, securityType : psk
                                    // hcap.network.setSoftAP({
                                    //     "channel": Number(_wlan_cfg.channel),
                                    //     "vlanId": 0,
                                    //     "signalStrength": Number(_wlan_cfg.signalStrength),
                                    //     "mode": "bridge",
                                    //     "securityType": (_wlan_cfg.securityType == "open") ? "open" : "psk",
                                    //     "onSuccess": function(s) {
                                    //         console.log("onSuccess");
                                    //     },
                                    //     "onFailure": function(f) {
                                    //         console.log("onFailure : errorMessage = " + f.errorMessage);
                                    //     }
                                    // });
                                } else if (_wlan_cfg.apMode == 'host') {
                                    console.log(`Net Cfg failed: ${_wlan_cfg.name} Unsupported mode at the moment!!!`);
                                }
                            } else {
                                console.log(`Net Cfg disabled: ${_wlan_cfg.name}`);
                            }
                        }

                        /* Wire Network Configuration */
                        if ('eth0' in _netCfg) {
                            let _lan_cfg = _netCfg['eth0'];
                            if (_lan_cfg.enable == true) {
                                console.log(`Net Cfg enabled: ${_lan_cfg.name}`);
                                if (_lan_cfg.ipv4.enable == true) {
                                    for (let _ndevIdx in _devinfo.network_info.details) {
                                        _dev_iface_info = _devinfo.network_info.details[_ndevIdx];
                                        if (_lan_cfg.name == _dev_iface_info.name) {
                                            if (_lan_cfg.ipv4.method == 'dhcp' && _dev_iface_info.dhcp == false) {
                                                need_to_reboot = true;
                                                hcap.network.setNetworkDevice({
                                                    "index": Number(_ndevIdx),
                                                    "dhcp": true,
                                                    "onSuccess": function() {
                                                        console.log("onSuccess");
                                                    },
                                                    "onFailure": function(f) {
                                                        console.log("onFailure : errorMessage = " + f.errorMessage);
                                                    }
                                                });
                                            } else if (_lan_cfg.ipv4.method != 'dhcp' &&
                                                ((_dev_iface_info.ip != _lan_cfg.ipv4.ipaddr) ||
                                                    (_dev_iface_info.gateway != _lan_cfg.ipv4.gateway) ||
                                                    (_dev_iface_info.netmask != _lan_cfg.ipv4.subnet) ||
                                                    (_dev_iface_info.primaryDns != _lan_cfg.ipv4.dns[0]) ||
                                                    (_dev_iface_info.dhcp == true))) {
                                                need_to_reboot = true;
                                                hcap.network.setNetworkDevice({
                                                    "index": Number(_ndevIdx),
                                                    "dhcp": false,
                                                    "ip": _lan_cfg.ipv4.ipaddr,
                                                    "gateway": _lan_cfg.ipv4.gateway,
                                                    "netmask": _lan_cfg.ipv4.subnet,
                                                    "primaryDns": _lan_cfg.ipv4.dns[0],
                                                    "secondaryDns": _lan_cfg.ipv4.dns[1],
                                                    "onSuccess": function() {
                                                        console.log("onSuccess");
                                                    },
                                                    "onFailure": function(f) {
                                                        console.log("onFailure : errorMessage = " + f.errorMessage);
                                                    }
                                                });
                                            }
                                        }
                                    }
                                } else {
                                    console.log(`Net interface config: ${_lan_cfg.name} will be disabled...`);
                                }
                            } else {
                                console.log(`Net Cfg disabled: ${_lan_cfg.name}`);
                            }
                        }
                    } else if (_cfg == 'system') {

                    } else if (_cfg == 'audio') {
                        // TV Default Volume
                        // 현재 오디오 볼륨과 같은 값으로 설정 시도시 에러: Kknow issue
                        hcap.volume.getVolumeLevel({
                            "onSuccess" : function(s) {
                                if ( Number(_devconfig[_cfg].defaultVolume.display)!=Number(s.level) ){
                                    hcap.volume.setVolumeLevel({
                                        "level": Number(_devconfig[_cfg].defaultVolume.display),
                                        "onSuccess": function() {
                                            console.log("onSuccess Set to TV default volume set as " + _devconfig[_cfg].defaultVolume.display);
                                        },
                                        "onFailure": function(__err) {
                                            console.log("onFailure : errorMessage = " + __err.errorMessage);
                                        }
                                    });
                                } else {
                                    console.log("onSuccess : no need default volume changing");
                                }
                            },
                            "onFailure" : function(__err) {
                                console.log("onFailure : errorMessage = " + __err.errorMessage);
                            }
                       });
                    }
                }

                //Specifial parameters
                if (_devinfo["boot_sequence_option"] !== undefined) {
                    if (_devinfo["boot_sequence_option"] != 1) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('boot_sequence_option', 1));
                    }
                }

                // Clock Display
                if (_devinfo["clock_display"] !== undefined) {
                    if (_devinfo["clock_display"] != 0) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('clock_display', 0));
                    }
                }

                // Input splash Image
                if (_devinfo["input_splash_image"] !== undefined) {
                    if (_devinfo["input_splash_image"] != 0) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('input_splash_image', 0));
                    }
                }

                // USB Device Blocking
                if (_devinfo["block_usb"] !== undefined) {
                    if (_devinfo["block_usb"] != 1) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('block_usb', 1));
                    }
                }

                // WOL
                if (_devinfo["wol_m"] !== undefined) {
                    if (_devinfo["wol_m"] != "normal") {
                        _pmFxnArProperty.push(__hcapfxn_set_property('wol_m', "normal"));
                    }
                }

                // WIFI SCREEN SHARE
                if (_devinfo["wifi_screen_share"] !== undefined) {
                    // if (_devinfo["wifi_screen_share"] != 1) {
                    //     _pmFxnArProperty.push(__hcapfxn_set_property('wifi_screen_share', 1));
                    // }
                    // PIN 번호를 이용한 screen share는 IDCAP API에서만 지원
                    // 일부 모바일 폰에서 연동 안되는 문제 있음.
                    if (_devinfo["wifi_screen_share"] != 2) {
                        _pmFxnArProperty.push(__idcapfxn_set_property('wifi_screen_share', 2));
                    }
                }

                // SMART SHARE
                if (_devinfo["smart_share"] !== undefined) {
                    if (_devinfo["smart_share"] != 0) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('smart_share', 0));
                    }
                }

                // SMART PARING
                if (_devinfo["smart_pairing"] !== undefined) {
                    if (_devinfo["smart_pairing"] != 0) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('smart_pairing', 0));
                    }
                }

                // DIAL
                if (_devinfo["dial"] !== undefined) {
                    if (_devinfo["dial"] != 1) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('dial', 1));
                    }
                }

                // DMR
                if (_devinfo["dmr"] !== undefined) {
                    if (_devinfo["dmr"] != 0) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('dmr', 0));
                    }
                }

                // SOFTAP UI
                if (_devinfo["soft_ap_ui"] !== undefined) {
                    if (_devinfo["soft_ap_ui"] != 0) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('soft_ap_ui', 0));
                    }
                }

                // SOFTAP
                if (_devinfo["soft_ap"] !== undefined) {
                    if (_devinfo["soft_ap"] != 0) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('soft_ap', 0));
                    }
                }

                // APPLICATION CHANNEL CONTROL
                if (_devinfo["application_channel_control"] !== undefined) {
                    if (_devinfo["application_channel_control"] != 1) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('application_channel_control', 1));
                    }
                }

                // TV CHANNEL UI
                if (_devinfo["tv_channel_ui"] !== undefined) {
                    if (_devinfo["tv_channel_ui"] != 0) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('tv_channel_ui', 0));
                    }
                }

                // MUTE ON TV INPUT: Prevent TV channel auto play when exit OTT
                if (_devinfo["mute_on_tv_input"] !== undefined) {
                    if (_devinfo["mute_on_tv_input"] != 1) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('mute_on_tv_input', 1));
                    }
                }

                // SECURITY LEVEL
                if (_devinfo["security_level"] !== undefined) {
                    if (_devinfo["security_level"] != 1) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('security_level', 1));
                    }
                }

                // // OSD LAYER ID
                // if (_devinfo["osd_layer_id"] !== undefined) {
                //     if (_devinfo["osd_layer_id"] != 0) {
                //         _pmFxnArProperty.push(__hcapfxn_set_property('osd_layer_id', 0));
                //     }
                // }

                // MISC
                if (_devinfo["tv_channel_attribute_floating_ui"] !== undefined) {
                    if (_devinfo["tv_channel_attribute_floating_ui"] != 0) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('tv_channel_attribute_floating_ui', 0));
                    }
                }


                //_pmFxnArProperty.push(__hcapfxn_set_property('clock_source', 'ntp'));

                if (_pmFxnArProperty.length > 0) {
                    Promise.all(_pmFxnArProperty)
                        .then(_ret => {
                            for (let i = 0; i < _ret.length; i++) {
                                let _set_item = _ret[i];
                                //리부팅을 하지 않아도 되는 항목들 no_need_reboot_param을 필터링
                                let no_need_reboot_param = ["wifi_screen_share", "soft_ap", "soft_ap_ui", "osd_layer_id"];
                                if (no_need_reboot_param.indexOf(_set_item.key) == -1) {
                                    //Needed reboot the system
                                    need_to_reboot = true;
                                }
                                console.log(`Device config[${_set_item.key}] set to ${_set_item.value}`);
                            }
                            resolve(need_to_reboot);
                        });
                } else {
                    resolve(need_to_reboot);
                }
            }).catch(function(_err) {
                console.log(`fail to perform SetDevice() ${_err}`);
            });
        },

        VideoWinSize: function(size) {
            let _res = HotelTV.devinfo.display_resolution.split("x");
            let max_width = Number(_res[0]);
            let max_height = Number(_res[1]);
            let _pos_size = { 'sx': 0, 'sy': 0, 'width': max_width, 'height': max_height };
            if (size != null) {
                _pos_size['sx'] = size.sx;
                _pos_size['sy'] = size.sy;
                _pos_size['width'] = size.width
                _pos_size['height'] = size.height;
            }
            __hcapfxn_set_vidwinsize(_pos_size['sx'], _pos_size['sy'], _pos_size['width'], _pos_size['height']);
        },


        MediaShutdown: function(cb_ok, cb_error) {
            __hcapfxn_media_shutdown().then(function() {
                if (cb_ok != null) {
                    cb_ok();
                }
            }).catch(function(err) {
                console.log(err); // Error: Request is failed
                if (cb_error != null) {
                    cb_error();
                }
            });
        },

        MediaPlay: function(uri_media, uri_srt, mime_typ, repeat, cb_play_ok, cb_play_err) {
            if (g_media.tm_lststat == null) {
                g_media.tm_lststat = new Date();
            } else {
                let _tm_cur = new Date();
                let _tm_diff_ms = _tm_cur.getTime() - g_media.tm_lststat.getTime();
                if (_tm_diff_ms < 2000) {
                    return;
                }
                g_media.tm_lststat = _tm_cur;
            }

            hcap.channel.getCurrentChannel({
                "onSuccess": function(s) {
                    if (s.channelStatus == hcap.channel.ChannelStatus.AV_DISPLAYED ||
                        s.channelStatus == hcap.channel.ChannelStatus.AUDIO_ONLY_BLOCKED ||
                        s.channelStatus == hcap.channel.ChannelStatus.VIDEO_ONLY_BLOCKED) {
                        hcap.channel.stopCurrentChannel({
                            "onSuccess": function() {
                                __hcapfxn_play_media(uri_media, uri_srt, mime_typ, repeat, cb_play_ok, cb_play_err);
                            },
                            "onFailure": function(f) {
                                console.log("onFailure : errorMessage = " + f.errorMessage);
                            }
                        });
                    } else {
                        __hcapfxn_play_media(uri_media, uri_srt, mime_typ, repeat, cb_play_ok, cb_play_err);
                    }
                },
                "onFailure": function(f) {
                    __hcapfxn_play_media(uri_media, uri_srt, mime_typ, repeat, cb_play_ok, cb_play_err);
                }
            });
        },

        MediaStop: function(cb_stop_ok, cb_stop_err) {
            if (g_media.hndl != null) {
                g_media.hndl.stop({
                    "onSuccess": function() {
                        g_media.hndl.destroy({
                            "onSuccess": function() {
                                console.log("onSuccess");
                                if (cb_stop_ok != null) {
                                    cb_stop_ok();
                                }
                            },
                            "onFailure": function(f) {
                                console.log("onFailure : errorMessage = " + f.errorMessage);
                                if (cb_stop_err != null) {
                                    cb_stop_err();
                                }
                            }
                        });
                    },
                    "onFailure": function(f) {
                        console.log("onFailure : errorMessage = " + f.errorMessage);
                        if (cb_stop_err != null) {
                            cb_stop_err();
                        }
                    }
                });
            }
        },

        ChannelShutDown: function() {
            // IP channel class 2 change request
            // CHANNEL STATUS TABLE
            // hcap.channel.ChannelStatus.UNKNOWN:0
            // hcap.channel.ChannelStatus.AUDIO_VIDEO_NOT_BLOCKED:16
            // hcap.channel.ChannelStatus.AV_DISPLAYED:16,
            // hcap.channel.ChannelStatus.AUDIO_VIDEO_BLOCKED:33
            // hcap.channel.ChannelStatus.NO_SIGNAL:33
            // hcap.channel.ChannelStatus.AUDIO_ONLY_BLOCKED:34
            // hcap.channel.ChannelStatus.VIDEO_ONLY_BLOCKED:35
            hcap.channel.getCurrentChannel({
                "onSuccess": function(s) {
                    console.log("onSuccess :" +
                        "\n channel status    : " + s.channelStatus +
                        "\n channel type      : " + s.channelType +
                        "\n logical number    : " + s.logicalNumber +
                        "\n frequency         : " + s.frequency +
                        "\n program number    : " + s.programNumber +
                        "\n major number      : " + s.majorNumber +
                        "\n minor number      : " + s.minorNumber +
                        "\n satellite ID      : " + s.satelliteId +
                        "\n polarization      : " + s.polarization +
                        "\n rf broadcast type : " + s.rfBroadcastType +
                        "\n ip                : " + s.ip +
                        "\n port              : " + s.port +
                        "\n ip broadcast type : " + s.ipBroadcastType +
                        "\n symbol rate       : " + s.symbolRate +
                        "\n pcr pid           : " + s.pcrPid +
                        "\n video pid         : " + s.videoPid +
                        "\n video stream type : " + s.videoStreamType +
                        "\n audio pid         : " + s.audioPid +
                        "\n audio stream type : " + s.audioStreamType +
                        "\n signal strength   : " + s.signalStrength +
                        "\n source address    : " + s.sourceAddress);
                    if (s.channelStatus == hcap.channel.ChannelStatus.AV_DISPLAYED ||
                        s.channelStatus == hcap.channel.ChannelStatus.AUDIO_ONLY_BLOCKED ||
                        s.channelStatus == hcap.channel.ChannelStatus.VIDEO_ONLY_BLOCKED) {
                        hcap.channel.stopCurrentChannel({
                            "onSuccess": null,
                            "onFailure": function(f) {
                                console.log("onFailure : errorMessage = " + f.errorMessage);
                            }
                        });
                    }
                },
                "onFailure": function(f) {
                    console.log("onFailure : errorMessage = " + f.errorMessage);
                }
            });
        },


        ChannelSetup: function(_type, _param) {
            if (g_media.pipeline == true) {
                g_media.pipeline = false;
                __hcapfxn_media_shutdown().then(function() {
                    setTimeout(__hcapfxn_play_channel(_type, _param), 500);
                }).catch(function(err) {
                    console.log(err); // Error: Request is failed
                });
            } else {
                __hcapfxn_play_channel(_type, _param);
            }
        },

        siAppAuth: function(sz_app_name, app_token, _en_show_msg) {
            let app_id = null;
            if (sz_app_name == "netflix") {
                app_id = "244115188075859013";
            }

            if (app_id && app_token) {
                hcap.application.RegisterSIApplicationList({
                    "tokenList": [{ "id": "netflix", "token": app_token }, ],
                    "onSuccess": function(s) {
                        if (_en_show_msg == true) {
                            console.log("register Success!");
                            HotelTV.hcap.PreAppGetInfo(true);
                        }
                    },
                    "onFailure": function(f) {
                        console.log("register Failed! reason : " + f.errorMessage);
                    }
                });
            }
        },

        PreAppGetInfo: function(_en_show_msg) {
            // if (g_nativApps_info.preapp == null) {
            //     hcap.preloadedApplication.getPreloadedApplicationList({
            //         "onSuccess": function(s) {
            //             if (_en_show_msg == true) {
            //                 console.log("onSuccess : list length = " + s.list.length);
            //                 for (var i = 0; i < s.list.length; i++) {
            //                     console.log(
            //                         "list[" + i + "].id = " + s.list[i].id +
            //                         "list[" + i + "].title = " + s.list[i].title +
            //                         "list[" + i + "].iconFilePath = " + s.list[i].iconFilePath
            //                     );
            //                 }
            //             }
            //             if (s.result == true) {
            //                 g_nativApps_info.preapp = s.list;
            //             }
            //         },
            //         "onFailure": function(f) {
            //             console.log("onFailure : errorMessage = " + f.errorMessage);
            //         }
            //     });
            // }

            return new Promise((resolve, reject) => {
                hcap.preloadedApplication.getPreloadedApplicationList({
                    "onSuccess": function(s) {
                        if (_en_show_msg == true) {
                            console.log("onSuccess : list length = " + s.list.length);
                            for (var i = 0; i < s.list.length; i++) {
                                console.log(
                                    "list[" + i + "].id = " + s.list[i].id +
                                    "list[" + i + "].title = " + s.list[i].title +
                                    "list[" + i + "].iconFilePath = " + s.list[i].iconFilePath
                                );
                            }
                        }
                        if (s.result == true) {
                            g_nativApps_info.preapp = s.list;
                            resolve({ "error": 0, "applist": g_nativApps_info.preapp });
                        }
                    },
                    "onFailure": function(f) {
                        console.log("onFailure : errorMessage = " + f.errorMessage);
                        resolve({ "error": -1, "applist": null });
                    }
                });
            });
        },

        LaunchPreApp: function(_name, _param) {
            if (g_nativApps_info.preapp != null) {
                if (_name == "youtube") {
                    for (const [key, item] of Object.entries(g_nativApps_info.preapp)) {
                        if (item.title == 'YouTube') {
                            hcap.preloadedApplication.launchPreloadedApplication({
                                "id": item.id, // YOUTUBE
                                "onSuccess": function() {
                                    console.log("onSuccess");
                                },
                                "onFailure": function(f) {
                                    console.log("onFailure : errorMessage = " + f.errorMessage);
                                }
                            });
                        }
                    }
                } else if (_name == "netflix") {
                    for (const [key, item] of Object.entries(g_nativApps_info.preapp)) {
                        if (item.title == 'Netflix') {
                            hcap.preloadedApplication.launchPreloadedApplication({
                                "id": item.id, // NETFLIX
                                "parameter": `{'params': {'hotel_id':${_param.hotel_name},'launcher_version':'1.0'}`,
                                "onSuccess": function() {
                                    console.log("onSuccess");
                                },
                                "onFailure": function(f) {
                                    console.log("onFailure : errorMessage = " + f.errorMessage);
                                }
                            });
                        }
                    }
                } else if (_name == "screenmirroring") {
                    for (const [key, item] of Object.entries(g_nativApps_info.preapp)) {
                        if (item.id == '144115188075855880') {
                            hcap.preloadedApplication.launchPreloadedApplication({
                                "id": item.id, // SCREEN SHARE
                                "onSuccess": function() {
                                    console.log("onSuccess");
                                },
                                "onFailure": function(f) {
                                    console.log("onFailure : errorMessage = " + f.errorMessage);
                                }
                            });
                        }
                    }
                } else if (_name == "BLUETOOTHAUDIO") {
                    for (const [key, item] of Object.entries(g_nativApps_info.preapp)) {
                        if (item.id == '244115188075859015') {
                            hcap.preloadedApplication.launchPreloadedApplication({
                                "id": item.id, // SCREEN SHARE
                                "onSuccess": function() {
                                    console.log("onSuccess");
                                },
                                "onFailure": function(f) {
                                    console.log("onFailure : errorMessage = " + f.errorMessage);
                                }
                            });
                        }
                    }
                }
            } else {
                console.log("Preloaded Application doesn't exist");
            }
        },

        SetPlatformLanguage: function(_param) {
            const _pmFxnArProperty = [];

            if (_param == "ko-KR") {
                _pmFxnArProperty.push(__hcapfxn_set_property('language', "ko"));
            } else {
                _pmFxnArProperty.push(__hcapfxn_set_property('language', "en"));
            }

            Promise.all(_pmFxnArProperty)
                .then(_ret => {
                    let _devinfo = HotelTV.devinfo;
                    for (let i = 0; i < _ret.length; i++) {
                        let _dic_item = _ret[i];
                        if (_dic_item.value != null) {
                            _devinfo[_dic_item.key] = _dic_item.value;
                        } else {
                            console.log(`ERROR::>Item[${_dic_item.key}] is NULL::>`);
                        }
                        //console.log(`Item[${_dic_item.key}] ::> ${_dic_item.value}`);
                    };
                });
        },

        SetSoftAp: function(_param) {
            return new Promise((resolve, reject) => {
                const _pmFxnArProperty = [];
                _pmFxnArProperty.push(__hcapfxn_get_property("soft_ap"));
                _pmFxnArProperty.push(__hcapfxn_get_property("soft_ap_ui"));

                if (_param.enable == true) {
                    let _devinfo = HotelTV.devinfo;
                    // // TV NAME(SSID)
                    // if (_devinfo["tv_name"] !== _param.ssid) {
                    //     _pmFxnArProperty.push(__hcapfxn_set_property('tv_name', _param.ssid));
                    //     _pmFxnArProperty.push(__hcapfxn_set_property('soft_ap_password', _param.password));
                    // }

                    // TV NAME(SSID)
                    if (_devinfo["tv_name"] !== _param.ssid) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('tv_name', _param.ssid));
                    }

                    if (_param.password) {
                        _pmFxnArProperty.push(__hcapfxn_set_property('soft_ap_password', _param.password));
                    }
                }

                Promise.all(_pmFxnArProperty)
                    .then(_ret => {
                        let _devinfo = HotelTV.devinfo;
                        for (let i = 0; i < _ret.length; i++) {
                            let _dic_item = _ret[i];
                            if (_dic_item.value != null) {
                                _devinfo[_dic_item.key] = _dic_item.value;
                                console.log(`Item[${_dic_item.key}] ::> ${_dic_item.value}`);
                            } else {
                                console.log(`ERROR::>Item[${_dic_item.key}] is NULL::>`);
                            }
                            //console.log(`Item[${_dic_item.key}] ::> ${_dic_item.value}`);
                        };

                        if (_param.enable == true) {
                            if (_devinfo["soft_ap_ui"] != 1) {
                                console.log("TRY TO TURN ON::> SoftAP");
                                __hcapfxn_set_property('soft_ap_ui', 1).then(_result => {
                                    if (_devinfo["soft_ap"] != 1) {
                                        __hcapfxn_set_property('soft_ap', 1).then(_result => {
                                            console.log("TRY TO TURN ONED::> SoftAP");
                                        });
                                    }
                                });
                            }
                        } else {
                            if (_devinfo["soft_ap"] != 0) {
                                console.log("TRY TO TURN OFF::> SoftAP");
                                __hcapfxn_set_property('soft_ap', 0).then(_result => {
                                    if (_devinfo["soft_ap_ui"] != 0) {
                                        __hcapfxn_set_property('soft_ap_ui', 0).then(_result => {
                                            console.log("TRY TO TURN OFFED::> SoftAP");
                                        });
                                    }
                                });
                            }
                        }
                    });
            });
        },

        GetDeviceUsage: function() {
            return new Promise((resolve, reject) => {
                const _pmFxnArProperty = [];
                _pmFxnArProperty.push(__hcapfxn_get_cpuUsage());
                _pmFxnArProperty.push(__hcapfxn_get_memUsage());
                Promise.all(_pmFxnArProperty)
                    .then(_ret => {
                        resolve({ "cpu": _ret[0].value, "mem": _ret[1].value });
                    }).catch(_err => {
                        resolve({ "cpu": -1, "mem": -1 });
                    });
            });
        },

        GetUptime: function() {
            let _devinfo = HotelTV.devinfo;
            __hcapfxn_get_cpuTime(function(_uptime) {
                _devinfo['uptime'] = _uptime;
            });
        },

        GetScrshot: function() {
            hcap.file.getUsbStorageList({
                "onSuccess": function(s) {
                    console.log("onSuccess : list length = " + s.list.length);
                    for (var i = 0; i < s.list.length; i++) {
                        console.log(
                            "[" + i + "].name = " + s.list[i].name +
                            "[" + i + "].displayName = " + s.list[i].displayName +
                            "[" + i + "].mountPoint = " + s.list[i].mountPoint +
                            "[" + i + "].status = " + s.list[i].status +
                            "[" + i + "].filesystemStatus = " + s.list[i].filesystemStatus +
                            "[" + i + "].totalSize = " + s.list[i].totalSize +
                            "[" + i + "].freeSize = " + s.list[i].freeSize
                        );
                    }
                },
                "onFailure": function(f) {
                    console.log("onFailure : errorMessage = " + f.errorMessage);
                }
            });

            hcap.system.requestScreenCaptureImage({
                "onSuccess": function() {
                    console.log("onSuccess");
                    hcap.system.getScreenCaptureImage({
                        "onSuccess": function(s) {
                            var _fileName = (new Date()).toISOString().slice(0, 19).replace(/[-:]/g, "").replace("T", "_");
                            console.log("onSuccess : uri = " + s.uri);
                            hcap.file.downloadFileToUsb({
                                "uri": s.uri,
                                "path": "/tmp/usb/sda/sda1/" + _fileName + ".png",
                                "onSuccess": function() {
                                    console.log("onSuccess");
                                },
                                "onFailure": function(f) {
                                    console.log("onFailure : errorMessage = " + f.errorMessage);
                                }
                            });
                        },
                        "onFailure": function(f) {
                            console.log("onFailure : errorMessage = " + f.errorMessage);
                        }
                    });
                },
                "onFailure": function(f) {
                    console.log("onFailure : errorMessage = " + f.errorMessage);
                }
            });
        },

        SetDeviceLocale: function(_new_locale) {
            hcap.system.requestLocaleChange({
                "specifier" : _new_locale,
                "onSuccess" : function() {
                    console.log("onSuccess");
                },
                "onFailure" : function(f) {
                    console.error("onFailure : errorMessage = " + f.errorMessage);
                }
            });

        },

        // _type은 hcap.externalinput.ExternalInputType형이고, 현재는 HDMI로 고정
        // _index는 HDMI포트 번호
        SetExternalInput: function(_type, _index) {
            hcap.externalinput.setCurrentExternalInput({
                "type" : hcap.externalinput.ExternalInputType.HDMI,
                "index" : _index,
                "onSuccess" : function() {
                    console.log("onSuccess");
                },
                "onFailure" : function(f) {
                    console.error("onFailure : errorMessage = " + f.errorMessage);
                }
           });
        },

        Test: function() {
            console.log("Test Start....");


            // hcap.bluetooth.getBluetoothSoundSync({
            //     "onSuccess": function(param) {
            //         console.log("onSuccess : bluetooth sound sync = " + param.enable);
            //     },
            //     "onFailure": function(f) {
            //         console.log("onFailure : errorMessage = " + f.errorMessage);
            //     }
            // });

            // hcap.externalinput.getExternalInputList({
            //     "onSuccess": function(s) {
            //         console.log("onSuccess : list length = " + s.list.length);
            //         for (var i = 0; i < s.list.length; i++) {
            //             console.log("(" + s.list[i].type + "," + s.list[i].index + "," + s.list[i].name + ")");
            //         }
            //     },
            //     "onFailure": function(f) {
            //         console.log("onFailure : errorMessage = " + f.errorMessage);
            //     }
            // });

            // // 외부 입력(HDMI, 등) 이벤트 리스너
            // document.addEventListener(
            //     "external_input_changed",
            //     function() {
            //         console.log("Event 'external_input_changed' is received.");
            //     },
            //     false
            // );

            // 프리 인스톨디드 어플리케이션 실행
            // hcap.preloadedApplication.getPreloadedApplicationList({
            //     "onSuccess": function(s) {
            //         console.log("onSuccess : list length = " + s.list.length);
            //         for (var i = 0; i < s.list.length; i++) {
            //             console.log(
            //                 "list[" + i + "].id = " + s.list[i].id +
            //                 "list[" + i + "].title = " + s.list[i].title +
            //                 "list[" + i + "].iconFilePath = " + s.list[i].iconFilePath
            //             );
            //         }
            //     },
            //     "onFailure": function(f) {
            //         console.log("onFailure : errorMessage = " + f.errorMessage);
            //     }
            // });


            // hcap.preloadedApplication.launchPreloadedApplication({
            //     "id": "244115188075859015", // BLUETOOTH
            //     "onSuccess": function() {
            //         console.log("onSuccess");
            //     },
            //     "onFailure": function(f) {
            //         console.log("onFailure : errorMessage = " + f.errorMessage);
            //     }
            // });

            // hcap.preloadedApplication.launchPreloadedApplication({
            //     "id": "144115188075859002", // YOUTUBE
            //     "onSuccess": function() {
            //         console.log("onSuccess");
            //     },
            //     "onFailure": function(f) {
            //         console.log("onFailure : errorMessage = " + f.errorMessage);
            //     }
            // });

            // hcap.preloadedApplication.launchPreloadedApplication({
            //     "id": "144115188075859002", // NK-Browser
            //     "onSuccess": function() {
            //         console.log("onSuccess");
            //     },
            //     "onFailure": function(f) {
            //         console.log("onFailure : errorMessage = " + f.errorMessage);
            //     }
            // });



            // hcap.preloadedApplication.launchPreloadedApplication({
            //     "id": "244115188075859022", // NK-Browser
            //     "parameters": "{'params':{'target': 'https://www.netflix.com/kr/login'}}",
            //     "onSuccess": function() {
            //         console.log("onSuccess");
            //     },
            //     "onFailure": function(f) {
            //         console.log("onFailure : errorMessage = " + f.errorMessage);
            //     }
            // });



            // 음성 인식 관련
            // hcap.speech.getSpeechRecognition({
            //     "onSuccess": function(param) {
            //         console.log("onSuccess : get speech recognition = " + param.enable);

            //         if (param.enable == false) {
            //             hcap.speech.setSpeechRecognition({
            //                 "enable": true,
            //                 "onSuccess": function() {
            //                     console.log("onSuccess");
            //                 },
            //                 "onFailure": function(f) {
            //                     console.log("onFailure : errorMessage = " + f.errorMessage);
            //                 }
            //             });
            //         }
            //     },
            //     "onFailure": function(f) {
            //         console.log("onFailure : errorMessage = " + f.errorMessage);
            //     }
            // });

            // document.addEventListener(
            //     "speech_to_text_status_changed",
            //     function(param) {
            //         // {String} param.status - "processing" : STT is processing. "ready" : STT is completed.
            //         // {String} param.actionData - STT intent parameter when STT status is changed from "processing" to "ready".
            //         // {String} param.serviceType - STT result category when STT status is changed from "processing" to "ready".
            //         // {String} param.actionType - STT result intent when STT status is changed from "processing" to "ready".
            //         // {String} param.userUtterance - STT result text when STT status is changed from "processing" to "ready".
            //         console.log(
            //             "Event 'speech_to_text_status_changed' is received.\n" +
            //             "status = " + param.status +
            //             "action data = " + param.actionData +
            //             "service type = " + param.serviceType +
            //             "action type = " + param.actionType +
            //             "user utterance = " + param.userUtterance
            //         );
            //     },
            //     false
            // );
            // hcap.channel.stopCurrentChannel({
            //     "onSuccess": function() {
            //         console.log("onSuccess");
            //     },
            //     "onFailure": function(f) {
            //         console.log("onFailure : errorMessage = " + f.errorMessage);
            //     }
            // });


            // // 채널 관련 API
            // hcap.channel.getChannelMap({
            //     "onSuccess": function(s) {
            //         console.log("onSuccess : list length = " + s.list.length);
            //         for (var i = 0; i < s.list.length; i++) {
            //             console.log(
            //                 "[" + i + "].img_url2 = " + s.list[i].img_url2 +
            //                 "[" + i + "].img_url = " + s.list[i].img_url +
            //                 "[" + i + "].short_cut = " + s.list[i].short_cut +
            //                 "[" + i + "].channel_type = " + s.list[i].channel_type +
            //                 "[" + i + "].channel_mode_id = " + s.list[i].channel_mode_id +
            //                 "[" + i + "].channel_number = " + s.list[i].channel_number +
            //                 "[" + i + "].channel_name = " + s.list[i].channel_name
            //             );
            //         }
            //     },
            //     "onFailure": function(f) {
            //         console.log("onFailure : errorMessage = " + f.errorMessage);
            //     }
            // });


            // hcap.video.getVideoSize({
            //     "onSuccess": function(s) {
            //         console.log("onSuccess : " +
            //             "\n x = " + s.x +
            //             "\n y = " + s.y +
            //             "\n width = " + s.width +
            //             "\n height = " + s.height);
            //     },
            //     "onFailure": function(f) {
            //         console.log("onFailure : errorMessage = " + f.errorMessage);
            //     }
            // });
        },
    }
})();