/****************
****************localStorage 값****************
serverData=>최초 회사 로그인시 받아옴****************
{
    "cust_digit_cnt":"5",
    "errcode":"0",
    "cust_func_code":"0", 기능제한코드
    "cust_con_ip":"211.220.138.26",
    "cust_mnt_date":"99991231",
    "cust_con_pbx_ip":"192.168.1.50",
    "cust_name":"지엔텔",
    "cust_con_port":"443",
    "cust_acc_code_used":"Y", 중계선호출코드사용여부
    "cust_ci_path":"http:\/\/touchsquare.co.kr\/wp\/wp-content\/uploads\/2019\/03\/touch-1.png",
    "cust_acc_code":"9" 중계선 호출코드 적용 자릿수
}

userData=>최초 로그인시 localStorage저장****************
{
    "method":"token.GET",
    "data":{
        "id":"user1",
        "node":"1",
        "systemType":"ipecs-ucm",
        "token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhcGlVc2VyIjoidHJ1ZSIsInRpbWVTdGFtcCI6MTU4OTE2NzA2M30.BlblCCjKj0uPzWiXpObK4vITFim9reYyrybvv6kn5hc",
        "mdn":"000010"
    },
    "apiVersion":"1"
}
settingData=>최초 회사 로그인시 설정함****************
 {
    accCodeUsed: jsonData.cust_acc_code_used,
    accCode: jsonData.cust_acc_code,
    digitCount: jsonData.cust_digit_cnt,
    companyId:companyId,
    companyPw:companyPw,
    autoLogin:"",
    checkIdSave:"",
    savedId:"",
    savedPw:"",
    mobileNumber:"",
    prefixNumber:""
};
*****************/
let settingData = window.localStorage.getArray("settingData");
let serverData = window.localStorage.getArray("serverData");
let userData = window.localStorage.getArray("userData");
let historyOrder = true;
let exitCheck = false;
let devicePlatform;
let deviceVersion;
let clusterizeAddress;
let clusterizeAddressSearch;
let clusterizeHistory;
let clusterizeHistorySearch;
let app_ver_string;
let from_top = false;
let default_setting = {
    region_number : ""
}
let menu_info = [];
try {
    menu_info = JSON.parse(window.localStorage.getItem("menu_info")||'[]');
} catch (error) {
    menu_info = [];
}
let searchContactByNumber;

//모바일 mcid용 
var mcid_tel_no_format = '`822890${user.cid_no}`'
, mcid_tel_name_format = '`[${user.dept_name}] ${user.name}`'
, mcid_mobile_no_format = '`82${user.mobile_no.replace(/0/,"")}`'

//프로파일 표시용 - 값은 null : 기본 값 반영 ,숫자 설정시 : 해당 넓이로 반영 , 배율( ex> 0.5f)반영시 : 폰 전체 넓이 혹은 높이의 배율곱한 값으로 반영 
, profile_incoming_top, profile_incoming_height, profile_incoming_width     // 수신시 웹뷰 생성위치(y축), 웹뷰의 높이, 웹뷰의 넓이 
, profile_outgoing_top, profile_outgoing_height, profile_outgoing_width     // 발신시 웹뷰 생성위치(y축), 웹뷰의 높이, 웹뷰의 넓이
;

