/**
 * common js of app(web).
 * The following is written.
 * 1.language
 * 2.loading
 * 3.alert
 * 4.url
 * 5.cms communication
 * 6.check if user is logged in
 * 7.jquery event
 *
 * @since cms:1.4.3.2&1.4.3.3 web:1.0
 */
var COMMON = {};

COMMON.hasErrorKey = 'AVW_HASERR';

COMMON.lang;

/**
 * get lang code in local storage
 * web gets lang form local storage
 * but app gets lnag from session storage
 */
COMMON.setLangCodeWeb = function () {
    let lang = COMMON.getLangWeb();
    if (lang.split('-')[0] == CONSTANT.LANG.English) {
        lang = CONSTANT.LANG.ENGLISH;
    } else if (lang.split('-')[0] == CONSTANT.LANG.KOREA) {
        lang = CONSTANT.LANG.KOREA;
    } else {
        lang = CONSTANT.LANG.JAPAN;
    }
    COMMON.lang = lang;
};

/**
 * get lang in local storage
 *
 * @returns String pageLang
 */
COMMON.getLangWeb = function () {
    if (!COMMON.lang) {
        let pageLang;
        if (localStorage[CONSTANT.LANG.SAVE_NAME]) {
            pageLang = localStorage[CONSTANT.LANG.SAVE_NAME];
        } else {
            pageLang = (window.navigator.languages && window.navigator.languages[0]) || window.navigator.language || window.navigator.userLanguage || window.navigator.browserLanguage;
            localStorage[CONSTANT.LANG.SAVE_NAME] = pageLang;
        }
        return pageLang;
    } else {
        return COMMON.lang;
    }

    return pageLang;
};

/**
 * change lang of html
 */
COMMON.updateLang = function () {
    $('.multi-lang').each(function () {
        const key = $(this).attr('data-msg');
        if (key) {
            if ($(this).prop('tagName').toLowerCase() == 'input' && ($(this).attr('type') == 'text' || $(this).attr('type') == 'search')) {
                const attr = $(this).attr('placeholder');
                if (typeof attr !== 'undefined' && attr !== false) {
                    $(this).attr('placeholder', COMMON.getMsg(key));
                } else {
                    $(this).val(COMMON.getMsg(key));
                }
            } else {
                $(this).html(COMMON.getMsg(key));
            }
        }
    });
};

/**
 * get any lang msg from COMMON.msgMap
 *
 * @param String key
 * @returns String msg
 */
COMMON.getMsg = function (key) {
    const msg = CONSTANT.MSG_MAP[key];
    if (!msg) {
        return '';
    }

    return msg[COMMON.lang];
};

/* page transition without outputting a warning message */
COMMON.avwScreenMove = function (url) {
    COMMON.showLoading();
    window.onbeforeunload = null;
    window.location = url;
};

/**
 * show loading dialog
 * show msg by key
 *
 * @param {String} key
 */
COMMON.showLoading = function () {
    $.LoadingOverlay('show', {
        image: '../common/img/loading.gif',
    });
};

/**
 * close loading
 */
COMMON.closeLoading = function () {
    $.LoadingOverlay('hide');
};

/**
 * show alert
 *
 * @param {String} msgCode
 */
COMMON.displayAlert = function (msgCode, title) {
    $('#alertMsg').html(I18N.i18nText(msgCode));
    $('.alert-overlay').removeClass('d-none');
    $('.alert-area').removeClass('d-none');

    const positionY = $(document).scrollTop() + screen.height / 8;
    const height = screen.height / 4;
    $('.alert-overlay').css('height', screen.height);
    $('.alert-area').css('top', positionY);
    $('.alert-area').css('min-height', height);
    $('body').css('overflow', 'hidden');
};

/**
 * close alert
 */
COMMON.alertClose = function () {
    $('.alert-overlay').addClass('d-none');
    $('.alert-area').addClass('d-none');
    $('body').css('overflow', 'visible');
};

/**
 * go Url page With Current Params
 *
 * ios will remove all web types data when reopen webview
 * need add common parameters: app, lang, debug, mobile_flg, isChat, ...
 *
 * @param {String} url
 * @param {Object} params
 */
COMMON.goUrlWithCurrentParams = function (url, params) {
    if (!params) {
        location.href = CONSTANT.URL.WEB.BASE + url;
    }

    const mixParams = Object.assign(COMMON.getUrlParameter(), params);
    if (url.includes('?')) {
        location.href = url + '&' + new URLSearchParams(mixParams);
    } else {
        location.href = url + '?' + new URLSearchParams(mixParams);
    }
};

