#ifndef _UTIL_H_
#define _UTIL_H_

/**
 *    WHAM - high-throughput sequence aligner
 *    Copyright (C) 2011  WHAM Group, University of Wisconsin
 *
 *    This program 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.
 *
 *    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*	$Id: util.h 157 2012-07-25 05:58:09Z yinan $ */

#include <iostream>
#include <iomanip>
#include <sys/time.h>
#include "error.h"

using namespace std;

extern int ELOG_LEVEL;

#define PROGRESS_BAR_WIDTH 40

class Timer {
public:
  void start() {
    gettimeofday(&s1, 0);
  }

  double stop() {
    double t;
    gettimeofday(&s2, 0);
    t = (s2.tv_sec - s1.tv_sec) + (s2.tv_usec - s1.tv_usec) * 0.000001;
    return t;
  }
private:
  struct timeval s1, s2;
};

class ProgressBar {
public:
  ProgressBar(long long maxwork, char width) :
      maxwork(maxwork), width(width), firsttime(true), value(0) {
  }

  void update(long long work) {
    if (ELOG_LEVEL < INFO
      )
      return;

    if (firsttime) {
      cout << '[';
      for (char i = 0; i < width; ++i) {
        cout << ' ';
      }
      cout << "] ";
      cout << "  0%" << flush;
      firsttime = false;
    }

    long long newvalue = (long long) (work * 100. / maxwork);
    if (newvalue == value) {
      if (work == maxwork)
        cout << endl;
      return;
    }

    value = newvalue;
    cout << "\b\b\b\b\b\b";
    for (char i = 0; i < width; ++i)
      cout << '\b';
    for (char i = 0; i < width * value / 100; ++i)
      cout << '#';
    for (char i = width * value / 100; i < width; ++i)
      cout << ' ';
    cout << "] ";
    cout << setw(3) << value << '%' << flush;

    if (work == maxwork)
      cout << endl;
  }

private:
  long long maxwork;
  char width;
  bool firsttime;
  long long value;
};

#endif
