import vertSingle from '../shaders/vertex/single.js'
import vertDouble from '../shaders/vertex/double.js'
import vertMulti3 from '../shaders/vertex/multi3.js'
import vertMulti4 from '../shaders/vertex/multi4.js'
import vertMulti5 from '../shaders/vertex/multi5.js'
import vertMulti6 from '../shaders/vertex/multi6.js'

import fragMulti1Calc from '../shaders/fragment/multiAnalyze1Calc.js'
import fragMulti2Calc from '../shaders/fragment/multiAnalyze2Calc.js'
import fragMulti3Calc from '../shaders/fragment/multiAnalyze3Calc.js'
import fragMulti4Calc from '../shaders/fragment/multiAnalyze4Calc.js'
import fragMulti5Calc from '../shaders/fragment/multiAnalyze5Calc.js'
import fragMulti6Calc from '../shaders/fragment/multiAnalyze6Calc.js'
import fragDiffCalc from '../shaders/fragment/diffCalc.js'
import fragDrawResult from '../shaders/fragment/drawResult.js'

import * as util from '../util'


export function createCalcTileMultiAnalyze1Command (
  regl,
  commonConfig
) {
  return regl({
    ...commonConfig,
    vert: vertSingle,
    frag: fragMulti1Calc,
    depth: {
      enable: false
    },
    uniforms: {
      ...commonConfig.uniforms,
      filterLowA: (_, { filterLowA }) => filterLowA,
      filterHighA: (_, { filterHighA }) => filterHighA,
      multiplierA: (_, { multiplierA }) => multiplierA,
      textureA: (_, { textureA }) => textureA
    },
    attributes: {
      ...commonConfig.attributes,
      texCoord: (_, { textureBoundsA }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsA)
    },
    framebuffer: regl.prop('fbo')
  })
}

export function createCalcTileMultiAnalyze2Command (
  regl,
  commonConfig
) {
  return regl({
    ...commonConfig,
    vert: vertDouble,
    frag: fragMulti2Calc,
    depth:  {
      enable: false
    },
    uniforms: {
      ...commonConfig.uniforms,
      filterLowA: (_, { filterLowA }) => filterLowA,
      filterHighA: (_, { filterHighA }) => filterHighA,
      filterLowB: (_, { filterLowB }) => filterLowB,
      filterHighB: (_, { filterHighB }) => filterHighB,
      multiplierA: (_, { multiplierA }) => multiplierA,
      multiplierB: (_, { multiplierB }) => multiplierB,
      textureA: (_, { textureA }) => textureA,
      textureB: (_, { textureB }) => textureB
    },
    attributes: {
      ...commonConfig.attributes,
      texCoordA: (_, { textureBoundsA }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsA),
      texCoordB: (_, { textureBoundsB }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsB)
    },
    framebuffer: regl.prop('fbo')
  })
}

export function createCalcTileMultiAnalyze3Command (
  regl,
  commonConfig
) {
  return regl({
    ...commonConfig,
    vert: vertMulti3,
    frag: fragMulti3Calc,
    depth:  {
      enable: false
    },
    uniforms: {
      ...commonConfig.uniforms,
      filterLowA: (_, { filterLowA }) => filterLowA,
      filterHighA: (_, { filterHighA }) => filterHighA,
      filterLowB: (_, { filterLowB }) => filterLowB,
      filterHighB: (_, { filterHighB }) => filterHighB,
      filterLowC: (_, { filterLowC }) => filterLowC,
      filterHighC: (_, { filterHighC }) => filterHighC,
      multiplierA: (_, { multiplierA }) => multiplierA,
      multiplierB: (_, { multiplierB }) => multiplierB,
      multiplierC: (_, { multiplierC }) => multiplierC,
      textureA: (_, { textureA }) => textureA,
      textureB: (_, { textureB }) => textureB,
      textureC: (_, { textureC }) => textureC
    },
    attributes: {
      ...commonConfig.attributes,
      texCoordA: (_, { textureBoundsA }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsA),
      texCoordB: (_, { textureBoundsB }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsB),
      texCoordC: (_, { textureBoundsC }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsC)
    },
    framebuffer: regl.prop('fbo')
  })
}

export function createCalcTileMultiAnalyze4Command (
  regl,
  commonConfig
) {
  return regl({
    ...commonConfig,
    vert: vertMulti4,
    frag: fragMulti4Calc,
    depth: {
      enable: false
    },
    uniforms: {
      ...commonConfig.uniforms,
      filterLowA: (_, { filterLowA }) => filterLowA,
      filterHighA: (_, { filterHighA }) => filterHighA,
      filterLowB: (_, { filterLowB }) => filterLowB,
      filterHighB: (_, { filterHighB }) => filterHighB,
      filterLowC: (_, { filterLowC }) => filterLowC,
      filterHighC: (_, { filterHighC }) => filterHighC,
      filterLowD: (_, { filterLowD }) => filterLowD,
      filterHighD: (_, { filterHighD }) => filterHighD,
      multiplierA: (_, { multiplierA }) => multiplierA,
      multiplierB: (_, { multiplierB }) => multiplierB,
      multiplierC: (_, { multiplierC }) => multiplierC,
      multiplierD: (_, { multiplierD }) => multiplierD,
      textureA: (_, { textureA }) => textureA,
      textureB: (_, { textureB }) => textureB,
      textureC: (_, { textureC }) => textureC,
      textureD: (_, { textureD }) => textureD
    },
    attributes: {
      ...commonConfig.attributes,
      texCoordA: (_, { textureBoundsA }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsA),
      texCoordB: (_, { textureBoundsB }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsB),
      texCoordC: (_, { textureBoundsC }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsC),
      texCoordD: (_, { textureBoundsD }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsD)
    },
    framebuffer: regl.prop('fbo')
  })
}

