#ifndef RecoLocalCalo_HcalRecAlgos_HcalDeterministicFit_h
#define RecoLocalCalo_HcalRecAlgos_HcalDeterministicFit_h

#include <typeinfo>
#include <vector>

#include "CalibCalorimetry/HcalAlgos/interface/HcalTimeSlew.h"
#include "RecoLocalCalo/HcalRecAlgos/interface/PedestalSub.h"

#include "DataFormats/HcalDetId/interface/HcalDetId.h"
#include "DataFormats/HcalRecHit/interface/HBHEChannelInfo.h"
#include "CalibCalorimetry/HcalAlgos/interface/HcalPulseShapes.h"
#include "CalibFormats/HcalObjects/interface/HcalCoder.h"
#include "CalibFormats/HcalObjects/interface/HcalCalibrations.h"

class HcalDeterministicFit {
public:
  HcalDeterministicFit();
  ~HcalDeterministicFit();

  enum FType { shapeLandau, shape205, shape206, shape207 };

  void init(HcalTimeSlew::ParaSource tsParam, HcalTimeSlew::BiasSetting bias, bool iApplyTimeSlew, double respCorr);

  void phase1Apply(const HBHEChannelInfo& channelData,
                   float& reconstructedEnergy,
                   float& reconstructedTime,
                   const HcalTimeSlew* hcalTimeSlew_delay) const;

  // This is the CMSSW Implementation of the apply function
  void getLandauFrac(float tStart, float tEnd, float& sum) const;
  void get205Frac(float tStart, float tEnd, float& sum) const;
  void get206Frac(float tStart, float tEnd, float& sum) const;
  void get207Frac(float tStart, float tEnd, float& sum) const;
  void getFrac(float, float, float&, FType) const;

private:
  HcalTimeSlew::ParaSource fTimeSlew_;
  HcalTimeSlew::BiasSetting fTimeSlewBias_;
  PedestalSub fPedestalSubFxn_;
  bool applyTimeSlew_;
  double frespCorr_;

  static constexpr int HcalRegion[2] = {16, 17};
  static constexpr int tsWidth = 25;
  static constexpr float negThresh[2] = {-3., 15.};
  static constexpr float invGpar[3] = {-13.11, 11.29, 5.133};
  static constexpr float rCorr[2] = {0.95, 0.95};
  static constexpr float rCorrSiPM[2] = {1., 1.};

  static constexpr float landauFrac[125] = {
      0,          7.6377e-05, 0.000418655, 0.00153692, 0.00436844, 0.0102076,  0.0204177,   0.0360559,  0.057596,
      0.0848493,  0.117069,   0.153152,    0.191858,   0.23198,    0.272461,   0.312438,    0.351262,   0.388476,
      0.423788,   0.457036,   0.488159,    0.517167,   0.54412,    0.569112,   0.592254,    0.613668,   0.633402,
      0.651391,   0.667242,   0.680131,    0.688868,   0.692188,   0.689122,   0.67928,     0.662924,   0.64087,
      0.614282,   0.584457,   0.552651,    0.51997,    0.487317,   0.455378,   0.424647,    0.395445,   0.367963,
      0.342288,   0.318433,   0.29636,     0.275994,   0.257243,   0.24,       0.224155,    0.2096,     0.196227,
      0.183937,   0.172635,   0.162232,    0.15265,    0.143813,   0.135656,   0.128117,    0.12114,    0.114677,
      0.108681,   0.103113,   0.0979354,   0.0931145,  0.0886206,  0.0844264,  0.0805074,   0.0768411,  0.0734075,
      0.0701881,  0.0671664,  0.0643271,   0.0616564,  0.0591418,  0.0567718,  0.054536,    0.0524247,  0.0504292,
      0.0485414,  0.046754,   0.0450602,   0.0434538,  0.041929,   0.0404806,  0.0391037,   0.0377937,  0.0365465,
      0.0353583,  0.0342255,  0.0331447,   0.032113,   0.0311274,  0.0301854,  0.0292843,   0.0284221,  0.0275964,
      0.0268053,  0.0253052,  0.0238536,   0.0224483,  0.0210872,  0.0197684,  0.0184899,   0.01725,    0.0160471,
      0.0148795,  0.0137457,  0.0126445,   0.0115743,  0.0105341,  0.00952249, 0.00853844,  0.00758086, 0.00664871,
      0.00574103, 0.00485689, 0.00399541,  0.00315576, 0.00233713, 0.00153878, 0.000759962, 0};

