/** * system route module */ define([ 'jquery', 'app/init', 'app/util', 'bootbox' ], function($, Init, Util, bootbox) { 'use strict'; var config = { // module info moduleClass: 'pf-module', // class for each module // system route module systemRouteModuleClass: 'pf-system-route-module', // class for this module // headline toolbar systemModuleHeadlineIcon: 'pf-module-icon-button', // class for toolbar icons in the head systemSecurityClassPrefix: 'pf-system-security-', // prefix class for system security level (color) // dialog routeDialogId: 'pf-route-dialog', // id for route dialog systemDialogSelectClass: 'pf-system-dialog-select', // class for system select Element systemInfoRoutesTableRowPrefix: 'pf-system-info-routes-row-', // prefix class for a row in the route table systemInfoRoutesTableClass: 'pf-system-route-table' // class for route tables }; // cache for system routes var cache = { systemRoutes: {} // jump information between solar systems }; /** * callback function, adds new row to a dataTable with jump information for a route * @param context * @param routesData */ var callbackAddRouteRow = function(context, routesData){ for(var i = 0; i < routesData.length; i++){ var routeData = routesData[i]; // format routeData var rowData = formatRouteData(routeData); if(rowData.route){ var cacheKey = routeData.route[0].system + '_' + routeData.route[ routeData.route.length - 1 ].system; // update route cache cache.systemRoutes[cacheKey] = rowData; addRow(context.dataTable, rowData); }else{ // route not possible Util.showNotify({title: 'Route not found', type: 'warning'}); } } }; /** * add a new dataTable row to the jump table * @param dataTable * @param rowData */ var addRow = function(dataTable, rowData){ var rowClass = config.systemInfoRoutesTableRowPrefix + dataTable.rows().data().length; // add new row var rowElement = dataTable.row.add( rowData ).draw().nodes().to$(); rowElement.addClass( rowClass ); rowElement.find('i').tooltip(); }; /** * show route dialog. User can search for systems and jump-info for each system is added to a data table * @param dialogData */ var showFindRouteDialog = function(dialogData){ var data = { id: config.routeDialogId, selectClass: config.systemDialogSelectClass, systemFrom: dialogData.systemFrom }; requirejs(['text!templates/dialog/route.html', 'mustache'], function(template, Mustache) { var content = Mustache.render(template, data); // disable modal focus event -> otherwise select2 is not working! -> quick fix $.fn.modal.Constructor.prototype.enforceFocus = function() {}; var findRouteDialog = bootbox.dialog({ title: 'Search shortest route', message: content, buttons: { close: { label: 'cancel', className: 'btn-default', callback: function(){ $(findRouteDialog).modal('hide'); } }, success: { label: ' search route', className: 'btn-primary', callback: function () { // add new route to route table // get form Values var form = $('#' + config.routeDialogId).find('form'); var routeDialogData = $(form).getFormValues(); // validate form form.validator('validate'); // check weather the form is valid var formValid = form.isValidForm(); if(formValid === false){ // don't close dialog return false; } var requestRouteData = [{ systemFrom: dialogData.systemFrom, systemTo: routeDialogData.systemTo }]; var contextData = { moduleElement: dialogData.moduleElement, dataTable: dialogData.dataTable }; getRouteData(requestRouteData, contextData, callbackAddRouteRow); } } } }); // init dialog findRouteDialog.on('shown.bs.modal', function(e) { var modalContent = $('#' + config.routeDialogId); // init system select live search - some delay until modal transition has finished var selectElement = modalContent.find('.' + config.systemDialogSelectClass); selectElement.delay(240).initSystemSelect({key: 'name'}); }); }); }; /** * requests route data from eveCentral API and execute callback * @param requestRouteData * @param contextData * @param callback */ var getRouteData = function(requestRouteData, contextData, callback){ var requestData = {routeData: requestRouteData}; contextData.moduleElement.showLoadingAnimation(); $.ajax({ url: Init.path.searchRoute, type: 'POST', dataType: 'json', data: requestData, context: contextData }).done(function(routesData){ this.moduleElement.hideLoadingAnimation(); // execute callback callback(this, routesData.routesData); }); }; /** * format route data from API request into dataTable row format * @param routeData * @returns {*[]} */ var formatRouteData = function(routeData){ var tableRowData = {}; if( routeData.routePossible === true && routeData.route.length > 0 ){ // route data available // add route Data var rowData = [routeData.route[ routeData.route.length - 1 ].system.toLowerCase(), routeData.routeJumps]; var jumpData = []; var avgSecTemp = 0; // loop all systems on this route for(var i = 0; i < routeData.route.length; i++){ var routeNodeData = routeData.route[i]; var systemSec = Number(routeNodeData.security).toFixed(1).toString(); var tempSystemSec = systemSec; if(tempSystemSec <= 0){ tempSystemSec = '0-0'; } var systemSecClass = config.systemSecurityClassPrefix + tempSystemSec.replace('.', '-'); var system = ''; jumpData.push( system ); avgSecTemp += Number(routeNodeData.security); } var avgSec = ( avgSecTemp / routeData.route.length).toFixed(2); var avgSecClass = config.systemSecurityClassPrefix + ( avgSecTemp / routeData.route.length).toFixed(1).toString().replace('.', '-'); tableRowData.system = rowData[0]; tableRowData.jumps = rowData[1]; tableRowData.avgTrueSec = { value: avgSec, formatted: '' + avgSec + '' }; tableRowData.route = jumpData.join(' '); } return tableRowData; }; /** * get the route finder moduleElement * @param systemData * @returns {*} */ var getModule = function(systemData){ var moduleElement = null; // load trade routes for k-space systems if(systemData.type.id === 2){ // create new module container moduleElement = $('
', { class: [config.moduleClass, config.systemRouteModuleClass].join(' ') }); // headline toolbar icons var headlineToolbar = $('
', { class: 'pull-right' }).append( $('', { class: ['fa', 'fa-fw', 'fa-search', config.systemModuleHeadlineIcon].join(' '), title: 'find route' }).attr('data-toggle', 'tooltip') ); moduleElement.append(headlineToolbar); // headline var headline = $('
', { class: 'pull-left', text: 'Routes' }); moduleElement.append(headline); // init tooltips var tooltipElements = moduleElement.find('[data-toggle="tooltip"]'); tooltipElements.tooltip({ container: 'body' }); // crate new route table var table = $('', { class: ['compact', 'stripe', 'order-column', 'row-border', config.systemInfoRoutesTableClass].join(' ') }); moduleElement.append( $(table) ); // init empty table var routesTable = table.DataTable( { paging: false, ordering: true, order: [ 1, 'asc' ], info: false, searching: false, hover: false, autoWidth: false, language: { emptyTable: 'No routes added' }, columnDefs: [ { targets: 0, orderable: true, title: 'system   ', data: 'system' },{ targets: 1, orderable: true, title: 'jumps   ', width: '40px', class: 'text-right', data: 'jumps' },{ targets: 2, orderable: true, title: 'Ø   ', width: '25px', class: 'text-right', data: 'avgTrueSec', render: { _: 'formatted', sort: 'value' } },{ targets: 3, orderable: false, title: 'route', data: 'route' } ], data: [] // will be added dynamic }); } return moduleElement; }; var initModule = function(moduleElement, systemData){ var systemFrom = systemData.name; var systemsTo = ['Jita', 'Amarr', 'Rens', 'Dodixie']; var routesTableElement = moduleElement.find('.' + config.systemInfoRoutesTableClass); var routesTable = routesTableElement.DataTable(); // init system search dialog ------------------------------------------------------------------------------- moduleElement.find('.' + config.systemModuleHeadlineIcon).on('click', function(e){ // show "find route" dialog var dialogData = { moduleElement: moduleElement, systemFrom: systemFrom, dataTable: routesTable }; showFindRouteDialog(dialogData); }); // fill routesTable with data ------------------------------------------------------------------------------ var requestRouteData = []; for(var i = 0; i < systemsTo.length; i++){ var systemTo = systemsTo[i]; if(systemFrom !== systemTo){ var cacheKey = systemFrom.toUpperCase() + '_' + systemTo.toUpperCase(); if(cache.systemRoutes.hasOwnProperty(cacheKey)){ addRow(routesTable, cache.systemRoutes[cacheKey]); }else{ // get route data requestRouteData.push({ systemFrom: systemFrom, systemTo: systemTo }); } } } // check if routes data is not cached and is requested if(requestRouteData.length > 0){ var contextData = { moduleElement: moduleElement, dataTable: routesTable }; getRouteData(requestRouteData, contextData, callbackAddRouteRow); } }; /** * updates an dom element with the system route module * @param systemData */ $.fn.drawSystemRouteModule = function(systemData){ var parentElement = $(this); // show route module var showModule = function(moduleElement){ if(moduleElement){ moduleElement.css({ opacity: 0 }); parentElement.append(moduleElement); moduleElement.velocity('transition.slideDownIn', { duration: Init.animationSpeed.mapModule, delay: Init.animationSpeed.mapModule, complete: function(){ initModule(moduleElement, systemData); } }); } }; // check if module already exists var moduleElement = parentElement.find('.' + config.systemRouteModuleClass); if(moduleElement.length > 0){ moduleElement.velocity('transition.slideDownOut', { duration: Init.animationSpeed.mapModule, complete: function(tempElement){ $(tempElement).remove(); moduleElement = getModule(systemData); showModule(moduleElement); } }); }else{ moduleElement = getModule(systemData); showModule(moduleElement); } }; });