/**
 * get url parameter
 *
 */
COMMON.getUrlParameter = function () {
    var ret = {};
    if (location.search) {
        var param = {};
        location.search
            .substring(1)
            .split('&')
            .forEach(function (val) {
                var kv = val.split('=');
                param[kv[0]] = kv[1];
            });
        ret = param;
    }
    console.log({ ret: ret });
    return ret;
};

/**
 * get sid in local Storage
 *
 * @returns sid
 */
COMMON.getSid = function () {
    return ClientData.userInfo_sid();
};

/**
 * cms communication
 *
 * @param {String} url
 * @param {Json} param
 * @param {boolean} async
 * @param {Object} callback
 * @param {Object} errorCallback
 */
COMMON.cmsAjax = function (url, param, async = true, callback, errorCallback, type) {
    var sysSettings = new COMMON.sysSetting();
    if (url) {
        $.ajax({
            type: 'post',
            url: url,
            data: param,
            dataType: type ? type : 'json',
            cache: false,
            async: async,
            crossDomain: true,
            beforeSend: function (xhr) {
                xhr.setRequestHeader('X-AGT-AppId', sysSettings.appName);
                xhr.setRequestHeader('X-AGT-AppVersion', sysSettings.appVersion);
            },
            success: function (result) {
                if (type == 'text') {
                    if (callback) callback(result);
                    return;
                }
                if (result.httpStatus == '200') {
                    if (callback) callback(result);
                } else if (errorCallback) {
                    errorCallback(result);
                } else if (result.httpStatus == '401') {
                    COMMON.goUrlWithCurrentParams(CONSTANT.PAGE_NAME.LOGIN);
                } else if (result.httpStatus == '403') {
                    COMMON.closeLoading();
                    COMMON.displayAlert('errorOccurred');
                } else {
                    COMMON.closeLoading();
                    COMMON.displayAlert(result.message);
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                if (errorCallback) {
                    errorCallback(XMLHttpRequest, textStatus, errorThrown);
                } else {
                    COMMON.closeLoading();
                    COMMON.displayAlert('errorCommunicationFailed');
                }
            },
        });
    } else {
        if (errorCallback) {
            errorCallback();
        } else {
            COMMON.closeLoading();
            COMMON.displayAlert('errorOccurred');
        }
    }
};

/**
 * Communicate with cms and post
 *
 * @param {String} url
 * @param {Object} params
 * @param {String} method
 */
COMMON.postCommunication = function (url, params, method = 'post') {
    const form = document.createElement('form');
    form.method = method;
    form.action = url;

    for (const key in params) {
        if (params.hasOwnProperty(key)) {
            const hiddenField = document.createElement('input');
            hiddenField.type = 'hidden';
            hiddenField.name = key;
            hiddenField.value = params[key];
            form.appendChild(hiddenField);
        }
    }

    document.body.appendChild(form);
    form.submit();
};

/**
 * Check if user is logged in
 *
 * @param {boolean} async
 */
COMMON.checkAuth = function (async = true) {
    let params = {};
    params.sid = COMMON.getSid;
    const url = COMMON.format(ClientData.conf_checkApiUrl(), ClientData.userInfo_accountPath()) + CONSTANT.URL.CMS.API.AUTH_SESSION;
    COMMON.cmsAjax(url, params, async, null, function () {
        COMMON.goUrlWithCurrentParams(CONSTANT.PAGE_NAME.LOGIN);
    });
};

var ClientData = {
    // Local :ユーザ情報(userInfo)_アカウントパス:String
    userInfo_accountPath: function (data) {
        if (arguments.length > 0) {
            COMMON.userSetting().set(CONSTANT.KEYS.userInfo_accountPath, data);
        } else {
            return COMMON.userSetting().get(CONSTANT.KEYS.userInfo_accountPath);
        }
    },

    // Local :ユーザ情報(userInfo)_ログインID:String
    userInfo_loginId: function (data) {
        if (arguments.length > 0) {
            COMMON.userSetting().set(CONSTANT.KEYS.userInfo_loginId, data);
        } else {
            return COMMON.userSetting().get(CONSTANT.KEYS.userInfo_loginId);
        }
    },

    // Local :ユーザ情報(userInfo)_アカウント情報記憶フラグ:Char(Y:可能, N:不可)
    userInfo_rememberLogin: function (data) {
        if (arguments.length > 0) {
            COMMON.userSetting().set(CONSTANT.KEYS.userInfo_rememberLogin, data);
        } else {
            return COMMON.userSetting().get(CONSTANT.KEYS.userInfo_rememberLogin);
        }
    },

    // Session :ユーザ情報(userInfo)_ログインID:String
    userInfo_loginId_session: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(CONSTANT.KEYS.userInfo_loginId, data);
        } else {
            return SessionStorageUtils.get(CONSTANT.KEYS.userInfo_loginId);
        }
    },

    // Session :ユーザ情報(userInfo)_アカウントパス:String
    userInfo_accountPath_session: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(CONSTANT.KEYS.userInfo_accountPath, data);
        } else {
            return SessionStorageUtils.get(CONSTANT.KEYS.userInfo_accountPath);
        }
    },

    // Session
    userInfo_userName: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(CONSTANT.KEYS.userInfo_userName, data);
        } else {
            return SessionStorageUtils.get(CONSTANT.KEYS.userInfo_userName);
        }
    },

    // Local :ユーザ情報(userInfo)_最終ログイン日時:Datetime
    userInfo_lastLoginTime: function (data) {
        if (arguments.length > 0) {
            COMMON.operateData(arguments, CONSTANT.KEYS.userInfo_lastLoginTime, undefined);
        } else {
            return COMMON.operateData(arguments, CONSTANT.KEYS.userInfo_lastLoginTime, undefined);
        }
    },

    // Session:ユーザ情報(userInfo)_セッションID:String
    userInfo_sid: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(CONSTANT.KEYS.userInfo_sid, data);
            // COMMON.userSetting().set(CONSTANT.KEYS.userInfo_sid, data);
        } else {
            // return COMMON.userSetting().get(CONSTANT.KEYS.userInfo_sid);
            if (COMMON.userSession()) {
                return SessionStorageUtils.get(CONSTANT.KEYS.userInfo_sid);
            }
            return null;
        }
    },

    // Local: ユーザ情報(userInfo)_セッションID:String
    userInfo_sid_local: function (data) {
        if (arguments.length > 0) {
            COMMON.userSetting().set(CONSTANT.KEYS.userInfo_sid_local, data);
        } else {
            return COMMON.userSetting().get(CONSTANT.KEYS.userInfo_sid_local);
        }
    },

    // Local: セッションIDのバックアップ
    userInfo_sid_local_bak: function (data) {
        if (arguments.length > 0) {
            COMMON.userSetting().set(CONSTANT.KEYS.userInfo_sid_bak, data);
        } else {
            return COMMON.userSetting().get(CONSTANT.KEYS.userInfo_sid_bak);
        }
    },

    // Session :通知情報(pushInfo)_新着件数:Interger
    pushInfo_newMsgNumber: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(CONSTANT.KEYS.pushInfo_newMsgNumber, data);
        } else {
            return SessionStorageUtils.get(CONSTANT.KEYS.pushInfo_newMsgNumber);
        }
    },

    conf_apiUrl: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(CONSTANT.KEYS.conf_apiUrl, data);
        } else {
            return SessionStorageUtils.get(CONSTANT.KEYS.conf_apiUrl);
        }
    },
    conf_apiLoginUrl: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(CONSTANT.KEYS.conf_apiLoginUrl, data);
        } else {
            return SessionStorageUtils.get(CONSTANT.KEYS.conf_apiLoginUrl);
        }
    },
    conf_checkApiUrl: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(CONSTANT.KEYS.conf_checkApiUrl, data);
        } else {
            return SessionStorageUtils.get(CONSTANT.KEYS.conf_checkApiUrl);
        }
    },
    conf_apiResourceDlUrl: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(CONSTANT.KEYS.conf_apiResourceDlUrl, data);
        } else {
            return SessionStorageUtils.get(CONSTANT.KEYS.conf_apiResourceDlUrl);
        }
    },

    // Local :ユーザ情報(userInfo)_パスワードスキップ日時:Datetime
    userInfo_pwdSkipDt: function (data) {
        if (arguments.length > 0) {
            COMMON.operateData(arguments, CONSTANT.KEYS.userInfo_pwdSkipDt, undefined);
        } else {
            return COMMON.operateData(arguments, CONSTANT.KEYS.userInfo_pwdSkipDt, undefined);
        }
    },

    // Session :事業者オプション(serviceOpt)_ABookCheck:Char(Y:有効, N:無効)
    serviceOpt_abook_check: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(CONSTANT.KEYS.serviceOpt_abook_check, data);
        } else {
            return SessionStorageUtils.get(CONSTANT.KEYS.serviceOpt_abook_check);
        }
    },

    // Session : Tenant Service_Option(serviceOpt)_ChatFunction:Char(Y:Use, N:Unused)
    serviceOpt_chat_function: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(CONSTANT.KEYS.serviceOpt_abook_check, data);
        } else {
            return SessionStorageUtils.get(CONSTANT.KEYS.serviceOpt_abook_check);
        }
    },

    // Session :事業者オプション(serviceOpt)_初回ログイン時パスワード強制変更:Integer(0:なし, 1:催促, 2:強制)
    serviceOpt_force_pw_change_on_login: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(CONSTANT.KEYS.serviceOpt_force_pw_change_on_login, data);
        } else {
            return SessionStorageUtils.get(CONSTANT.KEYS.serviceOpt_force_pw_change_on_login);
        }
    },

    // Session :事業者オプション(serviceOpt)_定期ログイン時パスワード強制変更:Integer(0:なし, 1:催促, 2:強制)
    serviceOpt_force_pw_change_periodically: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(CONSTANT.KEYS.serviceOpt_force_pw_change_periodically, data);
        } else {
            return SessionStorageUtils.get(CONSTANT.KEYS.serviceOpt_force_pw_change_periodically);
        }
    },

    // Session :事業者オプション(serviceOpt)_任意のプッシュメッセージ:Char(Y:可能, N:不可)
    serviceOpt_usable_push_message: function (data) {
        if (arguments.length > 0) {
            SessionStorageUtils.set(CONSTANT.KEYS.serviceOpt_usable_push_message, data);
        } else {
            return SessionStorageUtils.get(CONSTANT.KEYS.serviceOpt_usable_push_message);
        }
    },

    // Local
    JumpQueue: function (data) {
        if (arguments.length > 0) {
            COMMON.operateData(arguments, CONSTANT.KEYS.JumpQueue, []);
        } else {
            return COMMON.operateData(arguments, CONSTANT.KEYS.JumpQueue, []);
        }
    },

    // Local
    IsJumpBack: function (data) {
        if (arguments.length > 0) {
            COMMON.operateData(arguments, CONSTANT.KEYS.IsJumpBack, undefined);
        } else {
            return COMMON.operateData(arguments, CONSTANT.KEYS.IsJumpBack, undefined);
        }
    },
};