export function createCalcTileMultiAnalyze5Command (
  regl,
  commonConfig
) {
  return regl({
    ...commonConfig,
    vert: vertMulti5,
    frag: fragMulti5Calc,
    depth: {
      enable: false
    },
    uniforms: {
      ...commonConfig.uniforms,
      filterLowA: (_, { filterLowA }) => filterLowA,
      filterHighA: (_, { filterHighA }) => filterHighA,
      filterLowB: (_, { filterLowB }) => filterLowB,
      filterHighB: (_, { filterHighB }) => filterHighB,
      filterLowC: (_, { filterLowC }) => filterLowC,
      filterHighC: (_, { filterHighC }) => filterHighC,
      filterLowD: (_, { filterLowD }) => filterLowD,
      filterHighD: (_, { filterHighD }) => filterHighD,
      filterLowE: (_, { filterLowE }) => filterLowE,
      filterHighE: (_, { filterHighE }) => filterHighE,
      multiplierA: (_, { multiplierA }) => multiplierA,
      multiplierB: (_, { multiplierB }) => multiplierB,
      multiplierC: (_, { multiplierC }) => multiplierC,
      multiplierD: (_, { multiplierD }) => multiplierD,
      multiplierE: (_, { multiplierE }) => multiplierE,
      textureA: (_, { textureA }) => textureA,
      textureB: (_, { textureB }) => textureB,
      textureC: (_, { textureC }) => textureC,
      textureD: (_, { textureD }) => textureD,
      textureE: (_, { textureE }) => textureE
    },
    attributes: {
      ...commonConfig.attributes,
      texCoordA: (_, { textureBoundsA }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsA),
      texCoordB: (_, { textureBoundsB }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsB),
      texCoordC: (_, { textureBoundsC }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsC),
      texCoordD: (_, { textureBoundsD }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsD),
      texCoordE: (_, { textureBoundsE }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsE)
    },
    framebuffer: regl.prop('fbo')
  })
}

export function createCalcTileMultiAnalyze6Command (
  regl,
  commonConfig
) {
  return regl({
    ...commonConfig,
    vert: vertMulti6,
    frag: fragMulti6Calc,
    depth:  {
      enable: false
    },
    uniforms: {
      ...commonConfig.uniforms,
      filterLowA: (_, { filterLowA }) => filterLowA,
      filterHighA: (_, { filterHighA }) => filterHighA,
      filterLowB: (_, { filterLowB }) => filterLowB,
      filterHighB: (_, { filterHighB }) => filterHighB,
      filterLowC: (_, { filterLowC }) => filterLowC,
      filterHighC: (_, { filterHighC }) => filterHighC,
      filterLowD: (_, { filterLowD }) => filterLowD,
      filterHighD: (_, { filterHighD }) => filterHighD,
      filterLowE: (_, { filterLowE }) => filterLowE,
      filterHighE: (_, { filterHighE }) => filterHighE,
      filterLowF: (_, { filterLowF }) => filterLowF,
      filterHighF: (_, { filterHighF }) => filterHighF,
      multiplierA: (_, { multiplierA }) => multiplierA,
      multiplierB: (_, { multiplierB }) => multiplierB,
      multiplierC: (_, { multiplierC }) => multiplierC,
      multiplierD: (_, { multiplierD }) => multiplierD,
      multiplierE: (_, { multiplierE }) => multiplierE,
      multiplierF: (_, { multiplierF }) => multiplierF,
      textureA: (_, { textureA }) => textureA,
      textureB: (_, { textureB }) => textureB,
      textureC: (_, { textureC }) => textureC,
      textureD: (_, { textureD }) => textureD,
      textureE: (_, { textureE }) => textureE,
      textureF: (_, { textureF }) => textureF
    },
    attributes: {
      ...commonConfig.attributes,
      texCoordA: (_, { textureBoundsA }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsA),
      texCoordB: (_, { textureBoundsB }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsB),
      texCoordC: (_, { textureBoundsC }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsC),
      texCoordD: (_, { textureBoundsD }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsD),
      texCoordE: (_, { textureBoundsE }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsE),
      texCoordF: (_, { textureBoundsF }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsF)
    },
    framebuffer: regl.prop('fbo')
  })
}

export function createCalcTileDiffCommand (
  regl,
  commonConfig
) {
  return regl({
    ...commonConfig,
    vert: vertDouble,
    frag: fragDiffCalc,
    depth:  {
      enable: false
    },
    uniforms: {
      ...commonConfig.uniforms,
      textureA: (_, { textureA }) => textureA,
      textureB: (_, { textureB }) => textureB
    },
    attributes: {
      ...commonConfig.attributes,
      texCoordA: (_, { textureBoundsA }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsA),
      texCoordB: (_, { textureBoundsB }) => util.getTexCoordVerticesTriangleStripQuad(textureBoundsB)
    },
    framebuffer: regl.prop('fbo')
  })
}

export function createDrawResultCommand (
  regl,
  commonConfig,
  fragMacros
) {
  return regl({
    ...commonConfig,
    vert: vertSingle,
    frag: util.defineMacros(fragDrawResult, fragMacros),
    depth:  {
      enable: false
    },
    uniforms: {
      ...commonConfig.uniforms,
      scaleLength: regl.prop('scaleLength'),
      sentinelLength: regl.prop('sentinelLength'),
      scaleColormap: regl.prop('scaleColormap'),
      sentinelColormap: regl.prop('sentinelColormap'),
      texture: regl.prop('texture'),
      aboveColor: regl.prop('aboveColor'),
      belowColor: regl.prop('belowColor')
    },
    attributes: {
      ...commonConfig.attributes,
      texCoord: [[0, 1], [1, 1], [0, 0], [1, 0]]
    }
  })
}
