// Copyright (c) 2015 - 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import lightingShader from './lighting.glsl';
import project from '../project/project';
import { COORDINATE_SYSTEM } from '../../lib/constants';
import { projectPosition } from '../project/project-functions';
import memoize from '../../utils/memoize';

export default {
  name: 'lighting',
  dependencies: [project],
  vs: lightingShader,
  getUniforms: getUniforms,
  deprecations: [
  // Deprecated lighting functions
  { type: 'function', old: 'getLightWeight', new: 'lighting_getLightWeight', deprecated: true }]
};

var INITIAL_MODULE_OPTIONS = {};

var DEFAULT_LIGHTS_POSITION = [-122.45, 37.75, 8000];
var DEFAULT_LIGHTS_STRENGTH = [2.0, 0.0];
var DEFAULT_AMBIENT_RATIO = 0.05;
var DEFAULT_DIFFUSE_RATIO = 0.6;
var DEFAULT_SPECULAR_RATIO = 0.8;
var DEFAULT_COORDINATE_ORIGIN = [0, 0, 0];

var getMemoizedLightPositions = memoize(preprojectLightPositions);

// TODO: support partial update, e.g.
// `lightedModel.setModuleParameters({diffuseRatio: 0.3});`
function getUniforms() {
  var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : INITIAL_MODULE_OPTIONS;

  if (!opts.lightSettings) {
    return {};
  }

  var _opts$lightSettings = opts.lightSettings,
      _opts$lightSettings$n = _opts$lightSettings.numberOfLights,
      numberOfLights = _opts$lightSettings$n === undefined ? 1 : _opts$lightSettings$n,
      _opts$lightSettings$l = _opts$lightSettings.lightsPosition,
      lightsPosition = _opts$lightSettings$l === undefined ? DEFAULT_LIGHTS_POSITION : _opts$lightSettings$l,
      _opts$lightSettings$l2 = _opts$lightSettings.lightsStrength,
      lightsStrength = _opts$lightSettings$l2 === undefined ? DEFAULT_LIGHTS_STRENGTH : _opts$lightSettings$l2,
      _opts$lightSettings$c = _opts$lightSettings.coordinateSystem,
      coordinateSystem = _opts$lightSettings$c === undefined ? COORDINATE_SYSTEM.LNGLAT : _opts$lightSettings$c,
      _opts$lightSettings$c2 = _opts$lightSettings.coordinateOrigin,
      coordinateOrigin = _opts$lightSettings$c2 === undefined ? DEFAULT_COORDINATE_ORIGIN : _opts$lightSettings$c2,
      _opts$lightSettings$m = _opts$lightSettings.modelMatrix,
      modelMatrix = _opts$lightSettings$m === undefined ? null : _opts$lightSettings$m,
      _opts$lightSettings$a = _opts$lightSettings.ambientRatio,
      ambientRatio = _opts$lightSettings$a === undefined ? DEFAULT_AMBIENT_RATIO : _opts$lightSettings$a,
      _opts$lightSettings$d = _opts$lightSettings.diffuseRatio,
      diffuseRatio = _opts$lightSettings$d === undefined ? DEFAULT_DIFFUSE_RATIO : _opts$lightSettings$d,
      _opts$lightSettings$s = _opts$lightSettings.specularRatio,
      specularRatio = _opts$lightSettings$s === undefined ? DEFAULT_SPECULAR_RATIO : _opts$lightSettings$s;

  // Pre-project light positions

  var lightsPositionWorld = getMemoizedLightPositions({
    lightsPosition: lightsPosition,
    numberOfLights: numberOfLights,
    viewport: opts.viewport,
    modelMatrix: modelMatrix,
    coordinateSystem: opts.coordinateSystem,
    coordinateOrigin: opts.coordinateOrigin,
    fromCoordinateSystem: coordinateSystem,
    fromCoordinateOrigin: coordinateOrigin
  });

  return {
    lighting_lightPositions: lightsPositionWorld,
    lighting_lightStrengths: lightsStrength,
    lighting_ambientRatio: ambientRatio,
    lighting_diffuseRatio: diffuseRatio,
    lighting_specularRatio: specularRatio,
    lighting_numberOfLights: numberOfLights
  };
}

// Pre-project light positions
function preprojectLightPositions(_ref) {
  var lightsPosition = _ref.lightsPosition,
      numberOfLights = _ref.numberOfLights,
      viewport = _ref.viewport,
      modelMatrix = _ref.modelMatrix,
      coordinateSystem = _ref.coordinateSystem,
      coordinateOrigin = _ref.coordinateOrigin,
      fromCoordinateSystem = _ref.fromCoordinateSystem,
      fromCoordinateOrigin = _ref.fromCoordinateOrigin;

  var projectionParameters = {
    viewport: viewport,
    modelMatrix: modelMatrix,
    coordinateSystem: coordinateSystem,
    coordinateOrigin: coordinateOrigin,
    fromCoordinateSystem: fromCoordinateSystem,
    fromCoordinateOrigin: fromCoordinateOrigin
  };

  var lightsPositionWorld = [];
  for (var i = 0; i < numberOfLights; i++) {
    var position = projectPosition(lightsPosition.slice(i * 3, i * 3 + 3), projectionParameters);

    lightsPositionWorld[i * 3] = position[0];
    lightsPositionWorld[i * 3 + 1] = position[1];
    lightsPositionWorld[i * 3 + 2] = position[2];
  }

  return lightsPositionWorld;
}
//# sourceMappingURL=lighting.js.map