/* $Id: main.cpp 1136 2006-09-06 08:05:31Z olau $ */

/* Copyright (C) 2006 Oliver Lau <ola@ctmagazin.de>, Heise Zeitschriften Verlag */

#include <iostream>
#include <cstdlib>
#include <math.h>

#ifdef WIN32
#include <windows.h>
#endif /* WIN32 */

#ifdef USE_GD
#include <gd.h>
#define IMG_WIDTH                640
#define IMG_HEIGHT               480
#define IMG_NAME           "iso.png"
#endif /* USE_GD */

#define WIDTH                   6400
#define HEIGHT                  4800
#define sqr(x)                  ((x)*(x))

#include "tbb/task_scheduler_init.h"
#include "tbb/blocked_range.h"
#include "tbb/parallel_for.h"
#include "tbb/tick_count.h"

#include "iso.h"
#include "Generator.h"
#include "Generator2D.h"

#include "../tbb_demos.h"

using namespace tbb;

MEASUREMENT m[] = {
  {  1 * WIDTH /  2,  1 * HEIGHT / 14,    0.0 },
  {  1 * WIDTH /  5,  5 * HEIGHT /  8,  255.0 },
  {  3 * WIDTH /  4,  3 * HEIGHT /  3,   50.0 },
  {              -1,               -1,    0.0 },
};

double matrix[WIDTH][HEIGHT];

#ifdef WIN32
#pragma warning(disable: 4100)
#endif
int main(int argc, char *argv[])
{
  int numThreads = getNumTBBThreads();
  task_scheduler_init init(numThreads);
  tick_count t0, t1;

#ifdef USE_GD
  /* Grafik initialisieren */
  FILE *pngout;
  const char *pngname = IMG_NAME;
  int colors[256];
  gdImagePtr im = gdImageCreate(IMG_WIDTH, IMG_HEIGHT);

#ifdef WIN32
  errno_t err = fopen_s(&pngout, pngname, "wb+");
  if (err != 0)
    return err;
#else
  pngout = fopen(pngname, "wb+");
  if (pngout == 0)
    return 1;
#endif /* WIN32 */

  /* Farbpalette generieren */
  for (int i = 0; i < 256; ++i)
    colors[i] = gdImageColorAllocate(im, i, 255-i, i);
#endif /* USE_GD */


  /* Berechnen der "Isobaren" */
  std::cout << "Berechnen der \"Isobaren\" in einer " 
    << WIDTH << "x" << HEIGHT << " großen Matrix .." << std::endl;

  const int GrainSize = 100;

  std::cout << "Lineares Splitting: ";
  t0 = tick_count::now();
  parallel_for(blocked_range<size_t>(0, WIDTH, GrainSize),
    Generator(&matrix[0][0], WIDTH, HEIGHT, &m[0]
#ifdef USE_GD
    , im, IMG_WIDTH, IMG_HEIGHT, colors
#endif /* USE_GD */
    ));
  t1 = tick_count::now();
  std::cout << 1000 * (t1 - t0).seconds() << " ms" << std::endl;

  std::cout << "2D-Splitting: ";
  t0 = tick_count::now();
  parallel_for(blocked_range2d<size_t, size_t>(0, HEIGHT, GrainSize, 0, WIDTH, GrainSize),
    Generator2D(&matrix[0][0], WIDTH, HEIGHT, &m[0]
#ifdef USE_GD
    , im, IMG_WIDTH, IMG_HEIGHT, colors
#endif /* USE_GD */
    ));
  t1 = tick_count::now();
  std::cout << 1000 * (t1 - t0).seconds() << " ms" << std::endl;

#ifdef USE_GD
  /* Grafik in Datei schreiben */
  int pngsize;
  BYTE *pngbuf = (BYTE *) gdImagePngPtr(im, &pngsize);
  fwrite(pngbuf, sizeof(BYTE), pngsize, pngout);
  fclose(pngout);
  gdImageDestroy(im);
  gdFree((void *) pngbuf);
#endif

  return 0;
}
