/*
    Copyright 2005-2010 Intel Corporation.  All Rights Reserved.

    This file is part of Threading Building Blocks.

    Threading Building Blocks is free software; you can redistribute it
    and/or modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

    Threading Building Blocks 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 Threading Building Blocks; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    As a special exception, you may use this file as part of a free software
    library without restriction.  Specifically, if other files instantiate
    templates or use macros or inline functions from this file, or you compile
    this file and link it with other files to produce an executable, this
    file does not by itself cause the resulting executable to be covered by
    the GNU General Public License.  This exception does not however
    invalidate any other reasons why the executable file might be covered by
    the GNU General Public License.
*/

/* 
    Game_of_life.cpp : 
                      main project file.
*/
#include "Board.h"
#include "Form1.h"

#define WIN32_LEAN_AND_MEAN

#ifndef _CONSOLE
#include <windows.h>
#else
#include <iostream>
#include <sstream>
#include <time.h>
#include "Evolution.h"

#define BOARD_SQUARE_SIZE 2

int low;                            //! lower range limit of threads
int high;                           //! high range limit of threads
double execution_time;              //! time for game of life iterations
#endif

Board::Board(int width, int height, int squareSize, LabelPtr counter)
: m_width(width), m_height(height), m_squareSize(squareSize), m_counter(counter)
{
#ifndef _CONSOLE
    InitializeComponent();
    DoubleBuffered = true;

    this->Width = m_squareSize*width;
    this->Height = m_squareSize*height;
#endif
    m_matrix = new Matrix();
    m_matrix->width = width;
    m_matrix->height = height;
    m_matrix->data = new char[width*height];
    memset(m_matrix->data, 0, width*height);
#ifndef _CONSOLE
    m_occupiedBrush = gcnew SolidBrush(Color::Black);
    m_freeBrush = gcnew SolidBrush(Color::LightGray);
    
    m_graphics = CreateGraphics();
    m_bmp = gcnew Bitmap(Width, Height);
    m_mem_dc = Graphics::FromImage(m_bmp);
#endif
}

Board::~Board()
{
#ifndef _CONSOLE
    if (components)
    {
        delete components;
    }
#endif
    delete[] m_matrix->data;
    delete m_matrix;
}

void Board::seed(int s)
{        
    srand(s);
    for (int j=0; j<m_height; j++)
    {
        for (int i=0; i<m_width; i++)
        {        
            int x = rand()/(int)(((unsigned)RAND_MAX + 1) / 100);
            m_matrix->data[i+j*m_width] = x>75? 1: 0;               // 25% occupied
        }
    }
#ifndef _CONSOLE
    Invalidate();
#endif
}

void Board::seed( const BoardPtr src )
{        
            memcpy(m_matrix->data, src->m_matrix->data, m_height*m_width);
#ifndef _CONSOLE
    Invalidate();
#endif
}

#ifndef _CONSOLE
void Board::draw(Graphics^ g)
{
    m_mem_dc->FillRectangle(m_freeBrush, Drawing::Rectangle(0, 0, m_width*m_squareSize, m_height*m_squareSize));
    for (int j=0; j<m_height; j++)
    {
        for (int i=0; i<m_width; i++)
        {    
            if ( m_matrix->data[i+j*m_width] )
            {
                m_mem_dc->FillRectangle(m_occupiedBrush, Drawing::Rectangle(i*m_squareSize, j*m_squareSize, m_squareSize, m_squareSize));
            }
        }
    }
    g->DrawImage(m_bmp, 0, 0);
}

void Board::OnPaint(PaintEventArgs^ e)
{
    draw(e->Graphics);
}

[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
    // Enabling Windows XP visual effects before any controls are created
    Application::EnableVisualStyles();
    Application::SetCompatibleTextRenderingDefault(false); 

    // Create the main window and run it
    Application::Run(gcnew Form1());
    return 0;
}
#else

//! Print usage of this program
void PrintUsage() 
{
    printf("Usage: gol [M[:N] -t execution_time]\nM and N are a range of numbers of threads to be used.\nexecution_time is a time (in sec) for execution game_of_life iterations\n");
    printf("Default values:\nM:\t\tautomatic\nN:\t\tM\nexecution_time:\t10\n");
}

//! Parse command line
bool ParseCommandLine(int argc, char * argv []) 
{
    char* s = argv[1];
    char* end;
    //! command line without parameters
    if(argc == 1)
    {
        low = tbb::task_scheduler_init::automatic;
        high = low;
        execution_time = 5;
        return true;
    }
    //! command line with parameters
    if(argc != 4)
    {
        PrintUsage();
        return false;
    }
    if(std::string("-t") != argv[argc-2])
    //! process M[:N] parameter
    high = strtol(s,&end,0);
    low = strtol(s,&end,0);
    switch( *end ) 
    {
        case ':': 
            high = strtol(end+1,0,0); 
            break;
        case '\0':
            break;
        default:
            PrintUsage();
            return false;
    }
    if (high < low)
    {
        std::cout << "Set correct range. Current range: " << low << ":" << high << std::endl;
        PrintUsage();
        return false;

    }
    //! process execution_time parameter
    execution_time = strtol(argv[argc-1],&end,0);
    return true;
}

int main( int argc, char* argv[] ) 
{
    if(!ParseCommandLine( argc, argv ))
        return 1;
    SequentialEvolution* m_seq;
    ParallelEvolution* m_par;
    Board* m_board1;
    Board* m_board2; 
    int* count = NULL;
   
    int boardWidth = 300;
    int boardHeight = 300;

    m_board1 = new Board(boardWidth, boardHeight, BOARD_SQUARE_SIZE, count);
    m_board2 = new Board(boardWidth, boardHeight, BOARD_SQUARE_SIZE, count);

    time_t now = time(NULL);
    printf("Generate Game of life board\n");
    m_board1->seed((int)now);
    m_board2->seed(m_board1);

    m_seq = new SequentialEvolution(m_board1->m_matrix, m_board1);
    m_seq->Run(execution_time, 1);
    delete m_seq;

    m_par = new ParallelEvolution(m_board2->m_matrix, m_board2);
    for( int p = low; p <= high; ++p ) 
    {
        m_par->Run(execution_time, p);
    }
    delete m_par;

    delete m_board1;
    delete m_board2;
    return 0;
}
#endif
