
//
// This is G. Hagopian and CS7B students developing code for doing life on a hex grid.
/**
Bugs fixed:

1. Reversed i and j in row/column looping to make the hexes mesh right.
2. Use .as_int() for int comparison or FL_BLUE, or whatever instead.
3. Remember to return a value if you say you're going to.
4.

Bugs still to fix
1. Updating the same cells that are in the neighborhood changes the neighborhood (use a buffer).
2. Use int indexing once the hex grid is built.
*/
#define sqrt3 1.7320508075688772935274463415059
#include <iostream>

const int hexSize = 10;
int width = 800, height = 600;
//------------------------------------------------------------------------------

int countNeighbors(Vector_ref<Reg_polygon>& vr, int i, int j) {
    int counter{};
    if(j%2) { /// even column
        cout << "\nvr[int((i-1)*width/(1.5*hexSize))+j  ].color().as_int();"
             << "vr[" << int((i-1)*width/(1.5*hexSize))+j  << "].color().as_int();"
             << vr[int((i-1)*width/(1.5*hexSize))+j  ].color().as_int();
        if(vr[int((i-1)*width/(1.5*hexSize))+j  ].color().as_int()==1)
            ++counter;
        if(vr[int((i-1)*width/(1.5*hexSize))+j+1].color().as_int()==1) ++counter;
        if(vr[int((i  )*width/(1.5*hexSize))+j+1].color().as_int()==1) ++counter;
        if(vr[int((i+1)*width/(1.5*hexSize))+j  ].color().as_int()==1) ++counter;
        if(vr[int((i  )*width/(1.5*hexSize))+j-1].color().as_int()==1) ++counter;
        if(vr[int((i-1)*width/(1.5*hexSize))+j-1].color().as_int()==1) ++counter;
    }
    else { ///odd column
        if(vr[int((i-1)*width/(1.5*hexSize))+j  ].color().as_int()==1) ++counter;
        if(vr[int((i  )*width/(1.5*hexSize))+j+1].color().as_int()==1) ++counter;
        if(vr[int((i+1)*width/(1.5*hexSize))+j+1].color().as_int()==1) ++counter;
        if(vr[int((i+1)*width/(1.5*hexSize))+j  ].color().as_int()==1) ++counter;
        if(vr[int((i+1)*width/(1.5*hexSize))+j-1].color().as_int()==1) ++counter;
        if(vr[int((i  )*width/(1.5*hexSize))+j-1].color().as_int()==1) ++counter;
    }
    return counter;
}

int main()
try
{
    using namespace Graph_lib;   // our graphics facilities are in Graph_lib
    srand(time(0));

    Simple_window win(Point(100,100),800,600,"Images");

    //Image rita(Point(0,0),"rita.jpg");
    //Reg_polygon hex(6,Point(300,300),200);
    //win.attach(hex);

    //vector<Vector_ref<Reg_polygon> > vrh;
    Vector_ref<Reg_polygon> vr;
    /// i counts through rows and j through columns
    cout << "\nheight/(sqrt3*hexSize)=" << win.y_max() << '/' << sqrt3*hexSize << " = " << win.y_max()/(sqrt3*hexSize) << endl;
    cout << "\nwidth/(1.5*hexSize)=" << win.x_max() << '/'<< (1.5*hexSize) << " = " << win.x_max()/(1.5*hexSize);
    for(int i = 0; i < win.y_max()/(sqrt3*hexSize); i++) {
        for(int j = 0; j < win.x_max()/(1.5*hexSize); ++j) {
            vr.push_back(new Reg_polygon(6,Point(int(1.5*hexSize*j),
                                                 int(sqrt3*hexSize*i)
                                                 +(j%2)*int(sqrt3/2*hexSize)),
                                                                    hexSize));
            //if(j%2) vr[vr.size()-1].set_fill_color(2);
            //win.wait_for_button();
            win.attach(vr[vr.size()-1]);
        }
        //vrh.push_back(new Vector_ref<Reg_polygon>(vr));
    }
    //win.wait_for_button();
    ///while(1) {
    ///initialize hexes
    for(int i = 0; i < win.y_max()/(sqrt3*hexSize); ++i) {
        for(int j = 0; j < win.x_max()/(1.5*hexSize)+1; ++j) {
            if(rand()%2) {
                //cout << int(i*win.y_max()/(sqrt3*hexSize))+j << " ";
                vr[int(i*win.x_max()/(1.5*hexSize))+j].set_fill_color(2);
                vr[int(i*win.x_max()/(1.5*hexSize))+j].set_color(2);
            }
            else vr[int(i*win.x_max()/(1.5*hexSize))+j].set_fill_color(1);
                 vr[int(i*win.x_max()/(1.5*hexSize))+j].set_color(1);
        }
        //cout << endl;
    }
    win.wait_for_button();       /// Display initialized hexes!
    /// update
    int n{};
    while(1) {
        for(int i = 1; i < win.y_max()/(sqrt3*hexSize)-1; ++i) {
            for(int j = 1; j < win.x_max()/(1.5*hexSize); ++j) {
                n = countNeighbors(vr,i,j);
                cout << "\nn=" << n << " ";
                if(n<2 || n>3) { /// if under or overpopulated neighborhood, die
                    vr[int(i*win.x_max()/(1.5*hexSize))+j].set_fill_color(2);
                    vr[int(i*win.x_max()/(1.5*hexSize))+j].set_color(2);
                }
                else {
                    vr[int(i*win.x_max()/(1.5*hexSize))+j].set_fill_color(1);
                    vr[int(i*win.x_max()/(1.5*hexSize))+j].set_color(1);
                }
            }
            //cout << endl;
        }
        win.wait_for_button();
    }

}
catch(exception& e) {
    // some error reporting
    return 1;
}
catch(...) {
    // some more error reporting
    return 2;
}

//------------------------------------------------------------------------------
