// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_LOADER_MESH_PROJECTION_CODEC_PROJECTION_DECODER_H_
#define COBALT_LOADER_MESH_PROJECTION_CODEC_PROJECTION_DECODER_H_

#include <stddef.h>
#include <stdint.h>

#include <string>
#include <vector>

#include "base/basictypes.h"
#include "cobalt/loader/mesh/projection_codec/constants.h"
#include "cobalt/loader/mesh/projection_codec/indexed_vert.h"

namespace cobalt {
namespace loader {
namespace mesh {
namespace projection_codec {

class ProjectionDecoder {
 public:
  // We need limits to keep us from having crazy large meshes that eat up all of
  // our RAM and take down services. The values below are chosen to be large
  // enough for everything we see on the horizon, but if future valid meshes
  // need bigger numbers they can certainly be adjusted.
  static const uint32_t kMaxCoordinateCount = 10 * 1000;
  static const uint32_t kMaxVertexCount = 32 * 1000;
  static const uint32_t kMaxMeshCount = 32;
  static const uint32_t kMaxTriangleIndexCount = 128 * 1000;

  // This is a callback handler interface for a ProjecionDecoder.
  class Sink {
   public:
    virtual ~Sink();

    // These are the callbacks, with calling pattern like:
    //
    // BeginMeshCollection
    //   AddCoordinate
    //   ...
    //   AddVertex
    //   ...
    //   BeginMeshInstance
    //     SetMeshGeometryType
    //     AddVertexIndex
    //     ...
    //   EndMeshInstance
    // EndMeshCollection

    // Give the Sink an opportunity to check the CRC and decide whether it
    // is known already and skip the decoding. This helps with memory, cpu, and
    // streaming cost.
    virtual bool IsCached(uint32_t crc) = 0;

    virtual void BeginMeshCollection() = 0;
    virtual void AddCoordinate(float value) = 0;
    virtual void AddVertex(const IndexedVert& v) = 0;

    virtual void BeginMeshInstance() = 0;
    virtual void SetTextureId(uint8_t texture_id) = 0;
    virtual void SetMeshGeometryType(MeshGeometryType type) = 0;
    virtual void AddVertexIndex(size_t v_index) = 0;
    virtual void EndMeshInstance() = 0;

    virtual void EndMeshCollection() = 0;
  };

  // Decodes a full projection box that includes the full box header.
  static bool DecodeToSink(const uint8_t* data, size_t data_size, Sink* sink);

  // Decodes the contents of a projection box without the full box header.
  // |version| and |flags| are the values from the full box header provided by
  // an external parser. |data| contains all box contents after the full box
  // header.
  static bool DecodeBoxContentsToSink(uint8_t version, uint32_t flags,
                                      const uint8_t* data, size_t data_size,
                                      Sink* sink);

  // Decodes the contents of a projection box without the full box header or
  // CRC-32 or compression FourCC. |version|, |flags|, |crc|, and |compression|
  // are the values the partially parsed MeshProjectionBox. |data| contains all
  // the remaining box contents after compression FourCC.
  static bool DecodeMeshesToSink(uint8_t version, uint32_t flags, uint32_t crc,
                                 const std::string& compression,
                                 const uint8_t* data, size_t data_size,
                                 Sink* sink);

 private:
  class BitReader {
   public:
    BitReader(const uint8_t* data, size_t data_size);

    // Reads the requested number of big-endian bits. Sets ok() to false if an
    // error ocurred.
    uint32_t GetBits(int32_t num_bits);

    // Aligns the reader to an 8-bit boundary, potentially discarding up to 7
    // bits.
    void Align();

    // Discards the requested number of bits and advances the reader forward.
    void SkipBits(int64_t num_bits);

    // Gets a pointer to the underlying raw buffer of aligned bytes. Exactly
    // bits_remaining() / 8 bytes are available and may be accessed.
    const uint8_t* aligned_raw_bytes() const;

    // Gets the number of bits available in the buffer. If ok() is false, this
    // will be zero.
    int64_t bits_remaining() const;

    // Returns true if the reader is aligned on an 8-bit boundary.
    bool is_aligned() const;

    // Returns true if the reader is in a good state and everything is okay.
    bool ok() const;

   private:
    const uint8_t* data_begin_;  // Unowned.
    const uint8_t* data_end_;    // Unowned.

    // Cached bits, stored as big-endian. 7 or fewer bits may be cached between
    // method calls.
    uint64_t cached_bits_;

    // The number of cached bits in cached_bits_. Only fewer than 8 bits should
    // ever be cached between method calls.
    int32_t cached_bit_count_;

    bool ok_;
  };

  bool error_;
  Sink* sink_;  // Unowned.
  BitReader reader_;
  uint8_t version_;
  uint32_t flags_;
  uint32_t crc_;
  std::string compression_;
  std::vector<uint8_t> decompress_buffer_;

  ProjectionDecoder(const uint8_t* data, size_t data_size, Sink* sink);

  bool VerifyGreater(uint32_t a, uint32_t b);
  bool VerifyEqual(uint32_t a, uint32_t b);
  bool VerifyEqual(const std::string& a, const std::string& b);
  bool VerifyAligned();

  uint32_t GetBits(int32_t num_bits);
  uint8_t GetUInt8();
  uint32_t GetUInt32();
  float GetFloat();
  std::string GetFourCC();
  void SkipBits(int64_t num_bits);
  void Align();
  void CheckOK();

  void DecodeProjectionBox();
  void DecodeProjectionBoxContents(uint8_t version, uint32_t flags);
  void DecodeCompressedProjectionBoxContents(uint8_t version, uint32_t flags,
                                             uint32_t crc,
                                             const std::string& compression);
  void DecodeMeshData();
  void DeflateDecompress();

  DISALLOW_COPY_AND_ASSIGN(ProjectionDecoder);
};

}  // namespace projection_codec
}  // namespace mesh
}  // namespace loader
}  // namespace cobalt

#endif  // COBALT_LOADER_MESH_PROJECTION_CODEC_PROJECTION_DECODER_H_