/*
 * Variables
 */
COMMON.userSessionObj = null;
COMMON.userSettingObj = null;
COMMON.sysSettingObj = null;

/*
 * User Settings Class Definition
 */
var UserSetting = function () {
    this.US_KEY = 'AVWUS';
    this.userSetting = this.load();
};
/* get user setting from localStorage */
UserSetting.prototype.load = function () {
    var storage = window.localStorage;
    var value = null;
    var js = null;
    if (storage) {
        var value = storage.getItem(this.US_KEY);
        if (!value) {
            value = '{}'; // 空JSON文字列
        }
        js = JSON.parse(value);
    }
    return js;
};
/* store user setting */
UserSetting.prototype.set = function (key, value) {
    //if(!this.userSetting) {
    this.userSetting = this.load();
    //}
    var values = this.userSetting;
    if (!values) {
        values = { key: value };
    } else {
        values[key] = value;
    }
    var storage = window.localStorage;
    if (storage) {
        var jsonStr = JSON.stringify(values);
        storage.setItem(this.US_KEY, jsonStr);
    }
    this.userSetting = values;
};
/* grab user setting */
UserSetting.prototype.get = function (key) {
    //if(!this.userSetting) {
    this.userSetting = this.load();
    //}
    var values = this.userSetting;
    if (values) {
        return values[key];
    }
    return null;
};
/* show user setting object list */
UserSetting.prototype.show = function (elmid) {
    var storage = window.localStorage;
    var tags = '<p>';
    if (storage) {
        var value = storage.getItem(this.US_KEY);
        if (value) {
            var js = JSON.parse(value);
            $.each(js, function (k, v) {
                tags = tags + '<b>' + k + '</b>:' + v + '<br />';
            });
        }
        tags = tags + '</p>';
        $(elmid).html(tags);
    }
};
/* ユーザ設定のキーリストを取得 */
UserSetting.prototype.keys = function () {
    var storage = window.localStorage;
    var keyList = [];
    if (storage) {
        var value = storage.getItem(this.US_KEY);
        if (value) {
            var js = JSON.parse(value);
            var i = 0;
            $.each(js, function (k, v) {
                keyList[i++] = k;
            });
        }
        return keyList;
    }
    return null;
};
/* ユーザ設定を削除 */
UserSetting.prototype.remove = function (key) {
    var storage = window.localStorage;
    if (storage) {
        var value = storage.getItem(this.US_KEY);
        if (value) {
            var js = JSON.parse(value);
            if (js) {
                delete js[key];
                storage.setItem(this.US_KEY, JSON.stringify(js));
            }
        }
    }
};
/* ユーザ設定をすべて削除 */
UserSetting.prototype.removeAll = function () {
    var storage = window.localStorage;
    if (storage) {
        storage.remove(this.US_KEY);
    }
};

