// Copyright 2015 The Cobalt Authors. 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.

#include "cobalt/audio/audio_buffer.h"

#include <algorithm>
#include <limits>
#include <memory>
#include <utility>

#include "cobalt/audio/audio_helpers.h"
#include "cobalt/web/dom_exception.h"
#include "starboard/memory.h"

namespace cobalt {
namespace audio {

AudioBuffer::AudioBuffer(float sample_rate, std::unique_ptr<AudioBus> audio_bus)
    : sample_rate_(sample_rate), audio_bus_(std::move(audio_bus)) {
  DCHECK_GT(sample_rate_, 0);
  DCHECK_GT(length(), 0);
  DCHECK_GT(number_of_channels(), 0);
}

void AudioBuffer::CopyToChannel(
    const script::Handle<script::Float32Array>& source, uint32 channel_number,
    uint32 start_in_channel, script::ExceptionState* exception_state) {
  if (channel_number >= audio_bus_->channels() ||
      start_in_channel > audio_bus_->frames()) {
    web::DOMException::Raise(web::DOMException::kIndexSizeErr, exception_state);
    return;
  }

  size_t last_frame =
      std::min(audio_bus_->frames(), source->Length() + start_in_channel);
  float* src_data = source->Data();
  switch (audio_bus_->sample_type()) {
    case kSampleTypeFloat32: {
      if (audio_bus_->storage_type() == kStorageTypePlanar) {
        for (size_t frame = start_in_channel; frame < last_frame; ++frame) {
          float* dest_ptr = reinterpret_cast<float*>(
              audio_bus_->GetSamplePtrForType<float, kStorageTypePlanar>(
                  channel_number, frame));
          *dest_ptr = *src_data;
          ++src_data;
        }
      } else {
        for (size_t frame = start_in_channel; frame < last_frame; ++frame) {
          float* dest_ptr = reinterpret_cast<float*>(
              audio_bus_->GetSamplePtrForType<float, kStorageTypeInterleaved>(
                  channel_number, frame));
          *dest_ptr = *src_data;
          ++src_data;
        }
      }
      break;
    }
    case kSampleTypeInt16: {
      if (audio_bus_->storage_type() == kStorageTypePlanar) {
        for (size_t frame = start_in_channel; frame < last_frame; ++frame) {
          uint8* dest_ptr =
              audio_bus_->GetSamplePtrForType<int16, kStorageTypePlanar>(
                  channel_number, frame);
          *reinterpret_cast<int16*>(dest_ptr) =
              ConvertSample<float, int16>(*src_data);
          ++src_data;
        }
      } else {
        for (size_t frame = start_in_channel; frame < last_frame; ++frame) {
          uint8* dest_ptr =
              audio_bus_->GetSamplePtrForType<int16, kStorageTypeInterleaved>(
                  channel_number, frame);
          *reinterpret_cast<int16*>(dest_ptr) =
              ConvertSample<float, int16>(*src_data);
          ++src_data;
        }
      }
      break;
    }
  }
}

}  // namespace audio
}  // namespace cobalt
