void ribi::reversi::Widget::TogglePlayer()
{
  switch (GetCurrentPlayer())
  {
    case Player::player1: m_current_player = Player::player2; return;
    case Player::player2: m_current_player = Player::player1; return;
    default: assert(!"Should not get here");
  }
}
ribi::reversi::Player ribi::reversi::Widget::GetOtherPlayer() const noexcept
{
  switch (GetCurrentPlayer())
  {
    case Player::player1: return Player::player2;
    case Player::player2: return Player::player1;
    default: assert(!"Should not get here");
  }
  assert(!"Should not get here");
  throw std::logic_error("ribi::reversi::Widget::GetOtherPlayer: invalid player");
}
const std::vector<boost::shared_ptr<ribi::reversi::Move>> ribi::reversi::Widget::GetValidMoves() const noexcept
{
  std::vector<boost::shared_ptr<Move>> moves;
  for (const std::pair<int,int> p: m_board->GetValidMoves(GetCurrentPlayer()))
  {
    const boost::shared_ptr<Move> move {
      new MovePlacePiece(p.first,p.second)
    };
    assert(move);
    moves.push_back(move);
  }
  const boost::shared_ptr<Move> move_pass {
    new MovePass
  };
  moves.push_back(move_pass);
  return moves;
}
ribi::reversi::Winner ribi::reversi::Widget::GetWinner() const noexcept
{
  //static_assert(std::is_same<ribi::reversi::Widget::player1,Board::player1>(),"");
  //If both players cannot do moves, count the tiles
  if (GetBoard()->GetValidMoves(GetCurrentPlayer()).empty())
  {
    Board r(*m_board);
    const Player other_player = GetOtherPlayer();
    if (!r.GetValidMoves(other_player).empty())
    {
      const int n_1 { r.Count(Square::player1) };
      const int n_2 { r.Count(Square::player2) };
      if (n_1 > n_2) return Winner::player1;
      if (n_2 > n_1) return Winner::player2;
      assert(n_1 == n_2);
      return Winner::draw;
    }
  }
  return Winner::no_winner;
}
bool ribi::reversi::Widget::CanDoMove(const int x, const int y) const noexcept
{
  return m_board->CanDoMove(x,y,GetCurrentPlayer());
}
void ribi::reversi::Widget::DoMove(const int x, const int y) noexcept
{
  assert(GetBoard()->CanDoMove(x,y,GetCurrentPlayer()));
  m_board->DoMove(x,y,GetCurrentPlayer());
  TogglePlayer();
}
void CGameManager::NextPhase(void)
{
	int numcols= CTileManager::GetInstance()->GetNumColumns();
	int numrows= CTileManager::GetInstance()->GetNumRows();

	m_nPhaseCount++;
	if (m_nCurrentLevel != 5)
	{
		if (GetCurrentTurn() % 2 == 0)
			CGameplayState::GetInstance()->SetDayTime(false);
		else
			CGameplayState::GetInstance()->SetDayTime(true);

	}

	if (m_nCurrentPhase == GP_MOVE)
	{
		CAIManager::GetInstance()->BeginAttack();
		//Attack!!!(Attack Phase Transition)-DG
		CStateStack::GetInstance()->Push(CAttackPhaseTransState::GetInstance());

		m_nCurrentPhase = GP_ATTACK;

		if (GetTutorial()==true && GetCurrentPlayer()->GetPlayerID()==0 && GetCurrentTurn()==1)
		{
			CTutorialTextState::GetInstance()->SetTexttoShow(TTU_ATTACK);
			CStateStack::GetInstance()->Push(CTutorialTextState::GetInstance());
		}

		if (GetTutorial()==true && GetCurrentPlayer()->GetPlayerID()==0 && GetCurrentTurn()==2)
		{
			CTutorialTextState::GetInstance()->SetTexttoShow(TTU_SPELLS);
			CStateStack::GetInstance()->Push(CTutorialTextState::GetInstance());
		}
		if (GetTutorial()==true && GetCurrentPlayer()->GetPlayerID()==0 && GetCurrentTurn()==3)
		{
			CTutorialTextState::GetInstance()->SetTexttoShow(TTU_ATTACKTACTICS);
			CStateStack::GetInstance()->Push(CTutorialTextState::GetInstance());
		}


	}
	else if (m_nCurrentPhase == GP_ATTACK)
	{
		if( m_bExtraTurn == false )
		{
			CPlayer* pTemp = m_pCurrentPlayer;
			m_nCurrentPhase = GP_MOVE;
			m_pCurrentPlayer = m_pNextPlayer;
			m_pNextPlayer = pTemp;
		}
		else
		{
			m_nCurrentPhase = GP_MOVE;
			m_bExtraTurn = false;
		}

		//Chilling the cooldown: this function does the cooldowndown each turn  -DG
		CHero* Hero =  dynamic_cast <CHero*>(GetChampion(m_pCurrentPlayer->GetPlayerID()));
		Hero->ChillCooldown();		
		m_pCurrentPlayer->SetAP(nStartingAP);
		m_pCurrentPlayer->SetMaxPopCap(STARTING_CAP_PER_TURN);
		
		//Look At That, TileManager Takeing care of business! This added resoruces based on the owned tiles -DG
		CTileManager::GetInstance()->EvaluateResources(m_pCurrentPlayer->GetPlayerID());
		
		CGameplayState::GetInstance()->ClearSelections();
		if (GetChampion(m_pCurrentPlayer->GetPlayerID()) != nullptr)
		{
			CGameplayState::GetInstance()->SnapToPosition(GetChampion(m_pCurrentPlayer->GetPlayerID())->GetPos(), true);
		}

		CAIManager::GetInstance()->BeginMovement();

		for (decltype(m_vUnits.size()) i = 0; i < m_vUnits.size(); ++i)
		{
			if (m_vUnits[i]->GetPlayerID() == m_pCurrentPlayer->GetPlayerID())
			{
				m_vUnits[i]->SetTilesMoved(0);
				m_vUnits[i]->SetHasAttacked(false);
				m_vUnits[i]->UpdateEffects();
			}
		}
		//RAISE THE CASTLE WALLS!!!(Do the movement transition)-DG
		CStateStack::GetInstance()->Push(CMovetPhaseTransState::GetInstance());

		if (GetTutorial()==true && GetCurrentPlayer()->GetPlayerID()==0 && GetCurrentTurn()==2)
		{
			CTutorialTextState::GetInstance()->SetTexttoShow(TTU_MOVETACTICS);
			CStateStack::GetInstance()->Push(CTutorialTextState::GetInstance());
		}

	}
}