/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums', 'moment', 'store', 'modules/Modal', 'DOMPurify', 'moment-timezone', 'pnotify.buttons', 'pnotify.confirm'], function(require, Globals, pnotify, Messages, Enums, moment, store, Modal, DOMPurify) {
    'use strict';

    var Utils = {};
    var prevNetworkErrorTime = 0;

    Utils.generatePopover = function(options) {
        if (options.el) {
            var defaultObj = {
                placement: 'auto bottom',
                html: true,
                animation: false,
                container: 'body',
                sanitize: false
            };
            if (options.viewFixedPopover || options.contentClass) {
                defaultObj.template = '<div class="popover ' + (options.viewFixedPopover ? 'fixed-popover' : '') + ' fade bottom"><div class="arrow"></div><h3 class="popover-title"></h3><div class="' + (options.contentClass ? options.contentClass : '') + ' popover-content"></div></div>';
            }
            return options.el.popover(_.extend(defaultObj, options.popoverOptions));
        }
    }

    Utils.getNumberSuffix = function(options) {
        if (options && options.number) {
            var n = options.number,
                s = ["th", "st", "nd", "rd"],
                v = n % 100,
                suffix = (s[(v - 20) % 10] || s[v] || s[0]);
            return n + (options.sup ? '<sup>' + suffix + '</sup>' : suffix);
        }
    }

    Utils.generateUUID = function() {
        var d = new Date().getTime();
        if (window.performance && typeof window.performance.now === "function") {
            d += performance.now(); //use high-precision timer if available
        }
        var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            var r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
        });
        return uuid;
    };
    Utils.getBaseUrl = function(url, noPop) {
        var path = url.replace(/\/[\w-]+.(jsp|html)|\/+$/ig, ''),
            splitPath = path.split("/");
        if (noPop !== true && splitPath && splitPath[splitPath.length - 1] === "n") {
            splitPath.pop();
            return splitPath.join("/");
        }
        return path;
    };
    Utils.getEntityIconPath = function(options) {
        var entityData = options && options.entityData,
            serviceType,
            status,
            typeName,
            iconBasePath = Utils.getBaseUrl(window.location.pathname, true) + Globals.entityImgPath;
        if (entityData) {
            typeName = entityData.typeName;
            serviceType = entityData && entityData.serviceType;
            status = entityData && entityData.status;
        }

        function getImgPath(imageName) {
            return iconBasePath + (Enums.entityStateReadOnly[status] ? "disabled/" + imageName : imageName);
        }

        function getDefaultImgPath() {
            if (entityData.isProcess) {
                if (Enums.entityStateReadOnly[status]) {
                    return iconBasePath + 'disabled/process.png';
                } else {
                    return iconBasePath + 'process.png';
                }
            } else {
                if (Enums.entityStateReadOnly[status]) {
                    return iconBasePath + 'disabled/table.png';
                } else {
                    return iconBasePath + 'table.png';
                }
            }
        }

        if (entityData) {
            if (options.errorUrl) {
                var isErrorInTypeName = (options.errorUrl && options.errorUrl.match("entity-icon/" + typeName + ".png|disabled/" + typeName + ".png") ? true : false);
                if (serviceType && isErrorInTypeName) {
                    var imageName = serviceType + ".png";
                    return getImgPath(imageName);
                } else {
                    return getDefaultImgPath();
                }
            } else if (entityData.typeName) {
                var imageName = entityData.typeName + ".png";
                return getImgPath(imageName);
            } else {
                return getDefaultImgPath();
            }
        }
    }

    pnotify.prototype.options.styling = "fontawesome";
    var notify = function(options) {
        return new pnotify(_.extend({
            icon: true,
            hide: true,
            delay: 3000,
            remove: true,
            buttons: {
                classes: {
                    closer: 'fa fa-times',
                    pin_up: 'fa fa-pause',
                    pin_down: 'fa fa-play'
                }
            }
        }, options));
    }
    Utils.notifyInfo = function(options) {
        notify({
            type: "info",
            text: (options.html ? options.content : _.escape(options.content)) || "Info message."
        });
    };

    Utils.notifyWarn = function(options) {
        notify({
            type: "notice",
            text: (options.html ? options.content : _.escape(options.content)) || "Info message."
        });
    };

    Utils.notifyError = function(options) {
        notify({
            type: "error",
            text: (options.html ? options.content : _.escape(options.content)) || "Error occurred."
        });
    };

    Utils.notifySuccess = function(options) {
        notify({
            type: "success",
            text: (options.html ? options.content : _.escape(options.content)) || "Error occurred."
        });
    };

    Utils.notifyConfirm = function(options) {
        var modal = {};
        if (options && options.modal) {
            var myStack = { "dir1": "down", "dir2": "right", "push": "top", 'modal': true };
            modal['addclass'] = 'stack-modal ' + (options.modalClass ? modalClass : 'width-500');
            modal['stack'] = myStack;
        }
        notify(_.extend({
            title: 'Confirmation',
            hide: false,
            confirm: {
                confirm: true,
                buttons: [{
                        text: options.cancelText || 'Cancel',
                        addClass: 'btn-action btn-md cancel',
                        click: function(notice) {
                            options.cancel(notice);
                            notice.remove();
                        }
                    },
                    {
                        text: options.okText || 'Ok',
                        addClass: 'btn-atlas btn-md ok',
                        click: function(notice) {
                            if (options.ok) {
                                options.ok($.extend({}, notice, {
                                    hideButtonLoader: function() {
                                        notice.container.find("button.ok").hideButtonLoader();
                                    },
                                    showButtonLoader: function() {
                                        notice.container.find("button.ok").showButtonLoader();
                                    }
                                }));
                            }
                            if (options.okShowLoader) {
                                notice.container.find("button.ok").showButtonLoader();
                            }
                            if (options.okCloses !== false) {
                                notice.remove();
                            }
                        }
                    }
                ]
            },
            buttons: {
                closer: false,
                sticker: false
            },
            history: {
                history: false
            }

        }, modal, options)).get().on('pnotify.confirm', function() {
            if (options.ok) {
                options.ok();
            }
        }).on('pnotify.cancel', function() {
            if (options.cancel) {
                options.cancel();
            }
        });
    }
    Utils.defaultErrorHandler = function(model, error, options) {
        var skipDefaultError = null,
            defaultErrorMessage = null,
            isHtml = null;
        if (options) {
            skipDefaultError = options.skipDefaultError;
            defaultErrorMessage = options.defaultErrorMessage;
            isHtml = options.isHtml;
        }
        var redirectToLoginPage = function() {
            Utils.localStorage.setValue("last_ui_load", "v2");
            window.location = 'login.jsp';
        }
        if (error && error.status) {
            if (error.status == 401) {
                redirectToLoginPage();
            } else if (error.status == 419) {
                redirectToLoginPage();
            } else if (error.status == 403) {
                Utils.serverErrorHandler(error, "You are not authorized");
            } else if (error.status == "0" && error.statusText != "abort") {
                var diffTime = (new Date().getTime() - prevNetworkErrorTime);
                if (diffTime > 3000) {
                    prevNetworkErrorTime = new Date().getTime();
                    Utils.notifyError({
                        content: "Network Connection Failure : " +
                            "It seems you are not connected to the internet. Please check your internet connection and try again"
                    });
                }
            } else if (skipDefaultError !== true) {
                Utils.serverErrorHandler(error, defaultErrorMessage, isHtml);
            }
        } else if (skipDefaultError !== true) {
            Utils.serverErrorHandler(error, defaultErrorMessage);
        }
    };
    Utils.serverErrorHandler = function(response, defaultErrorMessage, isHtml) {
        var responseJSON = response ? response.responseJSON : response,
            message = defaultErrorMessage ? defaultErrorMessage : Messages.defaultErrorMessage
        if (response && responseJSON) {
            message = responseJSON.errorMessage || responseJSON.message || responseJSON.error || message
        }
        var existingError = $(".ui-pnotify-container.alert-danger .ui-pnotify-text").text();
        if (existingError !== message) {
            Utils.notifyError({
                html: isHtml,
                content: message
            });
        }
    };
    Utils.cookie = {
        setValue: function(cname, cvalue) {
            document.cookie = cname + "=" + cvalue + "; ";
        },
        getValue: function(findString) {
            var search = findString + "=";
            var ca = document.cookie.split(';');
            for (var i = 0; i < ca.length; i++) {
                var c = ca[i];
                while (c.charAt(0) == ' ') c = c.substring(1);
                if (c.indexOf(name) == 0) {
                    return c.substring(name.length, c.length);
                }
            }
            return "";
        }
    };
    Utils.localStorage = function() {
        this.setValue = function() {
            localStorage.setItem(arguments[0], arguments[1]);
        }
        this.getValue = function(key, value) {
            var keyValue = localStorage.getItem(key);
            if ((!keyValue || keyValue == "undefined") && (value != undefined)) {
                return this.setLocalStorage(key, value);
            } else {
                if (keyValue === "" || keyValue === "undefined" || keyValue === "null") {
                    return null;
                } else {
                    return keyValue;
                }

            }
        }
        this.removeValue = function() {
            localStorage.removeItem(arguments[0]);
        }
        if (typeof(Storage) === "undefined") {
            _.extend(this, Utils.cookie);
            console.log('Sorry! No Web Storage support');
        }
    }
    Utils.localStorage = new Utils.localStorage();

    Utils.setUrl = function(options) {
        if (options) {
            if (options.mergeBrowserUrl) {
                var param = Utils.getUrlState.getQueryParams();
                if (param) {
                    options.urlParams = $.extend(param, options.urlParams);
                }
            }
            if (options.urlParams) {
                var urlParams = "?";
                _.each(options.urlParams, function(value, key, obj) {
                    if (value) {
                        value = encodeURIComponent(String(value));
                        urlParams += key + "=" + value + "&";
                    }
                });
                urlParams = urlParams.slice(0, -1);
                options.url += urlParams;
            }
            if (options.updateTabState) {
                var urlUpdate = {
                    stateChanged: true
                };
                if (Utils.getUrlState.isTagTab(options.url)) {
                    urlUpdate['tagUrl'] = options.url;
                } else if (Utils.getUrlState.isSearchTab(options.url)) {
                    urlUpdate['searchUrl'] = options.url;
                } else if (Utils.getUrlState.isGlossaryTab(options.url)) {
                    urlUpdate['glossaryUrl'] = options.url;
                } else if (Utils.getUrlState.isBMDetailPage(options.url)) {
                    urlUpdate['bmDetailPageUrl'] = options.url;
                    urlUpdate['administratorUrl'] = options.url;
                } else if (Utils.getUrlState.isAdministratorTab(options.url)) {
                    urlUpdate['administratorUrl'] = options.url;
                } else if (Utils.getUrlState.isDebugMetricsTab(options.url)) {
                    urlUpdate['debugMetricsUrl'] = options.url;
                }
                $.extend(Globals.saveApplicationState.tabState, urlUpdate);
            }
            Backbone.history.navigate(options.url, { trigger: options.trigger != undefined ? options.trigger : true });
        }
    };

    Utils.getUrlState = {
        getQueryUrl: function(url) {
            var hashValue = window.location.hash;
            if (url) {
                hashValue = url;
            }
            return {
                firstValue: hashValue.split('/')[1],
                hash: hashValue,
                queyParams: hashValue.split("?"),
                lastValue: hashValue.split('/')[hashValue.split('/').length - 1]
            }
        },
        checkTabUrl: function(options) {
            var url = options && options.url,
                matchString = options && options.matchString,
                quey = this.getQueryUrl(url);
            return quey.firstValue == matchString || quey.queyParams[0] == "#!/" + matchString;
        },
        isInitial: function() {
            return this.getQueryUrl().firstValue == undefined;
        },
        isTagTab: function(url) {
            return this.checkTabUrl({
                url: url,
                matchString: "tag"
            });
        },
        isSearchTab: function(url) {
            return this.checkTabUrl({
                url: url,
                matchString: "search"
            });
        },
        isAdministratorTab: function(url) {
            return this.checkTabUrl({
                url: url,
                matchString: "administrator"
            });
        },
        isBMDetailPage: function(url) {
            var quey = this.getQueryUrl(url);
            return (quey.hash.indexOf("businessMetadata") > -1) ? true : false;
        },
        isDebugMetricsTab: function(url) {
            return this.checkTabUrl({
                url: url,
                matchString: "debugMetrics"
            });
        },
        isGlossaryTab: function(url) {
            return this.checkTabUrl({
                url: url,
                matchString: "glossary"
            });
        },
        isDetailPage: function(url) {
            return this.checkTabUrl({
                url: url,
                matchString: "detailPage"
            });
        },
        getLastValue: function() {
            return this.getQueryUrl().lastValue;
        },
        getFirstValue: function() {
            return this.getQueryUrl().firstValue;
        },
        getQueryParams: function(url) {
            var qs = this.getQueryUrl(url).queyParams[1];
            if (typeof qs == "string") {
                qs = qs.split('+').join(' ');
                var params = {},
                    tokens,
                    re = /[?&]?([^=]+)=([^&]*)/g;
                while (tokens = re.exec(qs)) {
                    params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
                }
                return params;
            }
        },
        getKeyValue: function(key) {
            var paramsObj = this.getQueryParams();
            if (key.length) {
                var values = [];
                _.each(key, function(objKey) {
                    var obj = {};
                    obj[objKey] = paramsObj[objKey]
                    values.push(obj);
                    return values;
                })
            } else {
                return paramsObj[key];
            }
        }
    }
    Utils.getName = function() {
        return Utils.extractKeyValueFromEntity.apply(this, arguments).name;
    }
    Utils.getNameWithProperties = function() {
        return Utils.extractKeyValueFromEntity.apply(this, arguments);
    }
    Utils.extractKeyValueFromEntity = function() {
        var collectionJSON = arguments[0],
            priorityAttribute = arguments[1],
            skipAttribute = arguments[2],
            returnObj = {
                name: '-',
                found: true,
                key: null
            }
        if (collectionJSON) {
            if (collectionJSON.attributes && collectionJSON.attributes[priorityAttribute]) {
                returnObj.name = _.escape(collectionJSON.attributes[priorityAttribute]);
                returnObj.key = priorityAttribute;
                return returnObj;
            }
            if (collectionJSON[priorityAttribute]) {
                returnObj.name = _.escape(collectionJSON[priorityAttribute]);
                returnObj.key = priorityAttribute;
                return returnObj;
            }
            if (collectionJSON.attributes) {
                if (collectionJSON.attributes.name) {
                    returnObj.name = _.escape(collectionJSON.attributes.name);
                    returnObj.key = 'name';
                    return returnObj;
                }
                if (collectionJSON.attributes.displayName) {
                    returnObj.name = _.escape(collectionJSON.attributes.displayName);
                    returnObj.key = 'displayName';
                    return returnObj;
                }
                if (collectionJSON.attributes.qualifiedName) {
                    returnObj.name = _.escape(collectionJSON.attributes.qualifiedName);
                    returnObj.key = 'qualifiedName';
                    return returnObj;
                }
                if (collectionJSON.attributes.displayText) {
                    returnObj.name = _.escape(collectionJSON.attributes.displayText);
                    returnObj.key = 'displayText';
                    return returnObj;
                }
                if (collectionJSON.attributes.guid) {
                    returnObj.name = _.escape(collectionJSON.attributes.guid);
                    returnObj.key = 'guid';
                    return returnObj;
                }
                if (collectionJSON.attributes.id) {
                    if (_.isObject(collectionJSON.attributes.id)) {
                        if (collectionJSON.id.id) {
                            returnObj.name = _.escape(collectionJSON.attributes.id.id);
                        }
                    } else {
                        returnObj.name = _.escape(collectionJSON.attributes.id);
                    }
                    returnObj.key = 'id';
                    return returnObj;
                }
            }
            if (collectionJSON.name) {
                returnObj.name = _.escape(collectionJSON.name);
                returnObj.key = 'name';
                return returnObj;
            }
            if (collectionJSON.displayName) {
                returnObj.name = _.escape(collectionJSON.displayName);
                returnObj.key = 'displayName';
                return returnObj;
            }
            if (collectionJSON.qualifiedName) {
                returnObj.name = _.escape(collectionJSON.qualifiedName);
                returnObj.key = 'qualifiedName';
                return returnObj;
            }
            if (collectionJSON.displayText) {
                returnObj.name = _.escape(collectionJSON.displayText);
                returnObj.key = 'displayText';
                return returnObj;
            }
            if (collectionJSON.guid) {
                returnObj.name = _.escape(collectionJSON.guid);
                returnObj.key = 'guid';
                return returnObj;
            }
            if (collectionJSON.id) {
                if (_.isObject(collectionJSON.id)) {
                    if (collectionJSON.id.id) {
                        returnObj.name = _.escape(collectionJSON.id.id);
                    }
                } else {
                    returnObj.name = _.escape(collectionJSON.id);
                }
                returnObj.key = 'id';
                return returnObj;
            }
        }
        returnObj.found = false;
        if (skipAttribute && returnObj.key == skipAttribute) {
            return {
                name: '-',
                found: true,
                key: null
            }
        } else {
            return returnObj;
        }

    }

    Utils.backButtonClick = function() {
        var queryParams = Utils.getUrlState.getQueryParams(),
            urlPath = "searchUrl";
        if (queryParams && queryParams.from) {
            if (queryParams.from == "classification") {
                urlPath = "tagUrl";
            } else if (queryParams.from == "glossary") {
                urlPath = "glossaryUrl";
            } else if (queryParams.from == "bm") {
                urlPath = "administratorUrl";
            }
        }
        Utils.setUrl({
            url: Globals.saveApplicationState.tabState[urlPath],
            mergeBrowserUrl: false,
            trigger: true,
            updateTabState: true
        });
    }

    Utils.showTitleLoader = function(loaderEl, titleBoxEl) {
        loaderEl.css ? loaderEl.css({
            'display': 'block',
            'position': 'relative',
            'height': '85px',
            'marginTop': '85px',
            'marginLeft': '50%',
            'left': '0%'
        }) : null;
        titleBoxEl.hide ? titleBoxEl.hide() : null;
    }
    Utils.hideTitleLoader = function(loaderEl, titleBoxEl) {
        loaderEl.hide ? loaderEl.hide() : null;
        titleBoxEl.fadeIn ? titleBoxEl.fadeIn() : null;
    }
    Utils.findAndMergeRefEntity = function(options) {
        var attributeObject = options.attributeObject,
            referredEntities = options.referredEntities
        var mergeObject = function(obj) {
            if (obj) {
                if (obj.attributes) {
                    Utils.findAndMergeRefEntity({
                        "attributeObject": obj.attributes,
                        "referredEntities": referredEntities
                    });
                } else if (referredEntities[obj.guid]) {
                    _.extend(obj, referredEntities[obj.guid]);
                }
            }
        }
        if (attributeObject && referredEntities) {
            _.each(attributeObject, function(obj, key) {
                if (_.isObject(obj)) {
                    if (_.isArray(obj)) {
                        _.each(obj, function(value) {
                            mergeObject(value);
                        });
                    } else {
                        mergeObject(obj);
                    }
                }
            });
        }
    }

    Utils.findAndMergeRelationShipEntity = function(options) {
        var attributeObject = options.attributeObject,
            relationshipAttributes = options.relationshipAttributes;
        _.each(attributeObject, function(val, key) {
            var attributVal = val;
            if (relationshipAttributes && relationshipAttributes[key]) {
                var relationShipVal = relationshipAttributes[key];
                if (_.isObject(val)) {
                    if (_.isArray(val)) {
                        _.each(val, function(attr) {
                            if (attr && attr.attributes === undefined) {
                                var entityFound = _.find(relationShipVal, { guid: attr.guid });
                                if (entityFound) {
                                    attr.attributes = _.omit(entityFound, 'typeName', 'guid', 'entityStatus');
                                    attr.status = entityFound.entityStatus;
                                }
                            }
                        });
                    } else if (relationShipVal && val.attributes === undefined) {
                        val.attributes = _.omit(relationShipVal, 'typeName', 'guid', 'entityStatus');
                        val.status = relationShipVal.entityStatus;
                    }
                }
            }
        })
    }

    Utils.getNestedSuperTypes = function(options) {
        var data = options.data,
            collection = options.collection,
            superTypes = [];

        var getData = function(data, collection) {
            if (data) {
                superTypes = superTypes.concat(data.superTypes);
                if (data.superTypes && data.superTypes.length) {
                    _.each(data.superTypes, function(superTypeName) {
                        if (collection.fullCollection) {
                            var collectionData = collection.fullCollection.findWhere({ name: superTypeName }).toJSON();
                        } else {
                            var collectionData = collection.findWhere({ name: superTypeName }).toJSON();
                        }
                        getData(collectionData, collection);
                    });
                }
            }
        }
        getData(data, collection);
        return _.uniq(superTypes);
    }
    Utils.getNestedSuperTypeObj = function(options) {
        var mainData = options.data,
            collection = options.collection,
            attrMerge = options.attrMerge,
            seperateRelatioshipAttr = options.seperateRelatioshipAttr || false,
            mergeRelationAttributes = options.mergeRelationAttributes || (seperateRelatioshipAttr ? false : true);

        if (mergeRelationAttributes && seperateRelatioshipAttr) {
            throw "Both mergeRelationAttributes & seperateRelatioshipAttr cannot be true!"
        }
        var attributeDefs = {};
        if (attrMerge && !seperateRelatioshipAttr) {
            attributeDefs = [];
        } else if (options.attrMerge && seperateRelatioshipAttr) {
            attributeDefs = {
                attributeDefs: [],
                relationshipAttributeDefs: []
            }
        }
        var getRelationshipAttributeDef = function(data) {
            return _.filter(
                data.relationshipAttributeDefs,
                function(obj, key) {
                    return obj;
                })
        }
        var getData = function(data, collection) {
            if (options.attrMerge) {
                if (seperateRelatioshipAttr) {
                    attributeDefs.attributeDefs = attributeDefs.attributeDefs.concat(data.attributeDefs);
                    attributeDefs.relationshipAttributeDefs = attributeDefs.relationshipAttributeDefs.concat(getRelationshipAttributeDef(data));
                } else {
                    attributeDefs = attributeDefs.concat(data.attributeDefs);
                    if (mergeRelationAttributes) {
                        attributeDefs = attributeDefs.concat(getRelationshipAttributeDef(data));
                    }
                }
            } else {
                if (attributeDefs[data.name]) {
                    attributeDefs[data.name] = _.toArrayifObject(attributeDefs[data.name]).concat(data.attributeDefs);
                } else {
                    if (seperateRelatioshipAttr) {
                        attributeDefs[data.name] = {
                            attributeDefs: data.attributeDefs,
                            relationshipAttributeDefs: data.relationshipAttributeDefs
                        };
                    } else {
                        attributeDefs[data.name] = data.attributeDefs;
                        if (mergeRelationAttributes) {
                            attributeDefs[data.name] = _.toArrayifObject(attributeDefs[data.name]).concat(getRelationshipAttributeDef(data));
                        }
                    }
                }
            }
            if (data.superTypes && data.superTypes.length) {
                _.each(data.superTypes, function(superTypeName) {
                    if (collection.fullCollection) {
                        var collectionData = collection.fullCollection.findWhere({ name: superTypeName });
                    } else {
                        var collectionData = collection.findWhere({ name: superTypeName });
                    }
                    collectionData = collectionData && collectionData.toJSON ? collectionData.toJSON() : collectionData;
                    if (collectionData) {
                        return getData(collectionData, collection);
                    } else {
                        return;
                    }
                });
            }
        }
        getData(mainData, collection);
        if (attrMerge) {
            if (seperateRelatioshipAttr) {
                attributeDefs = {
                    attributeDefs: _.uniq(_.sortBy(attributeDefs.attributeDefs, 'name'), true, function(obj) {
                        return obj.name
                    }),
                    relationshipAttributeDefs: _.uniq(_.sortBy(attributeDefs.relationshipAttributeDefs, 'name'), true, function(obj) {
                        return (obj.name + obj.relationshipTypeName)
                    })
                }
            } else {
                attributeDefs = _.uniq(_.sortBy(attributeDefs, 'name'), true, function(obj) {
                    if (obj.relationshipTypeName) {
                        return (obj.name + obj.relationshipTypeName)
                    } else {
                        return (obj.name)
                    }
                });
            }
        }
        return attributeDefs;
    }

    Utils.getProfileTabType = function(profileData, skipData) {
        var parseData = profileData.distributionData;
        if (_.isString(parseData)) {
            parseData = JSON.parse(parseData);
        }
        var createData = function(type) {
            var orderValue = [],
                sort = false;
            if (type === "date") {
                var dateObj = {};
                _.keys(parseData).map(function(key) {
                    var splitValue = key.split(":");
                    if (!dateObj[splitValue[0]]) {
                        dateObj[splitValue[0]] = {
                            value: splitValue[0],
                            monthlyCounts: {},
                            totalCount: 0 // use when count is null
                        }
                    }
                    if (dateObj[splitValue[0]] && splitValue[1] == "count") {
                        dateObj[splitValue[0]].count = parseData[key];
                    }
                    if (dateObj[splitValue[0]] && splitValue[1] !== "count") {
                        dateObj[splitValue[0]].monthlyCounts[splitValue[1]] = parseData[key];
                        if (!dateObj[splitValue[0]].count) {
                            dateObj[splitValue[0]].totalCount += parseData[key]
                        }
                    }
                });
                return _.toArray(dateObj).map(function(obj) {
                    if (!obj.count && obj.totalCount) {
                        obj.count = obj.totalCount
                    }
                    return obj
                });
            } else {
                var data = [];
                if (profileData.distributionKeyOrder) {
                    orderValue = profileData.distributionKeyOrder;
                } else {
                    sort = true;
                    orderValue = _.keys(parseData);
                }
                _.each(orderValue, function(key) {
                    if (parseData[key]) {
                        data.push({
                            value: key,
                            count: parseData[key]
                        });
                    }
                });
                if (sort) {
                    data = _.sortBy(data, function(o) {
                        return o.value.toLowerCase()
                    });
                }
                return data;
            }
        }
        if (profileData && profileData.distributionType) {
            if (profileData.distributionType === "count-frequency") {
                return {
                    type: "string",
                    label: Enums.profileTabType[profileData.distributionType],
                    actualObj: !skipData ? createData("string") : null,
                    xAxisLabel: "FREQUENCY",
                    yAxisLabel: "COUNT"
                }
            } else if (profileData.distributionType === "decile-frequency") {
                return {
                    label: Enums.profileTabType[profileData.distributionType],
                    type: "numeric",
                    xAxisLabel: "DECILE RANGE",
                    actualObj: !skipData ? createData("numeric") : null,
                    yAxisLabel: "FREQUENCY"
                }
            } else if (profileData.distributionType === "annual") {
                return {
                    label: Enums.profileTabType[profileData.distributionType],
                    type: "date",
                    xAxisLabel: "",
                    actualObj: !skipData ? createData("date") : null,
                    yAxisLabel: "COUNT"
                }
            }
        }
    }

    Utils.isUrl = function(url) {
        var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
        return regexp.test(url);
    }

    Utils.JSONPrettyPrint = function(obj, getValue) {
        var replacer = function(match, pIndent, pKey, pVal, pEnd) {
                var key = '<span class=json-key>';
                var val = '<span class=json-value>';
                var str = '<span class=json-string>';
                var r = pIndent || '';
                if (pKey)
                    r = r + key + pKey.replace(/[": ]/g, '') + '</span>: ';
                if (pVal)
                    r = r + (pVal[0] == '"' ? str : val) + getValue(pVal) + '</span>';
                return r + (pEnd || '');
            },
            jsonLine = /^( *)("[\w]+": )?("[^"]*"|[\w.+-]*)?([,[{])?$/mg;
        if (obj && _.isObject(obj)) {
            return JSON.stringify(obj, null, 3)
                .replace(/&/g, '&amp;').replace(/\\"/g, '&quot;')
                .replace(/</g, '&lt;').replace(/>/g, '&gt;')
                .replace(jsonLine, replacer);
        } else {
            return {};
        }
    };

    $.fn.toggleAttribute = function(attributeName, firstString, secondString) {
        if (this.attr(attributeName) == firstString) {
            this.attr(attributeName, secondString);
        } else {
            this.attr(attributeName, firstString);
        }
    }

    Utils.millisecondsToTime = function(duration) {
        var milliseconds = parseInt((duration % 1000) / 100),
            seconds = parseInt((duration / 1000) % 60),
            minutes = parseInt((duration / (1000 * 60)) % 60),
            hours = parseInt((duration / (1000 * 60 * 60)) % 24);

        hours = (hours < 10) ? "0" + hours : hours;
        minutes = (minutes < 10) ? "0" + minutes : minutes;
        seconds = (seconds < 10) ? "0" + seconds : seconds;

        return hours + ":" + minutes + ":" + seconds + "." + milliseconds;
    }
    Utils.togglePropertyRelationshipTableEmptyValues = function(object) {
        var inputSelector = object.inputType,
            tableEl = object.tableEl;
        if (inputSelector.prop('checked') == true) {
            tableEl.removeClass('hide-empty-value');
        } else {
            tableEl.addClass('hide-empty-value');
        }
    }
    $.fn.showButtonLoader = function() {
        $(this).attr("disabled", "true").addClass('button-loader');
        $(this).siblings("button.cancel").prop("disabled", true);
    }
    $.fn.hideButtonLoader = function() {
        $(this).removeClass('button-loader').removeAttr("disabled");
        $(this).siblings("button.cancel").prop("disabled", false);
    }
    Utils.formatDate = function(options) {
        var dateValue = null,
            dateFormat = Globals.dateTimeFormat,
            isValidDate = false;
        if (options && options.date) {
            dateValue = options.date;
            if (dateValue !== "-") {
                dateValue = parseInt(dateValue);
                if (_.isNaN(dateValue)) {
                    dateValue = options.date;
                }
                dateValue = moment(dateValue);
                if (dateValue._isValid) {
                    isValidDate = true;
                    dateValue = dateValue.format(dateFormat);
                }
            }
        }
        if (dateValue !== "-") {
            if (isValidDate === false && options && options.defaultDate !== false) {
                dateValue = moment().format(dateFormat);
            }
            if (Globals.isTimezoneFormatEnabled) {
                if (!options || options && options.zone !== false) {
                    dateValue += " (" + moment.tz(moment.tz.guess()).zoneAbbr() + ")";
                }
            }
        }
        return dateValue;
    }
    //-----------------------------------------DOMPurify--------------------------------------
    //This below function expects string that needs to be sanitize against XSS attack.
    Utils.sanitizeHtmlContent = function(string) {
        if (string) {
            return DOMPurify.sanitize(string, { FORBID_TAGS: ['img', 'script', 'iframe', 'embed', 'svg', 'meta'], ALLOWED_ATTR: ['target', 'href'] });
        }
    }
    //----------------------------------------------------------------------------------------
    //------------------------------------------------idleTimeout-----------------------------
    $.fn.idleTimeout = function(userRuntimeConfig) {

        //##############################
        //## Public Configuration Variables
        //##############################
        var defaultConfig = {
                redirectUrl: Utils.getBaseUrl(window.location.pathname) + '/index.html?action=timeout', // redirect to this url on logout. Set to "redirectUrl: false" to disable redirect

                // idle settings
                idleTimeLimit: Globals.idealTimeoutSeconds, // 'No activity' time limit in seconds. 1200 = 20 Minutes
                idleCheckHeartbeat: 2, // Frequency to check for idle timeouts in seconds

                // optional custom callback to perform before logout
                customCallback: false, // set to false for no customCallback
                // customCallback:    function () {    // define optional custom js function
                // perform custom action before logout
                // },

                // configure which activity events to detect
                // http://www.quirksmode.org/dom/events/
                // https://developer.mozilla.org/en-US/docs/Web/Reference/Events
                activityEvents: 'click keypress scroll wheel mousewheel mousemove', // separate each event with a space

                // warning dialog box configuration
                enableDialog: true, // set to false for logout without warning dialog
                dialogDisplayLimit: 10, // Time to display the warning dialog before logout (and optional callback) in seconds. 180 = 3 Minutes
                dialogTitle: 'Your session is about to expire!', // also displays on browser title bar
                dialogText: 'Your session is about to expire.',
                dialogTimeRemaining: 'You will be logged out in ',
                dialogStayLoggedInButton: 'Stay Logged In',
                dialogLogOutNowButton: 'Logout',

                // error message if https://github.com/marcuswestin/store.js not enabled
                errorAlertMessage: 'Please disable "Private Mode", or upgrade to a modern browser. Or perhaps a dependent file missing. Please see: https://github.com/marcuswestin/store.js',

                // server-side session keep-alive timer
                sessionKeepAliveTimer: 600, // ping the server at this interval in seconds. 600 = 10 Minutes. Set to false to disable pings
                sessionKeepAliveUrl: window.location.href // set URL to ping - does not apply if sessionKeepAliveTimer: false
            },

            //##############################
            //## Private Variables
            //##############################
            currentConfig = $.extend(defaultConfig, userRuntimeConfig), // merge default and user runtime configuration
            origTitle = document.title, // save original browser title
            activityDetector,
            startKeepSessionAlive, stopKeepSessionAlive, keepSession, keepAlivePing, // session keep alive
            idleTimer, remainingTimer, checkIdleTimeout, checkIdleTimeoutLoop, startIdleTimer, stopIdleTimer, // idle timer
            openWarningDialog, dialogTimer, checkDialogTimeout, startDialogTimer, stopDialogTimer, isDialogOpen, destroyWarningDialog, countdownDisplay, // warning dialog
            logoutUser;

        //##############################
        //## Public Functions
        //##############################
        // trigger a manual user logout
        // use this code snippet on your site's Logout button: $.fn.idleTimeout().logout();
        this.logout = function() {
            store.set('idleTimerLoggedOut', true);
        };

        //##############################
        //## Private Functions
        //##############################

        //----------- KEEP SESSION ALIVE FUNCTIONS --------------//
        startKeepSessionAlive = function() {

            keepSession = function() {
                $.get(currentConfig.sessionKeepAliveUrl);
                startKeepSessionAlive();
            };

            keepAlivePing = setTimeout(keepSession, (currentConfig.sessionKeepAliveTimer * 1000));
        };

        stopKeepSessionAlive = function() {
            clearTimeout(keepAlivePing);
        };

        //----------- ACTIVITY DETECTION FUNCTION --------------//
        activityDetector = function() {

            $('body').on(currentConfig.activityEvents, function() {

                if (!currentConfig.enableDialog || (currentConfig.enableDialog && isDialogOpen() !== true)) {
                    startIdleTimer();
                    $('#activity').effect('shake'); // added for demonstration page
                }
            });
        };

        //----------- IDLE TIMER FUNCTIONS --------------//
        checkIdleTimeout = function() {

            var timeIdleTimeout = (store.get('idleTimerLastActivity') + (currentConfig.idleTimeLimit * 1000));

            if ($.now() > timeIdleTimeout) {

                if (!currentConfig.enableDialog) { // warning dialog is disabled
                    logoutUser(); // immediately log out user when user is idle for idleTimeLimit
                } else if (currentConfig.enableDialog && isDialogOpen() !== true) {
                    openWarningDialog();
                    startDialogTimer(); // start timing the warning dialog
                }
            } else if (store.get('idleTimerLoggedOut') === true) { //a 'manual' user logout?
                logoutUser();
            } else {

                if (currentConfig.enableDialog && isDialogOpen() === true) {
                    destroyWarningDialog();
                    stopDialogTimer();
                }
            }
        };

        startIdleTimer = function() {
            stopIdleTimer();
            store.set('idleTimerLastActivity', $.now());
            checkIdleTimeoutLoop();
        };

        checkIdleTimeoutLoop = function() {
            checkIdleTimeout();
            idleTimer = setTimeout(checkIdleTimeoutLoop, (currentConfig.idleCheckHeartbeat * 1000));
        };

        stopIdleTimer = function() {
            clearTimeout(idleTimer);
        };

        //----------- WARNING DIALOG FUNCTIONS --------------//
        openWarningDialog = function() {


            var dialogContent = "<div id='idletimer_warning_dialog'><p>" + currentConfig.dialogText + "</p><p style='display:inline'>" + currentConfig.dialogTimeRemaining + ": <div style='display:inline' id='countdownDisplay'></div> secs.</p></div>";

            var that = this,
                modalObj = {
                    title: currentConfig.dialogTitle,
                    htmlContent: dialogContent,
                    okText: "Stay Signed-in",
                    cancelText: 'Logout',
                    mainClass: 'modal-lg',
                    allowCancel: true,
                    okCloses: false,
                    escape: false,
                    cancellable: true,
                    width: "500px",
                    mainClass: "ideal-timeout"
                };
            var modal = new Modal(modalObj);
            modal.open();
            modal.on('ok', function() {
                if (userRuntimeConfig && userRuntimeConfig.onModalKeepAlive) {
                    userRuntimeConfig.onModalKeepAlive(); //hit session API
                }
                destroyWarningDialog();
                modal.close();
                stopDialogTimer();
                startIdleTimer();
            });
            modal.on('closeModal', function() {
                logoutUser();
            });

            countdownDisplay();

            // document.title = currentConfig.dialogTitle;

            if (currentConfig.sessionKeepAliveTimer) {
                stopKeepSessionAlive();
            }
        };

        checkDialogTimeout = function() {
            var timeDialogTimeout = (store.get('idleTimerLastActivity') + (currentConfig.idleTimeLimit * 1000) + (currentConfig.dialogDisplayLimit * 1000));

            if (($.now() > timeDialogTimeout) || (store.get('idleTimerLoggedOut') === true)) {
                logoutUser();
            }
        };

        startDialogTimer = function() {
            dialogTimer = setInterval(checkDialogTimeout, (currentConfig.idleCheckHeartbeat * 1000));
        };

        stopDialogTimer = function() {
            clearInterval(dialogTimer);
            clearInterval(remainingTimer);
        };

        isDialogOpen = function() {
            var dialogOpen = $("#idletimer_warning_dialog").is(":visible");

            if (dialogOpen === true) {
                return true;
            }
            return false;
        };

        destroyWarningDialog = function() {
            if (currentConfig.sessionKeepAliveTimer) {
                startKeepSessionAlive();
            }
        };

        countdownDisplay = function() {
            var dialogDisplaySeconds = currentConfig.dialogDisplayLimit,
                mins, secs;

            remainingTimer = setInterval(function() {
                mins = Math.floor(dialogDisplaySeconds / 60); // minutes
                if (mins < 10) { mins = '0' + mins; }
                secs = dialogDisplaySeconds - (mins * 60); // seconds
                if (secs < 10) { secs = '0' + secs; }
                $('#countdownDisplay').html(mins + ':' + secs);
                dialogDisplaySeconds -= 1;
            }, 1000);
        };

        //----------- LOGOUT USER FUNCTION --------------//
        logoutUser = function() {
            store.set('idleTimerLoggedOut', true);

            if (currentConfig.sessionKeepAliveTimer) {
                stopKeepSessionAlive();
            }

            if (currentConfig.customCallback) {
                currentConfig.customCallback();
            }

            if (currentConfig.redirectUrl) {
                window.location.href = currentConfig.redirectUrl;
            }
        };

        //###############################
        // Build & Return the instance of the item as a plugin
        // This is your construct.
        //###############################
        return this.each(function() {

            if (store.enabled) {

                store.set('idleTimerLastActivity', $.now());
                store.set('idleTimerLoggedOut', false);

                activityDetector();

                if (currentConfig.sessionKeepAliveTimer) {
                    startKeepSessionAlive();
                }

                startIdleTimer();

            } else {
                alert(currentConfig.errorAlertMessage);
            }

        });
    };

    //------------------------------------------------
    return Utils;
});
