(function () {
    "use strict";

    angular.module('hip').component('adminNavBar', {
        templateUrl: '/components/AdminNavBar/Template.html',
        bindings: {
            selectedItem: '<'
        },
        controller: function () { }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('assetInputConfiguration', {
        templateUrl: '/components/AssetInputConfiguration/Template.html',
        bindings: {
            assetTypeId: '=',
            showOpHoursGraph: '=',
            tags: '=',
            m5AssetTypes: '=',
            m5TrackerConfigurations: '=',
            inputs: '='
        },
        controller: function ($scope, $q, m5Assets, assetInputConfigurations) {
            var self = this;
            this.inputDefinitions = [];
            this.loadingInputs = false;
            self.adminTags = [];
            //get all tags used in roles to pass to the tags controller
            assetInputConfigurations.tags().then(function (tagList) {
                self.adminTags = tagList;
            });

            $scope.$watch('$ctrl.assetTypeId', function (newValue, oldValue) {
                if (newValue) {
                    if (oldValue) {
                        self.inputs = [];
                    }
                    self.getAvailableInputs();
                }
            });

            this.getAvailableInputs = function () {
                self.loadingInputs = true;
                var analogInputReq = m5Assets.listAnalogInputDefinitions(self.assetTypeId);
                var digitalInputReq = m5Assets.listDigitalInputDefinitions(self.assetTypeId);
                var counterInputReq = m5Assets.listCounterInputDefinitions(self.assetTypeId);

                $q.all([analogInputReq, digitalInputReq, counterInputReq]).then(function (results) {
                    self.inputDefinitions = [];

                    results[0].forEach(function (input) {
                        var existingInput = self.inputs.find(function (i) {
                            return i.InputType === 0 && i.InputDefinitionId === input.Id;
                        });

                        if (existingInput) {
                            existingInput.isEnabled = true;
                        } else {
                            self.inputs.push({ InputType: 0, InputDefinitionId: input.Id, Name: input.Name });
                        }
                        input.InputType = 0;
                        self.inputDefinitions.push(input);
                    });

                    results[1].forEach(function (input) {
                        var existingInput = self.inputs.find(function (i) {
                            return i.InputType === 1 && i.InputDefinitionId === input.Id;
                        });

                        if (existingInput) {
                            existingInput.isEnabled = true;
                        } else {
                            self.inputs.push({ InputType: 1, InputDefinitionId: input.Id, Name: input.Name});
                        }
                        input.InputType = 1;
                        self.inputDefinitions.push(input);
                    });

                    results[2].forEach(function (input) {
                        var existingInput = self.inputs.find(function (i) {
                            return i.InputType === 2 && i.InputDefinitionId === input.Id;
                        });

                        if (existingInput) {
                            existingInput.isEnabled = true;
                        } else {
                            self.inputs.push({ InputType: 2, InputDefinitionId: input.Id, Name: input.Name });
                        }
                        input.InputType = 2;
                        self.inputDefinitions.push(input);
                    });

                    self.loadingInputs = false;
                });
            };

            this.getInputName = function (input) {
                var inputDefinition = self.inputDefinitions.find(function (def) {
                    return def.Id === input.InputDefinitionId && def.InputType === input.InputType;
                });
                if (inputDefinition) return inputDefinition.Name;
                else return 'Loading...';
            };

            this.getInputType = function (input) {
                var inputTypes = ['Analog', 'Digital', 'Counter'];
                return inputTypes[input.InputType];
            };

            this.isInputDigital = function (input) {
                return input.InputType === 1;
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('auditEntryList', {
        templateUrl: '/components/AuditEntryList/Template.html',
        bindings: {
            auditEntries: '='
        },
        controller: function ($attrs) {
            this.visible = ($attrs.visibleInitially || "true") === "true";
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('bipForm', {
        templateUrl: '/components/BIPForm/Template.html',
        bindings: {
            name: '=',
            database: '=',
            tableName: '=',
            hasGeometry: '=',
            hasMultimedia: '=',
            icon: '=',
            formInputs: '=',
            formValidationRules: '=',
            sections: '=',
            sectionId: '=',
            formId: '=',
            save: '&',
            cancel: '&',
            formGroupings: '=',
            notGrouped: '=',
            allowDatabaseChange: '='
        },
        controller: function ($location, rammMeta, formGroupings, formInputs, $mdDialog) {
            var self = this;
            this.databases = [];

            rammMeta.databases().then(function (databases) {
                Array.prototype.push.apply(self.databases, databases.map(function (database) { return database.DatabaseDescription; }));
            });
            this.sortableOptions = {
                placeholder: "input",
                connectWith: ".input-table"
            };
            this.update = function (formInput) {
                if (!formInput.FormInputValues) formInput.FormInputValues = [];
                return rammMeta.lookup(self.database, self.tableName, formInput.ColumnName).then(function (data) {
                    for (var i = formInput.FormInputValues.length -1; i >= 0; i--) {
                        if (!data.find(function (d) { return d.Key === formInput.FormInputValues[i].Value }))
                            formInput.FormInputValues.splice(i, 1);
                    }
                    data.forEach(function (d) {
                        var existing = formInput.FormInputValues.find(function (fvi) { return fvi.Value === d.LookupKey });
                        if (existing) {
                            existing.Text = d.LookupValue;
                            existing.Enabled = d.IsActive;
                            //existing.FormInputID = undefined;
                        }
                        else
                            formInput.FormInputValues.push({ Value: d.LookupKey, Text: d.LookupValue, Enabled: d.IsActive });

                    });
                    if (!self.allowDatabaseChange)
                        formInputs.updateValues(formInput.ID, formInput.FormInputValues);
                })
            }

            this.updateLookups = function () {
                var proms = [];
                $mdDialog.show({
                    controller: function DialogController($scope, $mdDialog) {
                    },
                    template:
                    '<md-dialog aria-label="Changing Database">' +
                    '        <md-toolbar>' +
                    '            <div class="md-toolbar-tools">' +
                    '                <h2>Changing Database</h2>' +
                    '                <span flex></span>' +
                    '            </div>' +
                    '        </md-toolbar>' +
                    '    ' +
                    '       <md-dialog-content>' +
                    '            <div class="map-overlay loading-overlay">' +
                    '                <div class="loading">' +
                    '                    <div class="loading-bar"></div>' +
                    '                    <div class="loading-bar"></div>' +
                    '                    <div class="loading-bar"></div>' +
                    '                    <div class="loading-bar"></div>' +
                    '                </div>' +
                    '            </div>' +
                    '        </md-dialog-content>' +
                    '</md-dialog>',
                    parent: angular.element(document.body),
                    clickOutsideToClose: false,
                });
                [].concat.apply(self.formInputs,self.formGroupings.map(function (fg) { return fg.FormInputs })).forEach(function (fi) { if(fi.LookupColumn) proms.push(self.update(fi)); })
                Promise.all(proms).then(function () { $mdDialog.hide(); })
            }

            this.saveInputValues = function (formInput) {
                formInputs.updateValues(formInput.ID, formInput.FormInputValues);
            }
            this.addGrouping = function () {
                var grouping = { FormInputs: [], FormID: self.formId }
                self.formGroupings.push(grouping);
                /*formGroupings.create(grouping).then(function (id) {
                    grouping.ID = id;
                })*/
            }
            this.deleteGrouping = function (index, grouping) {
                self.notGrouped = self.notGrouped.concat(grouping.FormInputs);
                self.formGroupings.splice(index, 1)
                /*grouping.FormInputs.forEach(function (fi) {
                    fi.FormInputID = null;
                })
                formGroupings.delete(grouping.ID);*/
            }

            this.addRule = function () {
                $location.path('Forms/' + self.formId + '/Validation');
            }

            this.editRule = function (validationRuleId) {
                $location.path('Forms/' + self.formId + '/Validation/' + validationRuleId);
            }
            this.copyRule = function (validationRuleId) {
                $location.path('Forms/' + self.formId + '/Validation/' + validationRuleId +'/Copy');
            }
        }
    });
})();
(function () {
    "use strict";

    angular.module("hip").component("bipHelp", {
        templateUrl: '/components/BIPHelp/Template.html',
        bindings: {
            id: '=',
            title: '=',
            description: '=',
            blobId: '=',
            tags: '=',
            groupingId: '=',
            groupings: '=',
            file: '=',
            uploading: '=',
            progress: '=',
            contentType: '=',
            contentTypes: '=',
            processUrl: '='
        },
        controller: function (blobStorageAccess, helpItems) {
            var self = this;
            this.files = [];
            self.adminTags = [];
            //get all tags used in roles to pass to the tags controller
            helpItems.tags().then(function (tagList) {
                self.adminTags = tagList;
            });

            self.fileChanged = function (element) {
                self.file = element.files[0];
            }
            blobStorageAccess.getHelpKey().then(function (key) {
                self.key = key;
            })
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('blobSelector', {
        templateUrl: '/components/BlobSelector/Template.html',
        bindings: {
            blobId: '=',
            onUpdate: '&'
        },
        controller: function (blobs, $attrs) {
            var self = this;
            this.title = $attrs.title || 'Select file';
            this.format = $attrs.format || '.png';
            self.setSource = function (element) {
                if (element.files.length === 0) {
                    blobId = undefined;
                    return;
                }

                self.uploading = true;
                var file = element.files[0];
                blobs.upload(file, file.name).then(function (id) {
                    self.blobId = id;
                    self.uploading = false;
                    self.onUpdate({ blobId: id });
                });
            };
        }
    })
})();
(function () {
    "use strict";

    angular.module('hip').component('colourSelector', {
        templateUrl: '/components/ColourSelector/Template.html',
        bindings: {
            colour: '=',
            defaultColour: '='
        },
        controller: function ($scope) {
            var self = this;

            $scope.$on('addPicker', function (ngRepeatFinishedEvent, element) {
                $(element).find('.colour-picker').spectrum({
                    replacerClassName: 'colour-dot',
                    containerClassName: 'colour-window',
                    preferredFormat: "name",
                    showPaletteOnly: true,
                    togglePaletteOnly: true,
                    togglePaletteMoreText: 'Advanced',
                    togglePaletteLessText: 'Simple',
                    color: self.colour || self.defaultColour || 'rebeccapurple',
                    palette: [
                        // Red 
                        ["#B71C1C", "#C62828", "#D32F2F", "#E53935", "#F44336", "#EF5350", "#E57373", "#EF9A9A", "#FFCDD2", "#FFEBEE"],
                        // Pink
                        ["#880E4F", "#AD1457", "#C2185B", "#D81B60", "#E91E63", "#EC407A", "#F06292", "#F48FB1", "#F8BBD0", "#FCE4EC"],
                        // Purple
                        ["#4A148C", "#6A1B9A", "#7B1FA2", "#8E24AA", "#9C27B0", "#AB47BC", "#BA68C8", "#CE93D8", "#E1BEE7", "#F3E5F5"],
                        // Deep Purple
                        ["#311B92", "#4527A0", "#512DA8", "#5E35B1", "#673AB7", "#7E57C2", "#9575CD", "#B39DDB", "#D1C4E9", "#EDE7F6"],
                        // Indigo
                        ["#1A237E", "#283593", "#303F9F", "#3949AB", "#3F51B5", "#5C6BC0", "#7986CB", "#9FA8DA", "#C5CAE9", "#E8EAF6"],
                        // Blue
                        ["#0D47A1", "#1565C0", "#1976D2", "#1E88E5", "#2196F3", "#42A5F5", "#64B5F6", "#90CAF9", "#BBDEFB", "#E3F2FD"],
                        // Light Blue
                        ["#01579B", "#0277BD", "#0288D1", "#039BE5", "#03A9F4", "#29B6F6", "#4FC3F7", "#81D4FA", "#B3E5FC", "#E1F5FE"],
                        // Cyan
                        ["#006064", "#00838F", "#0097A7", "#00ACC1", "#00BCD4", "#26C6DA", "#4DD0E1", "#80DEEA", "#B2EBF2", "#E0F7FA"],
                        // Teal
                        ["#004D40", "#00695C", "#00796B", "#00897B", "#009688", "#26A69A", "#4DB6AC", "#80CBC4", "#B2DFDB", "#E0F2F1"],
                        // Green
                        ["#1B5E20", "#2E7D32", "#388E3C", "#43A047", "#4CAF50", "#66BB6A", "#81C784", "#A5D6A7", "#C8E6C9", "#E8F5E9"],
                        // Light Green
                        ["#33691E", "#558B2F", "#689F38", "#7CB342", "#8BC34A", "#9CCC65", "#AED581", "#C5E1A5", "#DCEDC8", "#F1F8E9"],
                        // Lime
                        ["#827717", "#9E9D24", "#AFB42B", "#C0CA33", "#CDDC39", "#D4E157", "#DCE775", "#E6EE9C", "#F0F4C3", "#F9FBE7"],
                        // Yellow
                        ["#F57F17", "#F9A825", "#FBC02D", "#FDD835", "#FFEB3B", "#FFEE58", "#FFF176", "#FFF59D", "#FFF9C4", "#FFFDE7"],
                        // Amber
                        ["#FF6F00", "#FF8F00", "#FFA000", "#FFB300", "#FFC107", "#FFCA28", "#FFD54F", "#FFE082", "#FFECB3", "#FFF8E1"],
                        // Orange
                        ["#E65100", "#EF6C00", "#F57C00", "#FB8C00", "#FF9800", "#FFA726", "#FFB74D", "#FFCC80", "#FFE0B2", "#FFF3E0"],
                        // Deep Orange
                        ["#BF360C", "#D84315", "#E64A19", "#F4511E", "#FF5722", "#FF7043", "#FF8A65", "#FFAB91", "#FFCCBC", "#FBE9E7"],
                        // Brown
                        ["#3E2723", "#4E342E", "#5D4037", "#6D4C41", "#795548", "#8D6E63", "#A1887F", "#BCAAA4", "#D7CCC8", "#EFEBE9"],
                        // Blue Grey
                        ["#263238", "#37474F", "#455A64", "#546E7A", "#607D8B", "#78909C", "#90A4AE", "#B0BEC5", "#CFD8DC", "#ECEFF1"],
                        // Black
                        ["#000000", "#212121", "#424242", "#616161", "#757575", "#9E9E9E", "#BDBDBD", "#E0E0E0", "#EEEEEE", "#FFFFFF"]
                    ]
                });
            });
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('columnSelector', {
        templateUrl: '/components/ColumnSelector/Template.html',
        bindings: {
            columnId: '=',
            columns: '=',
            onUpdate: '&',
            hideEmpty: '=',
        },
        controller: function ($scope) {
            var self = this;
            $scope.$watch('$ctrl.columnId', function (newValue, oldValue) {
                var column = self.columns.findById(newValue);
                if (self.onUpdate)
                    self.onUpdate(column);
            });

            this.check = function (c) {
                return !self.columns.filter(function (t) { return c.ID === t.ContractID }).length || this.columnId === c.ID;
            }
        }

    });
})();
(function () {
    "use strict";

    angular.module('hip').component('contract', {
        templateUrl: '/components/Contract/Template.html',
        bindings: {
            contractId: '=',
            name: '=',
            description: '=',
            rammId: '=',
            database: '=',
            weekColumnId: '=',
            dayColumnId: '=',
            columnMapping: '=',
            columns: '=',
            calendarGrouping: '='
        },
        controller: function ($mdDialog, contracts) {
            this.openSource = function (source) {
                window.open(source.URL);
            }
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('contractLinkage', {
        templateUrl: '/components/ContractLinkage/Template.html',
        bindings: {
            values: '<',
            actualValues: '<',
            actualValuesStatic: '<',
            assetTypes: '<',
            defaultAssetTypes: '<',
            column: '<',
            excludeIds: '<',
            onUpdate: '&',
            loading: '='
        },
        controller: function () {
            var self = this;
            this.busy = true;
            this.usedValues = [];

            this.updateValue = function (value) {
                this.onUpdate(this.values);
            };

            this.perfectMatch = function (value) {
                return value.Value === value.ActualValue
            };

            this.getAssetType =
                function (SystemValueID) {
                    var self = this;
                    var value = self.values.findById(SystemValueID);
                    return value ? (self.defaultAssetTypes.findById(value.AssetTypeID) || {}).Value : "";
                };

            this.filter = function (values, value) {
                if (!values || !self.assetTypes)  {
                    return values; }
                else{
                    return values.filter(function (dv) { var temp = self.assetTypes.find(function (at) { return at.SystemValueID === dv.AssetTypeID }); return self.assetTypes.length === 0 ? true : temp ? temp.Value === value.AssetType : false; }); };

            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('contractMapper', {
        templateUrl: '/components/ContractMapper/Template.html',
        bindings: {
            columns: '=',
            excludeIds: '<',
            onUpdate: '&'
        },
        controller: function () {
            var self = this;
            this.busy = true;
            

            this.update = function () {
                this.onUpdate(this.columns);
            };

            this.isOneToOne = function (column) {
                return /\D$/.test(column.DatabaseColumnName);
            }
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('contractSelector', {
        templateUrl: '/components/ContractSelector/Template.html',
        bindings: {
            contractId: '=',
            database: '=',
            ignoreDatabase: '=',
            contracts: '=',
            excludeIds: '<',
            onUpdate: '&'
        },
        controller: function (contracts, $scope) {
            var self = this;
            
            $scope.$watch('$ctrl.contractId', function (newValue, oldValue) {
                var contract = self.contracts.findById(newValue);
                self.onUpdate(contract);
            });
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('bipDivision', {
        templateUrl: '/components/Division/Template.html',
        bindings: {
            name: '=',
            tags: '='
        },
        controller: function ($http, divisions) {
            var self = this;

            self.adminTags = [];

            divisions.tags().then(function (tagList) {
                self.adminTags = tagList;
            });
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('embeddedReport', {
        templateUrl: '/components/EmbeddedReport/Template.html',
        bindings: {
            name: '=',
            materialIcon: '=',
            sectionId: '=',
            typeId: '=',
            content: '=',
            url: '=',
            refreshInterval: '=',
            source: '=',
            tags: '=',
            sections: '=',
            types: '='
            
        },
        controller: function (embeddedReports) {
            var self = this;
            self.adminTags = [];
            embeddedReports.tags().then(function (tagList) {
                self.adminTags = tagList;
            });
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('embeddedReportSelector', {
        templateUrl: '/components/EmbeddedReportSelector/Template.html',
        bindings: {
            reportId: '=', 
            embeddedReports: '='
        },
        controller: function (embeddedReports) {
            var self = this;
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('formSelector', {
        templateUrl: '/components/FormSelector/Template.html',
        bindings: {
            formId: '=',
            forms: '='
        },
        controller: function () {
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('group', {
        templateUrl: '/components/Group/Template.html',
        bindings: {
            groupId: '=',
            name: '=',
            subtitle: '=',
            title: '=',
            isAdminOnly: '=',
            iconId: '=',
            colour: '=',
            origin: '=',
            timezone: '=',
            alwaysEnabled: '=',
            wfsGroupSources: '=',
            m5Groups: '=',
            embeddedReports: '=',
            rammDatabase: '=',
            contractId: '=',
            tags: '=',
            forms: '=',
            icons: '=',
            groups: '=',
            roles: '=',
            states: '=',
            layers: '=',
            reports: '=',
            sources: '=',
            userIds: '=',
            userMultiselectItems: '=',
            allEmbeddedReports: '=',
            planningBoards: '=',
            allPlanningBoards: '=',
            groupTypeId: '=',
            groupTypes: '=',
            validationError: '=',
            placeholder: '='

        },
        controller: function ($scope, rammAuthentication, contracts, forms, m5Groups, groups) {
            var self = this;
            this.contracts = [];
            this.allM5Groups = [];
            this.allForms = [];
            this.databaseAutocompleteLoading = true;
            self.adminTags = [];

            groups.tags().then(function (tagList) {
                self.adminTags = tagList;
            })

            contracts.all().then(function (contracts) { self.contracts = contracts });
            m5Groups.all().then(function (m5Groups) { self.allM5Groups = m5Groups });
            forms.all().then(function (forms) { self.allForms = forms });

            rammAuthentication.getDatabasesNoAuth().then(function (res) {
                self.databases = res;
                self.databaseAutocompleteLoading = false;

                self.wfsGroupSources.forEach(function (source) {
                    if (source.DatabaseName !== undefined) {
                        source.database = self.databases.find(function (item) { return item.DatabaseDescription === source.DatabaseName; });
                    }
                });
            });

            this.timezoneSearch = function (query) {
                var results = query ? moment.tz.names().filter(function (item) { return item.toUpperCase().indexOf(query.toUpperCase()) >= 0 }) : moment.tz.names();
                return results.sort(function (a, b) {
                    a = parseInt(moment.tz(a).format('Z'));
                    b = parseInt(moment.tz(b).format('Z'));
                    return a - b;
                });
            };

            this.onTimezoneChange = function (zone) {
                var formattedZone = self.formatTimezone(zone);
                if (formattedZone) {
                    self.selectedTimezone = formattedZone;
                    self.timezone = zone;
                }
            };

            this.formatTimezone = function (zoneName) {
                var zone = moment.tz.zone(zoneName);
                if (!zone) return;
                return '(UTC' + moment.tz(zone.name).format('Z') + ') ' + zone.name;
            };

            this.unbindWatch = $scope.$watch('$ctrl.timezone', function (newValue, oldValue) {
                if (newValue !== undefined && oldValue === undefined) {
                    self.selectedTimezone = self.formatTimezone(self.timezone);
                    self.unbindWatch();
                }
            });
            
            this.databaseSearch = function (query) {
                if (self.databaseAutocompleteLoading) {
                    return null;
                } else {
                    return self.databases.filter(function (item) { return item.DatabaseDescription.toUpperCase().indexOf(query.toUpperCase()) >= 0 });
                }
            };

            this.selectedDatabaseChange = function (item, source) {
                if (!item) return;
                source.DatabaseName = item.DatabaseDescription;
            };

            this.getSourcesOfType = function (type) {
                if (!self.wfsGroupSources) return [];
                return self.wfsGroupSources.filter(function (s) {
                    return s.Type === type || s.SourceID && !s.ReportID && type === 0 || s.DatabaseName && !s.ReportID && type === 1 || s.ReportID && type === 2;
                });
            };

            this.getReportType = function (reportId) {
                var report = self.reports.find(function (report) { return report.ID === reportId });
                if (report) return report.Type;
            };

            this.addWfsGroupSource = function (gs) {
                self.wfsGroupSources.push(gs);
            };

            this.openSource = function (source) {
                window.open(source.URL);
            };

            this.deleteSource = function (source) {
                self.wfsGroupSources.splice(self.wfsGroupSources.indexOf(source), 1);
            };            

            this.getFormName = function (formId) {
                var form = this.allForms.findById(formId)
                return form ? form.Name : "";
            };

            this.deleteForm = function (form, index) {
                self.wfsGroupSources.filter(function (source) { return source.FormID === form.FormID }).forEach(function (source) {
                    delete source.FormID;
                })
                self.forms.splice(index, 1);
            };
            this.deletePlanningBoard = function (planningBoard, index) {
                self.planningBoards.splice(index, 1);
            };

            this.sourceEmbeddedReportsChanged = function (source) {
                source.EmbeddedReports = source.embeddedReports.map(function (trid) { return { EmbeddedReportID: trid, GroupSourceID: source.ID } })
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('groupSelector', {
        templateUrl: '/components/GroupSelector/Template.html',
        bindings: {
            groups: '=',
            groupId: '<',
            excludeIds: '<',
            onUpdate: '&'
        },
        controller: function (groups) {
            var self = this;

            this.filter = function (group, index, groups) {
                if (self.excludeIds == undefined) {
                    return !group.AlwaysEnabled;
                }

                return !group.AlwaysEnabled && self.excludeIds.find(function (id) { return id === group.ID; }) == undefined;
            };

            this.update = function () {
                var group = this.groups.findById(this.groupId);
                this.onUpdate(group);
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('icon', {
        templateUrl: '/components/Icon/Template.html',
        bindings: {
            name: '=',
            description: '=',
            blobId: '=',
            svgBlobId: '=',
            tags: '='
        },
        controller: function (icons) {
            var self = this;
            self.adminTags = [];
            icons.tags().then(function (tagList) {
                self.adminTags = tagList;
            })
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('iconSelector', {
        templateUrl: '/components/IconSelector/Template.html',
        bindings: {
            icons: '=',
            iconId: '=',
            shape: '=',
            name: '=',
            description: '=',
            backgroundColor: '=',
            foregroundColor: '=',
            isEnabled: '=',
            loadAll: '=',
            onUpdate: '&'
        },
        controller: function ($scope, $attrs) {
            var self = this;
            if (self.loadAll)
                self.boundIcons = self.icons;

            this.allowShapeIcon = $attrs.allowShapeIcon === "true";
            this.labelText = $attrs.labelText || undefined;

            this.update = function () {
                this.onUpdate({ id: self.iconId });
            };

            this.click = function () {
                if (!self.boundIcons) self.boundIcons = self.icons;
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('iconSetSelector', {
        templateUrl: '/components/IconSetSelector/Template.html',
        bindings: {
            iconSets: '=',
            iconSetId: '=',
            onUpdate: '&'
        },
        controller: function (iconSets, $attrs) {
            var self = this;
            this.busy = true;
            this.type = $attrs.type || 'wfs';
            if (this.type === 'wfs') this.typeNum = 0;
            else if (this.type === 'ramm') this.typeNum = 1;
            else if (this.type === 'm5') this.typeNum = 2;

            this.hasDefault = $attrs.hasDefault === "true";
            this.defaultText = $attrs.defaultText || "No Icon Set";

            this.filterIconSets = function (iconSets) {
                return self.iconSets.filter(function (p) { return p.Type === self.typeNum; });
            };

            this.update = function () {
                this.onUpdate({ id: self.iconSetId });
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('indentedItemMultiSelector', {
        templateUrl: '/components/IndentedItemMultiSelector/Template.html',
        bindings: {            
            tree: '=',
            selectedItemIds: '=',
            isReviewing: '=',
            approvedItemIds: '=',
            deniedItemIds: '='
        },
        controller: function () {
            var self = this;
            this.updateSelected = function (groupId, state) {
                if (!self.isReviewing) {
                    var index = self.selectedItemIds.indexOf(groupId);
                    if (index < 0) {
                        self.selectedItemIds.push(groupId);
                    } else if (index > -1) {
                        self.selectedItemIds.splice(index, 1);
                    }
                } else {
                    var approvedIndex = self.approvedItemIds.indexOf(groupId);
                    var deniedIndex = self.deniedItemIds.indexOf(groupId);

                    if (state === 1) {
                        if (approvedIndex < 0) {
                            self.approvedItemIds.push(groupId);
                        } else {
                            self.approvedItemIds.splice(approvedIndex, 1);
                        }
                        if (deniedIndex > -1) {
                            self.deniedItemIds.splice(deniedIndex, 1);
                        }   
                    } else if (state === 2) {
                        if (deniedIndex < 0) {
                            self.deniedItemIds.push(groupId);
                        }else{
                            self.deniedItemIds.splice(deniedIndex, 1);
                        }
                        if (approvedIndex > -1) {
                            self.approvedItemIds.splice(approvedIndex, 1);
                        }
                    }
                }

            };
        }
    });
})();
(function () {
    "use strict";
    angular.module('hip').component('indentedItemMultiSelectorTree', {
        templateUrl: '/components/IndentedItemMultiSelectorTree/Template.html', 
        bindings: {
            onUpdate: '&',
            tree: '=',
            isReviewing: '='
        },
        controller: function () {
            var self = this;
            this.isVisible = {};

            this.updateVisibility = function (groupId) {
                    self.isVisible[groupId] = !self.isVisible[groupId];
            };

            this.update = function (groupId, state) {
                self.onUpdate({groupId: groupId, state: state});
            };

            this.show = function (node) {
                if (self.isVisible[node.ID]) {
                    return true;
                }
                else if (self.isReviewing && self.isVisible[node.ID] === undefined) {
                    self.isVisible[node.ID] = true;
                    return true;
                }
                else if (self.isVisible[node.ID] === false) {
                    return false;
                }
                else if (node.children.some(child => self.show(child))) {
                    self.isVisible[node.ID] = true;
                    return true;                   
                }
                else if (node.children.some(child => child.IsSelected === true)) {
                    self.isVisible[node.ID] = true;
                    return true;
                } else {
                    self.isVisible[node.ID] = false;
                    return false;
                }
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('itemMultiSelector', {
        templateUrl: '/components/ItemMultiSelector/Template.html',
        bindings: {
            items: '=',
            selectedItemIds: '=',
            heading: '@',
            rightHeading: '@',
            onUpdate: '&'
        },
        controller: function () {
            var self = this;
            self.filteredItems = [];
            self.searchQuery = '';
            
            this.isItemSelected = function (item) {
                return self.selectedItemIds.includes(item.ID);
            };

            this.itemMatchesFilter = function (item) {
                return !this.query ||
                    (item.Name && item.Name.toUpperCase().indexOf(this.query.toUpperCase()) >= 0) ||
                    (item.Description && item.Description.toUpperCase().indexOf(this.query.toUpperCase()) >= 0);
            };

            this.selectItem = function (item) {
                var index = self.selectedItemIds.indexOf(item.ID);
                if (index < 0) {
                    self.selectedItemIds.push(item.ID);
                }
            };

            this.deselectItem = function (item) {
                var index = self.selectedItemIds.indexOf(item.ID);
                if (index > -1) {
                    self.selectedItemIds.splice(index, 1);
                }
            };
        }
    });
})();
(function(){
    "use strict";

    angular.module('hip').component('layerSelector', {
        templateUrl: '/components/LayerSelector/Template.html',
        bindings: {
            layers: '=',
            layerId: '=',
            onChange: '=',
            onUpdate: '&'
        },
        controller: function (layers, $attrs) {
            var self = this;
            this.type = $attrs.type || 'wfs';
            if (this.type === 'wfs') this.typeNum = 0;
            else if (this.type === 'ramm') this.typeNum = 1;

            this.update = function () {
                this.onUpdate({ id: self.layerId });
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('layersNavBar', {
        templateUrl: '/components/LayersNavBar/Template.html',
        bindings: {
            selectedItem: '<'
        },
        controller: function () { }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('m5AssetTypeSelector', {
        templateUrl: '/components/M5AssetTypeSelector/Template.html',
        bindings: {
            assetTypes: '=',
            assetTypeId: '=',
            onUpdate: '&'
        },
        controller: function () {
            var self = this;

            this.update = function () {
                var assetType = this.assetTypes.find(function (type) { return type.Id === self.assetTypeId });
                this.onUpdate(assetType);
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('m5DigitalInputSelector', {
        templateUrl: '/components/M5DigitalInputSelector/Template.html',
        bindings: {
            digitalInputs: '=',
            assetTypeId: '=',
            inputNumber: '=',
            onUpdate: '&'
        },
        controller: function () {
            var self = this;
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('m5FunctionHistoryPropertySet', {
        templateUrl: '/components/M5FunctionHistoryPropertySet/Template.html',
        bindings: {
            m5AssetTypeId: '=',
            propertySetId: '=',
            tags: '=',
            m5AssetTypes: '=',
            propertySets: '='
        },
        controller: function (functionHistoryPropertySets) {
            var self = this
            self.adminTags = [];

            functionHistoryPropertySets.tags().then(function (tagList) {
                self.adminTags = tagList;
            });
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('m5FunctionHistoryStyle', {
        templateUrl: '/components/M5FunctionHistoryStyle/Template.html',
        bindings: {
            m5AssetTypeId: '=',
            rules: '=',
            tags: '=',
            m5AssetTypes: '='
        },
        controller: function ($scope, m5Assets, functionHistoryStyles) {
            var self = this;
            self.adminTags = [];

            functionHistoryStyles.tags().then(function (tagList) {
                self.adminTags = tagList;
            });

            this.m5DigitalInputs = [];

            this.$onInit = function () {
                $scope.$watch(function () { return self.m5AssetTypeId }, function (changesObj) {
                    self.m5DigitalInputs = [];
                    if (self.m5AssetTypeId) {
                        m5Assets.listDigitalInputDefinitions(self.m5AssetTypeId).then(function (m5DigitalInputs) {
                            self.m5DigitalInputs = m5DigitalInputs;
                        });
                    }
                });
            };

            this.valueSearch = function (query) {
                if (self.valueAutocompleteLoading) {
                    return null;
                } else {
                    return self.phyInputValues.filter(function (item) { return item.LookupValue.toUpperCase().indexOf(query.toUpperCase()) >= 0 });
                }
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('m5GroupSelector', {
        templateUrl: '/components/M5GroupSelector/Template.html',
        bindings: {
            groups: '=',
            groupId: '=',
            onUpdate: '&'
        },
        controller: function (m5Groups) {
            var self = this;

            this.update = function () {
                var group = this.groups.find(g => g.Id === this.groupId);
                if (this.onUpdate)
                    this.onUpdate(group);
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('m5IconSet', {
        templateUrl: '/components/M5IconSet/Template.html',
        bindings: {
            name: '=',
            filters: '=',
            tags: '=',
            icons: '=',
            isValid: '='
        },
        controller: function (m5Assets, $mdDialog, $scope, iconSets) {
            var self = this;

            this.propertyNames = [];
            this.propertyValues = {};
            this.propertyNamesLoading = true;
            this.propertyValuesLoading = true;
            self.adminTags = [];

            iconSets.tags().then(function (tagList) {
                self.adminTags = tagList;
            });

            this.$onInit = function () {
                $scope.$watch(function () { return self.filters }, function (changesObj) {
                    // Transform properties
                    if (!self.filters) return;
                    self.filters.forEach(function (filter) {
                        filter.Properties.forEach(function (property) {
                            property.MultiValue = property.Value.split(',');
                        });
                    });
                });
            };

            m5Assets.listPropertyKeys().then(function (res) {
                self.propertyNames = res;
                self.propertyNamesLoading = false;
                self.propertyNames.forEach(function (propertyName, i) {
                    m5Assets.listPropertyValues(propertyName).then(function (res) {
                        self.propertyValues[propertyName] = res;
                    });
                    if (i === self.propertyNames.length - 1) self.propertyValuesLoading = false;
                });
            })

            this.propertyNameSearch = function (query) {
                if (self.propertyNamesLoading) {
                    return null;
                } else {
                    return self.propertyNames.filter(function (item) { return item.toUpperCase().indexOf(query.toUpperCase()) >= 0 }).sort();
                }
            }

            this.propertyValueSearch = function (query, propertyName) {
                if (self.propertyValuesLoading) {
                    return null;
                } else {
                    return self.propertyValues[propertyName].filter(function (item) { return item.toUpperCase().indexOf(query.toUpperCase()) >= 0 }).sort();
                }
            }

            this.duplicate = function (filter) {
                var dupe = Object.clone(filter);
                delete dupe.$$hashKey;
                dupe.ID = undefined;
                this.filters.push(dupe);
            }

            this.multiValues = function (propertyName) {
                return self.propertyValues[propertyName] || [];
            }

            this.multiChanged = function (property) {
                property.Value = property.MultiValue.toString();
            }

            this.checkIfValid = function () {
                this.isValid = false;
                this.filters.forEach(function (filter) { if (!filter.IsForeground) { self.isValid = true; } });
            }

            this.showFunctions = function () {
                $mdDialog.show({
                    controller: function DialogController($scope, $mdDialog) {
                        $scope.hide = function () {
                            $mdDialog.hide();
                        };

                        $scope.cancel = function () {
                            $mdDialog.cancel();
                        };

                        $scope.answer = function (answer) {
                            $mdDialog.hide(answer);
                        };
                    },
                    template:
                    '<md-dialog aria-label="Value Functions">' +
                    '    <form ng-cloak>' +
                    '        <md-toolbar>' +
                    '            <div class="md-toolbar-tools">' +
                    '                <h2>Value Functions</h2>' +
                    '                <span flex></span>' +
                    '                <md-button class="md-icon-button" ng-click="cancel()">' +
                    '                    <i class="material-icons" aria-label="Close dialog">close</i>' +
                    '                </md-button>' +
                    '            </div>' +
                    '        </md-toolbar>' +
                    '    ' +
                    '       <md-dialog-content>' +
                    '            <div class="md-dialog-content">' +
                    '                <h2>Today</h2>' +
                    '                <p>' +
                    '                    The today function can be used to get a date relative to the date when the comparison is made.<br />' +
                    '                    <b>Usage: </b> today([<i>+/-</i>][<i>number</i>][<i>unit</i>]) <br />' +
                    '                    <table><tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="width:35px; padding: 0;"><b>Units: </b></td><td style="width:15px; padding: 0; text-align: center;">Y</td><td style="width:11px; padding: 0;  text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Years</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">M</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Months</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">W</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Weeks</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">D</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Days</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">h</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Hours</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">m</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Minutes</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">s</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Seconds</td></tr></table><br />' +
                    '                    <b>Example: </b> To use the date 6 months back use <i>today(-6M)</i>' +
                    '                </p>' +
                    '    ' +
                    '           </div>' +
                    '        </md-dialog-content>' +
                    '    ' +
                    '        <md-dialog-actions layout="row">' +
                    '           <span flex></span>' +
                    '            <md-button ng-click="cancel()">' +
                    '               Ok' +
                    '            </md-button>' +
                    '        </md-dialog-actions>' +
                    '    </form>' +
                    '</md-dialog>',
                    parent: angular.element(document.body),
                    clickOutsideToClose: true,
                });
            }
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('m5InputSelector', {
        templateUrl: '/components/M5InputSelector/Template.html',
        bindings: {
            assetTypeId: '=',
            inputId: '=',
            inputType: '=',
            m5AssetTypes: '=',
            m5TrackerConfigurations: '='
        },
        controller: function($scope, $q, m5Assets) {
            var self = this;
            this.inputDefinitions = [];
            this.inputs = [];
            this.loadingInputs = false;
            this.assetTypeId = undefined;

            $scope.$watch('$ctrl.assetTypeId', function (newValue) {
                if (newValue) {
                    self.inputs = [];
                    self.getAvailableInputs();
                }
            });

            this.getAvailableInputs = function () {
                self.loadingInputs = true;
                var analogInputReq = m5Assets.listAnalogInputDefinitions(self.assetTypeId);
                var digitalInputReq = m5Assets.listDigitalInputDefinitions(self.assetTypeId);
                var counterInputReq = m5Assets.listCounterInputDefinitions(self.assetTypeId);

                $q.all([analogInputReq, digitalInputReq, counterInputReq]).then(function (results) {
                    self.inputDefinitions = [];

                    results[0].forEach(function (input) {
                        input.InputType = 0;
                        self.inputDefinitions.push(input);
                    });

                    results[1].forEach(function (input) {
                        input.InputType = 1;
                        self.inputDefinitions.push(input);
                    });

                    results[2].forEach(function (input) {
                        input.InputType = 2;
                        self.inputDefinitions.push(input);
                    });

                    self.loadingInputs = false;
                    
                    self.input = self.inputType + '-' + self.inputId;
                });
            };
            this.getInputName = function (input) {
                var inputDefinition = self.inputDefinitions.find(function (def) {
                    return def.InputNumber === input.InputNumber && def.InputType === input.InputType;
                });
                if (inputDefinition) return inputDefinition.Name;
                else return 'Loading...';
            };

            this.getInputType = function (input) {
                var inputTypes = ['Analog', 'Digital', 'Counter'];
                return inputTypes[input.InputType];
            };

            this.update = function () {
                var split = this.input.split('-');
                self.inputType = parseInt(split[0]);
                self.inputId = parseInt(split[1]);
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('m5PropertySet', {
        templateUrl: '/components/M5PropertySet/Template.html',
        bindings: {
            name: '=',
            tableName: '=',
            properties: '=',
            tags: '=',
            icons: '=',
            m5AssetTypes: '=',
            m5TrackerConfigurations: '='
        },
        controller: function ($scope, $q, m5Assets, propertySets) {
            var self = this;

            self.adminTags = [];

            propertySets.tags().then(function (tagList) {
                self.adminTags = tagList;
            });

            this.$onInit = function () {
                $scope.$watch(function () { return self.properties }, function (changesObj) {
                    // Transform properties
                    if (!self.properties) return;
                    self.properties.forEach(function (property) {
                        if (!property.PropertyName) property.PropertyNameList = [];
                        else property.PropertyNameList = property.PropertyName.split(',');
                        
                        if (!property.momentStartDate && property.$type === 'Date') property.momentStartDate = moment(property.RangeStart || 0);
                        if (!property.momentEndDate && property.$type === 'Date') property.momentEndDate = moment(property.RangeEnd || '2100-01-01 00:00:00');
                    });
                });
            };

            this.propertyNames = [];
            this.propertyValues = {};
            this.propertyNamesLoading = true;
            this.propertyValuesLoading = true;

            m5Assets.listPropertyKeys().then(function (res) {
                self.propertyNames = res;
                self.propertyNamesLoading = false;
                self.propertyNames.forEach(function (propertyName, i) {
                    m5Assets.listPropertyValues(propertyName).then(function (res) {
                        self.propertyValues[propertyName] = res;
                        if (i === self.propertyNames.length - 1) self.propertyValuesLoading = false;
                    });
                });
            });
            
            this.propertyNameSearch = function (query) {
                if (self.propertyNamesLoading) {
                    return null;
                } else {
                    return self.propertyNames.filter(function (item) { return item.toUpperCase().indexOf(query.toUpperCase()) >= 0 }).sort();
                }
            }

            this.propertyValueSearch = function (query, propertyName) {
                if (self.propertyValuesLoading) {
                    return null;
                } else {
                    return self.propertyValues[propertyName].filter(function (item) { return item.toUpperCase().indexOf(query.toUpperCase()) >= 0 }).sort();
                }
            }

            this.selectedColumnChange = function (property) {
                property.PropertyName = property.PropertyNameList.join(',');
                if (property.PropertyName.length === 0) property.validationError = true;
                else property.validationError = false;
            }

            this.updateHeader = function (position) {
                self.properties.forEach(function (property, index) {
                    if (position != index)
                        property.UseAsHeading = false;
                });
            }

            this.updateShowInReport = function (position) {
                var property = self.properties[position];
                property.ShowInReport = property.HideInReport;
            }

            this.updateId = function (position) {
                self.properties.forEach(function (property, index) {
                    if (position != index)
                        property.UseAsId = false;
                });
            }
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('permissionRequestsNavBar', {
        templateUrl: '/components/permissionRequestsNavBar/Template.html',
        bindings: {
            selectedItem: '@'
        },
        controller: function () { }
    });
})();
(function () {
    "use strict";

    angular.module('hip').controller('PermissionsDialogController',
        function ($mdDialog, $q, groupSourcePermissions, groupLayerPermissions, groupReportPermissions, m5GroupPermissions, groupFormPermissions) {
            var self = this;
            this.wfsGroupSourcePermissions = [];
            this.rammSourcePermissions = [];
            this.m5GroupPermissions = [];
            this.reportPermissions = [];
            this.deletedPermissions = [];
            this.busy = true;

            $q.all([
                groupSourcePermissions.allGroup(self.groupId),
                groupLayerPermissions.allGroup(self.groupId),
                m5GroupPermissions.allGroup(self.groupId),
                groupReportPermissions.allGroup(self.groupId)
            ]).then(function (results) {
                self.wfsGroupSourcePermissions = results[0];
                self.rammSourcePermissions = results[1];
                self.m5GroupPermissions = results[2];
                self.reportPermissions = results[3];
                self.busy = false;
            });

            this.hide = function () {
                $mdDialog.hide();
            };

            this.cancel = function () {
                $mdDialog.cancel();
            };

            this.findLayerName = function (layerId) {
                return self.layers.find(function (layer) { return layer.ID === layerId; }).Name;
            };

            this.findSourceName = function (sourceId) {
                return self.sources.find(function (source) { return source.ID === sourceId; }).Name;
            };

            this.findM5GroupName = function (m5GroupId) {
                return self.allM5Groups.find(function (m5Group) { return m5Group.Id === m5GroupId; }).Name;
            }

            this.findReportName = function (reportId) {
                return self.allEmbeddedReports.find(function (report) { return report.ID === reportId; }).Name;
            }

            this.updateToggles = function () {
                if (self.roleId !== undefined && self.stateId !== undefined) {
                    self.wfsGroupSources.forEach(function (value) {
                        value.isEnabled = self.wfsGroupSourcePermissions.find(function (permission) {
                            return permission.RoleID === self.roleId && permission.StateID === self.stateId && permission.SourceID === value.SourceID;
                        }) != undefined;
                    });

                    self.rammGroupSources.forEach(function (item) {
                        item.isEnabled = self.rammSourcePermissions.find(function (permission) {
                            return permission.RoleID === self.roleId && permission.StateID === self.stateId && permission.LayerID === item.LayerID;
                        }) != undefined;
                    });

                    self.m5Groups.forEach(function (value) {
                        value.isEnabled = self.m5GroupPermissions.find(function (permission) {
                            return permission.RoleID === self.roleId && permission.StateID === self.stateId && permission.M5GroupID === value.ID;
                        }) != undefined;
                    });

                    self.reports.forEach(function (value) {
                        value.isEnabled = self.reportPermissions.find(function (permission) {
                            return permission.RoleID === self.roleId && permission.StateID === self.stateId && permission.ReportID === value.ReportID;
                        }) != undefined;
                    });

                }
            }

            this.save = function (type, item) {
                if (type === 'wfsGroupSource') {
                    var permission = self.wfsGroupSourcePermissions.find(function (permission) {
                        return permission.RoleID === self.roleId && permission.StateID === self.stateId && permission.SourceID === item.SourceID;
                    });
                    if (item.isEnabled) {
                        if (!permission) {
                            var newPermission = {
                                GroupID: self.groupId,
                                RoleID: self.roleId,
                                StateID: self.stateId,
                                SourceID: item.SourceID
                            };

                            groupSourcePermissions.create(newPermission).then(function (id) {
                                newPermission.ID = id;
                                self.wfsGroupSourcePermissions.push(newPermission);
                                self.updateToggles();
                            });
                        }
                    }
                    else {
                        if (permission) {
                            var index = self.wfsGroupSourcePermissions.findIndex(function (element) { return permission.ID === element.ID; });
                            groupSourcePermissions.delete(permission.ID);
                            self.wfsGroupSourcePermissions.splice(index, 1);
                            self.updateToggles();
                        }
                    }
                }

                if (type === 'rammGroupSource') {
                    var permission = self.rammSourcePermissions.find(function (permission) {
                        return permission.RoleID === self.roleId && permission.StateID === self.stateId && permission.LayerID === item.LayerID;
                    });
                    if (item.isEnabled) {
                        if (!permission) {
                            var newPermission = {
                                GroupID: self.groupId,
                                RoleID: self.roleId,
                                StateID: self.stateId,
                                LayerID: item.LayerID
                            };

                            groupLayerPermissions.create(newPermission).then(function (id) {
                                newPermission.ID = id;
                                self.rammSourcePermissions.push(newPermission);
                                self.updateToggles();
                            });
                        }
                    }
                    else {
                        if (permission) {
                            var index = self.rammSourcePermissions.findIndex(function (element) { return permission.ID === element.ID; });
                            groupLayerPermissions.delete(permission.ID);
                            self.rammSourcePermissions.splice(index, 1);
                            self.updateToggles();
                        }
                    }
                }

                if (type === 'm5Group') {
                    var permission = self.m5GroupPermissions.find(function (permission) {
                        return permission.RoleID === self.roleId && permission.StateID === self.stateId && permission.M5GroupID === item.ID;
                    });

                    if (item.isEnabled) {
                        if (!permission) {
                            var newPermission = {
                                GroupID: self.groupId,
                                RoleID: self.roleId,
                                StateID: self.stateId,
                                M5GroupID: item.ID
                            };

                            m5GroupPermissions.create(newPermission).then(function (id) {
                                newPermission.ID = id;
                                self.m5GroupPermissions.push(newPermission);
                                self.updateToggles();
                            });
                        }
                    }
                    else {
                        if (permission) {
                            var index = self.m5GroupPermissions.findIndex(function (element) { return permission.ID === element.ID; });
                            m5GroupPermissions.delete(permission.ID);
                            self.m5GroupPermissions.splice(index, 1);
                            self.updateToggles();
                        }
                    }
                }

                if (type === 'report') {
                    var permission = self.reportPermissions.find(function (permission) {
                        return permission.RoleID === self.roleId && permission.StateID === self.stateId && permission.ReportID === item.ReportID;
                    });

                    if (item.isEnabled) {
                        if (!permission) {
                            var newPermission = {
                                GroupID: self.groupId,
                                RoleID: self.roleId,
                                StateID: self.stateId,
                                ReportID: item.ReportID
                            };

                            groupReportPermissions.create(newPermission).then(function (id) {
                                newPermission.ID = id;
                                self.reportPermissions.push(newPermission);
                                self.updateToggles();
                            });
                        }
                    }
                    else {
                        if (permission) {
                            var index = self.reportPermissions.findIndex(function (element) { return permission.ID === element.ID; });
                            groupReportPermissions.delete(permission.ID);
                            self.reportPermissions.splice(index, 1);
                            self.updateToggles();
                        }
                    }
                }
            }
        });
})();
(function () {
    "use strict";

    angular.module('hip').component('planningBoardSelector', {
        templateUrl: '/components/PlanningBoardSelector/Template.html',
        bindings: {
            planningBoardId: '=',
            planningBoards: '='
        },
        controller: function () {
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('propertySetSelector', {
        templateUrl: '/components/PropertySetSelector/Template.html',
        bindings: {
            propertySets: '=',
            propertySetId: '=',
            onUpdate: '&'
        },
        controller: function (propertySets, $attrs) {
            var self = this;
            this.type = $attrs.type || 'wfs';
            if (this.type === 'wfs') this.typeNum = 0;
            else if (this.type === 'ramm') this.typeNum = 1;
            else if (this.type === 'm5') this.typeNum = 2;
            
            this.filterPropertySets = function (propertySets) {
                return self.propertySets.filter(function (p) { return p.Type === self.typeNum; });
            };

            this.update = function () {
                this.onUpdate({ id: self.propertySetId });
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('rammDatabaseSelector', {
        templateUrl: '/components/RammDatabaseSelector/Template.html',
        bindings: {
            databases: '=',
            username: '<',
            password: '<',
            database: '=',
            onDatabaseSelected: '&'
        },
        controller: function () { }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('rammFunctionHistoryPropertySet', {
        templateUrl: '/components/RammFunctionHistoryPropertySet/Template.html',
        bindings: {
            m5AssetTypeId: '=',
            propertySetId: '=',
            tags: '=',
            m5AssetTypes: '=',
            propertySets: '='
        },
        controller: function (functionHistoryPropertySets) {
            var self = this;
            self.adminTags = [];

            functionHistoryPropertySets.tags().then(function (tagList) {
                self.adminTags = tagList;
            });
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('rammFunctionHistoryStyle', {
        templateUrl: '/components/RammFunctionHistoryStyle/Template.html',
        bindings: {
            m5AssetTypeId: '=',
            rules: '=',
            tags: '=',
            m5AssetTypes: '='
        },
        controller: function ($scope, rammMeta, functionHistoryStyles) {
            var self = this;
            self.phyInputValues;
            this.rammMeta = rammMeta;
            this.valueAutocompleteLoading = true;
            self.adminTags = [];

            functionHistoryStyles.tags().then(function (tagList) {
                self.adminTags = tagList;
            });

            this.selectedValueChange = function (item, option) {
                if (!item) return;
                option.Value = item.LookupValue;
            };

            this.valueSearch = function (query) {
                if (self.valueAutocompleteLoading) {
                    return null;
                } else {
                    return self.phyInputValues.filter(function (item) { return item.LookupValue.toUpperCase().indexOf(query.toUpperCase()) >= 0; });
                }
            };

            //Only looking up one becuase they all come from the same table.
            this.rammMeta.lookup('Higgins - NZTA SH', 'ud_device_history_v2', 'phy_input_1').then(function (result) {
                self.phyInputValues = result;
                self.rules.forEach(function (rule) {
                    rule.InputNumberValues.forEach(function (val) {
                        if (val.Value != undefined) {
                            val.selectedValue = result.find(function (lookup) { return lookup.LookupValue === val.Value });
                        };
                    });
                });
                self.valueAutocompleteLoading = false;
            });
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('rammIconSet', {
        templateUrl: '/components/RammIconSet/Template.html',
        bindings: {
            name: '=',
            tableName: '=',
            filters: '=',
            tags: '=',
            iconsets: '=',
            tags: '=',
            icons: '=',
            isValid: '='
        },
        controller: function (rammMeta, $mdDialog, rammTables, systemColumns, iconSets) {
            var self = this;

            this.rammMeta = rammMeta;
            this.tableAutocompleteLoading = true;
            this.columnAutocompleteLoading = true;
            this.valueAutocompleteLoading = true;
            this.tables = [];
            this.linkageTables = [];
            this.linkageTable = undefined;
            this.systemColumns = [];
            this.columns = [];
            this.lookups = [];
            this.lookupRequests = [];
            self.adminTags = [];

            iconSets.tags().then(function (tagList) {
                self.adminTags = tagList;
            });

            Promise.all([self.rammMeta.tables('Higgins - NZTA SH'), rammTables.all()]).then(function (res) {
                self.tables.length = 0;
                Array.prototype.push.apply(self.tables, res[0]);
                self.linkageTables.length = 0;
                Array.prototype.push.apply(self.linkageTables, res[1]);
                self.tableAutocompleteLoading = false;
                if (self.tableName !== undefined) {
                    self.linkageTable = self.linkageTables.find(function (lt) { return lt.DatabaseTableName === self.tableName });
                    var table = self.tables.find(function (table) { return table.TableName === self.tableName; });
                    table.firstLoad = true;
                    self.table = table;

                    var columnPromises = [self.rammMeta.columns('Higgins - NZTA SH', self.tableName)]
                    if (self.linkageTable) columnPromises.push(systemColumns.getAllForTable(self.linkageTable.ID));
                    Promise.all(columnPromises).then(function (res) {
                        self.columnAutocompleteLoading = false;
                        self.columns.length = 0;
                        self.systemColumns.length = 0;
                        Array.prototype.push.apply(self.columns, res[0]);
                        Array.prototype.push.apply(self.systemColumns, res[1]);

                        self.filters.forEach(function (filter) {
                            filter.Properties.forEach(function (property) {
                                if (property.Field != undefined) {
                                    property.column = self.columns.find(function (column) { return column.ColumnName === property.Field; });
                                    property.MultiValue = property.Value.split(',');
                                    property.column.firstLoad = true;
                                    if (property.column.IsLookup && property.Value) {
                                        if (self.lookupRequests[property.Field] === undefined) {
                                            self.lookups[property.Field] = [];
                                            if (self.systemColumns) {
                                                var column = self.systemColumns.find(function (sc) { return sc.DatabaseColumnName === property.Field })
                                                self.lookupRequests[property.Field] = systemColumns.getSystemValues(column.ID).then(function (res) {
                                                    self.lookups[property.Field] = res.map(function (value) { return { LookupValue: value.Value }; });
                                                    self.valueAutocompleteLoading = false;
                                                    property.valueAutocompleteLoading = false;
                                                });
                                            }
                                            else
                                                self.lookupRequests[property.Field] = self.rammMeta.lookup('Higgins - NZTA SH', self.tableName, property.Field).then(function (res) {
                                                    self.lookups[property.Field] = res;
                                                    self.valueAutocompleteLoading = false;
                                                    property.valueAutocompleteLoading = false;
                                                });
                                        }
                                        self.lookupRequests[property.Field].then(function () {
                                            property.values = self.lookups[property.Field];
                                            property.selectedValue = property.values.find(function (lookup) { return lookup.LookupValue === property.Value; });
                                        });
                                    }
                                }
                            });
                        });
                    });
                }
            });
            this.tableSearch = function (query) {
                if (this.tableAutocompleteLoading) {
                    return null;
                } else {
                    return self.tables.filter(function (item) { return (item.TableDescription || "").toUpperCase().indexOf(query.toUpperCase()) >= 0 });
                }
            }

            this.columnSearch = function (query) {
                if (this.columnAutocompleteLoading) {
                    return null;
                } else {
                    return self.columns.filter(function (item) { return (item.ColumnDescription || "").toUpperCase().indexOf(query.toUpperCase()) >= 0 });
                }
            }

            this.duplicate = function (filter) {
                var dupe = Object.clone(filter);
                delete dupe.$$hashKey;
                dupe.ID = undefined;
                this.filters.push(dupe);
            }

            this.valueSearch = function (query, property) {
                if (property.valueAutocompleteLoading) {
                    return null;
                } else {
                    return property.values.filter(function (item) { return item.LookupValue.toUpperCase().indexOf(query.toUpperCase()) >= 0 });
                }
            }

            this.multiValues = function (property) {
                if (property.valueAutocompleteLoading) {
                    return [];
                } else {
                    return property.values ? property.values.filter(function (i) { return i.IsActive }).map(function (i) { return i.LookupValue }) : [];
                }
            }

            this.multiChanged = function (property) {
                property.Value = property.MultiValue.toString();
            }

            this.checkIfValid = function () {
                this.isValid = false;
                this.filters.forEach(function (filter) { if (!filter.IsForeground) { self.isValid = true; } });
            }

            this.selectedTableChange = function (item) {
                self.lookups = [];
                self.lookupRequests = [];
                if (!item) return;
                self.tableName = item.TableName;
                self.linkageTable = self.linkageTables.find(function (lt) { return lt.DatabaseTableName === self.tableName });

                if (self.table.firstLoad) {
                    self.table.firstLoad = false;
                    return;
                }

                self.columnAutocompleteLoading = true;
                var columnPromises = [self.rammMeta.columns('Higgins - NZTA SH', self.tableName)]
                if (self.linkageTable) columnPromises.push(systemColumns.getAllForTable(self.linkageTable.ID));
                Promise.all(columnPromises).then(function (res) {
                    self.columns = res[0];
                    self.systemColumns = res[1];
                    self.columnAutocompleteLoading = false;
                });
            }

            this.showFunctions = function () {
                $mdDialog.show({
                    controller: function DialogController($scope, $mdDialog) {
                        $scope.hide = function () {
                            $mdDialog.hide();
                        };

                        $scope.cancel = function () {
                            $mdDialog.cancel();
                        };

                        $scope.answer = function (answer) {
                            $mdDialog.hide(answer);
                        };
                    },
                    template:
                    '<md-dialog aria-label="Value Functions">' +
                    '    <form ng-cloak>' +
                    '        <md-toolbar>' +
                    '            <div class="md-toolbar-tools">' +
                    '                <h2>Value Functions</h2>' +
                    '                <span flex></span>' +
                    '                <md-button class="md-icon-button" ng-click="cancel()">' +
                    '                    <i class="material-icons" aria-label="Close dialog">close</i>' +
                    '                </md-button>' +
                    '            </div>' +
                    '        </md-toolbar>' +
                    '    ' +
                    '       <md-dialog-content>' +
                    '            <div class="md-dialog-content">' +
                    '                <h2>Today</h2>' +
                    '                <p>' +
                    '                    The today function can be used to get a date relative to the date when the comparison is made.<br />' +
                    '                    <b>Usage: </b> today([<i>+/-</i>][<i>number</i>][<i>unit</i>]) <br />' +
                    '                    <table><tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="width:35px; padding: 0;"><b>Units: </b></td><td style="width:15px; padding: 0; text-align: center;">Y</td><td style="width:11px; padding: 0;  text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Years</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">M</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Months</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">W</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Weeks</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">D</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Days</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">h</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Hours</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">m</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Minutes</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">s</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Seconds</td></tr></table><br />' +
                    '                    <b>Example: </b> To use the date 6 months back use <i>today(-6M)</i>' +
                    '                </p>' +
                    '    ' +
                    '           </div>' +
                    '        </md-dialog-content>' +
                    '    ' +
                    '        <md-dialog-actions layout="row">' +
                    '           <span flex></span>' +
                    '            <md-button ng-click="cancel()">' +
                    '               Ok' +
                    '            </md-button>' +
                    '        </md-dialog-actions>' +
                    '    </form>' +
                    '</md-dialog>',
                    parent: angular.element(document.body),
                    clickOutsideToClose: true,
                });
            }

            this.selectedColumnChange = function (item, property) {
                if (!item) return;
                var old = property.Field;
                property.Field = item.ColumnName;
                if (old !== property.Field && !this.checkNumeric(item.DataType) && ['<', '>', '<=', '>=', 'between'].indexOf(property.Operator) !== -1)
                    property.Operator = '==';
                if (!property.column.IsLookup) return;
                if (property.column.firstLoad) {
                    property.column.firstLoad = false;
                    return;
                }
                property.valueAutocompleteLoading = false;
                if (self.lookupRequests[property.Field] === undefined) {
                    self.lookups[property.Field] = [];
                    if (self.systemColumns) {
                        var column = self.systemColumns.find(function (sc) { return sc.DatabaseColumnName === property.Field });
                        self.lookupRequests[property.Field] = systemColumns.getSystemValues(column.ID).then(function (res) {
                            self.lookups[property.Field] = res.map(function (value) { return { LookupValue: value.Value }; });
                            self.valueAutocompleteLoading = false;
                            property.valueAutocompleteLoading = false;
                        });
                    }
                    else
                        self.lookupRequests[property.Field] = self.rammMeta.lookup('Higgins - NZTA SH', self.tableName, property.Field).then(function (res) {
                            self.lookups[property.Field] = res;
                            self.valueAutocompleteLoading = false;
                            property.valueAutocompleteLoading = false;
                        });
                }
                self.lookupRequests[property.Field].then(function () {
                    property.values = self.lookups[property.Field];
                });
            }


            this.checkNumeric = function (column) {
                if (!column || !column.DataType) return false;
                var possible = ['datetime', 'integer', 'smallint', 'decimal', 'currency', 'date', 'time', 'float', 'real', 'numeric', 'int', 'money']
                var numeric = false;
                possible.forEach(function (p) {
                    if (column.DataType.indexOf(p.toLowerCase()) !== -1) {
                        numeric = true;
                        return;
                    }
                });
                return numeric;
            }

            this.selectedValueChange = function (item, filter) {
                if (!item) return;
                filter.Value = item.LookupValue;
            }
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('rammLayer', {
        templateUrl: '/components/RammLayer/Template.html',
        bindings: {
            layerId: '=',
            name: '=',
            loadButton: '=',
            weight: '=',
            refreshInterval: '=',
            iconSetId: '=',
            infoIconSetId: '=',
            propertySetId: '=',
            showDetails: '=',
            filterDetails: '=',
            allowSituationReports: '=',
            geometricFilter: '=',
            forceShowIconKey: '=',
            hideIcons: '=',
            propertySets: '=',
            iconSets: '=',
            layerSectionId: '=',
            layerSections: '=',
            notifyChanges: '=',
            tags: '='
        },
        controller: function (layers) {
            var self = this;

            self.adminTags = [];

            layers.tags().then(function (tagList) {
                self.adminTags = tagList;
            });
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('rammLinkageNavBar', {
        templateUrl: '/components/RammLinkageNavBar/Template.html',
        bindings: {
            selectedItem: '<'
        },
        controller: function () { }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('rammPropertySet', {
        templateUrl: '/components/RammPropertySet/Template.html',
        bindings: {
            name: '=',
            tableName: '=',
            properties: '=',
            tags: '=',
            icons: '='
        },
        controller: function ($scope, $q, rammMeta, rammTables, systemColumns, propertySets) {
            var self = this;

            this.rammMeta = rammMeta;
            this.linkageTables = [];
            this.linkageTable = undefined;
            this.systemColumns = [];
            this.tableAutocompleteLoading = true;
            this.columnAutocompleteLoading = true;
            this.valueAutocompleteLoading = true;
            self.adminTags = [];

            propertySets.tags().then(function (tagList) {
                self.adminTags = tagList;
            });

            this.$onInit = function () {
                $scope.$watch(function () { return self.properties }, function (changesObj) {
                    // Transform properties
                    if (!self.properties) return;
                    self.properties.forEach(function (property) {
                        if (!property.PropertyName) property.PropertyNameList = [];
                        else property.PropertyNameList = property.PropertyName.split(',').map(function (item) { return { ColumnName: item, ColumnDescription: item }; });
                        
                        if (!property.momentStartDate && property.$type === 'Date') property.momentStartDate = moment(property.RangeStart || 0);
                        if (!property.momentEndDate && property.$type === 'Date') property.momentEndDate = moment(property.RangeEnd || '2100-01-01 00:00:00');
                        property.isEnabled = true;
                    });
                });
            };

            this.transformChip = function (chip) {
                return { ColumnName: chip.ColumnName, ColumnDescription: chip.ColumnDescription };
            }
            Promise.all([self.rammMeta.tables('Higgins - NZTA SH'), rammTables.all()]).then(function (values) {
                self.linkageTables = values[1];
                self.tables = values[0];
                self.tableAutocompleteLoading = false;

                if (self.tableName !== undefined && self.tableName !== null) {
                    self.linkageTable = self.linkageTables.find(function (lt) { return lt.DatabaseTableName === self.tableName });
                    var table = self.tables.find(function (table) { return table.TableName === self.tableName; });
                    table.firstLoad = true;
                    self.table = table;
                    var columnPromises = [self.rammMeta.columns('Higgins - NZTA SH', self.tableName)]
                    if (self.linkageTable) columnPromises.push(systemColumns.getAllForTable(self.linkageTable.ID));
                    Promise.all(columnPromises).then(function (values) {
                        self.columnAutocompleteLoading = false;
                        self.columns = values[0];
                        self.systemColumns = values[1];

                        var newProperties = [];
                        self.columns.forEach(function (column, i) {
                            if (self.properties.find(function (prop) { return prop.PropertyName === column.ColumnName }) == undefined) {
                                var property = {
                                    $type: self.getColumnType(column),
                                    DisplayName: column.ColumnDescription,
                                    PropertyName: column.ColumnName,
                                    PropertyNameList: [{ ColumnName: column.ColumnName, ColumnDescription: column.ColumnName }],
                                    ShowInReport: true,
                                    isEnabled: false
                                };

                                if (property.$type === 'Date') {
                                    property.momentStartDate = moment(0);
                                    property.momentEndDate = moment('2100-01-01 00:00:00');
                                    property.AllowNulls = true;
                                } else if (property.$type === 'Numeric') {
                                    property.RangeStart = 0;
                                    property.RangeEnd = 1000000000;
                                    property.AllowNulls = true;
                                }

                                newProperties.push(property);
                            }
                        });

                        self.properties.forEach(function (prop) {
                            newProperties.splice(prop.Index, 0, prop);
                        });

                        newProperties.forEach(function (prop, i) {
                            self.properties[i] = prop;
                        });

                        self.properties.forEach(function (p, i) {
                            if (p.PropertyName !== undefined && p.PropertyName !== null) {
                                p.PropertyNameList = p.PropertyNameList.map(function (propertyName) {
                                    var column = self.columns.find(function (column) { return column.ColumnName === propertyName.ColumnName; });
                                    column.firstLoad = true;
                                    return column;
                                });

                                if (p.Options !== undefined && p.Options !== null && p.PropertyNameList.length > 0 && self.propertyHasLookup(p)) {
                                    if (self.systemColumns) {
                                        var requests = p.PropertyNameList
                                            .filter(function (propertyName) { return propertyName.IsLookup; })
                                            .map(function (propertyName) {
                                                var column = self.systemColumns.find(function (sc) { return sc.DatabaseColumnName === propertyName.ColumnName })
                                                return systemColumns.getSystemValues(column.ID);
                                            });
                                        $q.all(requests).then(function (res) {
                                            self.valueAutocompleteLoading = false;
                                            p.valueAutocompleteLoading = false;
                                            p.values = [].concat.apply([], res.map(function (values) { return values.map(function (value) { return { LookupValue: value.Value }; }); }));
                                            p.Options.forEach(function (op) {
                                                if (op.Value !== undefined && op.Value !== null) {
                                                    op.selectedValue = p.values.find(function (lookup) { return lookup.LookupValue === op.Value; });
                                                }
                                            });
                                        });
                                    }
                                    else {
                                        var requests = p.PropertyNameList
                                            .filter(function (propertyName) { return propertyName.IsLookup; })
                                            .map(function (propertyName) {
                                                return self.rammMeta.lookup('Higgins - NZTA SH', self.tableName, propertyName.ColumnName);
                                            });
                                        $q.all(requests).then(function (res) {
                                            self.valueAutocompleteLoading = false;
                                            p.valueAutocompleteLoading = false;
                                            p.values = [].concat.apply([], res);

                                            p.Options.forEach(function (op) {
                                                if (op.Value != undefined) {
                                                    op.selectedValue = p.values.find(function (lookup) { return lookup.LookupValue === op.Value; });
                                                }
                                            });
                                        });
                                    }
                                } else {
                                    self.valueAutocompleteLoading = false;
                                }
                            }
                        });
                    });
                } else {
                    self.valueAutocompleteLoading = false;
                }
            });
            

            this.tableSearch = function (query) {
                if (this.tableAutocompleteLoading) {
                    return null;
                } else {
                    return this.tables.filter(function (item) { return item.TableDescription.toUpperCase().indexOf(query.toUpperCase()) >= 0 });
                }
            }

            this.columnSearch = function (query) {
                if (this.columnAutocompleteLoading) {
                    return null;
                } else {
                    return this.columns.filter(function (item) { return item.ColumnDescription.toUpperCase().indexOf(query.toUpperCase()) >= 0 });
                }
            }

            this.valueSearch = function (query, property) {
                if (property.valueAutocompleteLoading) {
                    return null;
                } else {
                    return property.values.filter(function (item) { return item.LookupValue.toUpperCase().indexOf(query.toUpperCase()) >= 0 });
                }
            }

            this.selectedTableChange = function (item) {
                if (!item) return;
                this.tableName = item.TableName;
                self.linkageTable = self.linkageTables.find(function (lt) { return lt.DatabaseTableName === self.tableName });

                if (self.table.firstLoad) {
                    self.table.firstLoad = false;
                    return;
                }

                self.columnAutocompleteLoading = true;
                var columnPromises = [self.rammMeta.columns('Higgins - NZTA SH', self.tableName)]
                if (self.linkageTable) columnPromises.push(systemColumns.getAllForTable(self.linkageTable.ID));
                Promise.all(columnPromises).then(function (values) {
                    self.columnAutocompleteLoading = false;
                    self.columns = values[0];
                    self.systemColumns = values[1];
                    self.columnAutocompleteLoading = false;

                    self.properties = [];
                    self.columns.forEach(function (column) {
                        var property = {
                            $type: self.getColumnType(column),
                            DisplayName: column.ColumnDescription,
                            PropertyName: column.ColumnName,
                            PropertyNameList: [{ ColumnName: column.ColumnName, ColumnDescription: column.ColumnName }],
                            ShowInReport: true,
                            isEnabled: false
                        };

                        if (property.$type === 'Date') {
                            property.momentStartDate = moment(0);
                            property.momentEndDate = moment('2100-01-01 00:00:00');
                            property.AllowNulls = true;
                        } else if (property.$type === 'Numeric') {
                            property.RangeStart = 0;
                            property.RangeEnd = 1000000000;
                            property.AllowNulls = true;
                        }

                        self.properties.push(property);
                    });
                });
            }

            this.getColumnType = function (column) {
                if (column.IsLookup) return 'Text'; // Should probably be multichoice, but doesn't work quite yet
                if (column.DataType.toLowerCase().includes('date') || column.DataType.toLowerCase().includes('time')) return 'Date';
                if (column.DataType.toLowerCase().includes('int') || column.DataType.toLowerCase().includes('decimal')) return 'Numeric';
                else return 'Text';
            }

            this.loadPropertyLookupValues = function (property) {
                property.PropertyName = property.PropertyNameList.map(function (item) { return item.ColumnName; }).join(',');
                if (property.PropertyName.length === 0) property.validationError = true;
                else property.validationError = false;
                if (!property.UseLookupValues) return;

                property.PropertyNameList = property.PropertyNameList.map(function (propertyName) {
                    return self.columns.find(function (column) { return column.ColumnName === propertyName.ColumnName; });
                });

                if (property.PropertyNameList.length < 2) {
                    property.CombineFields = false;
                    property.UseFieldsAsFlags = false;
                    if(property.Options)
                    property.Options.forEach(function (opt) {
                        opt.flags = [];
                    })
                }

                property.valueAutocompleteLoading = true;
                if (self.systemColumns) {
                    var requests = property.PropertyNameList
                        .filter(function (propertyName) { return propertyName.IsLookup; })
                        .map(function (propertyName) {
                            var column = self.systemColumns.find(function (sc) { return sc.DatabaseColumnName === propertyName.ColumnName })
                            return systemColumns.getSystemValues(column.ID);
                        });
                    $q.all(requests).then(function (res) {
                        self.valueAutocompleteLoading = false;
                        property.valueAutocompleteLoading = false;
                        property.values = [].concat.apply([], res.map(function (values) { return values.map(function (value) { return { LookupValue: value.Value }; }); }));
                    });
                }
                else {
                    var requests = property.PropertyNameList
                        .filter(function (propertyName) { return propertyName.IsLookup; })
                        .map(function (propertyName) {
                            return self.rammMeta.lookup('Higgins - NZTA SH', self.tableName, propertyName.ColumnName);
                        });
                    Promise.all(requests).then(function (res) {
                        property.values = [].concat.apply([], res);
                        property.valueAutocompleteLoading = false;
                    });
                }
            }

            this.combineFieldsChanged = function (property) {
                if (!property.CombineFields) {
                    property.UseFieldsAsFlags = false;
                    property.Options.forEach(function (opt) {
                        opt.flags = [];
                    });
                }
            };

            this.useFieldsAsFlagsChanged = function (property) {
                if (!property.UseFieldsAsFlags) {
                    property.Options.forEach(function (opt) {
                        opt.flags = [];
                    })
                }
            }

            this.indexToFlag = function (index) {
                return 1 << index;
            };

            this.flagsToValue = function (option) {
                var val = 0;
                if (option.flags)
                    option.flags.forEach(function (flag) {
                        val += flag;
                    });
                option.Value = val;
            };

            this.selectedValueChange = function (item, option) {
                if (!item) return;
                option.Value = item.LookupValue;
            };

            this.updateHeader = function (position) {
                self.properties.forEach(function (property, index) {
                    if (position != index)
                        property.UseAsHeading = false;
                });
            };

            this.updateShowInReport = function (position) {
                var property = self.properties[position];
                property.ShowInReport = property.HideInReport;
            }

            this.propertyHasLookup = function (property) {
                var propertyHasLookup = property.PropertyNameList.find(function (column) { return column.IsLookup; });
                return propertyHasLookup !== undefined && propertyHasLookup !== null;
            };

            this.updateId = function (position) {
                self.properties.forEach(function (property, index) {
                    if (position != index)
                        property.UseAsId = false;
                });
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('rammReport', {
        templateUrl: '/components/RammReport/Template.html',
        bindings: {
            name: '=',
            icon: '=',
            propertySetId: '=',
            propertySets: '=',
            tags: '='
        },
        controller: function (reports) {
            var self = this;

            self.adminTags = [];

            reports.tags().then(function (tagList) {
                self.adminTags = tagList;
            });
        }
    });
})();
(function(){
    "use strict";

    angular.module('hip').component('reportSelector', {
        templateUrl: '/components/ReportSelector/Template.html',
        bindings: {
            reports: '=',
            reportId: '=',
            onChange: '=',
            onUpdate: '&'
        },
        controller: function (reports, $attrs) {
            var self = this;
            this.type = $attrs.type || 'wfs';
            if (this.type === 'wfs') this.typeNum = 0;
            else if (this.type === 'ramm') this.typeNum = 1;

            this.update = function () {
                this.onUpdate({ id: self.reportId });
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('resourcesNavBar', {
        templateUrl: '/components/ResourcesNavBar/Template.html',
        bindings: {
            selectedItem: '<'
        },
        controller: function () { }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('ribbonPermissionsPicker', {
        templateUrl: '/components/RibbonPermissionsPicker/Template.html',
        bindings: {
            ribbonPermissions: '=',
        },
        controller: function () {
            var self = this;

            self.checkPermission = function (value) {
                return self.ribbonPermissions & value;
            };

            self.updatePermission = function (value) {
                self.ribbonPermissions ^= value;
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('bipRole', {
        templateUrl: '/components/Role/Template.html',
        bindings: {
            name: '=',
            ignorePermissions: '=',
            isVisibleAtSignUp: '=',
            ribbonPermissions: '=',
            canManageAssetPrivacy: '=',
            tags: '='
        },
        controller: function ($http, roles) {
            var self = this;
            self.adminTags = [];
            //get all tags used in roles to pass to the tags controller
            roles.tags().then(function (tagList) {
                self.adminTags = tagList;
            });
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('roleSelector', {
        templateUrl: '/components/RoleSelector/Template.html',
        bindings: {
            roleId: '=',
            roles: '=',
            onUpdate: '&'
        },
        controller: function ($attrs) {
            var self = this;
            this.hasDefault = $attrs.hasDefault === "true";
            this.defaultText = $attrs.defaultText || "No role";

            this.update = function () {
                if (this.onUpdate)
                    this.onUpdate({ id: self.roleId });
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('bipSource', {
        templateUrl: '/components/Source/Template.html',
        bindings: {
            id: '=',
            name: '=',
            url: '=',
            status: '=',
            lastVerified: '=',
            tags: '='
        },
        controller: function (sources) {
            var self = this;
            this.source = { Status: self.status, isVerifying: false };
            self.adminTags = [];

            sources.tags().then(function (tagList) {
                self.adminTags = tagList;
            });

            this.openSource = function () {
                window.open(self.url);
            }

            this.verifySource = function () {
                // Probably bad, but source.name and source.URL will be undefined, because the bidings aren't loaded
                // above when the source is initialised
                self.source.Name = self.name;
                self.source.URL = self.url;
                sources.verifySource(self.source, function () {
                    self.status = self.source.Status;
                    self.lastVerified = self.source.LastVerified;

                    if (!self.id) return;

                    sources.update(self.id, {
                        Name: self.source.Name,
                        URL: self.source.URL,
                        Status: self.source.Status,
                        LastVerified: self.source.LastVerified
                    });
                });
            }
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('sourceSelector', {
        templateUrl: '/components/SourceSelector/Template.html',
        bindings: {
            sources: '=',
            sourceId: '='
        },
        controller: function () {

        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('bipState', {
        templateUrl: '/components/State/Template.html',
        bindings: {
            name: '=',
            tags: '='
        },
        controller: function ($http, states) {
            var self = this;
            this.stateStatus = "";
            self.adminTags = [];

            states.tags().then(function (tagList) {
                self.adminTags = tagList;
            });
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('stateSelector', {
        templateUrl: '/components/StateSelector/Template.html',
        bindings: {
            stateId: '=',
            states: '=',
            onUpdate: '&'
        },
        controller: function ($attrs) {
            var self = this;
            this.hasDefault = $attrs.hasDefault === "true";
            this.defaultText = $attrs.defaultText || "Default state";
            
            this.update = function () {
                if (this.onUpdate)
                    this.onUpdate({ id: self.stateId });
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('tagsFilter', {
        templateUrl: '/components/TagsFilter/Template.html',
        bindings: {
            tags: '=',
            searchText: '='
        },
        controller: function ($scope, filterFilter, adminTags) {
            $scope.selectedItem = null;
            $scope.searchText = null;
            $scope.adminTags = null;
            $scope.loading = true;

            adminTags.all().then(function (tags) {
                $scope.loading = false;
                $scope.adminTags = tags;
            });

            $scope.transformChip = function (chip) {
                // If it is an object, it's already a known chip
                if (angular.isObject(chip)) {
                    return chip;
                } else {
                    var existingTag = $scope.adminTags.find(function (tag) { return tag.Text === chip });
                    if (existingTag) return existingTag;
                    else return { Text: chip, Keyword: true };
                }
            }

            $scope.tagSearch = function (searchText) {
                return filterFilter($scope.adminTags, searchText)
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('tagsSection', {
        templateUrl: '/components/TagsSection/Template.html',
        bindings: {
            tags: '=',
            adminTags: '='
        },
        controller: function ($scope, filterFilter, adminTags) {
            var self = this;
            self.selectedItem = null;
            self.searchText = "";
            self.loading = true;

            self.transformChip = function (chip) {
                // If it is an object, it's already a known chip
                if (angular.isObject(chip)) {
                    return chip;
                } else {
                    var existingTag = self.adminTags.find(function (tag) { return tag.Text === chip });
                    if (existingTag) return existingTag;
                    else return { Text: chip, New: true };
                }
            }

            self.tagSearch = function (searchText) {
                return filterFilter(self.adminTags, searchText)
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('theme', {
        templateUrl: '/components/Theme/Template.html',
        bindings: {
            name: '=',
            title: '=',
            iconId: '=',
            slogan: '=',
            primaryColour: '=',
            accentColour: '=',
            tags: '=',
            icons: '='
        },
        controller: function (themes) {
            var self = this;
            self.adminTags = [];
            themes.tags().then(function (tagList) {
                self.adminTags = tagList;
            })
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('themeSelector', {
        templateUrl: '/components/ThemeSelector/Template.html',
        bindings: {
            themeId: '=',
            themes: '=',
            onUpdate: '&'
        },
        controller: function () {
            this.update = function () {
                this.onUpdate({ id: self.themeId });
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('timezoneSelector', {
        templateUrl: '/components/TimezoneSelector/Template.html',
        bindings: {
            timezone: '='
        },
        controller: function () {
            this.suggest = function (queryText) {
                this.suggestions = query ? moment.tz.names().filter(function (item) {
                    return item.toUpperCase().indexOf(query.toUpperCase()) >= 0
                }) : moment.tz.names();
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('user', {
        templateUrl: '/components/User/Template.html',
        bindings: {
            userId: '=',
            userName: '=',
            emailAddress: '=',
            firstName: '=',
            lastName: '=',
            phoneNumber: '=',
            employeeNumber: '=',
            divisionIds: '=',
            themeId: '=',
            isAdministrator: '=',
            canChangeState: '=',
            subscribedToSos: '=',
            roleId: '=',
            themes: '=',
            roles: '=',
            divisionMultiselectItems: '=',
            groupMultiselectItems: '=',
            groupIds: '=',
            hideGroupSelect: '=',
            permissionReviewFrequency: '=', 
            tags: '=',
            onChange: '&',
            tree: '='
        },
        controller: function ($scope, users) {
            var self = this;
            $scope.busy = true;
            self.adminTags = [];

            users.tags().then(function (tagList) {
                self.adminTags = tagList;
            });

            this.change = function () {
                this.onChange({
                    userName: this.userName,
                    emailAddress: this.emailAddress,
                    firstName: this.firstName,
                    lastName: this.lastName,
                    phoneNumber: this.phoneNumber,
                    employeeNumber: this.employeeNumber,
                    divisionIds: this.divisionIds,
                    themeId: this.themeId,
                    isAdministrator: this.isAdministrator,
                    canChangeState: this.canChangeState,
                    subscribedToSos: this.subscribedToSos,
                    permissionReviewFrequency: this.permissionReviewFrequency,
                    roleId: this.roleId,
                    tags: this.tags
                });
            };

            this.renewLastReview = function () {
                users.renewLastReview(this.userId);
            };

            this.idExist = function () {
                if (this.userId !== undefined)
                    return true;
                return false;
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('userSelector', {
        templateUrl: '/components/UserSelector/Template.html',
        bindings: {
            users: '=',
            userId: '<',
            excludeIds: '<',
            onUpdate: '&'
        },
        controller: function (users) {
            var self = this;

            this.filter = function (user, index, users) {
                if (self.excludeIds == undefined) {
                    return true;
                }

                return self.excludeIds.find(function (id) { return id === user.ID; }) == undefined;
            };

            this.update = function () {
                var user = this.users.findById(this.userId);
                this.onUpdate(user);
            };
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('validationRule', {
        templateUrl: '/components/ValidationRule/Template.html',
        bindings: {
            formValidationRule: '=',
            form: '=',
            lookups: '='
        },
        controller: function ($mdDialog, layers, forms, formValidationRules) {
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('conditionSet', {
        templateUrl: '/components/ValidationRuleConditionSet/Template.html',
        bindings: {
            conditionSets: '=',
            form: '=',
            formValidationRule: '=',
            inner: '=',
            nested: '=',
            lookups: '='
        },
        controller: function () {

            var self = this;
            this.conditionMultiValueChanged = function (condition) {
                condition.Value = condition.Values.join(',');
            }

            this.updateConditionValue = function (condition) {
                if (condition.Operator === 8 || condition.Operator === 9) condition.Value = undefined;
                self.clearValues(condition);
            }

            this.clearValues = function (condition) {
                condition.Value = undefined;
                condition.Values = undefined;
            }
            
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('valueSelector', {
        templateUrl: '/components/ValueSelector/Template.html',
        bindings: {
            systemValue: '=',
            values: '=',
            assigningTo: '=',
            unique: '=',
            busy: '=',
            onUpdate: '&',
            usedValues: '=',
            extraFilter: '&',
            boundValues: '='
        },
        controller: function ($scope) {
            var self = this;
            
            this.check = function (c) {
                return true;
            }

            this.filter = function () {
                var self = this;
                this.boundValues = self.extraFilter();
            }
        }

    });
})();
(function () {
    "use strict";

    angular.module('hip').component('wfsIconSet', {
        templateUrl: '/components/WfsIconSet/Template.html',
        bindings: {
            name: '=',
            sourceName: '=',
            filters: '=',
            tags: '=',
            icons: '=',
            isValid: '='
        },
        controller: function ($mdDialog, $scope, sources, iconSets) {
            var self = this;

            this.sourceAutocompleteLoading = true
            this.columnAutocompleteLoading = true;
            this.columns = [];
            self.adminTags = [];

            iconSets.tags().then(function (tagList) {
                self.adminTags = tagList;
            });

            this.showFunctions = function () {
                $mdDialog.show({
                    controller: function DialogController($scope, $mdDialog) {
                        $scope.hide = function () {
                            $mdDialog.hide();
                        };

                        $scope.cancel = function () {
                            $mdDialog.cancel();
                        };

                        $scope.answer = function (answer) {
                            $mdDialog.hide(answer);
                        };
                    },
                    template:
                    '<md-dialog aria-label="Value Functions">' +
                    '    <form ng-cloak>' +
                    '        <md-toolbar>' +
                    '            <div class="md-toolbar-tools">' +
                    '                <h2>Value Functions</h2>' +
                    '                <span flex></span>' +
                    '                <md-button class="md-icon-button" ng-click="cancel()">' +
                    '                    <i class="material-icons" aria-label="Close dialog">close</i>' +
                    '                </md-button>' +
                    '            </div>' +
                    '        </md-toolbar>' +
                    '    ' +
                    '       <md-dialog-content>' +
                    '            <div class="md-dialog-content">' +
                    '                <h2>Today</h2>' +
                    '                <p>' +
                    '                    The today function can be used to get a date relative to the date when the comparison is made.<br />' +
                    '                    <b>Usage: </b> today([<i>+/-</i>][<i>number</i>][<i>unit</i>]) <br />' +
                    '                    <table><tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="width:35px; padding: 0;"><b>Units: </b></td><td style="width:15px; padding: 0; text-align: center;">Y</td><td style="width:11px; padding: 0;  text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Years</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">M</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Months</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">W</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Weeks</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">D</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Days</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">h</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Hours</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">m</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Minutes</td></tr>' +
                    '                    <tr style="height:unset;" onmouseover="this.style.background = \'unset\'"><td style="padding: 0;"></td><td style="padding: 0; text-align: center;">s</td><td style="padding: 0; text-align: center;">-</td><td style="padding: 0; padding-left: 4px;">Seconds</td></tr></table><br />' +
                    '                    <b>Example: </b> To use the date 6 months back use <i>today(-6M)</i>' +
                    '                </p>' +
                    '    ' +
                    '           </div>' +
                    '        </md-dialog-content>' +
                    '    ' +
                    '        <md-dialog-actions layout="row">' +
                    '           <span flex></span>' +
                    '            <md-button ng-click="cancel()">' +
                    '               Ok' +
                    '            </md-button>' +
                    '        </md-dialog-actions>' +
                    '    </form>' +
                    '</md-dialog>',
                    parent: angular.element(document.body),
                    clickOutsideToClose: true,
                });
            }

            Promise.all([sources.all()]).then(function (values) {
                self.sourceValues = values[0];
                self.sourceAutocompleteLoading = false;

                if (self.sourceName !== undefined && self.sourceName !== null) {

                    self.source = self.sourceValues.find(function (source) { return source.Name === self.sourceName });

                    jQuery.get(self.source.URL).then(function (data) {
                        self.columnAutocompleteLoading = false;
                        if (data.features && data.features[0]) {
                            self.columns = Object.getOwnPropertyNames(data.features[0].properties);
                        }
                    });
                }
            });

            this.sourceSearch = function (query) {
                if (self.sourceAutocompleteLoading) {
                    return [];
                }
                return this.sourceValues.filter(function (item) { return item.Name.toUpperCase().indexOf(query.toUpperCase()) >= 0 });
            }

            this.selectedSourceChange = function (item) {
                if (!item) return;
                this.sourceName = item.Name;
                self.columnAutocompleteLoading = true;
                //get the information from the selected source url
                jQuery.get(item.URL).then(function (data) {
                    self.columnAutocompleteLoading = false;
                    if (data.features && data.features[0]) {
                        self.columns = Object.getOwnPropertyNames(data.features[0].properties);
                    }
                });
            }

            this.selectedColumnChange = function (item, property) {
                if (!item) return;
                property.Field = item;
            }


            this.checkIfValid = function () {
                this.isValid = false;
                
                this.filters.forEach(function (filter) { if (!filter.IsForeground) { self.isValid = true; } });
            }

            this.columnSearch = function (query) {
                if (self.columnAutocompleteLoading) {
                    return [];
                }
                return self.columns.filter(function (item) { return item.toUpperCase().indexOf(query.toUpperCase()) >= 0 })
            }

            this.duplicate = function (filter) {
                var dupe = Object.clone(filter);
                delete dupe.$$hashKey;
                dupe.ID = undefined;
                this.filters.push(dupe);
            }
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('wfsLayer', {
        templateUrl: '/components/WfsLayer/Template.html',
        bindings: {
            layerId: '=',
            name: '=',
            loadButton: '=',
            weight: '=',
            refreshInterval: '=',
            iconSetId: '=',
            infoIconSetId: '=',
            propertySetId: '=',
            showDetails: '=',
            filterDetails: '=',
            allowSituationReports: '=',
            geometricFilter: '=',
            forceShowIconKey: '=',
            hideIcons: '=',
            iconSets: '=',
            propertySets: '=',
            layerSectionId: '=',
            layerSections: '=',
            notifyChanges: '=',
            tags: '='
        },
        controller: function (layers) {
            var self = this;

            self.adminTags = [];

            layers.tags().then(function (tagList) {
                self.adminTags = tagList;
            });
        }

    });
})();
﻿(function () {
    "use strict";

    angular.module('hip').component('wfsPropertySet', {
        templateUrl: '/components/WfsPropertySet/Template.html',
        bindings: {
            name: '=',
            sourceName: '=',
            properties: '=',
            tags: '=',
            icons: '='
        },
        controller: function ($scope, sources, propertySets) {
            var self = this;

            this.sourceAutocompleteLoading = true
            this.propertyNameAutocompleteLoading = true;
            this.propertyNames = [];
            self.adminTags = [];

            propertySets.tags().then(function (tagList) {
                self.adminTags = tagList;
            });


            this.$onInit = function () {
                $scope.$watch(function () { return self.properties }, function (changesObj) {
                    // Transform properties
                    if (!self.properties) return;
                    self.properties.forEach(function (property) {
                        if (!property.PropertyName) property.PropertyNameList = [];

                        else property.PropertyNameList = property.PropertyName.split(',');
                        
                        if (!property.momentStartDate && property.$type === 'Date') property.momentStartDate = moment(property.RangeStart || 0);
                        if (!property.momentEndDate && property.$type === 'Date') property.momentEndDate = moment(property.RangeEnd || '2100-01-01 00:00:00');
                    });
                });
            };

            Promise.all([sources.all()]).then(function (values) {
                self.sourceValues = values[0];
                self.sourceAutocompleteLoading = false;

                if (self.sourceName !== undefined && self.sourceName !== null) {
                    self.source = self.sourceValues.find(function (source) { return source.Name === self.sourceName });

                    jQuery.get(self.source.URL).then(function (data) {
                        self.propertyNameAutocompleteLoading = false;
                        if (data.features && data.features[0]) {
                            self.propertyNames = Object.getOwnPropertyNames(data.features[0].properties);
                        }
                    });
                }
            });

            this.propertySearch = function (query) {
                if (this.propertyNameAutocompleteLoading) {
                    return [];
                }
                return this.propertyNames.filter(function (item) { return item.toUpperCase().indexOf(query.toUpperCase()) >= 0 });
            }

            this.sourceSearch = function (query) {
                if (this.sourceAutocompleteLoading) {
                    return [];
                }
                return this.sourceValues.filter(function (item) {return item.Name.toUpperCase().indexOf(query.toUpperCase()) >= 0 });
            }

            this.selectedSourceChange = function (item) {
                if (!item) return;
                this.sourceName = item.Name;
                self.propertyNameAutocompleteLoading = true;
                //get the information from the selected source url
                jQuery.get(item.URL).then(function (data) {
                    self.propertyNameAutocompleteLoading = false;
                    if (data.features && data.features[0]) {
                        self.propertyNames = Object.getOwnPropertyNames(data.features[0].properties);
                    }

                    self.properties = [];
                    self.propertyNames.forEach(function (propertyName) {
                        var property = {
                            $type: 'Text',
                            DisplayName: propertyName,
                            PropertyName: propertyName,
                            isEnabled: false
                        }
                        self.properties.push(property);
                    });
                });
            }

            this.displayNameChanged = function (property) {
                property.PropertyName = property.PropertyNameList.join(',');
                if (property.PropertyName.length === 0) property.validationError = true;
                else property.validationError = false;
                if (property.PropertyNameList.length < 2) {
                    
                    property.CombineFields = false;
                    property.UseFieldsAsFlags = false;
                    if(property.Options)
                        property.Options.forEach(function (opt) {
                            opt.flags = [];
                        });
                }
            }

            this.combineFieldsChanged = function (property) {
                if (!property.CombineFields) {
                    property.UseFieldsAsFlags = false;
                    property.Options.forEach(function (opt) {
                        opt.flags = [];
                    })
                }
            }
            this.useFieldsAsFlagsChanged = function (property) {
                if (!property.UseFieldsAsFlags) {
                    property.Options.forEach(function (opt) {
                        opt.flags = [];
                    })
                }
            }

            this.indexToFlag = function(index){
                return 1 << index;
            }

            this.flagsToValue = function (option) {
                var val = 0;
                option.flags.forEach(function (flag) {
                    val += flag;
                })
                option.Value = val;
            }

            this.updateHeader = function (position) {
                self.properties.forEach(function (property, index) {
                    if (position != index)
                        property.UseAsHeading = false;
                });
            }

            this.updateShowInReport = function (position) {
                var property = self.properties[position];
                property.ShowInReport = property.HideInReport;
            }

            this.updateId = function (position) {
                self.properties.forEach(function (property, index) {
                    if (position != index)
                        property.UseAsId = false;
                });
            }
        }
    });
})();
(function () {
    "use strict";

    angular.module('hip').component('wfsReport', {
        templateUrl: '/components/WfsReport/Template.html',
        bindings: {
            name: '=',
            icon: '=',
            propertySetId: '=',
            propertySets: '=',
            tags: '='
        },
        controller: function (reports) {
            var self = this;

            self.adminTags = [];

            reports.tags().then(function (tagList) {
                self.adminTags = tagList;
            });
        }
    });
})();
