/// Copyright 2013 the V8 project authors. All rights reserved.
/// Copyright 2009 Oliver Hunt <http://nerget.com>
///
/// 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.

// Ported from the v8 benchmark suite by Google 2013.
// Uses Float64List for data.

import 'dart:math';
import 'dart:typed_data';

import 'package:benchmark_harness/benchmark_harness.dart';

/// Copyright 2009 Oliver Hunt <http://nerget.com>
///
/// 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.
// Ported from the v8 benchmark suite by Google 2013.
// Uses Float64List for data.

/// Copyright 2009 Oliver Hunt <http://nerget.com>
///
/// 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.
// Ported from the v8 benchmark suite by Google 2013.
// Uses Float64List for data.

main() {
  const FluidMotion().report();
}

class FluidMotion extends BenchmarkBase {
  static FluidField solver;
  static int framesTillAddingPoints = 0;
  static int framesBetweenAddingPoints = 5;

  const FluidMotion() : super('FluidMotion');

  static void setupFluidMotion() {
    framesTillAddingPoints = 0;
    framesBetweenAddingPoints = 5;
    solver = FluidField.create(null, 128, 128, 20);
    solver.setDisplayFunction((a) {});
    solver.setUICallback(prepareFrame);
  }

  static void runFluidMotion() {
    setupFluidMotion();
    for (int i = 0; i < 10; i++) {
      solver.update();
    }
    solver.validate(758.9012130174812, -352.56376676179076, -357.3690235879736);
  }

  static void main() {
    runFluidMotion();
  }

  static void addPoints(Field field) {
    var n = 64;
    for (var i = 1; i <= n; i++) {
      field.setVelocity(i, i, n.toDouble(), n.toDouble());
      field.setDensity(i, i, 5.0);
      field.setVelocity(i, n - i, -n.toDouble(), -n.toDouble());
      field.setDensity(i, n - i, 20.0);
      field.setVelocity(128 - i, n + i, -n.toDouble(), -n.toDouble());
      field.setDensity(128 - i, n + i, 30.0);
    }
  }

  static void prepareFrame(Field field) {
    if (framesTillAddingPoints == 0) {
      addPoints(field);
      framesTillAddingPoints = framesBetweenAddingPoints;
      framesBetweenAddingPoints++;
    } else {
      framesTillAddingPoints--;
    }
  }

  // Overrides of BenchmarkBase.

  void warmup() {
    runFluidMotion();
  }

  void exercise() {
    runFluidMotion();
  }
}

// Code from Oliver Hunt (http://nerget.com/fluidSim/pressure.js) starts here.

class FluidField {
  final canvas;
  final int iterations;
  final double dt = 0.1;
  final int size;
  Float64List dens, dens_prev;
  Float64List u, u_prev;
  Float64List v, v_prev;
  final int width, height;
  final int rowSize;
  var displayFunc;

  static FluidField _lastCreated;

  static bool approxEquals(double a, double b) => (a - b).abs() < 0.000001;

  validate(expectedDens, expectedU, expectedV) {
    var sumDens = 0.0;
    var sumU = 0.0;
    var sumV = 0.0;
    for (int i = 0; i < dens.length; i++) {
      sumDens += dens[i];
      sumU += u[i];
      sumV += v[i];
    }

    if (!approxEquals(sumDens, expectedDens) ||
        !approxEquals(sumU, expectedU) ||
        !approxEquals(sumV, expectedV)) {
      throw "Incorrect result";
    }
  }

  // Allocates a new FluidField or return previously allocated field if the
  // size is too large.
  factory FluidField.create(canvas, int hRes, int wRes, int iterations) {
    final res = wRes * hRes;
    if ((res > 0) && (res < 1000000)) {
      _lastCreated = FluidField(canvas, hRes, wRes, iterations);
    }
    _lastCreated ??= FluidField(canvas, 64, 64, iterations);
    assert((canvas == _lastCreated.canvas) &&
        (iterations == _lastCreated.iterations));
    return _lastCreated;
  }

  FluidField(this.canvas, this.height, this.width, this.iterations)
      : rowSize = width + 2,
        size = (width + 2) * (height + 2) {
    reset();
  }

  void reset() {
    // All Float64List elements are initialized to 0.0.
    dens = Float64List(size);
    dens_prev = Float64List(size);
    u = Float64List(size);
    u_prev = Float64List(size);
    v = Float64List(size);
    v_prev = Float64List(size);
  }

  void addFields(Float64List x, Float64List s, double dt) {
    for (var i = 0; i < size; i++) {
      x[i] += dt * s[i];
    }
  }

