/*
 * Copyright 2017 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_MESH_PROJECTION_H_
#define COBALT_LOADER_MESH_MESH_PROJECTION_H_

#include <vector>

#include "base/basictypes.h"
#include "base/logging.h"
#include "cobalt/render_tree/mesh.h"
#include "starboard/types.h"

namespace cobalt {
namespace loader {
namespace mesh {

// Represents a set of meshes to project a render subtree onto.
class MeshProjection : public base::RefCountedThreadSafe<MeshProjection> {
 public:
  // Represents a collection of meshes (vertex lists), each of which maps to a
  // texture ID. The specification currently only defines a valid ID of 0, with
  // all others reserved, so this vector should only have one mesh. In the
  // future more streams or static images could be represented by the texture
  // IDs.
  typedef std::vector<scoped_refptr<render_tree::Mesh> > MeshCollection;
  // Represents a list of mesh collections; in stereo mode, there is either
  // just one collection for both eyes (which undergoes an adjustment per eye)
  // or one for each eye. Mono video will only have one collection in the list.
  typedef ScopedVector<MeshCollection> MeshCollectionList;

  // Default mesh collection indices to GetMesh().
  enum CollectionIndex {
    kLeftEyeOrMonoCollection = 0,
    kRightEyeCollection = 1
  };

  MeshProjection(MeshCollectionList mesh_collections,
                 base::optional<uint32> crc = base::nullopt)
      : mesh_collections_(mesh_collections.Pass()), crc_(crc) {
    DCHECK_GT(mesh_collections_.size(), 0UL);
    DCHECK_LE(mesh_collections_.size(), 2UL);
    // Check that the left-eye collection holds at least one mesh.
    DCHECK_GT(mesh_collections_[0]->size(), 0UL);
  }

  const base::optional<uint32>& crc() const { return crc_; }

  // For stereo mode with distinct per-eye meshes, left eye is collection 0,
  // right is collection 1.
  scoped_refptr<render_tree::Mesh> GetMesh(size_t collection = 0) const {
    if (collection >= mesh_collections_.size()) {
      return NULL;
    }

    const MeshCollection& mesh_collection = *mesh_collections_[collection];

    CHECK(mesh_collection.size());

    return mesh_collection[0];
  }

  bool HasSeparateMeshPerEye() const { return mesh_collections_.size() == 2; }

  uint32 GetEstimatedSizeInBytes() const {
    uint32 estimate = sizeof(crc_);

    for (size_t i = 0; i < mesh_collections_.size(); i++) {
      for (size_t j = 0; j < mesh_collections_[i]->size(); j++) {
        estimate += mesh_collections_[i]->at(j)->GetEstimatedSizeInBytes();
      }
    }

    return estimate;
  }

  bool HasSameCrcAs(scoped_refptr<MeshProjection> other_meshproj) const {
    return other_meshproj && other_meshproj->crc() == crc_;
  }

 protected:
  virtual ~MeshProjection() {}

  // Allow the reference counting system access to our destructor.
  friend class base::RefCountedThreadSafe<MeshProjection>;

 private:
  const MeshCollectionList mesh_collections_;
  const base::optional<uint32> crc_;
};

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

#endif  // COBALT_LOADER_MESH_MESH_PROJECTION_H_
