
/*******************************************************************************
 * Copyright (c) 2015 Olivier Langella <Olivier.Langella@moulon.inra.fr>.
 *
 * This file is part of the PAPPSOms++ library.
 *
 *     PAPPSOms++ is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     PAPPSOms++ is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with PAPPSOms++.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     Olivier Langella <Olivier.Langella@moulon.inra.fr> - initial API and
 *implementation
 ******************************************************************************/

#include <cmath>
#include "tracepeak.h"
#include "../../trace/trace.h"

namespace pappso
{
TracePeak::TracePeak()
{
}

TracePeak::TracePeak(std::vector<DataPoint>::const_iterator it_begin,
                     std::vector<DataPoint>::const_iterator it_end)
{

  m_left  = *it_begin;
  m_right = *(it_end - 1);
  m_max   = *maxYDataPoint(it_begin, it_end);
  m_area  = areaTrace(it_begin, it_end);
}

TracePeak::TracePeak(std::vector<DataPoint>::const_iterator it_begin,
                     std::vector<DataPoint>::const_iterator it_end,
                     bool remove_base)
{

  m_left  = *it_begin;
  m_right = *(it_end - 1);
  m_max   = *maxYDataPoint(it_begin, it_end);
  m_area  = areaTrace(it_begin, it_end);
  if(remove_base)
    {
      // remove the base of this peak
      m_area -= std::min(m_left.y, m_right.y) * (m_right.x - m_left.x);
      if(m_area < 0)
        m_area = 0;
    }
}

TracePeak::TracePeak(const TracePeak &other)
{
  m_area  = other.m_area;
  m_left  = other.m_left;
  m_right = other.m_right;
  m_max   = other.m_max;
}

TracePeak::~TracePeak()
{
}


TracePeakCstSPtr
TracePeak::makeTracePeakCstSPtr() const
{
  return std::make_shared<const TracePeak>(*this);
}

DataPoint &
TracePeak::getMaxXicElement()
{
  return m_max;
};
void
TracePeak::setMaxXicElement(const DataPoint &max)
{
  m_max = max;
};
DataPoint &
TracePeak::getLeftBoundary()
{
  return m_left;
};
void
TracePeak::setLeftBoundary(const DataPoint &left)
{
  m_left = left;
};

DataPoint &
TracePeak::getRightBoundary()
{
  return m_right;
};
const DataPoint &
TracePeak::getRightBoundary() const
{
  return m_right;
};
void
TracePeak::setRightBoundary(const DataPoint &right)
{
  m_right = right;
};
pappso_double
TracePeak::getArea() const
{
  return m_area;
};
void
TracePeak::setArea(pappso_double area)
{
  m_area = area;
};

bool
TracePeak::containsRt(pappso::pappso_double rt) const
{
  if((rt >= m_left.x) && (rt <= m_right.x))
    {
      return (true);
    }
  return (false);
}


const DataPoint &
TracePeak::getMaxXicElement() const
{
  return m_max;
}

const DataPoint &
TracePeak::getLeftBoundary() const
{
  return m_left;
}


bool
TracePeak::operator==(const TracePeak &other) const
{
  return ((m_area == other.m_area) && (m_max == other.m_max) &&
          (m_left == other.m_left) && (m_right == other.m_right));
}

TracePeak &
TracePeak::operator=(const TracePeak &other)
{
  if(this == &other)
    return *this;

  m_area  = other.m_area;
  m_max   = other.m_max;
  m_left  = other.m_left;
  m_right = other.m_right;

  return *this;
}
} // namespace pappso
