import update from 'react-addons-update';
import { Utils } from 'cal';
import * as actions from '../../../actions/index.js';
import * as d3Tools from '../../../constants/d3Tools';
import { SHAPE_TYPE_PROPERTIES } from '../../../constants/shapeTypeProperties.js';
// import createDebug from 'debug';
// const debug = createDebug('d3d:reducer:twist');

const CHANGE_FACTOR = 0.002;
const maxTwist = 1;

export default function twistReducer(state, action) {
  // if (action.log !== false) debug(action.type);

  switch (action.category) {
    case actions.CAT_SELECTION:
      return initTwist(state);

    default:
      break;
  }

  switch (action.type) {
    case actions.D3_CHANGE_TOOL:
      return initTwist(state);

    case actions.TWIST_START:
    case actions.TWIST_END:
      state = update(state, {
        d3: {
          twist: {
            active: { $set: action.type === actions.TWIST_START }
          }
        }
      });
      return state;


    case actions.TWIST:
      const delta = action.delta.x * 1 * CHANGE_FACTOR;

      state = update(state, {
        d3: {
          twist: {
            rotation: { $set: state.d3.twist.rotation + delta }
          }
        }
      });

      for (const selectionData of state.selection.objects) {
        const shapeData = state.objectsById[selectionData.id];
        if (!SHAPE_TYPE_PROPERTIES[shapeData.type].tools[d3Tools.TWIST]) continue;
        const twist = Utils.MathExtended.clamb(shapeData.twist + delta, -maxTwist, maxTwist);
        // debug(UID, ': twist: ', shapeData.twist, '>', twist);

        state = update(state, {
          objectsById: {
            [shapeData.UID]: { twist: { $set: twist } }
          }
        });
      }
      return state;

    default:
      return state;
  }
}

function initTwist(state) {
  const twist = getInitialTwist(state);
  return update(state, {
    d3: {
      twist: {
        rotation: { $set: twist },
        active: { $set: false }
      }
    }
  });
}

function getInitialTwist(state) {
  const selectedObjects = state.selection.objects.map(({ id }) => state.objectsById[id]);
  let twist;
  if (selectedObjects.length === 0) {
    twist = 0;
  } else if (selectedObjects.length === 1) {
    // one shape selected: use shape's twist
    const [selectedObject] = selectedObjects;
    twist = selectedObject.twist;
  } else {
    twist = 0;
  }
  return twist;
}
