#ifndef PEAK_H
#define PEAK_H

#include "Header.hh"
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <vector>

#include "AdvPeakType.hh"


#ifndef PEAK_TYPE_H
#define PEAK_TYPE_H

#include <string>

enum peakTypeID {
    UNKNOWN_PEAK_TYPE_ID, /* unknown */
    PEAK_ID,              /* ordinal peak */
    SHOLDER_I_ID,         /* sholder in increase region */
      SHOLDER_D_ID,         /* sholder in decrease region */
    };

struct _peakType {
    enum peakTypeID id;
    std::string symbol;
};

typedef struct _peakType AdvPeakType;

const AdvPeakType UNKNOWN_PEAK_TYPE={ UNKNOWN_PEAK_TYPE, "uk" };
const AdvPeakType PEAK             ={ PEAK_ID,           "p"  };
const AdvPeakType SHOLDER_I        ={ SHOLDER_I_ID,      "si" };
const AdvPeakType SHOLDER_D        ={ SHOLDER_D_ID,      "sd" };

#endif // PEAK_TYPE_H

class AdvPeak {

    public:
        static const UInt4 fullSize; //  = 6;
        static const UInt4 shortSize; // = 3;

    protected:
        AdvPeakType type; /* the kind of the peak */
        Double   x;    /* the position of the peak */ 
        Double   h;    /* the height of the peak */
        Double   w;    /* the width of the peak */
        Double   xl;   /* the lower bound of the range of the peak at half height */
        Double   xu;   /* the upper bound of the range of the peak at half height */

    public:
        /** default constructor */
        AdvPeak();
        AdvPeak(const AdvPeakType type, const Double x, const Double h, const Double width, const Double xl, const Double  xu);

        /** copy constructor */
        AdvPeak(const AdvPeak &peak);

        /** destructor */
        ~AdvPeak();

        void set(const AdvPeakType type, const Double x, const Double h, const Double width, const Double xl, const Double  xu);

        /** assignment operator */
        AdvPeak operator = (const AdvPeak &peak);

        /** type of the peak, peak/sholder */
        AdvPeakType getType()     const ;
        /** the height of the peakA */
        Double getHeight()     const ;
        /** the position of the peak */
        Double getPosition()   const ;
        /** the width of the peak at the half heght */
        Double getWidth()      const ;
        /** the lower bound of the peak at the half heght */
        Double getLowerBound() const ;
        /** the upper bound of the peak at the half heght */
        Double getUpperBound() const ;

        /** vetrorise in short form */
        std::vector<Double> toVector() ;

        /** vetrorise in long form */
        std::vector<Double> toFullVector() ;
         
        /** print title */
        static void title();
        static void title(FILE *fp);
        static void title(std::ostream *);

        /** dump the peak */
        void dump();
        void dump(FILE *fp);
        void dump(std::ostream *);
};

#endif