let app = {
    initialize: function() {     
        document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
        document.addEventListener('pause', this.onDevicePause.bind(this), false);
        document.addEventListener('resume', this.onDeviceResume.bind(this), false);
    },
    onDevicePause: function() {
        FirebasePlugin.clearAllNotifications();
        FirebasePlugin.setBadgeNumber(0);  
    },
    onDeviceResume: function() {
        FirebasePlugin.clearAllNotifications();
        FirebasePlugin.setBadgeNumber(0);
        // 다이얼 입력 팝업은 화면 복귀시 무조건 닫는다
        $(".bg_calling").removeClass("on");
        $(".bg_calling").remove();
    },
    onDeviceReady: function() {
        console.log('onDeviceReady start');

        FirebasePlugin.clearAllNotifications();
        FirebasePlugin.setBadgeNumber(0);

        document.addEventListener("backbutton", onBackKeyDown, true);
        
        try {
            cordova.plugins.Keyboard.shrinkView(true);
        } catch(e)  {}

        //FCM푸시메세지 배너 클릭해서 들어오면 공지사항 페이지로 이동
        FirebasePlugin.onMessageReceived((msg)=>{
            // 공지사항 푸시는 messageType이 notification이고
            // 모바일 mcid 기능을 위한 통화이벤트 정보 푸시는 messageType이 data이다.
            if(msg.messageType == 'notification' && msg.body != undefined){
                $('#loadNoticesBtn').trigger('click');
            }
        });

        if (nullcheck(serverData) == false) {
            if (nullcheck(serverData.cust_logo3) == false) {
                $(".company_logo3").attr("src", server_host + server_port + serverData.cust_logo3);
            } else {
                $(".company_logo3").attr("src", "img/logo.png");
            };
        };

        window.addEventListener('keyboardDidShow', function () {
            // Describe your logic which will be run each time keyboard is shown.
            if($('.ui-page-active').attr('id') == "forwarding"){
                console.log('keyboardDidShow',"forwarding");
                $(window).scrollTop(500);
            }
        });

        cordova.getAppVersion.getVersionNumber().then(function (version) {
            app_ver_string = version;
            console.log('getVersionNumber callback',"app_ver_string11111:"+app_ver_string);
        });
        devicePlatform = device.platform;
        deviceVersion = device.version;

        // window.plugins.gntel.setProfileLayout();

        initMainHtml()
        .then(()=>{
            console.log('initMainHtml done');
            checkOrganization();
            createAddress();
            getForward(true);
            iniPage();
        });
    }
};
// -- END OF onDeviceReady

app.initialize();

async function asyncForEach(array, callback) {
    for (let index = 0; index < array.length; index++) {
        await callback(array[index], index, array);
    }
}

function loadHTML(filepath ,element){
    let df = $.Deferred();
    let xhr = new XMLHttpRequest();
    xhr.open('GET', filepath, true);
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            attachHTML(xhr.responseText ,element);
            df.resolve(true);
        }
    };
    xhr.send();
    return df.promise();
}

function loadNativeHTML(filepath ,element){
    let df = $.Deferred();

    window.resolveLocalFileSystemURL(`${cordova.file.documentsDirectory}www/${filepath}`, function(fileEntry) {
        fileEntry.file(function(file) {
            let reader = new FileReader();

            reader.onloadend = function() {
                attachHTML(this.result, element);
                console.log(`${filepath} attached`);
                df.resolve(true);
            };

            reader.onerror = function(error) {
                console.error(`Failed to read file: ${error}`);
                df.reject(`Failed to read file: ${error}`);
            };

            reader.readAsText(file);
        }, function(error) {
            console.error(`Failed to get file: ${error}`);
            df.reject(`Failed to get file: ${error}`);
        });
    }, function(error) {
        console.error(`Failed to resolve file system URL: ${error}`);
        df.reject(`Failed to resolve file system URL: ${error}`);
    });

    return df.promise();
}

function substituteVariables(content, variables) {
    // 정규 표현식을 사용하여 ${key} 패턴을 찾아서 해당 변수 값으로 치환합니다
    if( variables == null || variables == undefined ){
        return content;
    }
    return content.replace(/{{(.*?)}}/g, (match, key) => {
        return variables[key.trim()] || match; // 변수가 존재하지 않으면 원래의 문자열을 반환합니다
    });
}

function attachHTML(response, element){
    const outerAttr = element.getAttribute('data-outer');
    const shouldSubstitute = element.getAttribute('data-substitute');
    const id = element.getAttribute('data-id');
    //	치환문 처리
    if (shouldSubstitute !== 'false') {
        // 변수 치환 로직을 적용합니다
        response = substituteVariables(response, menu_info.filter( menu => menu.id == id)[0]);
    }
    
    if (outerAttr === 'true')	element.outerHTML = response;
    else	element.innerHTML = response;
}