  static constexpr float siPM205Frac[125] = {
      0,         0,         0,         0,         0.00133129, 0.00444633, 0.0115,    0.0243992, 0.0443875, 0.0716386,
      0.105298,  0.143832,  0.185449,  0.228439,  0.271367,   0.31315,    0.353041,  0.390587,  0.425555,  0.45788,
      0.487604,  0.514843,  0.539752,  0.562504,  0.583282,   0.602263,   0.619612,  0.635457,  0.649765,  0.66208,
      0.671249,  0.675509,  0.673048,  0.662709,  0.644394,   0.619024,   0.588194,  0.55375,   0.517448,  0.480768,
      0.444831,  0.410418,  0.378015,  0.347879,  0.320103,   0.294667,   0.271474,  0.250391,  0.231257,  0.213907,
      0.198178,  0.183914,  0.170967,  0.159205,  0.148505,   0.138758,   0.129864,  0.121737,  0.114299,  0.107478,
      0.101214,  0.0954507, 0.0901402, 0.0852385, 0.0807069,  0.0765108,  0.0726194, 0.0690052, 0.0656435, 0.0625123,
      0.0595916, 0.0568637, 0.0543125, 0.0519236, 0.0496838,  0.0475815,  0.0456058, 0.0437472, 0.0419966, 0.0403463,
      0.0387887, 0.0373173, 0.0359259, 0.034609,  0.0333615,  0.0321786,  0.0310561, 0.02999,   0.0289767, 0.0280127,
      0.0270951, 0.0262209, 0.0253875, 0.0245923, 0.0238333,  0.0231082,  0.022415,  0.021752,  0.0211174, 0.0205097,
      0.0199274, 0.0193692, 0.0188336, 0.0183196, 0.017826,   0.0173518,  0.0168959, 0.0164575, 0.0160356, 0.0156296,
      0.0152385, 0.0148617, 0.0144984, 0.0141482, 0.0138103,  0.0134842,  0.0131693, 0.0128652, 0.0125714, 0.0122873,
      0.0120127, 0.011747,  0.01149,   0.0112412, 0.0110002};

  static constexpr float siPM206Frac[125] = {
      0,         0,         0,         4.55043e-06, 0.00292008, 0.0147851, 0.0374319, 0.0688652, 0.105913,  0.145714,
      0.186153,  0.225892,  0.264379,  0.30145,     0.337074,   0.371247,  0.403973,  0.43526,   0.465115,  0.493554,
      0.520596,  0.546269,  0.570605,  0.59364,     0.615418,   0.635984,  0.655384,  0.673669,  0.690889,  0.707091,
      0.719418,  0.721882,  0.7127,    0.693915,    0.668746,   0.640097,  0.610129,  0.580218,  0.550958,  0.522548,
      0.495058,  0.468521,  0.442967,  0.418419,    0.394896,   0.37241,   0.350965,  0.330559,  0.31118,   0.292812,
      0.275432,  0.259013,  0.243523,  0.228928,    0.215193,   0.202281,  0.190154,  0.178773,  0.1681,    0.158098,
      0.148729,  0.139959,  0.131751,  0.124074,    0.116894,   0.110182,  0.103907,  0.0980423, 0.0925613, 0.0874393,
      0.0826525, 0.078179,  0.0739978, 0.0700894,   0.0664353,  0.0630185, 0.0598226, 0.0568328, 0.0540348, 0.0514156,
      0.0489628, 0.046665,  0.0445115, 0.0424924,   0.0405984,  0.038821,  0.037152,  0.0355841, 0.0341104, 0.0327243,
      0.0314199, 0.0301916, 0.0290343, 0.0279431,   0.0269136,  0.0259417, 0.0250235, 0.0241554, 0.0233341, 0.0225566,
      0.0218199, 0.0211214, 0.0204587, 0.0198294,   0.0192313,  0.0186626, 0.0181214, 0.0176059, 0.0171146, 0.016646,
      0.0161986, 0.0157713, 0.0153627, 0.0149719,   0.0145977,  0.0142393, 0.0138956, 0.0135659, 0.0132493, 0.0129451,
      0.0126528, 0.0123715, 0.0121007, 0.0118399,   0.0115885};

  static constexpr float siPM207Frac[125] = {
      8.79768e-07, 1.0741e-05, 7.99305e-05, 0.000401863, 0.00148019, 0.00425688, 0.0100505, 0.0202671, 0.0360159,
      0.0578184,   0.0855186,  0.118382,    0.155299,    0.195005,   0.236264,   0.277979,  0.319254,  0.359407,
      0.397953,    0.434579,   0.469106,    0.50146,     0.531646,   0.559717,   0.585765,  0.609901,  0.632248,
      0.652923,    0.672002,   0.689414,    0.70477,     0.717237,   0.725596,   0.728535,  0.725028,  0.714632,
      0.697574,    0.674653,   0.647036,    0.616039,    0.58295,    0.548907,   0.514845,  0.481483,  0.449338,
      0.418754,    0.389935,   0.36298,     0.337908,    0.314684,   0.293236,   0.27347,   0.255279,  0.23855,
      0.22317,     0.209031,   0.196027,    0.184061,    0.173041,   0.162884,   0.153513,  0.144857,  0.136854,
      0.129445,    0.122577,   0.116205,    0.110283,    0.104775,   0.0996449,  0.0948609, 0.0903944, 0.0862196,
      0.0823128,   0.0786528,  0.0752202,   0.0719973,   0.0689682,  0.0661182,  0.0634341, 0.0609038, 0.058516,
      0.0562608,   0.0541287,  0.0521113,   0.0502007,   0.0483898,  0.046672,   0.0450411, 0.0434916, 0.0420183,
      0.0406164,   0.0392815,  0.0380094,   0.0367964,   0.035639,   0.0345339,  0.0334781, 0.0324687, 0.0315032,
      0.030579,    0.0296939,  0.0288458,   0.0280326,   0.0272526,  0.0265039,  0.025785,  0.0250943, 0.0244304,
      0.0237919,   0.0231777,  0.0225864,   0.022017,    0.0214684,  0.0209397,  0.0204298, 0.0199381, 0.0194635,
      0.0190053,   0.0185629,  0.0181354,   0.0177223,   0.0173229,  0.0169366,  0.0165628, 0.0162011};
};

#endif  // HLTAnalyzer_h
