/*
 * libjingle
 * Copyright 2004--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.
 */


#ifndef TALK_SESSION_PHONE_WEBRTCVIE_H_
#define TALK_SESSION_PHONE_WEBRTCVIE_H_

#include "talk/base/common.h"
#include "talk/session/phone/webrtccommon.h"

#ifdef WEBRTC_RELATIVE_PATH
#include "common_types.h"
#include "modules/interface/module_common_types.h"
#include "modules/video_capture/main/interface/video_capture.h"
#include "modules/video_render/main/interface/video_render.h"
#include "video_engine/include/vie_base.h"
#include "video_engine/include/vie_capture.h"
#include "video_engine/include/vie_codec.h"
#include "video_engine/include/vie_errors.h"
#include "video_engine/include/vie_image_process.h"
#include "video_engine/include/vie_network.h"
#include "video_engine/include/vie_render.h"
#include "video_engine/include/vie_rtp_rtcp.h"
#else
#include "third_party/webrtc/files/include/common_types.h"
#include "third_party/webrtc/files/include/module_common_types.h"
#include "third_party/webrtc/files/include/video_capture.h"
#include "third_party/webrtc/files/include/video_render.h"
#include "third_party/webrtc/files/include/vie_base.h"
#include "third_party/webrtc/files/include/vie_capture.h"
#include "third_party/webrtc/files/include/vie_codec.h"
#include "third_party/webrtc/files/include/vie_errors.h"
#include "third_party/webrtc/files/include/vie_image_process.h"
#include "third_party/webrtc/files/include/vie_network.h"
#include "third_party/webrtc/files/include/vie_render.h"
#include "third_party/webrtc/files/include/vie_rtp_rtcp.h"
#endif  // WEBRTC_RELATIVE_PATH

namespace cricket {

// all tracing macros should go to a common file

// automatically handles lifetime of VideoEngine
class scoped_vie_engine {
 public:
  explicit scoped_vie_engine(webrtc::VideoEngine* e) : ptr(e) {}
  // VERIFY, to ensure that there are no leaks at shutdown
  ~scoped_vie_engine() {
    if (ptr) {
      webrtc::VideoEngine::Delete(ptr);
    }
  }
  webrtc::VideoEngine* get() const { return ptr; }
 private:
  webrtc::VideoEngine* ptr;
};

// scoped_ptr class to handle obtaining and releasing VideoEngine
// interface pointers
template<class T> class scoped_vie_ptr {
 public:
  explicit scoped_vie_ptr(const scoped_vie_engine& e)
       : ptr(T::GetInterface(e.get())) {}
  explicit scoped_vie_ptr(T* p) : ptr(p) {}
  ~scoped_vie_ptr() { if (ptr) ptr->Release(); }
  T* operator->() const { return ptr; }
  T* get() const { return ptr; }
 private:
  T* ptr;
};

// Utility class for aggregating the various WebRTC interface.
// Fake implementations can also be injected for testing.
class ViEWrapper {
 public:
  ViEWrapper()
      : engine_(webrtc::VideoEngine::Create()),
        base_(engine_), codec_(engine_), capture_(engine_),
        network_(engine_), render_(engine_), rtp_(engine_),
        image_(engine_) {
  }

  ViEWrapper(webrtc::ViEBase* base, webrtc::ViECodec* codec,
             webrtc::ViECapture* capture, webrtc::ViENetwork* network,
             webrtc::ViERender* render, webrtc::ViERTP_RTCP* rtp,
             webrtc::ViEImageProcess* image)
      : engine_(NULL),
        base_(base),
        codec_(codec),
        capture_(capture),
        network_(network),
        render_(render),
        rtp_(rtp),
        image_(image) {
  }

  virtual ~ViEWrapper() {}
  webrtc::VideoEngine* engine() { return engine_.get(); }
  webrtc::ViEBase* base() { return base_.get(); }
  webrtc::ViECodec* codec() { return codec_.get(); }
  webrtc::ViECapture* capture() { return capture_.get(); }
  webrtc::ViENetwork* network() { return network_.get(); }
  webrtc::ViERender* render() { return render_.get(); }
  webrtc::ViERTP_RTCP* rtp() { return rtp_.get(); }
  webrtc::ViEImageProcess* sync() { return image_.get(); }
  int error() { return base_->LastError(); }

 private:
  scoped_vie_engine engine_;
  scoped_vie_ptr<webrtc::ViEBase> base_;
  scoped_vie_ptr<webrtc::ViECodec> codec_;
  scoped_vie_ptr<webrtc::ViECapture> capture_;
  scoped_vie_ptr<webrtc::ViENetwork> network_;
  scoped_vie_ptr<webrtc::ViERender> render_;
  scoped_vie_ptr<webrtc::ViERTP_RTCP> rtp_;
  scoped_vie_ptr<webrtc::ViEImageProcess> image_;
};

// Adds indirection to static WebRtc functions, allowing them to be mocked.
class ViETraceWrapper {
 public:
  virtual ~ViETraceWrapper() {}

  virtual int SetTraceFilter(const unsigned int filter) {
    return webrtc::VideoEngine::SetTraceFilter(filter);
  }
  virtual int SetTraceFile(const char* fileNameUTF8) {
    return webrtc::VideoEngine::SetTraceFile(fileNameUTF8);
  }
  virtual int SetTraceCallback(webrtc::TraceCallback* callback) {
    return webrtc::VideoEngine::SetTraceCallback(callback);
  }
};

}  // namespace cricket

#endif  // TALK_SESSION_PHONE_WEBRTCVIE_H_
