(function (angular) {
'use strict';
/**
* @memberof spApp
* @ngdoc service
* @name LayoutService
* @description
* Management of spatial-hub dialogs and panels
*/
angular.module('layout-service', [])
.factory("LayoutService", ['$uibModal', '$timeout', '$rootScope', 'SessionsService', 'HttpService', 'WorkflowService', 'LoggerService',
function ($uibModal, $timeout, $rootScope, sessionsService, httpService, WorkflowService, LoggerService) {
var showLegend = [false];
var showOptions = [false];
var layoutStack = [];
var modelessStack = [];
var toOpenStack = [];
var panelMode = ['default'];
var panels = ['default', 'area', 'envelope', 'nearestLocality', 'pointComparison'];
//default, area
var panelData = {
area: {}
};
var _this = {
showOptions: showOptions,
showLegend: showLegend,
panelMode: panelMode,
toOpenStack: toOpenStack,
panelData: panelData,
getStack: function () {
return layoutStack;
},
enable: function (type, data) {
if (type === 'legend') {
showLegend[0] = data === undefined ? false : data;
showOptions[0] = false;
} else if (type === 'options') {
showLegend[0] = false;
showOptions[0] = true;
}
},
getValue: function (component, param, defaultValue) {
var top = layoutStack[layoutStack.length - 1];
if (top !== undefined) {
if (top[2][component] !== undefined && top[2][component][param] !== undefined) {
return top[2][component][param]
}
}
return defaultValue
},
saveValues: function () {
var top = layoutStack[layoutStack.length - 1];
if (top !== undefined) {
for (var k1 in top[1]) {
if (k1[0] !== '$' && k1[0] !== '_' && top[1].hasOwnProperty(k1)) {
var s = top[1][k1];
for (var k2 in s) {
if (k2[0] !== '$' && k2[0] !== '_' && s.hasOwnProperty(k2)) {
if (!(s[k2] instanceof Function)) {
if (top[2][s.componentName] === undefined)
top[2][s.componentName] = {};
top[2][s.componentName][k2] = s[k2]
}
}
}
}
}
this.createCheckpoint();
}
},
/* Save the state of a modal controller. Call after initialising controller vars. */
addToSave: function (scopeToSave) {
if (layoutStack.length > 0) {
var top = layoutStack[layoutStack.length - 1];
//apply saved values, if any
if (top[2][scopeToSave.componentName]) {
for (var k in top[2][scopeToSave.componentName]) {
if (k[0] !== '$' && k[0] !== '_' && top[2][scopeToSave.componentName].hasOwnProperty(k)) {
var v = top[2][scopeToSave.componentName][k];
if (scopeToSave[k] !== undefined && !(v instanceof Function) &&
(v instanceof Array || v instanceof Object || v instanceof String ||
v instanceof Number || typeof(v) == 'string' || typeof(v) == 'number' ||
typeof(v) == 'boolean')) {
scopeToSave[k] = v
}
}
}
}
top[1][scopeToSave.componentName] = scopeToSave
}
},
/* adds popup to modeless stack */
addToModeless: function (scope) {
// remove from modal stack
layoutStack.pop()
// add to modeless stack
modelessStack.push(scope)
},
saveScope: function (scopeToSave) {
if (layoutStack.length > 0) {
var top = layoutStack[layoutStack.length - 1];
top[1][scopeToSave.componentName] = scopeToSave;
}
},
/* open a panel */
openPanel: function (type, data, reopen) {
this.saveSession();
this._closeOpen(reopen);
if (panelData[type] === undefined) panelData[type] = {};
panelData[type].data = data;
this.panelMode[0] = type;
this.createCheckpoint();
},
/* clear all saved panel info */
clear: function (data) {
layoutStack = []
},
/* list valid panels */
panels: function () {
return panels
},
/* test if a string is a valid panel name */
isPanel: function (name) {
return panels.indexOf(name) >= 0
},
/* close a panel */
closePanel: function (data) {
this.panelMode[0] = 'default';
this.openFromStack(data);
$timeout(function () {
$(window).trigger('resize');
}, 0)
},
openModal: function (type, data, reopen, openingFromStack) {
this.saveSession();
if (openingFromStack === undefined || !openingFromStack)
this._closeOpen(reopen);
var size = 'lg';
if (data && data.display && data.display.size) size = data.display.size;
var modalInstance = $uibModal.open({
animation: false,
templateUrl: '/spApp/' + type + 'Content.htm',
controller: type[0].toUpperCase() + type.substring(1) + 'Ctrl',
size: size,
backdrop: 'static',
resolve: {
data: function () {
return data;
}
}
});
if (openingFromStack === undefined || !openingFromStack) {
layoutStack.push(["openModal", {}, [], type, data]);
this.createCheckpoint()
}
modalInstance.result.then(function (data) {
if (data !== undefined) {
if (data[0]) {
//do save
_this.saveValues()
} else {
for (var i in layoutStack) {
if (layoutStack[i] === data[1]) {
layoutStack.splice(Number(i), 1)
}
}
}
} else {
layoutStack.pop();
//layoutCtrl will call openFromStack because it has a $watch on toOpenStack
toOpenStack.push(data)
}
}, function () {
});
},
/* open window from the save stack */
openFromStack: function (data) {
if (layoutStack.length > 0) {
var top = layoutStack[layoutStack.length - 1];
var _autoClose = true;
for (var k in top[1]) {
if (top[1].hasOwnProperty(k)) {
if (top[1][k]._autoClose !== undefined) {
_autoClose = top[1][k]._autoClose
}
}
}
if (_autoClose) {
$timeout(function (item) {
if (item[0] === 'openModal') {
_this.openModal(item[3], item[4], false, true)
}
}, 0, false, top)
}
}
},
/* close one or all modeless windows */
closeModeless: function (nameOrId) {
for (var k in modelessStack) {
if (modelessStack.hasOwnProperty(k)) {
if (!nameOrId ||
modelessStack[k].componentName == nameOrId ||
modelessStack[k].$id == nameOrId) {
if (modelessStack[k].close) {
// custom close method
modelessStack[k].close()
} else if (modelessStack[k].$close) {
// default close method
modelessStack[k].$close()
}
modelessStack.splice(k, 1)
}
}
}
},
/* close top modal window */
_closeOpen: function (reopen) {
if (layoutStack.length > 0) {
_this.saveValues();
var top = layoutStack[layoutStack.length - 1];
var close = undefined;
for (var k in top[1]) {
if (top[1].hasOwnProperty(k)) {
if (top[1][k].$close !== undefined && !top[1][k]._autoClose) {
close = top[1][k].$close
}
}
}
if (close) close([reopen, top])
}
},
/* open an iframe */
openIframe: function (url, reopen) {
this._openIframe(url, '', '', '', reopen, false)
},
_openIframe: function (url, title, notes, returnData, reopen, openingFromStack) {
if (openingFromStack === undefined || !openingFromStack)
this._closeOpen(reopen);
var modalInstance = $uibModal.open({
animation: true,
templateUrl: '/spApp/modalIframeContent.htm',
controller: 'ModalIframeInstanceCtrl',
size: 'full',
backdrop: 'static',
resolve: {
src: function () {
return url;
},
title: function () {
return title;
},
notes: function () {
return notes;
}
}
});
modalInstance.opened.then(function (data) {
$(".modal-body").height($(window).height() - 100);
});
modalInstance.result.then(function (data) {
toOpenStack.push(data)
}, function () {
});
},
createCheckpoint: function () {
httpService.saveLayout(this.panelMode[0], layoutStack)
},
restoreCheckpoint: function (checkpoint) {
if (!checkpoint) {
checkpoint = httpService._status
}
this.panelMode[0] = checkpoint.panel;
layoutStack = checkpoint.stack;
if (this.panelMode[0] === 'default') {
this.openFromStack();
} else {
// TODO: restore panel data and map state
}
},
saveSession: function () {
if (this.panelMode[0] === 'default' && layoutStack.length === 0) {
httpService.saveSession(sessionsService.current())
}
},
resetLayout: function (layout) {
if (layoutStack.length > 0) {
_this._closeOpen(false);
$timeout(function (layout) {
_this.resetLayout(layout)
}, 0, false, layout);
} else {
this.closePanel();
if (layout) {
this.restoreCheckpoint(layout)
}
}
},
info: function (item) {
if (item.layertype === 'species') {
item.display = {size: 'full'};
this.openModal('speciesInfo', item, false)
} else if (item.layertype === 'area' && item.metadataUrl === undefined) {
var b = item.bbox;
if ((item.bbox + '').match(/^POLYGON/g) != null) {
//convert POLYGON box to bounds
var split = item.bbox.split(',');
var p1 = split[1].split(' ');
var p2 = split[3].split(' ');
b = [[Math.min(p1[1], p2[1]), Math.min(p1[0], p2[0])], [Math.max(p1[1], p2[1]), Math.max(p1[0], p2[0])]]
}
if (item.bbox && item.bbox.length === 4) {
b = [[item.bbox[1], item.bbox[0]], [item.bbox[3], item.bbox[2]]]
}
var metadata = "";
if (item.metadata !== undefined) {
for (var k in item.metadata) {
if (item.metadata.hasOwnProperty(k)) {
if (item.metadata[k].indexOf !== undefined && item.metadata[k].indexOf("http") == 0) {
metadata += "<tr><td>" + k + "</td><td><a target='_blank' href='" + item.metadata[k] + "'>" + item.metadata[k] + "</a></td></tr>"
} else {
metadata += "<tr><td>" + k + "</td><td>" + item.metadata[k] + "</td></tr>"
}
}
}
}
bootbox.alert("<b>Area</b><br/><br/>" +
"<table class='table-striped table table-bordered'>" +
"<tr><td style='width:100px'>" + $i18n("Name") + "</td><td>" + item.name + "</td></tr>" +
"<tr><td>" + $i18n(347, "Description") + "</td><td>" + item.description + "</td></tr>" +
"<tr><td>" + $i18n(348, "Area (sq km)") + "</td><td>" + item.area_km.toFixed(2) + "</td></tr>" +
"<tr><td>" + $i18n(349, "Extents") + "</td><td>" + b[0][0] + " " + b[0][1] + ", " +
b[1][0] + " " + b[1][1] + "</td></tr>" + metadata + "</table>")
} else {
if (item.metadataUrl !== undefined) {
this.openIframe(item.metadataUrl, '', '')
} else if (item.layerId) {
this.openIframe($SH.layersServiceUrl + '/layer/more/' + item.layerId, '', '')
}
}
}
};
$rootScope.$on('resetLayout', function (event, data) {
_this.resetLayout(data);
});
$rootScope.$on('showLegend', function (event, data) {
_this.enable('legend', data);
});
return _this;
}])
}(angular));