// 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.

#include "starboard/shared/starboard/player/player_internal.h"

#include "starboard/log.h"

using starboard::shared::starboard::player::InputBuffer;

namespace {

SbMediaTime GetMediaTime(SbMediaTime media_pts,
                         SbTimeMonotonic media_pts_update_time) {
  SbTimeMonotonic elapsed = SbTimeGetMonotonicNow() - media_pts_update_time;
  return media_pts + elapsed * kSbMediaTimeSecond / kSbTimeSecond;
}

}  // namespace

SbPlayerPrivate::SbPlayerPrivate(
    SbMediaTime duration_pts,
    SbPlayerDeallocateSampleFunc sample_deallocate_func,
    SbPlayerDecoderStatusFunc decoder_status_func,
    SbPlayerStatusFunc player_status_func,
    void* context,
    starboard::scoped_ptr<PlayerWorker::Handler> player_worker_handler)
    : sample_deallocate_func_(sample_deallocate_func),
      context_(context),
      ticket_(SB_PLAYER_INITIAL_TICKET),
      duration_pts_(duration_pts),
      media_pts_(0),
      media_pts_update_time_(SbTimeGetMonotonicNow()),
      frame_width_(0),
      frame_height_(0),
      is_paused_(true),
#if SB_API_VERSION >= 4
      playback_rate_(1.0),
#endif  // SB_API_VERSION >= 4
      volume_(1.0),
      total_video_frames_(0),
      dropped_video_frames_(0),
      worker_(new PlayerWorker(this,
                               player_worker_handler.Pass(),
                               decoder_status_func,
                               player_status_func,
                               this,
                               context)) {
}

void SbPlayerPrivate::Seek(SbMediaTime seek_to_pts, int ticket) {
  {
    starboard::ScopedLock lock(mutex_);
    SB_DCHECK(ticket_ != ticket);
    media_pts_ = seek_to_pts;
    media_pts_update_time_ = SbTimeGetMonotonicNow();
    ticket_ = ticket;
  }

  worker_->Seek(seek_to_pts, ticket);
}

void SbPlayerPrivate::WriteSample(
    SbMediaType sample_type,
    const void** sample_buffers,
    int* sample_buffer_sizes,
    int number_of_sample_buffers,
    SbMediaTime sample_pts,
    const SbMediaVideoSampleInfo* video_sample_info,
    const SbDrmSampleInfo* sample_drm_info) {
  if (sample_type == kSbMediaTypeVideo) {
    ++total_video_frames_;
  }
  InputBuffer input_buffer(sample_type, sample_deallocate_func_, this, context_,
                           sample_buffers, sample_buffer_sizes,
                           number_of_sample_buffers, sample_pts,
                           video_sample_info, sample_drm_info);
  worker_->WriteSample(input_buffer);
}

void SbPlayerPrivate::WriteEndOfStream(SbMediaType stream_type) {
  worker_->WriteEndOfStream(stream_type);
}

void SbPlayerPrivate::SetBounds(int x, int y, int width, int height) {
  PlayerWorker::Bounds bounds = {x, y, width, height};
  worker_->SetBounds(bounds);
  // TODO: Wait until a frame is rendered with the updated bounds.
}

void SbPlayerPrivate::GetInfo(SbPlayerInfo* out_player_info) {
  SB_DCHECK(out_player_info != NULL);

  starboard::ScopedLock lock(mutex_);
  out_player_info->duration_pts = duration_pts_;
  if (is_paused_) {
    out_player_info->current_media_pts = media_pts_;
  } else {
    out_player_info->current_media_pts =
        GetMediaTime(media_pts_, media_pts_update_time_);
  }
  out_player_info->frame_width = frame_width_;
  out_player_info->frame_height = frame_height_;
  out_player_info->is_paused = is_paused_;
  out_player_info->volume = volume_;
  out_player_info->total_video_frames = total_video_frames_;
  out_player_info->dropped_video_frames = dropped_video_frames_;
  out_player_info->corrupted_video_frames = 0;
#if SB_API_VERSION >= 4
  out_player_info->playback_rate = playback_rate_;
#endif  // SB_API_VERSION >= 4
}

void SbPlayerPrivate::SetPause(bool pause) {
  worker_->SetPause(pause);
}

#if SB_API_VERSION >= 4
void SbPlayerPrivate::SetPlaybackRate(double playback_rate) {
  playback_rate_ = playback_rate;
  worker_->SetPlaybackRate(playback_rate);
}
#endif  // SB_API_VERSION >= 4

void SbPlayerPrivate::SetVolume(double volume) {
  SB_UNREFERENCED_PARAMETER(volume);
  SB_NOTIMPLEMENTED();
}

void SbPlayerPrivate::UpdateMediaTime(SbMediaTime media_time, int ticket) {
  starboard::ScopedLock lock(mutex_);
  if (ticket_ != ticket) {
    return;
  }
  media_pts_ = media_time;
  media_pts_update_time_ = SbTimeGetMonotonicNow();
}

void SbPlayerPrivate::UpdateDroppedVideoFrames(int dropped_video_frames) {
  starboard::ScopedLock lock(mutex_);
  dropped_video_frames_ = dropped_video_frames;
}

#if SB_API_VERSION >= 4
SbDecodeTarget SbPlayerPrivate::GetCurrentDecodeTarget() {
  return worker_->GetCurrentDecodeTarget();
}
#endif  // SB_API_VERSION >= 4