async function initMainHtml(){

    let main_html = "";
    menu_info.forEach((item , idx) =>{
        let prev_item = menu_info[idx==0?(menu_info.length-1):(idx-1)];
        let next_item = menu_info[idx==(menu_info.length-1)?0:(idx+1)];
        item['swipe-next'] = next_item.id;
        item['swipe-prev'] = prev_item.id;
        item['index'] = idx;

        $('.gnb_wrap ul.gnb').append(
            $('#header_menu_li_template').text()
            .replace(/{{(.*?)}}/g,(match, key)=>{
                return item[key]||match;
            })
        );

        main_html += $('#main_area_contents_template').text()
        .replace(/{{(.*?)}}/g,(match, key)=>{
            return item[key]||match;
        })
    });

    $('#mainarea')[0].outerHTML = main_html;

    const fileContentElements = document.querySelectorAll('.file-content');

    await asyncForEach(fileContentElements , async (element)=>{
        const filePath = element.getAttribute('data-file');

        if(device.platform === 'iOS'){
            await loadNativeHTML(filePath ,element);
        }else{
            await loadHTML(filePath ,element);
        }
    });
    
    await loadScriptAsync();

    $(`.gnb_wrap a[href='#${front_pageId}']`).trigger('click').addClass('selected');
    $(`.search_wrap_${front_pageId}`).show();
    $('body').show();
}

function loadScript(src) {
    return new Promise((resolve, reject) => {
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = src;
        script.onload = () => {
            console.log(`${src} loaded successfully`);
            resolve();
        };
        script.onerror = () => {
            console.error(`Failed to load ${src}`);
            reject(new Error(`Failed to load ${src}`));
        };
        document.head.appendChild(script);
    });
}
async function loadScriptAsync(){
    const scripts = [
        'js/jquery.mobile-1.4.5.js',
        'content/js/content-address.js',
        'content/js/content-dial.js',
        'content/js/content-forwarding.js',
        'content/js/content-notice.js',
        'content/js/content-organization.js',
        'content/js/content-history.js',
        'content/js/content-settings.js'
    ];

    for (let i = 0; i < scripts.length; i++) {
        try {
            await loadScript(scripts[i]);
        } catch (error) {
            console.error(error);
            break;
        }
    }
}

