/// 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];
  }
}