/*
 * User Session Class Definition
 */
var UserSession = function () {
    this.available = false;
};
/* Initialize User Session */
UserSession.prototype.init = function (option) {
    this.available = false;
    if (option == 'restore') {
        var value = null;
        try {
            value = this._get('init');
        } catch (e) {
            value = null;
        } finally {
            if (value) {
                this.available = true;
            }
        }
    } else {
        this.set('init', new Date().toLocaleString());
        this.available = true;
    }
};
/* store key, value item to user session */
UserSession.prototype.set = function (key, value) {
    var storage = window.sessionStorage;
    if (storage) {
        if (this.available == false) {
            if (key == 'init') {
                storage.setItem('AVWS_' + key, value);
            } else {
                throw new Error('Session destoryed.');
            }
        } else {
            storage.setItem('AVWS_' + key, value);
        }
    }
};
/* get session item value */
UserSession.prototype.get = function (key) {
    var value = null;
    if (this.available) {
        value = this._get(key);
    } else {
        throw new Error('Session Destroyed.');
    }
    return value;
};
/* get item value from session storage */
UserSession.prototype._get = function (key) {
    var storage = window.sessionStorage;
    var value = null;
    if (storage) {
        value = storage.getItem('AVWS_' + key);
    }
    return value;
};
/* destroy user session */
UserSession.prototype.destroy = function () {
    var storage = window.sessionStorage;
    if (storage) {
        storage.clear();
        this.available = false;
    }
};
/* show user session object list */
UserSession.prototype.show = function (elmid) {
    var storage = window.sessionStorage;
    var tags = '<p>';
    if (storage) {
        for (var i = 0; i < storage.length; i++) {
            var key = storage.key(i);
            var value = storage.getItem(key);
            tags = tags + '<b>' + key + '</b>:' + value + '<br />';
        }
        tags = tags + '</p>';
        $(elmid).html(tags);
    }
};