// INIT EVENT START
function iniPage(){

    if (nullcheck(serverData) == false) {
        if (nullcheck(serverData.cust_logo3) == false) {
            $(".title_image").attr("src", server_host + server_port + serverData.cust_logo3);
        } else {
            $(".title_image").attr("src", company_logo0);
        }
    };

    $(".title").text(title);

    $("#goTop").on("click",function(){
        if(isIOS12()){
            $(window).scrollTop(0);
        }else{
            if($('.ui-page-active').attr('id') == "address"){
                document.getElementById('scrollArea').style.overflow = 'hidden';
                document.getElementById('scrollArea').scrollTop = 0;
                setTimeout(function() {
                    document.getElementById('scrollArea').style.overflow = '';
                }, 10);
            }else if($('.ui-page-active').attr('id') == "addr_search"){
                document.getElementById('scrollAreaSearch').style.overflow = 'hidden';
                document.getElementById('scrollAreaSearch').scrollTop = 0;
                setTimeout(function() {
                    document.getElementById('scrollAreaSearch').style.overflow = '';
                }, 10);
            }else if($('.ui-page-active').attr('id') == "history"){
                document.getElementById('scrollAreaHistory').style.overflow = 'hidden';
                document.getElementById('scrollAreaHistory').scrollTop = 0;
                setTimeout(function() {
                    document.getElementById('scrollAreaHistory').style.overflow = '';
                }, 10);
            }else if($('.ui-page-active').attr('id') == "history_search"){
                document.getElementById('scrollAreaSearchHistory').style.overflow = 'hidden';
                document.getElementById('scrollAreaSearchHistory').scrollTop = 0;
                setTimeout(function() {
                    document.getElementById('scrollAreaSearchHistory').style.overflow = '';
                }, 10);
            }
        }
    });

    let whitelist = '*#';
    //set_code,set_digit,myMobileNumber,myPrefixNumber
    $('.maxLength11').alphanum({
        maxLength:11
    });
    //set_code,set_digit,myMobileNumber,myPrefixNumber
    $('.maxLength16').alphanum({
        allow : whitelist,  // Specify characters to disallow
        maxLength:16
    });
    let blacklist = '!@$%^&()+=[]\\\';,/{}|":<>?~`.- _';
    //set_code,set_digit,myMobileNumber,myPrefixNumber
    $('.maxLength1').alphanum({
        maxLength:1
    });
    $('.maxLength4').alphanum({
        maxLength:4
    });

    $('.maxLength6').alphanum({
        maxLength:6
    });

    $('.maxLength8').alphanum({

        allow : whitelist,  // Specify characters to disallow
        //disallow : blacklist,  // Specify characters to disallow
        maxLength:8
    });

    //전화 팝업 콜백 버튼
    $(document).on("click", ".pop_calling .btn_calling_01", function(){
        let thisID = $(this).data("id");
        let numberOrder = $('input[name="sel_num"]:checked').val();
        let numberObj = JSON.parse(numberOrder);
        console.log('pop_calling .btn_calling_01 on click',"numberOrder:"+JSON.stringify(numberObj));
        let telephoneNumber = numberObj.normalizedNumber;
        let type = numberObj.type
        console.log('pop_calling .btn_calling_01 on click',"btn_calling_01:"+thisID +"::::" +telephoneNumber+"::::" +type);
        closeCalling();

        callBack(thisID, telephoneNumber, type);
    });

    //전화 팝업 클릭콜 버튼
    $(document).on("click", ".pop_calling .btn_calling_02", function(){
        let thisID = $(this).data("id");
        let numberOrder = $('input[name="sel_num"]:checked').val();
        let numberObj = JSON.parse(numberOrder);
        console.log('pop_calling .btn_calling_02 on click',"numberOrder:"+JSON.stringify(numberObj));
        let telephoneNumber = numberObj.normalizedNumber;
        let type = numberObj.type;
        console.log('pop_calling .btn_calling_02 on click',"btn_calling_01:"+thisID +"::::" +telephoneNumber+"::::" +type);
        closeCalling();

        clickToCall(thisID, telephoneNumber, type);
    });

    //전화 팝업 클릭콜 버튼
    $(document).on("click", ".pop_calling .btn_calling_03", function(){
        let thisID = $(this).data("id");
        let numberOrder = $('input[name="sel_num"]:checked').val();
        let numberObj = JSON.parse(numberOrder);
        console.log('pop_calling .btn_calling_03 on click',"numberOrder:"+JSON.stringify(numberObj));
        let telephoneNumber = numberObj.normalizedNumber;
        let type = numberObj.type
        console.log('pop_calling .btn_calling_03 on click',"btn_calling_01:"+thisID +"::::" +telephoneNumber+"::::" +type);
        closeCalling();

        callthrough(thisID, telephoneNumber, type);
    });

    //전화걸기 팝업 닫기 버튼
    $(document).on("click", ".close_calling", function(){
        $(".bg_calling").removeClass("on");
        $(".bg_calling").remove();
    });

     //공지사항 팝업 버튼
     $(document).on("click", ".btn_notice", function(){
        // getNotices("#tab01");
        getNotices("all");
    });

    //페이지 이동시 보여질때
    $(document).on('pagecontainershow', (event,ui)=>{

        if (ui.toPage.prop('id') === 'organization') {
            if( $('.search_wrap_05 .input_search').val() != ''){
                $(".search_wrap_05").css("padding-left",'102px');
            }else{
                $(".search_wrap_05").css("padding-left",'16px');
            }

            $(".gnb_02").addClass("selected");
        }

        if (ui.toPage.prop('id') === 'dial') {
            // let method_callback = settingData.method_callback
            // let method_callthrough = settingData.method_callthrough
            // let method_click_to_call = settingData.method_click_to_call
        }
        if (ui.toPage.prop('id') === 'address') {
            $("#goTop").show();
            console.log('pagecontainershow','pagecontainershow address');
            if(!isIOS12() && !nullcheck(clusterizeAddress)){

                console.log('pagecontainershow','pagecontainershow address 2');
                clusterizeAddress.refresh(true);
                let offset = document.querySelector(".article_favorites").offsetHeight+24+31+61;
                console.log('pagecontainershow','pagecontainershow offset = ' + offset);
                clusterizeAddress.setTopHeightOffset(offset);
            }


            console.log('pagecontainershow',"from_top"+from_top);

            if(from_top){
                console.log('pagecontainershow',"from_top");
                if(isIOS12()){
                    $(window).scrollTop(0);
                }else{
                    document.getElementById('scrollArea').scrollTop = 0;
                }
            }

            //$(window).scrollTop(0);
            from_top = false;

        }
        if (ui.toPage.prop('id') === 'history') {
            $("#goTop").show();
            try{
                printHistory();
            }catch(e){}
        }
        if (ui.toPage.prop('id') === 'addr_search') {
            //$("#goTop").show();
            $(".btn_sch_all").focus();
            $(".btn_sch_all").on("keyup", function(){
                searchAll();
            });
        }
        if (ui.toPage.prop('id') === 'history_search') {
            //$("#goTop").show();
            $(".btn_sch_history").focus();
            $(".btn_sch_history").on("keyup", function(){
                try {
                    searchHistory();
                } catch (error) { }
            });
        }
        if (ui.toPage.prop('id') === 'forwarding') {
            try{
                getForward(false);
            }catch(e){}
        }
        if (ui.toPage.prop('id') === 'setting') {
            try {
                settingRefresh();
            } catch (error) {}
        }
    });

    //페이지 이동시 사라질때
    $(document).on('pagebeforehide', (event, ui)=>{
        $("#goTop").hide();
        $(".gnb li a").removeClass("selected");
        $('.search_wrap:visible').hide();
        $(`.search_wrap_${ui.toPage.prop('id')}`).show();
        if (ui.prevPage.prop('id') === 'organization') {
            if( $('.search_wrap_05 .input_search').val() == ''){
                $('#btn_cancel_org_search').trigger('click');
            }
        }
        if (ui.prevPage.prop('id') === 'dial') {
            $(".calling_num").html("");
            callNum = "";
            try {
                resetCaret();
            } catch (error) { }
            $(".src_result_box").hide();
        }
        if (ui.prevPage.prop('id') === 'address') {
            localStorage.setItem("addrTop",$(window).scrollTop());
        }

        ///보여지는 페이지가
        if (ui.toPage.prop('id') === 'dial') {
            $(".gnb_01").addClass("selected");
        }
        if (ui.toPage.prop('id') === 'address') {
            //$(".search_wrap_01").show();
            $(".gnb_03").addClass("selected");

            if(isIOS12()){
                $.mobile.defaultHomeScroll = localStorage.getItem("addrTop");
            }
        }
        if (ui.toPage.prop('id') === 'addr_search') {
            //$(".search_wrap_02").show();
            $(".list_sch_all").empty();
            $(".btn_sch_all").val("");

            $(".gnb_03").addClass("selected");
        }
        if (ui.toPage.prop('id') === 'history') {
            //$(".search_wrap_03").show();
            $(".gnb_05").addClass("selected");
            // $.mobile.defaultHomeScroll = 0;
        }
        if (ui.toPage.prop('id') === 'history_search') {
            //$(".search_wrap_04").show();
            $(".list_sch_history").empty();
            $(".btn_sch_history").val("");

            $(".gnb_05").addClass("selected");
        }
        if (ui.toPage.prop('id') === 'forwarding') {
            $(".gnb_06").addClass("selected");
        }
        if (ui.toPage.prop('id') === 'setting') {
        }
    });


}
//-------------INIT PAGE -----------------

