Source: core/AppDataReducers.js

/*
 * License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt
 */

import {SHOW_DROPDOWN} from './LayoutCntlr.js';
import * as AppDataCntlr from './AppDataCntlr.js';
import {updateSet} from '../util/WebUtil.js';
import BrowserCache from '../util/BrowserCache.js';
import {smartMerge} from '../tables/TableUtil.js';

const APP_PREFERENCES= 'APP_PREFERENCES';

export function appDataReducer(state, action={}) {
    switch (action.type) {
        case AppDataCntlr.APP_LOAD  :
            return getInitState();

        case AppDataCntlr.APP_UPDATE  :
            return smartMerge(state, action.payload);

        case AppDataCntlr.ACTIVE_TARGET  :
            return updateActiveTarget(state,action);

        case AppDataCntlr.REMOVE_TASK_COUNT  :
            return removeTaskCount(state,action);

        case AppDataCntlr.ADD_TASK_COUNT  :
            return addTaskCount(state,action);

        case AppDataCntlr.ADD_PREF  :
            return addPreference(state,action);

        case AppDataCntlr.REMOVE_PREF  :
            return removePreference(state,action);

        case AppDataCntlr.SET_USER_INFO  :
            return setUserInfo(state,action);

        case AppDataCntlr.ROOT_URL_PATH :
            return Object.assign({},state, {rootUrlPath:action.payload.rootUrlPath});

        case AppDataCntlr.WS_CONN_UPDATED :
            return updateSet(state, ['connections'], action.payload);

        case AppDataCntlr.APP_OPTIONS :
            return updateSet(state, ['appOptions'], action.payload.appOptions);

        default:
            return state;
    }
}



export function menuReducer(state={}, action={}) {
    switch (action.type) {
        case SHOW_DROPDOWN  :
            const {visible, view=''} = action.payload;
            const selected = visible ? view : '';
            return updateSet(state, ['menu', 'selected'], selected);
        default:
            return state;
    }
}

export function alertsReducer(state={}, action={}) {
    switch (action.type) {
        case AppDataCntlr.SET_ALERTS :
            const {msg=''} = action.payload || {};
            return updateSet(state, ['alerts'], {msg});
        default:
            return state;
    }
}



/*---------------------------- REDUCING FUNTIONS -----------------------------*/
const updateActiveTarget= function(state,action) {
    const {worldPt,corners}= action.payload;
    return Object.assign({}, state, {activeTarget:{worldPt,corners}});
};

const addTaskCount= function(state,action) {
    const {componentId,taskId, replace}= action.payload;
    if (!componentId && !taskId) return state;
    let taskArray= state.taskCounters[componentId] || [];
    if (replace) {
        taskArray= taskArray.includes(taskId) ? taskArray : [...taskArray,taskId];
    }
    else {
        taskArray= [...taskArray,taskId];
    }
    const taskCounters= Object.assign({}, state.taskCounters, {[componentId]:taskArray});
    return Object.assign({},state, {taskCounters});
};

const removeTaskCount= function(state,action) {
    const {componentId,taskId}= action.payload;
    if (!componentId && !taskId) return state;
    let taskArray= state.taskCounters[componentId] || [];
    taskArray= taskArray.filter( (id) => id!==taskId);
    const taskCounters= Object.assign({}, state.taskCounters, {[componentId]:taskArray});
    return Object.assign({},state, {taskCounters});
};

function addPreference(state,action) {
    if (!action.payload) return state;
    const {name,value}= action.payload;
    const preferences= Object.assign({},state.preferences,{[name]:value} );
    BrowserCache.put(APP_PREFERENCES,preferences);
    return Object.assign({},state,{preferences});
}

function removePreference(state,action) {
    if (!action.payload) return state;
    const {name}= action.payload;
    const preferences= Object.assign({},state.preferences);
    Reflect.deleteProperty(preferences,name);
    BrowserCache.put(APP_PREFERENCES,preferences);
    return Object.assign({},state,{preferences});
}

function setUserInfo(state,action) {
    const userInfo = action.payload;
    return Object.assign({}, state, {userInfo});
}


/**
 *
 * @returns {AppDataStore}
 */
function getInitState() {


    /**
     * @global
     * @public
     * @typedef {Object} AppDataStore
     *
     * @summary Information about the core of the application
     *
     * @prop {boolean} isReady : false,
     * @prop {Object.<String,Array>} connections  channel:[] ... keyed by channel, contains an array of connId(s).
     * @prop {WorldPt} activeTarget
     * @prop {string} rootUrlPath
     * @prop {Array} taskCounters
     * @prop {Object} commandState
     * @prop {Object.<String,String>} preferences,
     * @prop {Object} appOptions : {}
     * @prop {Object} menu  
     * @prop {Object} alerts  ie. system notification messages
     * @prop {SearchInfo} searches define searches available to this application.
     */
    return {
        isReady : false,
        connections: {},      // channel:[] ... keyed by channel, contains an array of connId(s).
        activeTarget: null,
        rootUrlPath : null,
        taskCounters: [],
        commandState:{},   // key is command id, value is anything the action drops in, only stateful commands need this
        preferences:initPreferences(),  // preferences, will be backed by local storage
        appOptions : {},
        menu: {},
        alerts: {},
        searches: {}
    };
}

function initPreferences() {
    const prefs= BrowserCache.get(APP_PREFERENCES);
    return prefs || {};
}