/**============================================================================
 *
 * \file   progress_bar.cpp
 * \brief  Contains implementations for the ProgressBar class.
 *
 * Source:
 *
 * http://www.siteduzero.com/forum-83-691036-p1-barre-de-progression-console-c.html
 *
 * \author Leblanc Christophe
 * \date   01/01/2013
 * \email cleblancad@gmail.com
 *
 *===========================================================================*/

#include "progress_bar.hpp"

namespace marinov {

ProgressBar::ProgressBar(std::ostream& os, const int& length):
  m_Length(length),
  m_Mark(0),
  m_Progress(0),
  m_Os(&os)
{}

ProgressBar::ProgressBar(const ProgressBar& rhs):
  m_Length(rhs.m_Length),
  m_Mark(rhs.m_Mark),
  m_Progress(rhs.m_Progress),
  m_Os(rhs.m_Os)
{}

ProgressBar& ProgressBar::operator=(const ProgressBar& rhs)
{
  if(this != &rhs)
  {
    m_Length	= rhs.m_Length;
    m_Mark	= rhs.m_Mark;
    m_Progress	= rhs.m_Progress;
    m_Os 	= rhs.m_Os;
  }
  
  return *this;
}

void ProgressBar::Init()
{
  m_Mark = m_Progress = 0;
  
  (*m_Os) << "Progress: [";
  for(int i = 0; i < m_Length; ++i) (*m_Os) << " ";
  (*m_Os) << "]";
  
  for(int i = 0; i < m_Length; ++i) (*m_Os) << "\b";
  
  m_Os->flush();
}

bool ProgressBar::Update(const int i, const int n)
{
  bool updated = false;
  m_Progress = static_cast<int>((static_cast<float>(i)/(n-1)) * m_Length);
  
  if(m_Progress > m_Mark)
  {
    m_Mark = m_Progress;
    (*m_Os) << "=";
    updated = true;
  }
  
  m_Os->flush();
  return updated;
}

void ProgressBar::Complete()
{
  (*m_Os) << "\r";
  (*m_Os) << "Progress: [";
  for(int i = 0; i < m_Length; ++i) (*m_Os) << "=";
  (*m_Os) << "] 100%\n";
}

} // namespace marinov