//저장된로그내용을 서버로전송
function sendGLog(){
    window.plugins.gntel.getGLog(function(log) {
        console.log('sendGLog','log.length ::', log.length);
        let data = {
            "title": formatDate(new Date()).replace(/[^\d]/g,'')
            ,"log":  log
        };

        let dataSerializer = cordova.plugin.http.getDataSerializer();
        cordova.plugin.http.setDataSerializer('utf8');

        let tempUrl = server_host+server_port+'/astroapi/launcher/v1/clientlog/client/send';
        cordova.plugin.http.post(tempUrl, JSON.stringify(data), {
            'Content-Type': 'application/json'
        }, function(response) {
            popAlert("전송성공");
            console.log('sendGLog','send success');
        }, function(response) {
            popAlert("전송실패");
            console.log('sendGLog',"response status:"+response.status);
            console.log('sendGLog',response.error);
        });

        cordova.plugin.http.setDataSerializer(dataSerializer);

    }, function(error) {
        console.error(error);
    })
}

function writeFile(filename, data, callback) {

    // 파일 삭제
    let type = window.PERSISTENT;
    let size = 5 * 1024 * 1024;
    window.requestFileSystem(type, size, deleteSuccessCallback, deleteErrorCallback);
    function deleteSuccessCallback(fs) {
        fs.root.getFile(filename, { create: false}, function (fileEntry) {
            fileEntry.remove(function (file) {
                // 삭제가 완료되어도
                write();
            }, function (error) {
                // 에러가 발생했어도
                write();
            }, function () {
                // 원래 파일이 없어도
                write();
            });
        }, function errorCallback(error) {
            console.log(arguments.callee.name,error);
            write();
        });
    }
    function deleteErrorCallback(error) {
        console.log(error);
        write();
    }

    // 파일 작성
    function write() {
        window.requestFileSystem(type, size, writeSuccessCallback, writeErrorCallback);
        function writeSuccessCallback(fs) {
            fs.root.getFile(filename, { create: true, exclusive: false }, function (fileEntry) {
                fileEntry.createWriter(function (fileWriter) {
                    fileWriter.onwriteend = function (e) {
                        callback();
                    };
    
                    fileWriter.onerror = function (e) {
                        callback();
                    };
                    fileWriter.write(data);
                },  function errorCallback(error) {
                    console.log(arguments.callee.name,error);
                });
            },  function errorCallback(error) {
                console.log(arguments.callee.name,error);
            });
        }
        function writeErrorCallback(error) {
            console.log(error);
        }
    }
}