/* Initialize system */
$(function () {
    // システム設定ファイルの配置先パスの決定

    var location = window.location.toString().toLowerCase();

    var sysFile = '';
    if (location.indexOf('/abweb') < 0) {
        sysFile = '../abweb/common/json/sys/conf.json';
    } else {
        sysFile = '../common/json/sys/conf.json';
    }

    // システム設定ファイルを読み込む
    $.ajax({
        url: sysFile,
        async: false,
        cache: false,
        dataType: 'json',
        success: function (data) {
            COMMON.sysSettingObj = data;
        },
        error: function (xmlHttpRequest, txtStatus, errorThrown) {
            var error = 'Could not load the system configuration file. Please check it.';
            error += '\n' + xmlHttpRequest.status + ' ' + txtStatus + ' ' + errorThrown + ' : ' + sysFile;
            alert(error);
        },
    });

    // ロード時に一旦エラー状態をクリアしておく
    COMMON.clearError();

    //#31919 【調査】商談支援システム GoogleChromeでビッチイン・アウトが効かない
    navigator.pointerEnabled = navigator.maxTouchPoints > 0; // Edge 17 touch support workaround
    document.documentElement.ontouchstart = navigator.maxTouchPoints > 0 ? function () {} : undefined; // Chrome 70 touch support workaround
});

// Hide the locking layout
COMMON.unlockLayout = function () {
    $('#avw-sys-modal').hide();
};

