#include "AdvPeak.hh"

const UInt4 AdvPeak::shortSize=3;
const UInt4 AdvPeak::fullSize =6;

/**
 *  default constructor
 */
AdvPeak::AdvPeak() {
    this->type=UNKNOWN_PEAK_TYPE;
}

/**
 *  explicit constructor
 */
AdvPeak::AdvPeak(const AdvPeakType type, const Double x, const Double h, const Double w, const Double xl, const Double xu) {
    set(type, x, h, w, xl, xu);
}

/**
 *  copy constructor
 */
AdvPeak::AdvPeak(const AdvPeak &peak) {
    this->type = peak.type;
    this->x    = peak.x;
    this->h    = peak.h;
    this->w    = peak.w;
    this->xl   = peak.xl;
    this->xu   = peak.xu;
}

/**
 *  destructor
 */
AdvPeak::~AdvPeak() {
}

/**
 *  assignment operator
 */
AdvPeak AdvPeak::operator = (const AdvPeak &peak) {
    this->type = peak.type;
    this->x    = peak.x;
    this->h    = peak.h;
    this->w    = peak.w;
    this->xl   = peak.xl;
    this->xu   = peak.xu;

    return *this;
}

/**
 *
 */
void AdvPeak::set(const AdvPeakType type, const Double x, const Double h, const Double w, const Double xl, const Double xu) {
    this->type = type;
    this->x    = x;
    this->h    = h;
    this->w    = w;
    this->xl   = xl;
    this->xu   = xu;
}

AdvPeakType AdvPeak::getType() const {
    return this->type;
}

Double AdvPeak::getHeight() const {
    return this->h;
}

Double AdvPeak::getPosition() const {
    return this->x;
}

Double AdvPeak::getWidth() const {
    return this->w;
}

Double AdvPeak::getLowerBound() const {
    return this->xl;
}

Double AdvPeak::getUpperBound() const {
    return this->xu;
}

/**
 *  vectrize (in short form)
 */
std::vector<Double> AdvPeak::toVector() {
    std::vector<Double> *v=new std::vector<Double>();
    v->clear();

    v->push_back(h);
    v->push_back(x);
    v->push_back(w);

    return *v;
}

/**
 *  vectrize (in full form)
 */
std::vector<Double> AdvPeak::toFullVector() {
    std::vector<Double> v = this->toVector();

    v.push_back(this->xl);
    v.push_back(this->xu);
    v.push_back(static_cast<Double>(this->type.id));

    return v;
}

/**
 *  print title
 */
void AdvPeak::title(FILE *fp) {
   std::fprintf(fp, "%4s %23s %23s %23s %23s %23s\n", "type", "position", "height", "width", "lower bound", "upper bound");
}

void AdvPeak::title() {
    AdvPeak::title(stdout);
}

void AdvPeak::title(std::ostream* ost) {
    (*ost) << std::setw(4) << "type";
    (*ost) << " ";
    (*ost) << std::setw(23) << "position";
    (*ost) << " ";
    (*ost) << std::setw(23) << "height";
    (*ost) << " ";
    (*ost) << std::setw(23) << "width";
    (*ost) << " ";
    (*ost) << std::setw(23) << "lower bound";
    (*ost) << " ";
    (*ost) << std::setw(23) << "upper bound";
    (*ost) << std::endl;
}

/**
 *  dump the peak
 */
void AdvPeak::dump(FILE *fp) {
   std::fprintf(fp, "%4s %23.15e %23.15e %23.15e %23.15e %23.15e\n", this->type.symbol.c_str(), x, h, w, xl, xu);
}

void AdvPeak::dump() {
    this->dump(stdout);
}

void AdvPeak::dump(std::ostream* ost) {
    (*ost) << std::setw(4) << this->type.symbol.c_str();
    (*ost) << " ";
    (*ost) << std::setw(23) << std::setprecision(15) << std::setiosflags(std::ios::scientific) << x;
    (*ost) << " ";
    (*ost) << std::setw(23) << std::setprecision(15) << std::setiosflags(std::ios::scientific) << h;
    (*ost) << " ";
    (*ost) << std::setw(23) << std::setprecision(15) << std::setiosflags(std::ios::scientific) << w;
    (*ost) << " ";
    (*ost) << std::setw(23) << std::setprecision(15) << std::setiosflags(std::ios::scientific) << xl;
    (*ost) << " ";
    (*ost) << std::setw(23) << std::setprecision(15) << std::setiosflags(std::ios::scientific) << xu;
    (*ost) << std::endl;
}
