/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   200X/X/X - 2016/12/02
/// 
/// @brief  バッファコレクションクラス
/// 
/// ****************************************************************************


#include <algorithm>
#include "CPL_DX_BufferCollection.h"


namespace CPL {
namespace DX {
//namespace Graph {
namespace Buffer {


// _____________________________________________________________________________
/// @brief バッファの追加
/// 
/// @param[in] in_sp_buffer
///   : 登録するバッファオブジェクトを指すスマートポインタを指定します。
/// 
/// @return 常にtrueが返ります。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool Collection::EntryBuffer( _in<sdptr<BufIface>> in_sp_buffer )
{
  //
  //SpBufTable::iterator itr_vsb = m_buf_table.begin();
  //SpBufTable::iterator itr_end = m_buf_table.end();

  //while( itr_vsb != itr_end )
  //{
  //  if( (*itr_vsb)->GetSlotNo() == input_slot ) // 該当あり
  //  {
  //    (*itr_vsb) = in_sp_buffer; // 上書きして抜ける
  //    return;
  //  }

  //  ++itr_vsb;
  //}

  // 該当ないので最後尾に追加
  m_buf_table.push_back( in_sp_buffer );

  return true;
}



// _____________________________________________________________________________
/// @brief ストリーム頂点バッファの登録抹消
/// 
/// @param[in] in_sp_buffer
///   : 登録を抹消するバッファオブジェクトを指すスマートポインタを指定します。
/// 
/// @return 
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool Collection::CancelBuffer( _in<sdptr<BufIface>> in_sp_buffer )
{
  auto itr_res =
    std::remove_if
      ( m_buf_table.begin()
      , m_buf_table.end()
      , [&]( sdptr<BufIface>& sp_buf ){ return sp_buf == in_sp_buffer; }
      );
  if( itr_res != m_buf_table.end() )
  {
    m_buf_table.erase( itr_res, m_buf_table.end() );
    return true;
  }
  return false;
}


// _____________________________________________________________________________
/// @brief ストリームバッファの取得（index version）
/// 
/// @param[in] in_index : 登録バッファのインデックスを指定します。
/// 
/// @return
/// 指定されたインデックスのバッファのスマートポインタを返します。\n
/// インデックスが範囲外の場合、nullptrが返ります。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sdptr<Collection::BufIface>
  Collection::GetBuffer_by_Index( _in<size_t> in_index ) const
{
  if( in_index < m_buf_table.size() )
  {
    return m_buf_table[ in_index ];
  }
  return nullptr;
}


// _____________________________________________________________________________
/// @brief ストリームバッファの取得（name version）
/// 
/// @param[in] in_buf_name : 登録バッファの名前を指定します。
/// 
/// @return
/// 指定された名前のバッファのスマートポインタを返します。\n
/// 該当する名前が無い場合、nullptrが返ります。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sdptr<Collection::BufIface>
  Collection::GetBuffer_by_Name( _in<char_cptr> in_buf_name ) const
{
  SpBufTable::const_iterator itr_buffer = m_buf_table.begin();
  SpBufTable::const_iterator itr_end    = m_buf_table.end();

  while( itr_buffer != itr_end )
  {
    if( (*itr_buffer)->GetName() == in_buf_name )
    {
      return (*itr_buffer);
    }

    ++itr_buffer;
  }

  return nullptr;
}


// _____________________________________________________________________________
/// @brief 保持する全てのバッファの所有権を解放します。
/// 
/// @return なし。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Collection::Release()
{
  m_buf_table.clear();
}


// _____________________________________________________________________________
/// @brief 描画準備コールバック関数
/// 
/// 登録バッファのRenderSetup()を呼び出します。
/// ※ 基本的にユーザーが呼び出す必要はありません。
/// 
/// @return
/// 全登録バッファのRenderSetup()の戻り値が正常だった場合、S_OKを返します。\n
/// 何らかのエラーコードを返した場合、そのコードを返します。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HRESULT Collection::RenderSetup( DXDeviceContext* in_ptr_d3d_IC )
{
  //CPL_LOOP2( m_buf_table.GetNum(), buf_idx )
  for( auto& sp_buf : m_buf_table )
  {
    HRESULT hr = sp_buf->RenderSetup( in_ptr_d3d_IC );
    if( FAILED(hr) )
    {
      return hr;
    }
  }
  return S_OK;
}



} // namespace Buffer
//} // namespace Graph
} // namespace DX
} // namespace CPL