// Show the locking layout
COMMON.lockLayout = function () {
    if (document.getElementById('avw-sys-modal')) {
        $('#avw-sys-modal').show();
    } else {
        var tags = '<div id="avw-sys-modal"></div>';
        $('body').prepend(tags);
        $('#avw-sys-modal').css({
            opacity: 0.7,
            position: 'fixed',
            top: '0',
            left: '0',
            width: $(window).width(),
            height: $(window).height(),
            background: '#999',
            'z-index': 100,
        });
        // resize error page
        $(window).resize(function () {
            $('#avw-sys-modal').css({
                width: $(window).width(),
                height: $(window).height(),
            });
        });
    }
};

/* エラー状態をクリア */
COMMON.clearError = function () {
    var session = window.sessionStorage;
    if (session) {
        session.setItem(COMMON.hasErrorKey, false);
    }
};
/* エラー状態を取得 */
COMMON.hasError = function () {
    var session = window.sessionStorage;
    var isError = false;
    if (session) {
        isError = session.getItem(COMMON.hasErrorKey);
    }
    return isError == 'true';
};
/* エラー状態にセット */
COMMON.setErrorState = function () {
    var session = window.sessionStorage;
    if (session) {
        session.setItem(COMMON.hasErrorKey, true);
    }
};
///* get user environment object */
//function avwUserEnv() {
//	if(COMMON.avwUserEnvObj == null) {
//		COMMON.avwUserEnvObj = new UserEnvironment();
//	}
//	return COMMON.avwUserEnvObj;
//};
/* get user session object */
COMMON.userSession = function () {
    if (!COMMON.userSessionObj) {
        var obj = new UserSession();
        obj.init('restore');
        if (obj.available) {
            COMMON.userSessionObj = obj;
            return COMMON.userSessionObj;
        } else {
            return null;
        }
    }
    return COMMON.userSessionObj;
};
/* create user session object */
COMMON.createUserSession = function () {
    if (COMMON.userSessionObj) {
        COMMON.userSessionObj.destroy();
    } else {
        COMMON.userSessionObj = new UserSession();
        COMMON.userSessionObj.init();
    }
    return COMMON.userSessionObj;
};

/* get user setting object */
COMMON.userSetting = function () {
    if (COMMON.userSettingObj == null) {
        COMMON.userSettingObj = new UserSetting();
    }
    return COMMON.userSettingObj;
};

/* get system setting object */
COMMON.sysSetting = function () {
    return COMMON.sysSettingObj;
};

/*
 * Operations for session storage [start]
 */

var SessionStorageUtils = {
    login: function () {
        if (COMMON.userSession()) {
            // Skip this case
        } else {
            COMMON.avwCreateUserSession();
        }
    },
    get: function (strKey) {
        return COMMON.userSession().get(strKey);
    },
    set: function (strKey, objValue) {
        COMMON.userSession().set(strKey, objValue);
    },
    clear: function () {
        if (COMMON.userSession()) {
            COMMON.userSession().destroy();
        }
    },
    remove: function (strKey) {
        COMMON.userSession().set(strKey, null);
    },
};

/*
 * Operations for local storage
 */
var LocalStorageUtils = {
    getUniqueId: function () {
        var uniqueId = '';

        if (COMMON.userSetting().get(CONSTANT.KEYS.userInfo_accountPath)) {
            uniqueId += COMMON.userSetting().get(CONSTANT.KEYS.userInfo_accountPath);
        }
        if (COMMON.userSetting().get(CONSTANT.KEYS.userInfo_loginId)) {
            uniqueId += '.' + COMMON.userSetting().get(CONSTANT.KEYS.userInfo_loginId);
        }
        if (uniqueId != '') {
            uniqueId += '.';
        }

        return uniqueId;
    },
    get: function (strKey) {
        var key = this.getUniqueId() + strKey;

        return COMMON.userSetting().get(key);
    },
    set: function (strKey, objValue) {
        var key = this.getUniqueId() + strKey;
        COMMON.userSetting().set(key, objValue);
    },
    remove: function (strKey) {
        var key = this.getUniqueId() + strKey;
        COMMON.userSetting().remove(key);
        SessionStorageUtils.remove(strKey);
    },
    clear: function () {
        var localStorageKeys = COMMON.userSetting().keys();
        for (var nIndex = 0; nIndex < localStorageKeys.length; nIndex++) {
            var strKey = localStorageKeys[nIndex];

            if ((strKey + '').contains(this.getUniqueId())) {
                COMMON.userSetting().remove(strKey);
            }
        }
    },
    existKey: function (strKey) {
        var keys = COMMON.userSetting().keys();
        var findKey = this.getUniqueId() + strKey;
        var isExisted = false;
        if (keys != null && keys != undefined) {
            for (var nIndex = 0; nIndex < keys.length; nIndex++) {
                if (keys[nIndex] == findKey) {
                    isExisted = true;
                    break;
                }
            }
        }
        return isExisted;
    },
};

