// Copyright (c) 2015, Google Inc. 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.

part of vector_math_geometry;

class CylinderGenerator extends GeometryGenerator {
  double _topRadius;
  double _bottomRadius;
  double _height;
  int _segments;

  @override
  int get vertexCount => ((_segments + 1) * 2) + (_segments * 2);

  @override
  int get indexCount => (_segments * 6) + ((_segments - 2) * 6);

  MeshGeometry createCylinder(num topRadius, num bottomRadius, num height,
      {int segments: 16,
      GeometryGeneratorFlags flags: null,
      List<GeometryFilter> filters: null}) {
    _topRadius = topRadius.toDouble();
    _bottomRadius = bottomRadius.toDouble();
    _height = height.toDouble();
    _segments = segments;

    return createGeometry(flags: flags, filters: filters);
  }

  @override
  void generateIndices(Uint16List indices) {
    int i = 0;

    // Sides
    int base1 = 0;
    final int base2 = _segments + 1;
    for (int x = 0; x < _segments; ++x) {
      indices[i++] = base1 + x;
      indices[i++] = base1 + x + 1;
      indices[i++] = base2 + x;

      indices[i++] = base1 + x + 1;
      indices[i++] = base2 + x + 1;
      indices[i++] = base2 + x;
    }

    // Top cap
    base1 = (_segments + 1) * 2;
    for (int x = 1; x < _segments - 1; ++x) {
      indices[i++] = base1;
      indices[i++] = base1 + x + 1;
      indices[i++] = base1 + x;
    }

    // Bottom cap
    base1 = (_segments + 1) * 2 + _segments;
    for (int x = 1; x < _segments - 1; ++x) {
      indices[i++] = base1;
      indices[i++] = base1 + x;
      indices[i++] = base1 + x + 1;
    }
  }

  @override
  void generateVertexPositions(Vector3List positions, Uint16List indices) {
    int i = 0;

    // Top
    for (int x = 0; x <= _segments; ++x) {
      final double u = x / _segments;

      positions[i++] = new Vector3(_topRadius * math.cos(u * math.PI * 2.0),
          _height * 0.5, _topRadius * math.sin(u * math.PI * 2.0));
    }

    // Bottom
    for (int x = 0; x <= _segments; ++x) {
      final double u = x / _segments;

      positions[i++] = new Vector3(_bottomRadius * math.cos(u * math.PI * 2.0),
          _height * -0.5, _bottomRadius * math.sin(u * math.PI * 2.0));
    }

    // Top cap
    for (int x = 0; x < _segments; ++x) {
      final double u = x / _segments;

      positions[i++] = new Vector3(_topRadius * math.cos(u * math.PI * 2.0),
          _height * 0.5, _topRadius * math.sin(u * math.PI * 2.0));
    }

    // Bottom cap
    for (int x = 0; x < _segments; ++x) {
      final double u = x / _segments;

      positions[i++] = new Vector3(_bottomRadius * math.cos(u * math.PI * 2.0),
          _height * -0.5, _bottomRadius * math.sin(u * math.PI * 2.0));
    }
  }

  @override
  void generateVertexTexCoords(
      Vector2List texCoords, Vector3List positions, Uint16List indices) {
    int i = 0;

    // Cylinder top
    for (int x = 0; x <= _segments; ++x) {
      final double u = 1.0 - (x / _segments);
      texCoords[i++] = new Vector2(u, 0.0);
    }

    // Cylinder bottom
    for (int x = 0; x <= _segments; ++x) {
      final double u = 1.0 - (x / _segments);
      texCoords[i++] = new Vector2(u, 1.0);
    }

    // Top cap
    for (int x = 0; x < _segments; ++x) {
      final double r = (x / _segments) * math.PI * 2.0;
      texCoords[i++] =
          new Vector2((math.cos(r) * 0.5 + 0.5), (math.sin(r) * 0.5 + 0.5));
    }

    // Bottom cap
    for (int x = 0; x < _segments; ++x) {
      final double r = (x / _segments) * math.PI * 2.0;
      texCoords[i++] =
          new Vector2((math.cos(r) * 0.5 + 0.5), (math.sin(r) * 0.5 + 0.5));
    }
  }
}