function writeFileX(filename, data, callback) {
    let type = window.PERSISTENT;
    let size = 10 * 1024 * 1024;
    //  o12nolja
    console.log('writeFileX','########### writeFile', filename, "size=", data.length);
    alert(" size="+ data.length);
    
    window.requestFileSystem(type, size, successCallback, errorCallback);
    function successCallback(fs) {
        fs.root.getFile(filename, { create: true, exclusive: false }, function (fileEntry) {

            fileEntry.createWriter(function (fileWriter) {
                fileWriter.onwriteend = function (e) {
                    callback();
                };
                fileWriter.onerror = function (e) {
                    callback();
                };
                fileWriter.write(data);
            }, errorCallback);
        }, errorCallback);
    }
    function errorCallback(error) {
        console.log('writeFileX',"EEEEEEEEEEEEEEEE", error);
        alert("ERROR: " + error.code);
    }
}

function readFile(filename, callback) {
    let type = window.PERSISTENT;
    let size = 50 * 1024 * 1024;
    window.requestFileSystem(type, size, successCallback, errorCallback);
    function successCallback(fs) {
        fs.root.getFile(filename, {create: true, exclusive: false}, function (fileEntry) {
            fileEntry.file(function (file) {
                let reader = new FileReader();
                reader.onloadend = function (e) {
                    let arrayBuffer = new Uint8Array(e.target.result);
                    let enc = new TextDecoder("utf-8");
                    callback(enc.decode(arrayBuffer));
                };
                reader.readAsArrayBuffer(file);
            }, errorCallback);
        }, errorCallback);
    }
    function errorCallback(error) {
        callback("{}");
        // alert("ERROR: " + error.code);
    }
}	

function isIOS12(){
    if(devicePlatform == "iOS" && (parseInt(deviceVersion) < 13)){
        return true;
        //return false;
    }else{
        return false;
    }
}

function onBackKeyDown() {
    if($('.ui-page-active').attr('id') == front_pageId){
        if(exitCheck){
            navigator.app.exitApp();
        }else{
            exitCheck = true;
            setTimeout(() => {
                exitCheck = false;
            }, 2000);
            toast("한번 더 누를 시 앱이 종료됩니다.");
        }
    }else{
        window.history.back();
    }
}