/* String.format function def. */
COMMON.format = function (fmt) {
    for (var i = 1; i < arguments.length; i++) {
        var reg = new RegExp('\\{' + (i - 1) + '\\}', 'g');
        fmt = fmt.replace(reg, arguments[i]);
    }
    return fmt;
};

// Get param url
COMMON.getUrlParam = function (name, url) {
    if (!url) {
        url = window.location.href;
    }

    name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
    var regexS = '[\\?&]' + name + '=([^&#]*)';
    var regex = new RegExp(regexS);
    var results = regex.exec(url);
    if (results == null) {
        return '';
    } else {
        // alert("results[0]:" + results[0]);
        // alert("results[1]:" + results[1]);
        return results[1];
    }
};

COMMON.ToogleLogoutNortice = function () {
    window.onbeforeunload = function (event) {
        var message = I18N.i18nText('sysInfoWithoutLogout');
        var e = event || window.event;
        if (e) {
            e.returnValue = message;
        }
        return message;
    };
};

/*
 * Get data from localstorage and sessionstorage synchronization If has any
 * param (args.length > 0) -> setter If has not param (args.length = 0) ->
 * getter . Get from session: + if it existed and key existed in localstorage ->
 * return result + else: set value from local to sessionstorage -> return value
 * of sessionstorage if value is not empty, otherwise, return default result.
 *
 */
COMMON.operateData = function (args, strKey, returnDefaultData) {
    if (args.length > 0) {
        var data = args[0];
        LocalStorageUtils.set(strKey, data);
        SessionStorageUtils.set(strKey, JSON.stringify(data));
    } else {
        if (
            SessionStorageUtils.get(strKey) != 'undefined' &&
            SessionStorageUtils.get(strKey) != undefined &&
            SessionStorageUtils.get(strKey) != '' &&
            SessionStorageUtils.get(strKey) != null &&
            SessionStorageUtils.get(strKey) != 'null'
        ) {
            if (LocalStorageUtils.existKey(strKey) == true) {
                return JSON.parse(SessionStorageUtils.get(strKey));
            } else {
                return returnDefaultData;
            }
        } else {
            if (LocalStorageUtils.existKey(strKey) == true) {
                SessionStorageUtils.set(strKey, JSON.stringify(LocalStorageUtils.get(strKey)));
                return JSON.parse(SessionStorageUtils.get(strKey));
            }
            return returnDefaultData;
        }
    }
};

/**
 * UTC current Time (millisecond)
 *
 * @returns UTC time
 */
COMMON.currentTime = function () {
    return Date.now();
};

/*
 * Operations for session storage [ end ]
 */

// =============================================================================================
// Utils for string, date, number [start]
// =============================================================================================
/*
 * Convert date to JP format date time [start]
 */

/*
 * YYYY/MM/DD HH:MM:SS
 */
Date.prototype.jpDateTimeString = function () {
    var strResult = '';
    var strYear = this.getFullYear() + '';
    var strMonth = this.getMonth() + 1 + '';
    var strDayInMonth = this.getDate() + '';
    var strHour = this.getHours() + '';
    var strMinute = this.getMinutes() + '';
    var strSecond = this.getSeconds() + '';

    strResult += strYear.padLeft('0', 4) + '/' + strMonth.padLeft('0', 2) + '/' + strDayInMonth.padLeft('0', 2);
    strResult += ' ' + strHour.padLeft('0', 2) + ':' + strMinute.padLeft('0', 2) + ':' + strSecond.padLeft('0', 2);
    return strResult;
};
/*
 * YYYY-MM-DD HH:MM:SS
 */
Date.prototype.jpDateTimeString1 = function () {
    var strResult = '';
    var strYear = this.getFullYear() + '';
    var strMonth = this.getMonth() + 1 + '';
    var strDayInMonth = this.getDate() + '';
    var strHour = this.getHours() + '';
    var strMinute = this.getMinutes() + '';
    var strSecond = this.getSeconds() + '';

    strResult += strYear.padLeft('0', 4) + '-' + strMonth.padLeft('0', 2) + '-' + strDayInMonth.padLeft('0', 2);
    strResult += ' ' + strHour.padLeft('0', 2) + ':' + strMinute.padLeft('0', 2) + ':' + strSecond.padLeft('0', 2);
    return strResult;
};
/*
 * yyyy/MM/dd
 */