  void set_bnd(int b, Float64List x) {
    if (b == 1) {
      var i = 1;
      for (; i <= width; i++) {
        x[i] = x[i + rowSize];
        x[i + (height + 1) * rowSize] = x[i + height * rowSize];
      }

      for (var j = 1; j <= height; j++) {
        x[j * rowSize] = -x[1 + j * rowSize];
        x[(width + 1) + j * rowSize] = -x[width + j * rowSize];
      }
    } else if (b == 2) {
      for (var i = 1; i <= width; i++) {
        x[i] = -x[i + rowSize];
        x[i + (height + 1) * rowSize] = -x[i + height * rowSize];
      }

      for (var j = 1; j <= height; j++) {
        x[j * rowSize] = x[1 + j * rowSize];
        x[(width + 1) + j * rowSize] = x[width + j * rowSize];
      }
    } else {
      for (var i = 1; i <= width; i++) {
        x[i] = x[i + rowSize];
        x[i + (height + 1) * rowSize] = x[i + height * rowSize];
      }

      for (var j = 1; j <= height; j++) {
        x[j * rowSize] = x[1 + j * rowSize];
        x[(width + 1) + j * rowSize] = x[width + j * rowSize];
      }
    }
    var maxEdge = (height + 1) * rowSize;
    x[0] = 0.5 * (x[1] + x[rowSize]);
    x[maxEdge] = 0.5 * (x[1 + maxEdge] + x[height * rowSize]);
    x[(width + 1)] = 0.5 * (x[width] + x[(width + 1) + rowSize]);
    x[(width + 1) + maxEdge] =
        0.5 * (x[width + maxEdge] + x[(width + 1) + height * rowSize]);
  }

  void lin_solve(int b, Float64List x, Float64List x0, int a, int c) {
    if (a == 0 && c == 1) {
      for (var j = 1; j <= height; j++) {
        var currentRow = j * rowSize;
        ++currentRow;
        for (var i = 0; i < width; i++) {
          x[currentRow] = x0[currentRow];
          ++currentRow;
        }
      }
      set_bnd(b, x);
    } else {
      var invC = 1 / c;
      for (var k = 0; k < iterations; k++) {
        for (var j = 1; j <= height; j++) {
          var lastRow = (j - 1) * rowSize;
          var currentRow = j * rowSize;
          var nextRow = (j + 1) * rowSize;
          var lastX = x[currentRow];
          ++currentRow;
          for (var i = 1; i <= width; i++) {
            lastX = x[currentRow] = (x0[currentRow] +
                    a *
                        (lastX +
                            x[++currentRow] +
                            x[++lastRow] +
                            x[++nextRow])) *
                invC;
          }
        }
        set_bnd(b, x);
      }
    }
  }

  void diffuse(int b, Float64List x, Float64List x0, double dt) {
    var a = 0;
    lin_solve(b, x, x0, a, 1 + 4 * a);
  }

  void lin_solve2(Float64List x, Float64List x0, Float64List y, Float64List y0,
      int a, int c) {
    if (a == 0 && c == 1) {
      for (var j = 1; j <= height; j++) {
        var currentRow = j * rowSize;
        ++currentRow;
        for (var i = 0; i < width; i++) {
          x[currentRow] = x0[currentRow];
          y[currentRow] = y0[currentRow];
          ++currentRow;
        }
      }
      set_bnd(1, x);
      set_bnd(2, y);
    } else {
      var invC = 1 / c;
      for (var k = 0; k < iterations; k++) {
        for (var j = 1; j <= height; j++) {
          var lastRow = (j - 1) * rowSize;
          var currentRow = j * rowSize;
          var nextRow = (j + 1) * rowSize;
          var lastX = x[currentRow];
          var lastY = y[currentRow];
          ++currentRow;
          for (var i = 1; i <= width; i++) {
            lastX = x[currentRow] = (x0[currentRow] +
                    a * (lastX + x[currentRow] + x[lastRow] + x[nextRow])) *
                invC;
            lastY = y[currentRow] = (y0[currentRow] +
                    a *
                        (lastY +
                            y[++currentRow] +
                            y[++lastRow] +
                            y[++nextRow])) *
                invC;
          }
        }
        set_bnd(1, x);
        set_bnd(2, y);
      }
    }
  }

  void diffuse2(Float64List x, Float64List x0, y, Float64List y0, double dt) {
    var a = 0;
    lin_solve2(x, x0, y, y0, a, 1 + 4 * a);
  }

