
#include <cmath>
#include <complex>
#include <algorithm>
#include <iostream>

#include "hark-lib/node/CalcSpecAddPower.h"

namespace hark
{
namespace node
{
    CalcSpecAddPower::CalcSpecAddPower():
        NodeDef("CalcSpecAddPower")
    {
        *this
            << Terminal::in("INPUT_POWER_SPEC1")
            << Terminal::in("INPUT_POWER_SPEC2")
            >> Terminal::out("OUTPUT_POWER_SPEC");
    }

    void
    CalcSpecAddPower::reset()
    {
    }

    void
    CalcSpecAddPower::initialize(InputDataBundle &input)
    {
    }

    bool
    CalcSpecAddPower::operator () (size_t count, InputDataBundle &input, OutputDataBundle &output)
    {
        const auto &input_power_spectrum1 = input["INPUT_POWER_SPEC1"].last().cast<std::map<int, std::vector<float> > >();
        const auto &input_power_spectrum2 = input["INPUT_POWER_SPEC2"].last().cast<std::map<int, std::vector<float> > >();

#ifdef DEBUG
        ptime start_time;
        ptime end_time;
        start_time = microsec_clock::local_time();
#endif

        //if(count == 0){ this->initialize(input); }

        auto out = data::create<std::map<int, std::vector<float> > >();
        auto &output_power_spectrum = out.cast<std::map<int, std::vector<float> > >();

        if(input_power_spectrum1.size() != input_power_spectrum2.size()){
            std::stringstream ss;
            ss << "CalcSpecAddPower: InputMap size not match.\n" << "FILE: " << __FILE__ << ", LINE: " << __LINE__;
            throw RuntimeError(ss.str());
        }

        if(input_power_spectrum1.size() > 0){
            std::map<int, std::vector<float> >::const_iterator it_in_spec1 = input_power_spectrum1.begin();
            std::map<int, std::vector<float> >::const_iterator it_in_spec2 = input_power_spectrum2.begin();

            for(; it_in_spec1 != input_power_spectrum1.end(); ++it_in_spec1, ++it_in_spec2){
                std::vector<float> output_vector;
                if(it_in_spec1->first != it_in_spec2->first){
                    std::stringstream ss;
                    ss << "CalcSpecAddPower: InputMap keys not match.\n" << "FILE: " << __FILE__ << ", LINE: " << __LINE__;
                    throw RuntimeError(ss.str());
                }
                output_vector.resize(it_in_spec1->second.size());
                for(size_t k = 0; k < it_in_spec1->second.size(); k++){
                    output_vector[k] = it_in_spec1->second[k] + it_in_spec2->second[k];
                }
                output_power_spectrum.insert(std::pair<int, std::vector<float> >(it_in_spec1->first, output_vector));
            }
        }

        output["OUTPUT_POWER_SPEC"].push(out);

#ifdef DEBUG
        end_time = microsec_clock::local_time();
        std::cout << end_time - start_time << std::endl;
#endif

        return true;
    }
}
}

/* end of file */