Date.prototype.jpDateString = function () {
    var strResult = '';
    var strYear = this.getFullYear() + '';
    var strMonth = this.getMonth() + 1 + '';
    var strDayInMonth = this.getDate() + '';

    strResult += strYear.padLeft('0', 4) + '/' + strMonth.padLeft('0', 2) + '/' + strDayInMonth.padLeft('0', 2);

    return strResult;
};
/*
 * HH:mm:ss
 */
Date.prototype.jpTimeString = function () {
    var strResult = '';
    var strHour = this.getHours() + '';
    var strMinute = this.getMinutes() + '';
    var strSecond = this.getSeconds() + '';

    strResult += ' ' + strHour.padLeft('0', 2) + ':' + strMinute.padLeft('0', 2) + ':' + strSecond.padLeft('0', 2);
    return strResult;
};
/*
 * HH:mm
 */
Date.prototype.jpShortTimeString = function () {
    var strResult = '';
    var strHour = this.getHours() + '';
    var strMinute = this.getMinutes() + '';
    var strSecond = this.getSeconds() + '';

    strResult += ' ' + strHour.padLeft('0', 2) + ':' + strMinute.padLeft('0', 2);
    return strResult;
};
/*
 * yyyyMMddHHmmss
 */
Date.prototype.toIdString = function () {
    var strResult = '';
    var strYear = this.getFullYear() + '';
    var strMonth = this.getMonth() + 1 + '';
    var strDayInMonth = this.getDate() + '';
    var strHour = this.getHours() + '';
    var strMinute = this.getMinutes() + '';
    var strSecond = this.getSeconds() + '';
    var strMilisecond = this.getMilliseconds() + '';

    strResult += strYear.padLeft('0', 4) + strMonth.padLeft('0', 2) + strDayInMonth.padLeft('0', 2);
    strResult += strHour.padLeft('0', 2) + strMinute.padLeft('0', 2) + strSecond.padLeft('0', 2) + strMilisecond.padLeft('0', 3);
    return strResult;
};
// Subtract date to get days
Date.prototype.subtractByDays = function (targetDate) {
    var milis = Math.abs(this - targetDate);
    var days = Math.floor(milis / (60 * 60 * 24 * 1000));
    return days;
};
Date.prototype.addSeconds = function (plusSeconds) {
    var newDate = new Date(this.getTime() + plusSeconds * 1000);
    return newDate;
};

// Subtract date to get days
Date.prototype.subtractBySeconds = function (targetDate) {
    var milis = Math.abs(this - targetDate);
    var days = Math.floor(milis / 1000);
    return days;
};

/*
 * Convert date to JP format date time [ end ]
 */

// trimming space from both side of the string
String.prototype.trim = function () {
    return this.replace(/^\s+|\s+$/g, '');
};

// trimming space from left side of the string
String.prototype.trimLeft = function () {
    return this.replace(/^\s+/, '');
};

// trimming space from right side of the string
String.prototype.trimRight = function () {
    return this.replace(/\s+$/, '');
};

// String: pads left
String.prototype.padLeft = function (padString, length) {
    var str = this;
    while (str.length < length) str = padString + str;
    return str;
};

// String: pads right
String.prototype.padRight = function (padString, length) {
    var str = this;
    while (str.length < length) str = str + padString;
    return str;
};
// Check contain string
String.prototype.contains = function (string) {
    if (this.indexOf(string) != -1) {
        return true;
    }
    return false;
};

// Number: pads left
Number.prototype.padLeft = function (padString, length) {
    var str = this + '';
    return str.padLeft(padString, length);
};

// Number: pads right
Number.prototype.padRight = function (padString, length) {
    var str = this + '';
    return str.padRight(padString, length);
};
// Clear data of array
Array.prototype.clear = function () {
    this.splice(0, this.length);
};

// Function to set position of object to center
jQuery.fn.center = function () {
    this.css('position', 'fixed');

    this.css('top', ($(window).height() - this.height()) / 2 + 'px');
    this.css('left', ($(window).width() - this.width()) / 2 + 'px');

    return this;
};