function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import { merge } from "lodash";
import * as createYourOwnEnzyme from "./createYourOwnEnzyme";
import * as showGCContent from "./showGCContent";
import * as annotationLabelVisibility from "./annotationLabelVisibility";
import * as annotationsToSupport from "./annotationsToSupport";
import * as annotationVisibility from "./annotationVisibility";
import * as caretPosition from "./caretPosition";
import * as copyOptions from "./copyOptions";
import * as deletionLayers from "./deletionLayers";
import * as digestTool from "./digestTool";
import * as findTool from "./findTool";
import * as toolBar from "./toolBar";
import * as frameTranslations from "./frameTranslations";
import * as hoveredAnnotation from "./hoveredAnnotation";
import * as minimumOrfSize from "./minimumOrfSize";
import * as alignments from "./alignments";
import * as panelsShown from "./panelsShown";
import * as propertiesTool from "./propertiesTool";
import * as lastSavedId from "./lastSavedId";
import * as readOnly from "./readOnly";
import * as versionHistory from "./versionHistory";
import * as replacementLayers from "./replacementLayers";
import * as restrictionEnzymes from "./restrictionEnzymes";
import * as selectedAnnotations from "./selectedAnnotations";
import * as selectionLayer from "./selectionLayer";
import * as sequenceDataHistory from "./sequenceDataHistory";
import * as sequenceData from "./sequenceData";
import * as useAdditionalOrfStartCodons from "./useAdditionalOrfStartCodons";
import * as uppercaseSequenceMapFont from "./uppercaseSequenceMapFont";
import * as charWidth from "./charWidth";
import * as labelLineIntensity from "./labelLineIntensity";
import * as labelSize from "./labelSize";
import * as featureLengthsToHide from "./featureLengthsToHide";
import * as primerLengthsToHide from "./primerLengthsToHide";
import * as partLengthsToHide from "./partLengthsToHide";
import * as selectedPartTags from "./selectedPartTags";
import { combineReducers } from "redux";
import createAction from "./utils/createMetaAction";
export { default as vectorEditorMiddleware } from "./middleware";
var subReducers = {
  createYourOwnEnzyme: createYourOwnEnzyme,
  annotationLabelVisibility: annotationLabelVisibility,
  annotationsToSupport: annotationsToSupport,
  annotationVisibility: annotationVisibility,
  caretPosition: caretPosition,
  copyOptions: copyOptions,
  deletionLayers: deletionLayers,
  digestTool: digestTool,
  toolBar: toolBar,
  findTool: findTool,
  frameTranslations: frameTranslations,
  hoveredAnnotation: hoveredAnnotation,
  minimumOrfSize: minimumOrfSize,
  panelsShown: panelsShown,
  propertiesTool: propertiesTool,
  lastSavedId: lastSavedId,
  readOnly: readOnly,
  versionHistory: versionHistory,
  replacementLayers: replacementLayers,
  restrictionEnzymes: restrictionEnzymes,
  selectedAnnotations: selectedAnnotations,
  selectionLayer: selectionLayer,
  sequenceDataHistory: sequenceDataHistory,
  sequenceData: sequenceData,
  useAdditionalOrfStartCodons: useAdditionalOrfStartCodons,
  charWidth: charWidth,
  uppercaseSequenceMapFont: uppercaseSequenceMapFont,
  showGCContent: showGCContent,
  labelLineIntensity: labelLineIntensity,
  labelSize: labelSize,
  partLengthsToHide: partLengthsToHide,
  primerLengthsToHide: primerLengthsToHide,
  featureLengthsToHide: featureLengthsToHide,
  selectedPartTags: selectedPartTags
};
var vectorEditorInitialize = createAction("VECTOR_EDITOR_UPDATE");
var vectorEditorClear = createAction("VECTOR_EDITOR_CLEAR");

//export the actions for use elsewhere
export var actions = _extends({}, Object.keys(subReducers).reduce(function (acc, k) {
  return _extends({}, acc, subReducers[k]);
}, {}), alignments, {
  vectorEditorInitialize: vectorEditorInitialize,
  vectorEditorClear: vectorEditorClear
});
var mergeDeepKeys = [];
//define the reducer
var reducers = _extends({}, Object.keys(subReducers).reduce(function (acc, k) {
  var _extends2;
  if (subReducers[k]["default"] && subReducers[k]["default"].__shouldUseMergedState) {
    mergeDeepKeys.push(k);
  }
  return _extends({}, acc, (_extends2 = {}, _extends2[k] = subReducers[k]["default"], _extends2));
}, {}), {
  instantiated: function instantiated() {
    return true;
  }
});
export var editorReducer = combineReducers(reducers);
var customDeepMerge = function customDeepMerge(state, newState) {
  if (state === void 0) {
    state = {};
  }
  if (newState === void 0) {
    newState = {};
  }
  return _extends({}, state, newState, mergeDeepKeys.reduce(function (acc, key) {
    acc[key] = merge(state[key], newState[key]);
    return acc;
  }, {}));
};
export default function reducerFactory(initialState) {
  if (initialState === void 0) {
    initialState = {};
  }
  // if (!initialState || !Object.keys(initialState).length) {
  //   throw new Error(
  //     "Please pass an initial state to the vector editor reducer like: {DemoEditor: {}}!"
  //   );
  // }
  return function (state, action) {
    if (state === void 0) {
      state = initialState;
    }
    var editorNames;
    var newState = {};
    if (action.meta && action.meta.editorName) {
      editorNames = Array.isArray(action.meta.editorName) ? action.meta.editorName : [action.meta.editorName];
    }
    var stateToReturn;
    if (editorNames) {
      //we're dealing with an action specific to a given editor
      editorNames.forEach(function (editorName) {
        var currentState = state[editorName];
        if (action.type === "VECTOR_EDITOR_UPDATE") {
          //deep merge certain parts of the exisiting state with the new payload of props
          //(if you want to do a clean wipe, use VECTOR_EDITOR_CLEAR)
          currentState = customDeepMerge(state[editorName], action.payload);
        }
        if (action.type === "VECTOR_EDITOR_CLEAR") {
          currentState = undefined;
        }
        newState[editorName] = editorReducer(currentState, action);
      });
      stateToReturn = _extends({}, state, newState);
    } else {
      //just a normal action
      Object.keys(state).forEach(function (editorName) {
        if (editorName === "__allEditorsOptions") return; //we deal with __allEditorsOptions below so don't pass it here
        newState[editorName] = editorReducer(state[editorName], action);
      });
      stateToReturn = newState;
    }
    return _extends({}, stateToReturn, {
      //these are reducers that are not editor specific (aka shared across editor instances)
      __allEditorsOptions: [["createYourOwnEnzyme", createYourOwnEnzyme], ["uppercaseSequenceMapFont", uppercaseSequenceMapFont], ["showGCContent", showGCContent], ["labelLineIntensity", labelLineIntensity], ["labelSize", labelSize], ["alignments", alignments]].reduce(function (acc, _ref) {
        var key = _ref[0],
          val = _ref[1];
        acc[key] = val["default"](!state.__allEditorsOptions ? undefined : state.__allEditorsOptions[key], action);
        return acc;
      }, {})
    });
  };
}

// export const getBlankEditor = (state) => (state.blankEditor)
export var getEditorByName = function getEditorByName(state, editorName) {
  return state[editorName];
};

// export default connect((state, ownProps) => {
//   return {
//     toggled: state.VectorEditor[ownProps.editorName].annotationVisibility.features
//   }
// })()