#include "HullWhiteCalibratorAD.h"

void HullWhiteCalibratorADPrices::calculate_next_J0y(TwoCurrencyArrowDebreuCalibrator& next_calibrator, const InterestRateTimeSliceProcess* dom_process, const FXTimeSliceProcess* fx_process, const InterestRateTimeSliceProcess* fgn_process, InterestRateTimeSliceProcess* next_dom_process, FXTimeSliceProcess* next_fx_process, InterestRateTimeSliceProcess* next_fgn_process, SliceProcessCorrelations3d const& next_increment)
{
	gelib::d_vector* J0y = next_fx_process->get_J0_grid();
	const gelib::d_vector* next_ygrid = next_fx_process->get_grid();

	for (size_t j = 0; j < J0y->size(); ++j)
	{
		(*J0y)[j] = m_gauss_J0[0]->e_beta_expectation((*next_ygrid)[j]) / next_fx_process->get_spot_fx();
	}

}

void HullWhiteCalibratorADPrices::calculate_next_J0z(TwoCurrencyArrowDebreuCalibrator& next_calibrator, const InterestRateTimeSliceProcess* dom_process, const FXTimeSliceProcess* fx_process, const InterestRateTimeSliceProcess* fgn_process, InterestRateTimeSliceProcess* next_dom_process, FXTimeSliceProcess* next_fx_process, InterestRateTimeSliceProcess* next_fgn_process, SliceProcessCorrelations3d const& next_increment)
{

	gelib::d_vector* J0z = next_fgn_process->get_J0_grid();
	const gelib::d_vector* next_zgrid = next_fgn_process->get_grid();

	for (size_t j = 0; j < J0z->size(); ++j)
	{
		(*J0z)[j] = m_gauss_J0[1]->e_beta_expectation((*next_zgrid)[j]);
	}

}

void HullWhiteCalibratorADPrices::calculate_next_spot_values(std::vector<std::unique_ptr<TimeSliceProcess>>& next_processes)
{
	// This will calculate the spot values from the J0 numerically as in general method
	TwoCurrencyArrowDebreuCalibrator::calculate_next_spot_values(next_processes);

	// this will calculate analytic libors if the flags are set to do so, otherwise we'll have the numerical ones
	UsesHullWhiteJ0::calculate_next_spot_values(next_processes); // TODO should really accept just x and z libors
}

std::unique_ptr<HullWhiteCalibratorADPrices> HullWhiteCalibratorADPrices::construct()
{
	std::unique_ptr<HullWhiteCalibratorADPrices> ad = std::unique_ptr<HullWhiteCalibratorADPrices>(
		new HullWhiteCalibratorADPrices());
	return std::move(ad);
}
