/*
 * libjingle
 * Copyright 2011, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "talk/app/webrtc/mediastreamhandler.h"

#ifdef WEBRTC_RELATIVE_PATH
#include "modules/video_capture/main/interface/video_capture.h"
#else
#include "third_party/webrtc/files/include/video_capture.h"
#endif

namespace webrtc {

VideoTrackHandler::VideoTrackHandler(VideoTrackInterface* track,
                                     MediaProviderInterface* provider)
    : provider_(provider),
      video_track_(track),
      state_(track->state()),
      enabled_(track->enabled()),
      renderer_(track->GetRenderer()) {
  video_track_->RegisterObserver(this);
}

VideoTrackHandler::~VideoTrackHandler() {
  video_track_->UnregisterObserver(this);
}

void VideoTrackHandler::OnChanged() {
  if (state_ != video_track_->state()) {
    state_ = video_track_->state();
    OnStateChanged();
  }
  if (renderer_.get() != video_track_->GetRenderer()) {
    renderer_ = video_track_->GetRenderer();
    OnRendererChanged();
  }
  if (enabled_ != video_track_->enabled()) {
    enabled_ = video_track_->enabled();
    OnEnabledChanged();
  }
}

LocalVideoTrackHandler::LocalVideoTrackHandler(
    LocalVideoTrackInterface* track,
    MediaProviderInterface* provider)
    : VideoTrackHandler(track, provider),
      local_video_track_(track) {
}

LocalVideoTrackHandler::~LocalVideoTrackHandler() {
  // cricket::VideoRenderer and cricket::VideoCapturer is owned and deleted by
  // the track. It must be removed from the media stream provider since it is
  // possible that the tracks reference count is set to zero when
  // local_video_track_ falls out of scope.
  provider_->SetLocalRenderer(local_video_track_->label(), NULL);
  provider_->SetCaptureDevice(local_video_track_->label(), NULL);
}

void LocalVideoTrackHandler::OnRendererChanged() {
  VideoRendererWrapperInterface* renderer = video_track_->GetRenderer();
  if (renderer)
    provider_->SetLocalRenderer(video_track_->label(), renderer->renderer());
  else
    provider_->SetLocalRenderer(video_track_->label(), NULL);
}

void LocalVideoTrackHandler::OnStateChanged() {
  if (local_video_track_->state() == VideoTrackInterface::kLive) {
    provider_->SetCaptureDevice(local_video_track_->label(),
                                local_video_track_->GetVideoCapture());
    VideoRendererWrapperInterface* renderer = video_track_->GetRenderer();
    if (renderer)
      provider_->SetLocalRenderer(video_track_->label(), renderer->renderer());
    else
      provider_->SetLocalRenderer(video_track_->label(), NULL);
  }
}

void LocalVideoTrackHandler::OnEnabledChanged() {
  // TODO What should happen when enabled is changed?
}

RemoteVideoTrackHandler::RemoteVideoTrackHandler(
    VideoTrackInterface* track,
    MediaProviderInterface* provider)
    : VideoTrackHandler(track, provider),
      remote_video_track_(track) {
}

RemoteVideoTrackHandler::~RemoteVideoTrackHandler() {
  // Since cricket::VideoRenderer is not reference counted
  // we need to remove the renderer before we are deleted.
  provider_->SetRemoteRenderer(video_track_->label(), NULL);
}


void RemoteVideoTrackHandler::OnRendererChanged() {
  VideoRendererWrapperInterface* renderer = video_track_->GetRenderer();
  if (renderer)
    provider_->SetRemoteRenderer(video_track_->label(), renderer->renderer());
  else
    provider_->SetRemoteRenderer(video_track_->label(), NULL);
}

void RemoteVideoTrackHandler::OnStateChanged() {
}

void RemoteVideoTrackHandler::OnEnabledChanged() {
  // TODO: What should happen when enabled is changed?
}

MediaStreamHandler::MediaStreamHandler(MediaStreamInterface* stream,
                                       MediaProviderInterface* provider)
    : stream_(stream),
      provider_(provider) {
}

MediaStreamHandler::~MediaStreamHandler() {
  for (VideoTrackHandlers::iterator it = video_handlers_.begin();
       it != video_handlers_.end(); ++it) {
    delete *it;
  }
}

MediaStreamInterface* MediaStreamHandler::stream() {
  return stream_.get();
}

void MediaStreamHandler::OnChanged() {
  // TODO: Implement state change and enabled changed.
}


LocalMediaStreamHandler::LocalMediaStreamHandler(
    MediaStreamInterface* stream,
    MediaProviderInterface* provider)
    : MediaStreamHandler(stream, provider) {
  VideoTracks* tracklist(stream->video_tracks());

  for (size_t j = 0; j < tracklist->count(); ++j) {
    LocalVideoTrackInterface* track =
        static_cast<LocalVideoTrackInterface*>(tracklist->at(j));
    VideoTrackHandler* handler(new LocalVideoTrackHandler(track, provider));
    video_handlers_.push_back(handler);
  }
}

RemoteMediaStreamHandler::RemoteMediaStreamHandler(
    MediaStreamInterface* stream,
    MediaProviderInterface* provider)
    : MediaStreamHandler(stream, provider) {
  VideoTracks* tracklist(stream->video_tracks());

  for (size_t j = 0; j < tracklist->count(); ++j) {
    VideoTrackInterface* track =
        static_cast<VideoTrackInterface*>(tracklist->at(j));
    VideoTrackHandler* handler(new RemoteVideoTrackHandler(track, provider));
    video_handlers_.push_back(handler);
  }
}

MediaStreamHandlers::MediaStreamHandlers(MediaProviderInterface* provider)
    : provider_(provider) {
}

MediaStreamHandlers::~MediaStreamHandlers() {
  for (StreamHandlerList::iterator it = remote_streams_handlers_.begin();
       it != remote_streams_handlers_.end(); ++it) {
    delete *it;
  }
  for (StreamHandlerList::iterator it = local_streams_handlers_.begin();
       it != local_streams_handlers_.end(); ++it) {
    delete *it;
  }
}

void MediaStreamHandlers::AddRemoteStream(MediaStreamInterface* stream) {
  RemoteMediaStreamHandler* handler = new RemoteMediaStreamHandler(stream,
                                                                   provider_);
  remote_streams_handlers_.push_back(handler);
}

void MediaStreamHandlers::RemoveRemoteStream(MediaStreamInterface* stream) {
  StreamHandlerList::iterator it = remote_streams_handlers_.begin();
  for (; it != remote_streams_handlers_.end(); ++it) {
    if ((*it)->stream() == stream) {
      delete *it;
      break;
    }
  }
  ASSERT(it != remote_streams_handlers_.end());
  remote_streams_handlers_.erase(it);
}

void MediaStreamHandlers::CommitLocalStreams(
    StreamCollectionInterface* streams) {
  // Iterate the old list of local streams.
  // If its not found in the new collection it have been removed.
  // We can not erase from the old collection at the same time as we iterate.
  // That is what the ugly while(1) fix.
  while (1) {
    StreamHandlerList::iterator it = local_streams_handlers_.begin();
    for (; it != local_streams_handlers_.end(); ++it) {
      if (streams->find((*it)->stream()->label()) == NULL) {
        delete *it;
        break;
      }
    }
    if (it != local_streams_handlers_.end()) {
      local_streams_handlers_.erase(it);
      continue;
    }
    break;
  }

  // Iterate the new collection of local streams.
  // If its not found in the old collection it have been added.
  for (size_t j = 0; j < streams->count(); ++j) {
    MediaStreamInterface* stream = streams->at(j);
    StreamHandlerList::iterator it = local_streams_handlers_.begin();
    for (; it != local_streams_handlers_.end(); ++it) {
      if (stream == (*it)->stream())
        break;
    }
    if (it == local_streams_handlers_.end()) {
      LocalMediaStreamHandler* handler = new LocalMediaStreamHandler(
          stream, provider_);
      local_streams_handlers_.push_back(handler);
    }
  }
};


}  // namespace webrtc
