// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// @assertion Float32x4List asFloat32x4List([int offsetInBytes = 0, int length])
/// Creates a Float32x4List view of a region of this byte buffer.
/// The view is backed by the bytes of this byte buffer. Any changes made to the
/// Float32x4List will also change the buffer, and vice versa.
/// @description Checks that method asFloat32x4List creates a Float32x4List view
/// of a region of this byte buffer, and any changes made to Float32x4List will
/// also change the buffer, and vice versa.
/// @author ngl@unipro.ru


import "dart:typed_data";
import "../../../Utils/expect.dart";

void check(ByteBuffer buffer){
  int bufSizeInBytes = buffer.lengthInBytes;
  var res = buffer.asFloat32x4List(0);
  Float32x4List res1 = buffer.asFloat32x4List(0);
  int viewSizeInBytes = res.lengthInBytes;
  int viewLength = res.length;
  int shift = (Float32x4List.bytesPerElement == 16) ? 4 : 0;

  Expect.isTrue(res is Float32x4List);
  Expect.runtimeIsType<Float32x4List>(res);
  Expect.equals(bufSizeInBytes >> shift, viewLength);

  if (viewSizeInBytes != 0) {
    Expect.equals(res1[0].x, res[0].x);
    Expect.equals(res1[0].y, res[0].y);
    Expect.equals(res1[0].z, res[0].z);
    Expect.equals(res1[0].w, res[0].w);

    Float32x4 v1 = new Float32x4(2.0, 2.1, 2.2, 2.3);
    // set value to the first element of res1
    res1[0] = v1;
    // the first element of res is equal to set value
    Expect.equals(v1.x, res[0].x);
    Expect.equals(v1.y, res[0].y);
    Expect.equals(v1.z, res[0].z);
    Expect.equals(v1.w, res[0].w);

    Float32x4 v2 = new Float32x4(4.0, 4.1, 4.2, 4.3);
    // set value to the last element of res
    res[viewLength - 1] = v2;
    // the last element of res1 is equal to set value
    Expect.equals(v2.x, res[viewLength - 1].x);
    Expect.equals(v2.y, res[viewLength - 1].y);
    Expect.equals(v2.z, res[viewLength - 1].z);
    Expect.equals(v2.w, res[viewLength - 1].w);
  }
  Expect.notEquals(res, res1);
  Expect.equals(res.buffer, res1.buffer);
}

main() {
  var list0 = <int>[];
  var list1 = new List.filled(5, 0);
  var list2 = new List.filled(8, 0);
  var list3 = new Int32x4List(1);
  var list4 = new Int32x4List(5);
  var list5 = new Int32x4List(0);

  check((new Int8List.fromList(list0)).buffer);
  check((new Int8List.fromList(list1)).buffer);
  check((new Int8List.fromList(list2)).buffer);

  check((new Int16List.fromList(list0)).buffer);
  check((new Int16List.fromList(list1)).buffer);
  check((new Int16List.fromList(list2)).buffer);

  check((new Int32List.fromList(list0)).buffer);
  check((new Int32List.fromList(list1)).buffer);
  check((new Int32List.fromList(list2)).buffer);

  if (!isJS) {
    check((new Int64List.fromList(list0)).buffer);
    check((new Int64List.fromList(list1)).buffer);
    check((new Int64List.fromList(list2)).buffer);
  }

  check((new Int32x4List.fromList(list5)).buffer);
  check((new Int32x4List.fromList(list3)).buffer);
  check((new Int32x4List.fromList(list4)).buffer);
}