  void advect(int b, Float64List d, Float64List d0, Float64List u,
      Float64List v, double dt) {
    var Wdt0 = dt * width;
    var Hdt0 = dt * height;
    var Wp5 = width + 0.5;
    var Hp5 = height + 0.5;
    for (var j = 1; j <= height; j++) {
      var pos = j * rowSize;
      for (var i = 1; i <= width; i++) {
        var x = i - Wdt0 * u[++pos];
        var y = j - Hdt0 * v[pos];
        if (x < 0.5)
          x = 0.5;
        else if (x > Wp5) x = Wp5;
        var i0 = x.toInt();
        var i1 = i0 + 1;
        if (y < 0.5)
          y = 0.5;
        else if (y > Hp5) y = Hp5;
        var j0 = y.toInt();
        var j1 = j0 + 1;
        var s1 = x - i0;
        var s0 = 1 - s1;
        var t1 = y - j0;
        var t0 = 1 - t1;
        var row1 = j0 * rowSize;
        var row2 = j1 * rowSize;
        d[pos] = s0 * (t0 * d0[i0 + row1] + t1 * d0[i0 + row2]) +
            s1 * (t0 * d0[i1 + row1] + t1 * d0[i1 + row2]);
      }
    }
    set_bnd(b, d);
  }

  void project(Float64List u, Float64List v, Float64List p, Float64List div) {
    var h = -0.5 / sqrt(width * height);
    for (var j = 1; j <= height; j++) {
      var row = j * rowSize;
      var previousRow = (j - 1) * rowSize;
      var prevValue = row - 1;
      var currentRow = row;
      var nextValue = row + 1;
      var nextRow = (j + 1) * rowSize;
      for (var i = 1; i <= width; i++) {
        div[++currentRow] = h *
            (u[++nextValue] - u[++prevValue] + v[++nextRow] - v[++previousRow]);
        p[currentRow] = 0.0;
      }
    }
    set_bnd(0, div);
    set_bnd(0, p);

    lin_solve(0, p, div, 1, 4);
    var wScale = 0.5 * width;
    var hScale = 0.5 * height;
    for (var j = 1; j <= height; j++) {
      var prevPos = j * rowSize - 1;
      var currentPos = j * rowSize;
      var nextPos = j * rowSize + 1;
      var prevRow = (j - 1) * rowSize;
      var nextRow = (j + 1) * rowSize;

      for (var i = 1; i <= width; i++) {
        u[++currentPos] -= wScale * (p[++nextPos] - p[++prevPos]);
        v[currentPos] -= hScale * (p[++nextRow] - p[++prevRow]);
      }
    }
    set_bnd(1, u);
    set_bnd(2, v);
  }

  void dens_step(
      Float64List x, Float64List x0, Float64List u, Float64List v, double dt) {
    addFields(x, x0, dt);
    diffuse(0, x0, x, dt);
    advect(0, x, x0, u, v, dt);
  }

  void vel_step(
      Float64List u, Float64List v, Float64List u0, Float64List v0, double dt) {
    addFields(u, u0, dt);
    addFields(v, v0, dt);
    var temp = u0;
    u0 = u;
    u = temp;
    temp = v0;
    v0 = v;
    v = temp;
    diffuse2(u, u0, v, v0, dt);
    project(u, v, u0, v0);
    temp = u0;
    u0 = u;
    u = temp;
    temp = v0;
    v0 = v;
    v = temp;
    advect(1, u, u0, u0, v0, dt);
    advect(2, v, v0, u0, v0, dt);
    project(u, v, u0, v0);
  }

  var uiCallback;

  void setDisplayFunction(func) {
    displayFunc = func;
  }

  void setUICallback(callback) {
    uiCallback = callback;
  }

  void queryUI(Float64List d, Float64List u, Float64List v) {
    for (var i = 0; i < size; i++) {
      u[i] = v[i] = d[i] = 0.0;
    }
    uiCallback(Field(d, u, v, rowSize));
  }

  void update() {
    queryUI(dens_prev, u_prev, v_prev);
    vel_step(u, v, u_prev, v_prev, dt);
    dens_step(dens, dens_prev, u, v, dt);
    displayFunc(Field(dens, u, v, rowSize));
  }
}

// Difference from JS version: Field takes an argument rowSize, but this
// used for display purpose only.
class Field {
  final Float64List dens, u, v;
  final int rowSize;

  Field(this.dens, this.u, this.v, this.rowSize);

  void setDensity(int x, int y, double d) {
    dens[(x + 1) + (y + 1) * rowSize] = d;
  }

  double getDensity(int x, int y) {
    return dens[(x + 1) + (y + 1) * rowSize]; // rowSize from FluidField?
  }

  void setVelocity(int x, int y, double xv, double yv) {
    u[(x + 1) + (y + 1) * rowSize] = xv;
    v[(x + 1) + (y + 1) * rowSize] = yv;
  }

  double getXVelocity(int x, int y) {
    return u[(x + 1) + (y + 1) * rowSize];
  }

  double getYVelocity(int x, int y) {
    return v[(x + 1) + (y + 1) * rowSize];
  }
}
