// Interface exposed to emscripten's WebIDL Binder.
// http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/WebIDL-Binder.html
enum draco_GeometryAttribute_Type {
  "draco_GeometryAttribute::INVALID",
  "draco_GeometryAttribute::POSITION",
  "draco_GeometryAttribute::NORMAL",
  "draco_GeometryAttribute::COLOR",
  "draco_GeometryAttribute::TEX_COORD",
  "draco_GeometryAttribute::GENERIC"
};

[Prefix="draco::"]
interface GeometryAttribute {
  void GeometryAttribute();
};

enum draco_EncodedGeometryType {
  "draco::INVALID_GEOMETRY_TYPE",
  "draco::POINT_CLOUD",
  "draco::TRIANGULAR_MESH"
};

enum draco_MeshEncoderMethod {
  "draco::MESH_SEQUENTIAL_ENCODING",
  "draco::MESH_EDGEBREAKER_ENCODING"
};

[Prefix="draco::"]
interface PointAttribute {
  void PointAttribute();
  long size();

  // From GeometryAttribute
  long attribute_type();
  long data_type();
  byte num_components();
  boolean normalized();
  long byte_stride();
  long byte_offset();
  long unique_id();
};

[Prefix="draco::"]
interface PointCloud {
  void PointCloud();

  long num_attributes();
  long num_points();
};

[Prefix="draco::"]
interface Mesh : PointCloud {
  void Mesh();
  long num_faces();

  // From PointCloud
  long num_attributes();
  long num_points();
  void set_num_points(long num_points);
};

[Prefix="draco::"]
interface Metadata {
  void Metadata();
};

interface DracoInt8Array {
  void DracoInt8Array();
  long GetValue(long index);
  long size();
};

interface MetadataBuilder {
  void MetadataBuilder();

  boolean AddStringEntry(Metadata metadata,
                         [Const] DOMString entry_name,
                         [Const] DOMString entry_value);
  boolean AddIntEntry(Metadata metadata,
                      [Const] DOMString entry_name,
                      long entry_value);
  boolean AddIntEntryArray(Metadata metadata,
                          [Const] DOMString entry_name,
                          [Const] long[] att_values,
                          long num_values);
  boolean AddDoubleEntry(Metadata metadata,
                         [Const] DOMString entry_name,
                         double entry_value);
};

interface PointCloudBuilder {
  void PointCloudBuilder();
  long AddFloatAttribute(PointCloud pc, draco_GeometryAttribute_Type type,
                         long num_vertices, long num_components,
                         [Const] float[] att_values);
  long AddInt8Attribute(PointCloud pc, draco_GeometryAttribute_Type type,
                        long num_vertices, long num_components,
                        [Const] byte[] att_values);
  long AddUInt8Attribute(PointCloud pc, draco_GeometryAttribute_Type type,
                         long num_vertices, long num_components,
                         [Const] octet[] att_values);
  long AddInt16Attribute(PointCloud pc, draco_GeometryAttribute_Type type,
                         long num_vertices, long num_components,
                         [Const] short[] att_values);
  long AddUInt16Attribute(PointCloud pc, draco_GeometryAttribute_Type type,
                          long num_vertices, long num_components,
                          [Const] unsigned short[] att_values);
  long AddInt32Attribute(PointCloud pc, draco_GeometryAttribute_Type type,
                         long num_vertices, long num_components,
                         [Const] long[] att_values);
  long AddUInt32Attribute(PointCloud pc, draco_GeometryAttribute_Type type,
                          long num_vertices, long num_components,
                          [Const] unsigned long[] att_values);

  boolean AddMetadata(PointCloud pc, [Const] Metadata metadata);
  boolean SetMetadataForAttribute(PointCloud pc, long attribute_id,
                                  [Const] Metadata metadata);
};

interface MeshBuilder : PointCloudBuilder {
  void MeshBuilder();

  boolean AddFacesToMesh(Mesh mesh, long num_faces, [Const] long[] faces);

  // Deprecated.
  long AddFloatAttributeToMesh(Mesh mesh, draco_GeometryAttribute_Type type,
                               long num_vertices, long num_components,
                               [Const] float[] att_values);
  // Deprecated.
  long AddInt32AttributeToMesh(Mesh mesh, draco_GeometryAttribute_Type type,
                               long num_vertices, long num_components,
                               [Const] long[] att_values);
  // Deprecated.
  boolean AddMetadataToMesh(Mesh mesh, [Const] Metadata metadata);

  // From PointCloudBuilder
  long AddFloatAttribute(PointCloud pc, draco_GeometryAttribute_Type type,
                         long num_vertices, long num_components,
                         [Const] float[] att_values);
  long AddInt8Attribute(PointCloud pc, draco_GeometryAttribute_Type type,
                        long num_vertices, long num_components,
                        [Const] byte[] att_values);
  long AddUInt8Attribute(PointCloud pc, draco_GeometryAttribute_Type type,
                         long num_vertices, long num_components,
                         [Const] octet[] att_values);
  long AddInt16Attribute(PointCloud pc, draco_GeometryAttribute_Type type,
                         long num_vertices, long num_components,
                         [Const] short[] att_values);
  long AddUInt16Attribute(PointCloud pc, draco_GeometryAttribute_Type type,
                          long num_vertices, long num_components,
                          [Const] unsigned short[] att_values);
  long AddInt32Attribute(PointCloud pc, draco_GeometryAttribute_Type type,
                         long num_vertices, long num_components,
                         [Const] long[] att_values);
  long AddUInt32Attribute(PointCloud pc, draco_GeometryAttribute_Type type,
                          long num_vertices, long num_components,
                          [Const] unsigned long[] att_values);

  boolean AddMetadata(PointCloud pc, [Const] Metadata metadata);
  boolean SetMetadataForAttribute(PointCloud pc, long attribute_id,
                                  [Const] Metadata metadata);
};

interface Encoder {
  void Encoder();
  void SetEncodingMethod(long method);
  void SetAttributeQuantization(draco_GeometryAttribute_Type type,
                                long quantization_bits);
  void SetAttributeExplicitQuantization(draco_GeometryAttribute_Type type,
                                        long quantization_bits,
                                        long num_components,
                                        [Const] float[] origin,
                                        float range);
  void SetSpeedOptions(long encoding_speed, long decoding_speed);
  void SetTrackEncodedProperties(boolean flag);

  long EncodeMeshToDracoBuffer(Mesh mesh,
                               DracoInt8Array encoded_data);
  long EncodePointCloudToDracoBuffer(PointCloud pc, boolean deduplicate_values,
                                     DracoInt8Array encoded_data);

  // Returns the number of encoded points or faces from the last Encode
  // operation. Returns 0 if SetTrackEncodedProperties was not set to true.
  long GetNumberOfEncodedPoints();
  long GetNumberOfEncodedFaces();
};

interface ExpertEncoder {
  void ExpertEncoder(PointCloud pc);
  void SetEncodingMethod(long method);
  void SetAttributeQuantization(long att_id,
                                long quantization_bits);
  void SetAttributeExplicitQuantization(long att_id,
                                        long quantization_bits,
                                        long num_components,
                                        [Const] float[] origin,
                                        float range);
  void SetSpeedOptions(long encoding_speed, long decoding_speed);
  void SetTrackEncodedProperties(boolean flag);

  long EncodeToDracoBuffer(boolean deduplicate_values,
                           DracoInt8Array encoded_data);

  // Returns the number of encoded points or faces from the last Encode
  // operation. Returns 0 if SetTrackEncodedProperties was not set to true.
  long GetNumberOfEncodedPoints();
  long GetNumberOfEncodedFaces();
};