//Łukasz Dobrodziej T-TIZ
//Biblioteka boost::timer
//Program ilustruje mozliwosci wykorzystania klas z biblioteki boost::timer.
//Demonstruje przykladowe operacje na zegarach (kopiowanie, restartowanie), 
//tworzy paski postepu, mierzy czas wykonania operacji przy pomocy progress_timer. 

#include "stdafx.h" //biblioteka do visual studio, na innych platformach jest zbedna
#include <boost/progress.hpp>
#include <iostream>
#include <climits>

using boost::timer;
using boost::progress_timer;
using boost::progress_display;
using std::cout;
using std::endl;


int main(int argc, _TCHAR* argv[]) 
{

  bool time_waster; //zmienna, w ktorek przechowywujemy wynik z iteracji - zapobiega optymalizacjom
					//kompilatora, dzieki temu petle poniezej beda trwac mniej wiecej tyle ile pierwsza petla


  timer t0;  // uzywany tylko do pokazania wartosci minimalnej i maksymalnej dla elapsed()

  cout << "timer::elapased_min() wynosi " << t0.elapsed_min() << " sekund\n";
  cout << "timer::elapased_max() wynosi " << t0.elapsed_max()
       << " sekund, ktore stanowia " << t0.elapsed_max()/3600.0 << " godzin\n";

//==============================================

  //sprawdzenie czy progress_display dziala prawidlowo z wartoscia docelowa =0
  cout << "\nsprawdzanie czy progress_display(0) dzieli przez 0" << endl;
  progress_display zero( 0 ); 
  ++zero;

//==============================================

  //wprowadzenie ograniczenia czasowego dla petli  
  long loops; //wskazuje liczbe iteracji wykonanych w zadanym czasie
  timer loop_timer; //zegar rusza
  const double time = 2.0; //czas zakonczenia operacji

  cout << "\nOgraniczenie rowne " << time << " sekundy dla petli" << endl;
  for ( loops = 0; loops < LONG_MAX
     && loop_timer.elapsed() < time; ++loops ) {
		 time_waster = loop_timer.elapsed() < time;} //zapobieganie optymalizacji kompilatora 
  cout << loops << " iteracji w czasie "<< time << " sekund"<< endl; //wyswietla liczbe iteracji wykonanych w czasie time
  
//==============================================

  
  long i; //licznik iteracji
  progress_timer pt; //utworzenie zegara - mierzy czas az do destrukcji - wtedy wyswietla zmierzony czas
  timer t1; //utworzenie kilku zegarow ktore juz zaczynaja odmierzac czas
  timer t4;
  timer t5;
  
  
  
  cout << "\nCzekamy " << time << " sekundy" << endl;
  progress_display pd( loops ); //utworzenie paska postepu z wartoscia docelowa rowna liczbie iteracji z poprzedniej petli
  //wykorzystanie paska postepu - dojscie do 100% powinno mu zajac tyle ile wskazuje ograniczenie time z poprzednije petli 
  for ( i = loops; i--; )
    {time_waster = loop_timer.elapsed() < time; //zapobieganie optymalizacji kompilatora 
    ++pd; } //zwiekszenie wewnetrzego licznika paska postepu o 1 - gdy istenieje potrzeba dorysowywany jest kolejny znaczek postepu

//==============================================

  //pare operacji na timerach
  timer t2( t1 ); //utworzenienowego zegara z czasem wskazywnym przez istniejacy zegar
  timer t3; //utworzenie nowego zegara
  t4 = t3; //zegar 4 wskazuje to samo co zegar 3
  t5.restart(); //zrestartowanie zegara - znowu zaczyna mierzyc od 0

//==============================================

  cout << "\nPonownie czekamy " << time << " sekundy" << endl;
  pd.restart( loops ); //restartujemy pasek postepu przez podanie mu nowej wartosci docelowej
  for ( i = loops; i--; )
    {time_waster = loop_timer.elapsed() < time; //zapobieganie optymalizacji kompilatora
    ++pd; } //zwiekszenie wewnetrzego licznika paska postepu o 1 - gdy istenieje potrzeba dorysowywany jest kolejny znaczek postepu

//==============================================

  cout << "\nOdliczamy do 50% na opisanym pasku postepu\n";
  //tworzymy nowy pasek postepu - nadajemy tytuly dla kazdego wierszu
  progress_display pd2( 50, cout, "\nOpis 1 ", "Opis 2 ", "Opis 3 " );
  //pasek odlicza do 25 co stanowi 50% wartosci docelowej - czas wykonania prawie zerowy 
  for ( ; pd2.count() < 50; ++pd2 ) {if(pd2.count()>25){break;}}

  cout << endl;

//==============================================

  //sprawdzamy jaki czas wskazuja poszczegolne zegary
  cout << "\nt1 wskazuje: " << t1.elapsed() << '\n';
  cout << "t2 wskazuje: " << t2.elapsed() << '\n';
  cout << "t3 wskazuje: " << t3.elapsed() << '\n';
  cout << "t4 wskazuje: " << t4.elapsed() << '\n';
  cout << "t5 wskazuje: " << t5.elapsed() << '\n';
  cout << "t1 i t2 powinny wskazywac to samo (teoretycznie "
       << 2*time << " sekund ale kompilator ma tu"<< endl << "duzo do powiedzenia).\n";
  cout << "t3, t4 i t5 powinny wskazywac ten sam czas,\n";
  cout << "i powinien on byc mniej wiecej polowa czasu wskazywanego przez zegary t1 i t2.\n";
  cout << "Teraz wyswietli sie progress_timer, poniewaz jego obiekt ulegnie zniszczeniu."
       << endl
	   << "Powinien wskazywac czas nieco wiekszy niz t1 i t2 poniewaz powstawl przed nimi"
	   << endl
	   << "i troche pozniej pokazuje czas: ";
	   
  return 0;
}

