import vertSingle from '../shaders/vertex/single.js'
import vertDouble from '../shaders/vertex/double.js'

import fragInterpolateColor from '../shaders/fragment/interpolateColor.js'
import fragInterpolateColorOnly from '../shaders/fragment/interpolateColorOnly.js'
import fragInterpolateValue from '../shaders/fragment/interpolateValue.js'

import * as util from '../util'

/**
 * The DrawCommand output by this function interpolates, for each pixel, between two values, one
 * from `textureA` and one from `textureB`. The same color scale / sentinel values are applied to
 * both.
 */
export function createDrawTileInterpolateValueCommand (
  regl,
  commonConfig,
  fragMacros
) {
  return regl({
    ...commonConfig,
    vert: vertDouble,
    frag: util.defineMacros(fragInterpolateValue, fragMacros),
    uniforms: {
      ...commonConfig.uniforms,
      scaleLength: regl.prop('scaleLength'),
      sentinelLength: regl.prop('sentinelLength'),
      scaleColormap: regl.prop('scaleColormap'),
      sentinelColormap: regl.prop('sentinelColormap'),
      aboveColor: regl.prop('aboveColor'),
      belowColor: regl.prop('belowColor'),
      textureA: (_, { textureA }) => textureA,
      textureB: (_, { textureB }) => textureB,
      interpolationFraction: (_, { interpolationFraction }) => interpolationFraction
    },
    attributes: {
      ...commonConfig.attributes,
      texCoordA: (_, { textureBoundsA }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsA),
      texCoordB: (_, { textureBoundsB }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsB)
    }
  })
}

/**
 * The behavior of this DrawCommand is similar to the one above, except that pixels from `textureA`
 * are colorized with one color scale / set of sentinel values, while pixels from `textureB` use a
 * different color scale / set of sentinel values.
 */
export function createDrawTileInterpolateColorCommand (
  regl,
  commonConfig,
  fragMacros
) {
  return regl({
    ...commonConfig,
    vert: vertDouble,
    frag: util.defineMacros(fragInterpolateColor, fragMacros),
    uniforms: {
      ...commonConfig.uniforms,
      scaleLengthA: regl.prop('scaleLengthA'),
      sentinelLengthA: regl.prop('sentinelLengthA'),
      scaleColormapA: regl.prop('scaleColormapA'),
      sentinelColormapA: regl.prop('sentinelColormapA'),
      scaleLengthB: regl.prop('scaleLengthB'),
      sentinelLengthB: regl.prop('sentinelLengthB'),
      scaleColormapB: regl.prop('scaleColormapB'),
      sentinelColormapB: regl.prop('sentinelColormapB'),
      textureA: (_, { textureA }) => textureA,
      textureB: (_, { textureB }) => textureB,
      interpolationFraction: (_, { interpolationFraction }) => interpolationFraction
    },
    attributes: {
      ...commonConfig.attributes,
      texCoordA: (_, { textureBoundsA }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsA),
      texCoordB: (_, { textureBoundsB }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsB)
    }
  })
}

/**
 * The behavior of this DrawCommand is similar to the one above, except that the pixel values
 * are the same. Only the colorscale changes.
 */
export function createDrawTileInterpolateColorOnlyCommand (
  regl,
  commonConfig,
  fragMacros
) {
  return regl({
    ...commonConfig,
    vert: vertSingle,
    frag: util.defineMacros(fragInterpolateColorOnly, fragMacros),
    uniforms: {
      ...commonConfig.uniforms,
      scaleLengthA: regl.prop('scaleLengthA'),
      sentinelLengthA: regl.prop('sentinelLengthA'),
      scaleColormapA: regl.prop('scaleColormapA'),
      sentinelColormapA: regl.prop('sentinelColormapA'),
      scaleLengthB: regl.prop('scaleLengthB'),
      sentinelLengthB: regl.prop('sentinelLengthB'),
      scaleColormapB: regl.prop('scaleColormapB'),
      sentinelColormapB: regl.prop('sentinelColormapB'),
      texture: (_, { texture }) => texture,
      interpolationFraction: (_, { interpolationFraction }) => interpolationFraction
    },
    attributes: {
      ...commonConfig.attributes,
      texCoord: (_, { textureBounds }) => util.getTexCoordVerticesTriangleStripQuad(textureBounds)
    }
  })
}