//화면 슬라이드하여 메뉴변경
$( document ).one( "pagecreate", ".body_wrap", function() {
    // Handler for navigating to the next page
    function navnext( next ) {
        //location.href = "#" + next;

        $( ":mobile-pagecontainer" ).pagecontainer( "change", "#" + next , {
            transition: "slidefade"
        });
    }

    // Handler for navigating to the previous page
    function navprev( prev ) {
        //location.href = "#" + prev;

        $( ":mobile-pagecontainer" ).pagecontainer( "change", "#" + prev , {
            transition: "slidefade",
            reverse: true
        });
    }

    $( document ).on( "swipeleft", ".ui-page", function( event ) {
        let next = $( this ).jqmData( "next" );
        if ( next ) {
            navnext( next );
        }
    });

    $( document ).on( "swiperight", ".ui-page", function( event ) {
        let prev = $( this ).jqmData( "prev" );
        if ( prev ) {
            navprev( prev );
        }
    });

});
/**
 * 전화번호 포맷 (하이픈 추가).
 */
let format_phone_number = function(number){
    if(number == undefined ||  (number+'').trim() == '') return '　';
    number = number +'';

    if(/[*#]/.test(number)) return number;
    number = number.replace(/[^0-9]/g, "");
    if(number.length == 12){
        return number.replace(/([0-9]{4})([0-9]+)?([0-9]{4})$/,"$1-$2-$3").replace("--", "-")
    }else{
        return number.replace(/(^02|^0505|^1[0-9]{3}|^0[0-9]{2})([0-9]+)?([0-9]{4})$/,"$1-$2-$3").replace("--", "-")
    }
}

// 
let emptyToSpace = function(value){
    if(value == undefined ||  (value+'').trim() == '') return '　';
    return value;
}

// ISO 8601 형식의 날짜를 다른 형태로 변환하는 함수
function formatDate(isoDateTime) {
    let date = new Date(isoDateTime);
    let year = date.getFullYear();
    let month = ('0' + (date.getMonth() + 1)).slice(-2);
    let day = ('0' + date.getDate()).slice(-2);
    let hours = ('0' + date.getHours()).slice(-2);
    let minutes = ('0' + date.getMinutes()).slice(-2);
    let formattedDate = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes;
    return formattedDate;
}

// 날짜 + 시간 변환 함수
// 날짜와 시간을 받아서 지역 시간대를 고려한 ISO 형식의 문자열로 반환하는 함수
function formatDateTime(date, time) {
    date = date.replace(/\./g,'-');
    let combinedDateTime = new Date(date + "T" + time);
    let timezoneOffset = new Date().getTimezoneOffset();
    combinedDateTime.setMinutes(combinedDateTime.getMinutes() - timezoneOffset);
    let isoDateTime = combinedDateTime.toISOString().replace('Z', '');
    let localTimezoneOffset = (timezoneOffset < 0 ? '+' : '-') + pad(Math.abs(timezoneOffset / 60), 2) + ':00';
    return isoDateTime + localTimezoneOffset;
}

// 지역 시간대 오프셋을 두 자리 숫자로 패딩하는 함수
function pad(number, length) {
    let str = '' + number;
    while (str.length < length) {
        str = '0' + str;
    }
    return str;
}

// 시작 시간과 종료 시간을 설정하는 함수
function setDateTimeInputs(datetime, startDateInput, startTimeInput) {
    if (!datetime) return;
    let date = new Date(datetime);
    $(startDateInput).val(date.toISOString().substring(0, 10));
    $(startTimeInput).val(formatUTCtoLocalTime(datetime.substring(11, 16)));
}

// UTC 시간을 로컬 시간으로 변환하여 "HH:mm" 형식으로 반환하는 함수
function formatUTCtoLocalTime(timeStr) {
    if (!timeStr || timeStr.length !== 5) return timeStr; // 잘못된 입력이거나 시간 정보가 없는 경우

    let date = new Date("2023-12-14T" + timeStr + ":00.000+09:00");
    
    // 시간대를 설정해줍니다.
    let localTime = new Date(date.toLocaleString('en-US', {timeZone: 'Asia/Seoul'}));

    let hours = localTime.getHours();
    let minutes = localTime.getMinutes();

    // "HH:mm" 형식으로 반환
    return ('0' + hours).slice(-2) + ':' + ('0' + minutes).slice(-2);
}

const requestAstro = async (url, params, method ) =>{
    if(!url.startsWith('http://') && !url.startsWith('https://')){
        url = `${server_host}${server_port}/astroapi/${url}`
    }

    let fetchoptions = {
        method : method
        ,headers : {
            "Content-Type": "application/json"
            ,'Authorization' : `Bearer ${userData.astroToken}`
        }
    }

    if(method.toLowerCase() != 'get'){
        try {
            fetchoptions.body = JSON.stringify(params);
        } catch (error) {
            console.warn('params is not JSON', params);
        }
    }

    try {
        let response = await fetch(
            url
            ,fetchoptions
        );

        if (!response.ok) {
            throw new Error(`Response status: ${response.status}`);
        }

        return await response.json();

    } catch (error) {
        console.error(error);
        throw error;
    }

}

const listFiles = async (dirEntry, fileList, callback)=>{
    var directoryReader = dirEntry.createReader();
    await directoryReader.readEntries(function(entries) {
        var pending = entries.length;
        if (pending <= 0) return callback(fileList);

        entries.forEach(function(entry) {
            if (entry.isDirectory) {
                listFiles(entry, fileList, function() {
                    if (--pending <= 0) callback(fileList);
                });
            } else {
                fileList.push(entry.fullPath);
                if (--pending <= 0) callback(fileList);
            }
        });
    }, function(error) {
        console.error("디렉토리 읽기 실패:", error);
    });
};

/**
 * 하위디렉토리까지 조회
 * @param {} dir 
 * @param {*} callback 
 */
const listWholeFiles = async (dir, callback)=>{
    window.resolveLocalFileSystemURL(`${cordova.file.applicationDirectory}${dir}`, function(dirEntry) {
        listFiles(dirEntry, [], function(fileList) {
            callback(fileList);
        });
    }, function(error) {
        console.error("디렉토리 접근 실패:", error);
    });
};

/**
 * 전화 수신시 착신전환된 통화인지 확인
 * @param {} telno 
 */
const getCheckForwardCM = (telno) => {
    requestAstro(`ipecscm/v1/rest/callrequest`
        , {
            url: `https://${serverData.cust_con_pbx_ip}:${serverData.cust_con_port}/ipxapi/v1/users/${settingData.prefixEx.replace(settingData.svcPrefixNo,'')}/fwdcall?callerId=${telno}`
            , token : window.localStorage.getArray('userData').token
            , telno: telno
        }, 'post')
    .then(r =>{
        if(r.data.data.result == 'true'){
            window.cordova.exec(null, null, 'GntelPlugin', 'checkForwardCallBack', [JSON.stringify({telno : telno, cid_no : `${settingData.prefixEx.replace(settingData.svcPrefixNo,'')}`})]);
        }
    })
    .catch(e =>{
        console.error('getCheckForwardCM error :: ', e);
    });
}

const requestToCm = (params, callback) => {
    if(typeof REQUEST_CM_THROUGH_ASTRO === 'undefined' || !REQUEST_CM_THROUGH_ASTRO){
        cordova.plugin.http.setServerTrustMode('nocheck', function() {}, function(e) {});
        cordova.plugin.http[(params.method||'post').toLowerCase()](params.url, { }, {
            Authorization: `Bearer ${params.token}`
        }, function(response) {
            let json = null;
            try {
                json = JSON.parse(response.data||'{}');
            } catch (error) {
                console.error(JSON.stringify(params), response);
                return;
            }
            callback({
                code : '0000'
                ,data : json
            });
        }, function(response) {
            console.error(JSON.stringify(response))
            popAlert("오류가 발생했습니다.<br/>잠시 후 다시 시도해 주세요");
        });
    }else{
        requestAstro(`ipecscm/v1/rest/callrequest`, params, 'post')
        .then(response =>{
            if(callback) callback(response);
        })
        .catch(e =>{
            console.error(e);
            popAlert("오류가 발생했습니다.<br/>잠시 후 다시 시도해 주세요");
        });
    }

}