/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   200X/X/X - 2016/11/25
/// 
/// @brief  ファイルダイアログ。
/// 
/// ****************************************************************************



#include "CPL_WIN_FileDialog.h"



namespace CPL {
namespace WIN {


// 静的メンバ実体 -------------------
OPENFILENAME FileDialog::sm_open_file_name;


// _____________________________________________________________________________
/// @brief "ファイルを保存"ダイアログを開く。
/// 
/// @param[in]  in_hdl_win_owner      : オーナーとなるウィンドウのハンドル。
/// @param[out] out_file_name         : ファイル名を格納するバッファポインタ。
/// @param[in]  in_file_name_buf_size : ファイル名を格納するバッファのサイズ（UNICODEは文字数）
/// @param[in]  in_str_filter         : フィルタリング文字列。詳しくはlpstrFilterを検索してちょ。
/// 
/// @return GetSaveFileName関数の戻り値を参照してください。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int
  FileDialog::Save
    ( _in <HWND    > in_hdl_win_owner
    , pout<str_type> out_file_name
    , _in <DWORD   > in_file_name_buf_size
    , _in <str_cptr> in_str_filter
    )
{
  ZeroMemory( &sm_open_file_name, sizeof(OPENFILENAME) );  // ゼロクリア

//  static char name[256] = SwS("name");
  // メンバ設定
  sm_open_file_name.lStructSize     = sizeof(OPENFILENAME);
  sm_open_file_name.hwndOwner       = in_hdl_win_owner;
  sm_open_file_name.hInstance       = (HINSTANCE)GetWindowLongPtr( in_hdl_win_owner, GWLP_HINSTANCE );
  sm_open_file_name.lpstrFilter     = in_str_filter;
  sm_open_file_name.nFilterIndex    = 0;
  sm_open_file_name.lpstrFile       = out_file_name;
  sm_open_file_name.nMaxFile        = in_file_name_buf_size;
  sm_open_file_name.Flags           = OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT;
  sm_open_file_name.lpstrDefExt     = SwS("*");

  return GetSaveFileName( &sm_open_file_name );
}


// _____________________________________________________________________________
/// @brief "ファイルを開く"ダイアログを開く。
/// 
/// @param[in]  in_hdl_win_owner      : オーナーとなるウィンドウのハンドル。
/// @param[out] out_file_name         : ファイル名を格納するバッファポインタ。
/// @param[in]  in_file_name_buf_size : ファイル名を格納するバッファのサイズ（UNICODEは文字数）
/// @param[in]  in_str_filter         : フィルタリング文字列。詳しくはlpstrFilterを検索してちょ。
/// 
/// @return GetOpenFileName関数の戻り値を参照してください。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int
  FileDialog::Load
    ( _in <HWND    > in_hdl_win_owner
    , pout<str_type> out_file_name
    , _in <DWORD   > in_file_name_buf_size
    , _in <str_cptr> in_str_filter
    )
{
  ZeroMemory( &sm_open_file_name, sizeof(OPENFILENAME) );  // ゼロクリア

  // メンバ設定
  sm_open_file_name.lStructSize     = sizeof(OPENFILENAME);
  sm_open_file_name.hwndOwner       = in_hdl_win_owner;
  sm_open_file_name.hInstance       = (HINSTANCE)GetWindowLongPtr( in_hdl_win_owner, GWLP_HINSTANCE );
  sm_open_file_name.lpstrFilter     = in_str_filter;
//  sm_open_file_name.lpstrCustomFilter  = strCustom;
//  sm_open_file_name.nMaxCustFilter  = sizeof(strCustom);
  sm_open_file_name.nFilterIndex    = 0;
  sm_open_file_name.lpstrFile       = out_file_name;
  sm_open_file_name.nMaxFile        = in_file_name_buf_size;
//  sm_open_file_name.lpstrFileTitle  = strTitle;
//  sm_open_file_name.nMaxFileTitle  = sizeof(strTitle);
  sm_open_file_name.Flags           = OFN_FILEMUSTEXIST;
  sm_open_file_name.lpstrDefExt     = SwS("*");

  return GetOpenFileName( &sm_open_file_name );
}





// **********  FolderDialog ********************************************************************


BROWSEINFO FolderDialog::sm_browse_info;


// _____________________________________________________________________________
/// @brief FolderDialog デフォルトコンストラクタ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FolderDialog::FolderDialog()
{
  // 初期化
  ::memset( &sm_browse_info, 0, sizeof(sm_browse_info) ); // ゼロクリア
  sm_browse_info.hwndOwner      = nullptr;
  sm_browse_info.pidlRoot       = nullptr; // ルートフォルダ
  sm_browse_info.pszDisplayName = nullptr; // フォルダ名取得用バッファ（今はまだ設定しない）
  sm_browse_info.lpszTitle      = nullptr; // 説明文字列へのポインタ
  sm_browse_info.ulFlags        = BIF_RETURNONLYFSDIRS; // デフォルト設定（ドライブとフォルダ選択）
  sm_browse_info.lpfn           = nullptr; // BrowseCallbackProcコールバック関数
  sm_browse_info.lParam         = 0; // 任意データ
  // sm_browse_info.iImage  = インデックス格納用
}


// _____________________________________________________________________________
/// @brief フォルダ選択ダイアログの起動
/// 
/// @copydetails doxycomment::arg_in_hdl_win_parent
/// @param[in] out_folder_name
///   : フォルダ名を受け取るバッファアドレスを指定します。
/// @param[in] in_text
///   : 表示する文字列を指定します。
/// @param[in] in_flag
///   : フラグの組み合わせを指定します。\n
///   : 詳しくはBROWSEINFOのulFlagsを参照してください。
/// @param[in] in_call_function
///   : コールバック関数のアドレスを指定します。\n
///   : コールバック関数が必要ない場合はnullptrを指定します。
/// 
/// @return 
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int
  FolderDialog::Show
    ( _in<HWND       > in_hdl_win_parent
    , _in<LPTSTR     > out_folder_name
    , _in<LPCTSTR    > in_text
    , _in<UINT       > in_flag
    , _in<BFFCALLBACK> in_call_function
    )
{
  // 設定
  sm_browse_info.pszDisplayName = out_folder_name;
  sm_browse_info.lpszTitle      = in_text;
  sm_browse_info.ulFlags        = in_flag;
  sm_browse_info.lpfn           = in_call_function;

  // 表示
  LPITEMIDLIST ret_folder = ::SHBrowseForFolder( &sm_browse_info );
  BOOL ret_flag = false;

  if( ret_folder )
  {
    // フルパス取得
    ret_flag = ::SHGetPathFromIDList( ret_folder, out_folder_name );
    ::CoTaskMemFree( ret_folder ); // 開放
  }
  return ret_flag;
}


} // namespace WIN
} // namespace CPL

