/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   2002/X/X - 2015/03/03
/// 
/// @brief  Win32 フレーム管理
/// 
/// ****************************************************************************

#include <tchar.h>
#include "CPL_WIN_Frame.h"

namespace CPL {
namespace WIN {

// _____________________________________________________________________________
/// @brief イベント駆動アプリ用メッセージループ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SDEF FrameEvent::Run()
{
  MSG msg;

  if( !Init() ){  return 0;  }

  size_t mdi_client_num = m_client_window_table.GetNum();
  if( mdi_client_num > 0 ) // クライアントウィンドウがある場合（）
  {
    // メイン メッセージ ループ
    while( GetMessage( &msg, nullptr, 0, 0 ) )
    {
      if( m_hdl_accel_table )
      {
        BOOL accFlag = !::TranslateAccelerator( GetWindowHandle(), m_hdl_accel_table, &msg );
        if( !accFlag ) // ↓ クライアントウィンドウテーブル分検査
        {
          CPL_LOOP2( mdi_client_num, i )
          {
            accFlag |= !::TranslateMDISysAccel( m_client_window_table[i]->GetWindowHandle(), &msg );
          }
        }
        if( accFlag )
        {
          TranslateMessage( &msg );
          DispatchMessage( &msg );
        }
      }
      else // ショートカットなしの場合
      {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
      }
    }
  }
  else
  {
    // メイン メッセージ ループ
    while( GetMessage( &msg, nullptr, 0, 0 ) )
    {
      if( m_hdl_accel_table == nullptr  ||
          !TranslateAccelerator( GetWindowHandle(), m_hdl_accel_table, &msg ) ) // ショートカットなしの場合
      {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
      }
    }
  }
  Release();
  return static_cast<SDEF>(msg.wParam);
}




// _____________________________________________________________________________
/// @brief リアルタイム？アプリ用メッセージループ（ショートカットキーに未対応）
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SDEF FrameLoop::Run()
{
  if( !Init() )
  {
    return 0;
  }

  MSG msg;
  memset( &msg, 0, sizeof(msg) );

  m_timer.Reset();
  auto next_time = m_timer.GetTime_msec();
  auto base_time = next_time;

  while( !m_flag_end.load() )
  {
    // メッセージ取得
    if( PeekMessage( &msg, nullptr, 0, 0, PM_REMOVE ) )
    {
      TranslateMessage( &msg );
      DispatchMessage( &msg );
    }
    else
    {
      auto next_step = td_time_msec(int(1000 * m_fps_step));
      next_time += next_step;
      if( next_time < m_timer.GetTime_msec() )
      {
        next_time = m_timer.GetTime_msec() + next_step;
      }
      if( On_Frame() )
      {
        break;
      }
      // ウエイト
      auto wait_time = next_time - m_timer.GetTime_msec();
      if( wait_time > td_time_msec(0) )
      {
        CPL_Sleep( wait_time );
      }
    }
  }

  Release();

  return static_cast<SDEF>(msg.wParam);
};



} // namespace WIN
} // namespace CPL


//#ifdef CPL_UNICODE
//#   define CPL_tWinMain   wWinMain
//#else
//#   define CPL_tWinMain   WinMain
//#endif



//#ifdef CPL_USE_WINMAIN

//#ifdef CPL_UNICODE

#if 0
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// UNICODE版
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int WINAPI wWinMain
  ( HINSTANCE in_hdl_instance
  , HINSTANCE in_hdl_prev_instance
  , wchar_t*  in_ptr_cmd_line
  , int       in_flag_cmd_show
  )
{

#if CPL_DBGSW_CATCH_WINMAIN_EXCEPTION
  try{
#endif
    CPL::WIN::Mouse::Setup( 4 );

    auto sp_frame = CPL::WIN::GetWinFrame();

    sp_frame->StartupW(
        in_hdl_instance,
        in_hdl_prev_instance,
        in_ptr_cmd_line,
        in_flag_cmd_show );
    return static_cast<int>(sp_frame->Run());

#if CPL_DBGSW_CATCH_WINMAIN_EXCEPTION
  }
  //catch( CPL_ERROR_CODE code )
  //{
  //  char str[256];
  //  ExceptionMessage( code, str, sizeof(str) );
  //  ::MessageBox( NULL, str, "例外", MB_OK );
  //}
  //catch( CPL::Core::Expceion e )
  //{
  //  ::MessageBox( NULL, "test", "例外", MB_OK );
  //}
  catch(...)
  {
    CPL_WIN_OUTPUT_EX( "例外キャッチ\n" );
  }
#endif
  return 0;
}

//#else // CPL_UNICODE
#endif

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// マルチバイト版
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int WINAPI WinMain
  ( HINSTANCE in_hdl_instance
  , HINSTANCE in_hdl_prev_instance
  , char*     in_ptr_cmd_line
  , int       in_flag_cmd_show
  )
{

#ifdef CPL_DBGSW_CATCH_WINMAIN_EXCEPTION
  try{
#endif

    CPL::WIN::Mouse::Setup( 4 );

    auto sp_frame = CPL::WIN::GetWinFrame();

    sp_frame->Startup(
        in_hdl_instance,
        //in_hdl_prev_instance,
        in_ptr_cmd_line,
        in_flag_cmd_show );
    return static_cast<int>(sp_frame->Run());

#ifdef CPL_DBGSW_CATCH_WINMAIN_EXCEPTION
  }
  //catch( CPL_ERROR_CODE code )
  //{
  //  char str[256];
  //  ExceptionMessage( code, str, sizeof(str) );
  //  ::MessageBox( NULL, str, "例外", MB_OK );
  //}
  //catch( CPL::Core::Exception e )
  //{
  //  ::MessageBox( NULL, "test", "例外", MB_OK );
  //}
  catch(...)
  {
    CPL_WIN_OUTPUT_EX( SwS("例外キャッチ\n") );
  }
#endif
  return 0;
}

//#endif // CPL_UNICODE

//#endif // CPL_USE_WINMAIN


