#ifndef STAN_MATH_FWD_SCAL_FUN_INC_BETA_HPP
#define STAN_MATH_FWD_SCAL_FUN_INC_BETA_HPP

#include <stan/math/fwd/meta.hpp>
#include <stan/math/prim/scal/fun/grad_reg_inc_beta.hpp>
#include <stan/math/fwd/scal/fun/pow.hpp>
#include <stan/math/fwd/scal/fun/exp.hpp>
#include <stan/math/fwd/scal/fun/beta.hpp>
#include <stan/math/fwd/scal/fun/digamma.hpp>
#include <stan/math/fwd/core.hpp>
#include <stan/math/prim/scal/fun/lbeta.hpp>
#include <stan/math/prim/scal/fun/digamma.hpp>

namespace stan {
namespace math {

template <typename T>
inline fvar<T> inc_beta(const fvar<T>& a, const fvar<T>& b, const fvar<T>& x) {
  using std::exp;
  using std::pow;

  T d_a;
  T d_b;
  T d_x;
  const T beta_ab = beta(a.val_, b.val_);

  grad_reg_inc_beta(d_a, d_b, a.val_, b.val_, x.val_, digamma(a.val_),
                    digamma(b.val_), digamma(a.val_ + b.val_), beta_ab);
  d_x = pow((1 - x.val_), b.val_ - 1) * pow(x.val_, a.val_ - 1) / beta_ab;
  return fvar<T>(inc_beta(a.val_, b.val_, x.val_),
                 a.d_ * d_a + b.d_ * d_b + x.d_ * d_x);
}
}  // namespace math
}  // namespace stan

#endif
