/**
 * 例外を使用しない場合のサンプル
 *
 * ASSERTを使用せず、必ず各種エラーを処理するものとする
 *
 */
 
//================================================================
#define SUCCESS 0
#define FAILED  1
//================================================================
typedef enum
{
  E_ERR_FILE_NOT_FOUND = (FAILED+0x100),
  E_ERR_ALLOCATE_ERROR,
  E_ERR_IO_ERR,
}E_ERR_CODE;
//================================================================


//========================================================================================


//==============================================
// Procクラス
//==============================================
class Proc :public gfl::proc::BaseProcess
{
  SampleClass *m_samp;
  bool         m_isFalt;
  
  void DoMainProcess();
};



Proc::Proc( APP_PARAM * prm ) : m_samp(NULL), m_isFalt(false)
{
}

gfl::proc::Result Proc::DoMainProcess()
{
  // 各処理で継続できない状況に陥ったかチェック！
  // 1関数毎にチェックする必要があるので面倒！
  if( SUCCESS != ControlChara() ){
    return gfl::proc::RES_ERROR;
  }
  if( SUCCESS != ControlField() ){
    return gfl::proc::RES_ERROR;
  }
  if( SUCCESS != ControlSound() ){
    return gfl::proc::RES_ERROR;
  }
  if( SUCCESS != ControlNetwork() ){
    return gfl::proc::RES_ERROR;
  }

  return isFinish() ? gfl::proc::RES_FINISH : gfl::proc::RES_CONTINUE;
}


gfl::proc::Result Proc::InitFunc( gfl::proc::Manager * )
{
  gfl::heap::HeapBase* systemHeap = gfl::heap::Manager::GetHeapByHeapId( gfl::heap::HEAPID_SYSTEM );
  m_samp = GFL_NEW(systemHeap) SampleClass();

  if( m_samp == NULL ){
    m_isFalt = true;
  }
  else if( !m_samp->Initialize() ){
    m_isFalt = true;
  }
}

gfl::proc::Result Proc::UpdateFunc( gfl::proc::Manager * )
{
  if( !m_isFalt )
  {
    gfl::proc::Result result = DoMainProcess();
    if( gfl::proc::RES_ERROR != result ){
      return result;
    }
    m_isFalt = true;
  }

  // エラーが発生した旨を呼び出し元に通知するための処理を準備
  // ここでは、返却値にエラーが発生した場合のリザルトコードを返すものとする
  return gfl::proc::RES_ERROR;
}

void Proc::DrawFunc( gfl::proc::Manager * )
{
  if( m_isFalt ){
    return; // エラーなので表示しない
  }

    // 描画本体が記載される
}

gfl::proc::Result GameProc::EndFunc(gfl::proc::Manager* pManager)
{
  GFL_SAFE_DELETE( m_samp );
  return gfl::proc::RES_FINISH;
}


//========================================================================================

void SampleClass::SampleClass()
{
}

void SampleClass::~SampleClass()
{
}

bool SampleClass::CheckError( u32 result, const char* funcName ) 
{
  switch( result )
  {
    case    SUCCESS:
      return true;

    case  E_ERR_FILE_NOT_FOUND:
      NN_LOG( "[%s] File Not Found Error!", funcName );
      return false;
    case  E_ERR_ALLOCATE_ERROR:
      NN_LOG( "[%s] MemoryAllocation Error!", funcName );
      return false;
    case  E_ERR_IO_ERR:
      NN_LOG( "[%s] IO Error!", funcName );
      return false;

    default:
      NN_LOG( "[%s] Unknown result code!", funcName );
      return false;
  }
}

// 一式、初期化 
bool SampleClass::Initialize()
{
  u32 result;

  result = InitializeFont();
  if( !CheckError( result, "InitializeFont" ) ){
    return false;
  }
  result = InitializeCharaModel();
  if( !CheckError( result, "InitializeCharaModel" ) ){
    return false;
  }
  result = InitializeFieldModel();
  if( !CheckError( result, "InitializeFieldModel" ) ){
    return false;
  }
  result = InitializeSound();
  if( !CheckError( result, "InitializeSound" ) ){
    return false;
  }
  result = InitializeNetwork();
  if( !CheckError( result, "InitializeNetwork" ) ){
    return false;
  }

  return true;
}



// フォントの初期化 
u32 SampleClass::InitializeFont()
{
  gfl::fs::RomFile file;
  u32              result = SUCCESS;

  bool open_result = file.Open( L"rom:/cbf_std.bcfnt", gfl::fs::OPEN_MODE_READ );
  if( !open_result ){
     return E_ERR_FILE_NOT_FOUND;  // ファイルオープンに失敗
  }

  size_t fileSize = file.GetSize();
  u8f*   fontData = m_deviceAllocator->Alloc( fileSize, 128 );

  if( fontData == NULL )
  { 
     result = E_ERR_ALLOCATE_ERROR;   // メモリアロケート失敗
  }
  else
  {
    size_t readSize = file.Read( fontData, fileSize );

    if( readSize == fileSize )
    {
      gfl::grp::util::DrawUtil::Initialize( m_graphics, m_heapAllocator, m_deviceAllocator );
      gfl::grp::util::DrawUtil::SetFontResource( fontData );
    }
    else{
      result = E_ERR_IO_ERR; // 読み込みに失敗
    }
    delete []fontData;
  }

  file.Close();

  return result;
}





