/*
* License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt
*/
import React from 'react';
import {isString} from 'lodash';
import {dispatchOnAppReady} from '../core/AppDataCntlr.js';
import {ServerRequest } from '../data/ServerRequest.js';
import {getJsonData } from '../rpc/SearchServicesJson.js';
// Used for dispatch and action type constants
import * as TableStatsCntlr from '../charts/TableStatsCntlr.js';
import * as ChartsCntlr from '../charts/ChartsCntlr.js';
import * as TablesCntlr from '../tables/TablesCntlr.js';
import * as ReadoutCntlr from '../visualize/MouseReadoutCntlr.js';
import * as ImPlotCntlr from '../visualize/ImagePlotCntlr.js';
import * as MultiViewCntlr from '../visualize/MultiViewCntlr.js';
import * as AppDataCntlr from '../core/AppDataCntlr.js';
import * as DrawLayerCntlr from '../visualize/DrawLayerCntlr.js';
import * as ComponentCntlr from '../core/ComponentCntlr.js';
import {ApiExpandedView} from './ApiExpandedView.jsx';
import {dispatchAddCell, dispatchRemoveCell, dispatchEnableSpecialViewer} from '../core/LayoutCntlr.js';
import {dispatchAddSaga, dispatchAddActionWatcher, dispatchAddTableTypeWatcherDef} from '../core/MasterSaga.js';
import {showWorkspaceDialog, WorkspacePickerPopup} from '../ui/WorkspaceViewer.jsx';
import {FieldGroup} from '../ui/FieldGroup.jsx';
// Parts of the lowlevel api
import * as ApiUtil from './ApiUtil.js';
import * as ApiUtilChart from './ApiUtilChart.jsx';
import * as ApiUtilImage from './ApiUtilImage.jsx';
import * as ApiUtilTable from './ApiUtilTable.jsx';
// UI component
import {MultiImageViewer} from '../visualize/ui/MultiImageViewer.jsx';
import {ImageViewer} from '../visualize/iv/ImageViewer.jsx';
import {ImageMetaDataToolbar} from '../visualize/ui/ImageMetaDataToolbar.jsx';
import {MultiViewStandardToolbar} from '../visualize/ui/MultiViewStandardToolbar.jsx';
import {ImageExpandedMode} from '../visualize/iv/ImageExpandedMode.jsx';
import {ApiExpandedDisplay} from '../visualize/ui/ApiExpandedDisplay.jsx';
import {ApiFullImageDisplay} from '../visualize/ui/ApiFullImageDisplay.jsx';
import {TablesContainer} from '../tables/ui/TablesContainer.jsx';
import {TablePanel} from '../tables/ui/TablePanel.jsx';
import {ChartsContainer} from '../charts/ui/ChartsContainer.jsx';
import {ChartPanel} from '../charts/ui/ChartPanel.jsx';
import {MultiChartViewer} from '../charts/ui/MultiChartViewer.jsx';
import {PlotlyWrapper} from '../charts/ui/PlotlyWrapper.jsx';
import {PopupMouseReadoutFull, PopupMouseReadoutMinimal} from '../visualize/ui/PopupMouseReadout.jsx';
// builds the highlevel api
import {buildHighLevelApi} from './ApiHighlevelBuild.js';
import {buildViewerApi} from './ApiViewer.js';
// CSS
import './ApiStyle.css';
import {startTTFeatureWatchers} from '../templates/common/ttFeatureWatchers.js';
import {activeRowCenterDef} from '../visualize/saga/ActiveRowCenterWatcher.js';
import {urlLinkWatcherDef} from '../visualize/saga/UrlLinkWatcher.js';
/**
* High-level API.
* @public
* @namespace firefly
*/
/**
* Actions and action dispatchers.
* @public
* @namespace firefly.action
*/
/**
* React components.
* @public
* @namespace firefly.ui
*/
/**
* Utilities.
* @public
* @namespace firefly.util
*/
/**
* Chart utilities.
* @public
* @namespace firefly.util.chart
*/
/**
* @namespace firefly.util.data
*/
/**
* Image utilities.
* @public
* @namespace firefly.util.image
*/
/**
* Table utilities.
* @public
* @namespace firefly.util.table
*/
/**
* Start in api mode. Will create the api and call window.onFireflyLoaded(firefly)
* @ignore
*/
export function initApi() {
const lowlevelApi= buildLowlevelAPI();
const viewInterface= buildViewerApi();
const highLevelApi= buildHighLevelApi(lowlevelApi);
// a method to get JSON data from external task launcher
const getJsonFromTask = function(launcher, task, taskParams) {
const req = new ServerRequest('JsonFromExternalTask');
req.setParam({name : 'launcher', value : launcher});
req.setParam({name : 'task', value : task});
req.setParam({name : 'taskParams', value : JSON.stringify(taskParams)});
return getJsonData(req);
};
if (!window.firefly) window.firefly= {getJsonFromTask};
window.firefly.ignoreHistory = true;
Object.assign(window.firefly, lowlevelApi, highLevelApi, viewInterface);
const firefly= window.firefly;
dispatchOnAppReady(() => {
window.onFireflyLoaded && window.onFireflyLoaded(firefly);
});
startTTFeatureWatchers([urlLinkWatcherDef.id, activeRowCenterDef.id]);
initExpandedView();
}
/**
Structure of API
{
//--- High level API , all high level api are in the root
all high level functions....
//--- Low level API, lowlevel api are under action, ui, util
action : { all dispatch functions...
type: {all action type constants}
}
ui: { high level react components }
util { renderDom, unrenderDom, isDebug, debug // built by ApiUtil.js
image : {image utility routines} // imported from ApiUtilImage.js
chart : {chart utility routines} // imported from ApiUtilChart.js
table : {table utility routines} // imported from ApiUtilTable.js
data : {data utility routines???? } //todo do we need this?????
}
}
*/
/**
* Return the api object.
* @return {{action:{},ui:{},util:{}}}
* @ignore
*/
export function buildLowlevelAPI() {
const type= Object.assign({},
findActionType(TableStatsCntlr,TableStatsCntlr.TBLSTATS_DATA_KEY),
findActionType(ChartsCntlr, ChartsCntlr.DATA_PREFIX ),
findActionType(TablesCntlr, TablesCntlr.DATA_PREFIX),
findActionType(TablesCntlr, TablesCntlr.RESULTS_PREFIX),
findActionType(TablesCntlr, TablesCntlr.UI_PREFIX),
findActionType(ReadoutCntlr, ReadoutCntlr.READOUT_PREFIX),
findActionType(MultiViewCntlr, MultiViewCntlr.IMAGE_MULTI_VIEW_PREFIX),
findActionType(ImPlotCntlr.default, ImPlotCntlr.PLOTS_PREFIX),
findActionType(AppDataCntlr, AppDataCntlr.APP_DATA_PATH),
findActionType(DrawLayerCntlr.default, DrawLayerCntlr.DRAWLAYER_PREFIX)
);
const action= Object.assign({},
{type},
findDispatch(TableStatsCntlr),
findDispatch(ChartsCntlr),
findDispatch(TablesCntlr),
findDispatch(ReadoutCntlr),
findDispatch(MultiViewCntlr),
findDispatch(ImPlotCntlr),
findDispatch(AppDataCntlr),
findDispatch(DrawLayerCntlr),
{dispatchAddCell, dispatchRemoveCell, dispatchEnableSpecialViewer},
{dispatchAddSaga, dispatchAddActionWatcher, dispatchAddTableTypeWatcherDef}
);
const ui= {
ImageViewer,
MultiImageViewer,
MultiViewStandardToolbar,
ApiExpandedDisplay,
ApiFullImageDisplay,
ImageExpandedMode,
ImageMetaDataToolbar,
TablesContainer,
TablePanel,
ChartsContainer,
MultiChartViewer,
ChartPanel,
PlotlyWrapper,
PopupMouseReadoutMinimal,
PopupMouseReadoutFull,
showWorkspaceDialog,
WorkspacePickerPopup: fieldGroupWrap(WorkspacePickerPopup)
};
const util= Object.assign({}, ApiUtil, {image:ApiUtilImage}, {chart:ApiUtilChart}, {table:ApiUtilTable}, {data:{}} );
return { action, ui, util };
}
/**
* pull all the dispatch functions out of the object
* @param {Object} obj
* @return {*}
* @ignore
*/
function findDispatch(obj) {
return Object.keys(obj).reduce( (res,key) => {
if (key.startsWith('dispatch')) res[key]= obj[key];
return res;
},{} );
}
/**
* pull all the action type constants out of the object
* @param {Object} obj
* @param {string} prefix
* @return {*}
* @ignore
*/
function findActionType(obj,prefix) {
return Object.keys(obj).reduce( (res,key) => {
if (isString(obj[key]) && obj[key].startsWith(prefix) && obj[key].length>prefix.length) {
res[key]= obj[key];
}
return res;
},{} );
}
function initExpandedView(div){
const EXPANDED_DIV= 'expandedArea';
var expandedDivEl;
if (div) {
expandedDivEl= isString(div) ? document.getElementById(div) : div;
} else {
expandedDivEl= document.createElement('div');
document.body.appendChild(expandedDivEl);
expandedDivEl.id= EXPANDED_DIV;
}
ApiUtil.renderDOM(expandedDivEl, ApiExpandedView);
}
function fieldGroupWrap(Component, groupKey='firefly-api-fieldgroup') {
return (props) => {
return (
<FieldGroup groupKey={groupKey}>
<Component {...props}/>
</FieldGroup>
);
};
}