#include <stdio.h>
#include <iostream>

#include "Sand.h"
#include <wx/wx.h>
#include <wx/dcscreen.h>
#include <wx/dcbuffer.h>


#define NUMBEROFELEMENTS 13

#define EMPTY 0
#define WALL 1
#define FIRE 2
#define WATER 3
#define PLANT 4
#define SAND 5
#define SPOUT 6
#define CERA 7
#define Q 8
#define OIL 9
#define SALT 10
#define EMBER 11
#define FCERA 12

double gravity[NUMBEROFELEMENTS] =  {0, 0,-0.6, 0.6, 0, 0.6, 0, 0, 0, 0.6, 0.6, 0.0, 0.6};
double friction[NUMBEROFELEMENTS] = {0, 1,   0,   0, 1, 0,   1, 1, 0, 0,   0,   0, 0};
double density[NUMBEROFELEMENTS] =  {0, 1,   1,   1, 1, 1,   1, 1, 1, 1,   1,   1, 1};
const wxString names[NUMBEROFELEMENTS] =    {"Eraser", "Wall",   "Fire",   "Water", "Plant", 
					     "Sand",  "Spout", "Cera", "???", "Oil", "Salt", "Ember", "Molten Cera"};
wxColor colors[NUMBEROFELEMENTS] = {wxColor(0,0,0),     wxColor(100,100,100), wxColor(200,50,50),
				    wxColor(10,10,200), wxColor(10,200,10), wxColor(238,204,128),
				    wxColor(10,100,10), wxColor(255,220,200), wxColor(100,0,100),
				    wxColor(100,70,40), wxColor(255,255,255), wxColor(200,50,50), wxColor(255,220,200)};

double trans_prob[NUMBEROFELEMENTS][NUMBEROFELEMENTS];
char trans_to[NUMBEROFELEMENTS][NUMBEROFELEMENTS];
char trans_from[NUMBEROFELEMENTS][NUMBEROFELEMENTS];


BEGIN_EVENT_TABLE(Canvas, wxWindow)
  //EVT_PAINT(Canvas::OnPaint)
  EVT_ERASE_BACKGROUND(Canvas::OnEraseBG)
  EVT_LEFT_DOWN(Canvas::OnMouseLeftDown)
  EVT_LEFT_UP(Canvas::OnMouseLeftUp)
  EVT_MOTION(Canvas::OnMouseMove)
  EVT_TIMER(1000, Canvas::OnTimer)
END_EVENT_TABLE()


BEGIN_EVENT_TABLE(MainFrame, wxFrame)
  EVT_SET_FOCUS(MainFrame::OnMove)
  EVT_SIZE(MainFrame::OnSize)
  EVT_LISTBOX(1000, MainFrame::OnChoice)
  EVT_LISTBOX(1001, MainFrame::OnChoice)
END_EVENT_TABLE()


IMPLEMENT_APP(Sand)

MainFrame* g_mainFrame;
Canvas* g_canvas;
char data[1000][800];
bool draw[1000][800];
wxTimer* m_timer;
bool mouseIsDown = false;
int mousex, mousey;
char sand_type;
int pen_width;
int draw_counter = 0;

Canvas::Canvas(wxWindow* parent, wxWindowID id = -1, wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize) : wxWindow( parent, id, pos, size, wxSUNKEN_BORDER | wxCLIP_CHILDREN ){
  g_canvas = this;
  //this->SetBackgroundStyle(wxBG_STYLE_CUSTOM);
  this->SetBackgroundColour(wxColor("BLACK"));
  //this->SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
  m_timer = new wxTimer(this, 1000);
  sand_type = 1;
  pen_width = 2;

  for(int y=0;y<800;++y){
    for(int x=0;x<1000;++x){
      data[x][y] = 0;
      draw[x][y] = true;
    }
  }

  //this->ClearBackground();

  for(int i=0;i<NUMBEROFELEMENTS;++i){
    for(int j=0;j<NUMBEROFELEMENTS;++j){
      trans_prob[i][j] = 0;
      trans_to[i][j] = 0;
      trans_from[i][j] = 0;
    }
  }

  //embers
  trans_prob[EMBER][EMPTY] = 0.001;
  trans_to[EMBER][EMPTY] = EMPTY;
  trans_from[EMBER][EMPTY] = EMPTY;

  trans_prob[EMBER][WATER] = 0.9;
  trans_to[EMBER][WATER] = EMPTY;
  trans_from[EMBER][WATER] = EMPTY;

  trans_prob[EMBER][OIL] = 0.75;
  trans_to[EMBER][OIL] = FIRE;
  trans_from[EMBER][OIL] = FIRE;

  trans_prob[EMBER][PLANT] = 1;
  trans_to[EMBER][PLANT] = FIRE;
  trans_from[EMBER][PLANT] = FIRE;

  trans_prob[EMBER][CERA] = 0.004;
  trans_to[EMBER][CERA] = FCERA;
  trans_from[EMBER][CERA] = EMBER;

  //fire
  trans_prob[FIRE][EMPTY] = 0.05;
  trans_to[FIRE][EMPTY] = EMPTY;
  trans_from[FIRE][EMPTY] = EMPTY;

  trans_prob[FIRE][FIRE] = 0.01;
  trans_to[FIRE][FIRE] = EMPTY;
  trans_from[FIRE][FIRE] = EMPTY;

  trans_prob[FIRE][WATER] = 0.9;
  trans_to[FIRE][WATER] = EMPTY;
  trans_from[FIRE][WATER] = EMPTY;

  trans_prob[FIRE][OIL] = 0.75;
  trans_to[FIRE][OIL] = FIRE;
  trans_from[FIRE][OIL] = FIRE;

  trans_prob[FIRE][PLANT] = 1;
  trans_to[FIRE][PLANT] = FIRE;
  trans_from[FIRE][PLANT] = FIRE;

  trans_prob[FIRE][CERA] = 0.1;
  trans_to[FIRE][CERA] = FCERA;
  trans_from[FIRE][CERA] = EMBER;

  //fcera turns back into cera.
  trans_prob[FCERA][CERA] = 0.001;
  trans_to[FCERA][CERA] = CERA;
  trans_from[FCERA][CERA] = CERA;

  trans_prob[FCERA][WALL] = 0.001;
  trans_to[FCERA][WALL] = CERA;
  trans_from[FCERA][WALL] = WALL;

  trans_prob[FCERA][WATER] = 0.001;
  trans_to[FCERA][WATER] = CERA;
  trans_from[FCERA][WATER] = WATER;

  trans_prob[FCERA][PLANT] = 0.001;
  trans_to[FCERA][PLANT] = CERA;
  trans_from[FCERA][PLANT] = PLANT;

  trans_prob[FCERA][SAND] = 0.001;
  trans_to[FCERA][SAND] = CERA;
  trans_from[FCERA][SAND] = SAND;

  trans_prob[FCERA][OIL] = 0.001;
  trans_to[FCERA][OIL] = CERA;
  trans_from[FCERA][OIL] = OIL;

  trans_prob[FCERA][SPOUT] = 0.001;
  trans_to[FCERA][SPOUT] = CERA;
  trans_from[FCERA][SPOUT] = SPOUT;

  //plant
  trans_prob[PLANT][WATER] = 0.2;
  trans_to[PLANT][WATER] = PLANT;
  trans_from[PLANT][WATER] = PLANT;

  //spout
  trans_prob[SPOUT][EMPTY] = 0.75;
  trans_to[SPOUT][EMPTY] = SPOUT;
  trans_from[SPOUT][EMPTY] = WATER;

  trans_prob[SPOUT][SAND] = 0.5;
  trans_to[SPOUT][SAND] = EMPTY;
  trans_from[SPOUT][SAND] = EMPTY;

  //???
  trans_prob[Q][SPOUT] = 0.2;
  trans_to[Q][SPOUT] = EMPTY;
  trans_from[Q][SPOUT] = Q;
  
  trans_prob[Q][SALT] = 0.2;
  trans_to[Q][SALT] = EMPTY;
  trans_from[Q][SALT] = Q;
  
  trans_prob[Q][EMPTY] = 0.2;
  trans_to[Q][EMPTY] = Q;
  trans_from[Q][EMPTY] = Q;
  
  trans_prob[Q][WATER] = 0.2;
  trans_to[Q][WATER] = EMPTY;
  trans_from[Q][WATER] = Q;
  
  trans_prob[Q][OIL] = 0.2;
  trans_to[Q][OIL] = EMPTY;
  trans_from[Q][OIL] = Q;
  
  trans_prob[Q][FCERA] = 0.2;
  trans_to[Q][FCERA] = EMPTY;
  trans_from[Q][FCERA] = Q;
  
  trans_prob[Q][CERA] = 0.2;
  trans_to[Q][CERA] = EMPTY;
  trans_from[Q][CERA] = Q;
  
  trans_prob[Q][WALL] = 0.2;
  trans_to[Q][WALL] = EMPTY;
  trans_from[Q][WALL] = Q;
  
  trans_prob[Q][SAND] = 0.2;
  trans_to[Q][SAND] = EMPTY;
  trans_from[Q][SAND] = Q;
  

  /*
  trans_prob[][] = 0;
  trans_to[][] = ;
  trans_from[][] = ;

  */

  m_timer->Start(50);    // 1/10 second interval
}


inline bool checkForTransformation(int x, int y, int dx, int dy){
  char t1 = data[x][y];
  char t2 = data[dx][dy];
  if (trans_prob[t1][t2] == 0) return false;
  if (rand() < trans_prob[t1][t2]*RAND_MAX){
    data[x][y] = trans_to[t1][t2];
    data[dx][dy] = trans_from[t1][t2];
    draw[x][y] = true;
    draw[dx][dy] = true;
    return true;
  }
  return false;
}



void Canvas::OnTimer(wxTimerEvent& event){
  int j = 100;

  for(int i=100;i<110;++i)
    if (rand() < RAND_MAX/4){
      data[i][j] = SAND;
      draw[i][j] = true;
    }
  for(int i=200;i<210;++i)
    if (rand() < RAND_MAX/4){
      data[i][j] = WATER;
      draw[i][j] = true;
    }
  for(int i=300;i<310;++i)
    if (rand() < RAND_MAX/4){
      data[i][j] = SALT;
      draw[i][j] = true;
    }
  for(int i=400;i<410;++i)
    if (rand() < RAND_MAX/4){
      data[i][j] = OIL;
      draw[i][j] = true;
    }

  for(int y=797;y>1;--y){
    //Randomly calculate left or right.
    int startx = 2;
    int endx = 998;
    int move = 1;
    if (rand() < 0.5*RAND_MAX){
      startx = 998;
      endx = 1;
      move = -1;
    }

    for(int x = startx; x != endx-move; x += move){
      if (data[x][y] == 0)
	continue;

      if (y == 799){
	data[x][y] = 0;
	draw[x][y] = true;
	continue;
      }

      if (rand() > 0.5*RAND_MAX){
	//Check for specific transformations.
	//if(checkForTransformation(x,y,x-1,y-1)) continue;
	if(checkForTransformation(x,y,x-1,y  )) continue;
	//if(checkForTransformation(x,y,x-1,y+1)) continue;
	if(checkForTransformation(x,y,x  ,y+1)) continue;
	//if(checkForTransformation(x,y,x+1,y+1)) continue;
	if(checkForTransformation(x,y,x+1,y  )) continue;
	//if(checkForTransformation(x,y,x+1,y-1)) continue;
	if(checkForTransformation(x,y,x  ,y-1)) continue;
      }
      else{
	//Check for specific transformations.
	if(checkForTransformation(x,y,x  ,y-1)) continue;
	if(checkForTransformation(x,y,x+1,y  )) continue;
	if(checkForTransformation(x,y,x  ,y+1)) continue;
	if(checkForTransformation(x,y,x-1,y  )) continue;
      }


      if (gravity[data[x][y]] == 0 && friction[data[x][y]] == 1)
	continue;

      //Check for falling through the air.
      if (gravity[data[x][y]] > 0){
	if (data[x][y+1] == 0){
	  if (rand() < gravity[data[x][y]]*RAND_MAX){
	    data[x][y+1] = data[x][y];
	    data[x][y] = 0;
	    draw[x][y] = true;
	    draw[x][y+1] = true;
	    continue;
	  }
	}
      }
      else{
	double g = -gravity[data[x][y]];
	if (data[x][y-1] == 0){
	  if (rand() < g*RAND_MAX){
	    data[x][y-1] = data[x][y];
	    data[x][y] = 0;
	    draw[x][y] = true;
	    draw[x][y-1] = true;
	    continue;
	  }
	}
	if (rand() < 0.5*RAND_MAX){
	  if (data[x-1][y-1] == 0){
	    if (rand() < g*RAND_MAX){
	      data[x-1][y-1] = data[x][y];
	      data[x][y] = 0;
	      draw[x][y] = true;
	      draw[x-1][y-1] = true;
	      continue;
	    }
	  }
	}
	else{
	  if (data[x+1][y-1] == 0){
	    if (rand() < g*RAND_MAX){
	      data[x+1][y-1] = data[x][y];
	      data[x][y] = 0;
	      draw[x][y] = true;
	      draw[x+1][y-1] = true;
	      continue;
	    }
	  }
	}
      }


      //Randomly move side-to-side.
      if ((data[x][y+1] != 0) && (data[x-1][y] == 0 || data[x+1][y] == 0 )){
	if ((data[x+1][y+1] != 0) || (data[x-1][y+1] != 0)){
	  if (rand() < 0.5*RAND_MAX)
	    continue;
	}
	if (data[x-1][y] == 0){
	  if (rand() > 0.5){
	    data[x-1][y] = data[x][y];
	    data[x][y] = 0;
	    draw[x][y] = true;
	    draw[x-1][y] = true;
	    continue;
	  }
	}
	if (data[x+1][y] == 0){
	  if (rand() > 0.5){
	    data[x+1][y] = data[x][y];
	    data[x][y] = 0;
	    draw[x][y] = true;
	    draw[x+1][y] = true;
	    continue;
	  }
	}

      }

      /*
      //Check for being pushed to the side.
      //Randomize which direction to check first.
      if (data[x-1][y] == 0 || data[x+1][y] == 0 ){
	if (rand() < 0.5*RAND_MAX){
	  if (data[x-1][y] == 0 && data[x+1][y] > 0){
	    if (rand() < friction[data[x][y]]*RAND_MAX){
	      data[x-1][y] = data[x][y];
	      data[x][y] = 0;
	      draw[x][y] = true;
	      draw[x-1][y] = true;
	      continue;
	    }
	    continue;
	  }
	  else if (data[x+1][y] == 0 && data[x-1][y] > 0){
	    if (rand() < friction[data[x][y]]*RAND_MAX){
	      data[x+1][y] = data[x][y];
	      data[x][y] = 0;
	      draw[x][y] = true;
	      draw[x+1][y] = true;
	      continue;
	    }
	    continue;
	  }
	}
	else{
	  if (data[x+1][y] == 0 && data[x-1][y] > 0){
	    if (rand() < friction[data[x][y]]*RAND_MAX){
	      data[x+1][y] = data[x][y];
	      data[x][y] = 0;
	      draw[x][y] = true;
	      draw[x+1][y] = true;
	      continue;
	    }
	    continue;
	  }
	  else if (data[x-1][y] == 0 && data[x+1][y] > 0){
	    if (rand() < friction[data[x][y]]*RAND_MAX){
	      data[x-1][y] = data[x][y];
	      data[x][y] = 0;
	      draw[x][y] = true;
	      draw[x-1][y] = true;
	      continue;
	    }
	    continue;
	  }
	}
      }
      */

      //Check for falling downhill
      if (data[x-1][y+1] == 0 || data[x+1][y+1] == 0 ){
	if (rand() < 0.5*RAND_MAX){
	  if (data[x+1][y+1] == 0){
	    if (rand() < friction[data[x][y]]*RAND_MAX){
	      data[x+1][y+1] = data[x][y];
	      data[x][y] = 0;
	      draw[x][y] = true;
	      draw[x+1][y+1] = true;
	      continue;
	    }
	    continue;
	  }
	}
	else{
	  if (data[x-1][y+1] == 0){
	    if (rand() < friction[data[x][y]]*RAND_MAX){
	      data[x-1][y+1] = data[x][y];
	      data[x][y] = 0;
	      draw[x][y] = true;
	      draw[x-1][y+1] = true;
	      continue;
	    }
	    continue;
	  }
	}
      }

      /*
      //Check for falling through another material.
      if (density[data[x][y]] != 1.0){
	if (density[data[x][y]] > density[data[x][y+1]]){
	  if ( rand() < ((density[data[x][y]] - density[data[x][y+1]]))*RAND_MAX ){
	    char t = data[x][y];
	    data[x][y] = data[x][y+1];
	    data[x][y+1] = t;
	    draw[x][y] = true;
	    draw[x][y+1] = true;
	    continue;
	  }
	}
	if (rand() < 0.5*RAND_MAX){
	  if (density[data[x][y]] > density[data[x-1][y+1]]){
	    if ( rand() < ((density[data[x][y]] - density[data[x-1][y+1]]))*RAND_MAX ){
	      char t = data[x][y];
	      data[x][y] = data[x-1][y+1];
	      data[x-1][y+1] = t;
	      draw[x][y] = true;
	      draw[x-1][y+1] = true;
	      continue;
	    }
	  }
	}
	else{
	  if (density[data[x][y]] > density[data[x+1][y+1]]){
	    if ( rand() < ((density[data[x][y]] - density[data[x+1][y+1]]))*RAND_MAX ){
	      char t = data[x][y];
	      data[x][y] = data[x+1][y+1];
	      data[x+1][y+1] = t;
	      draw[x][y] = true;
	      draw[x+1][y+1] = true;
	      continue;
	    }
	  }
	}
	//Pushing left and right.
	//Randomly choose which side goes first.
	if (rand() < 0.5*RAND_MAX){
	  if (density[data[x][y]] > density[data[x-1][y]]){
	    if ( rand() < ((density[data[x][y]] - density[data[x-1][y]]))*RAND_MAX ){
	      char t = data[x][y];
	      data[x][y] = data[x-1][y];
	      data[x-1][y] = t;
	      draw[x][y] = true;
	      draw[x-1][y] = true;
	      continue;
	    }
	  }
	  if (density[data[x][y]] > density[data[x+1][y]]){
	    if ( rand() < ((density[data[x][y]] - density[data[x+1][y]]))*RAND_MAX ){
	      char t = data[x][y];
	      data[x][y] = data[x+1][y];
	      data[x+1][y] = t;
	      draw[x][y] = true;
	      draw[x+1][y] = true;
	      continue;
	    }
	  }
	}
	else{
	  if (density[data[x][y]] > density[data[x+1][y]]){
	    if ( rand() < ((density[data[x][y]] - density[data[x+1][y]]))*RAND_MAX ){
	      char t = data[x][y];
	      data[x][y] = data[x+1][y];
	      data[x+1][y] = t;
	      draw[x][y] = true;
	      draw[x+1][y] = true;
	      continue;
	    }
	  }
	  if (density[data[x][y]] > density[data[x-1][y]]){
	    if ( rand() < ((density[data[x][y]] - density[data[x-1][y]]))*RAND_MAX ){
	      char t = data[x][y];
	      data[x][y] = data[x-1][y];
	      data[x-1][y] = t;
	      draw[x][y] = true;
	      draw[x-1][y] = true;
	      continue;
	    }
	  }
	}
      }

      */
      

    }
  }
  if (mouseIsDown){
    for(int i=mousex-pen_width/2;i<mousex+pen_width/2;++i){
      for(int j=mousey-pen_width/2;j<mousey+pen_width/2;++j){
	if (i > 0 && i < 1000 && j > 0 && j < 800){
	  data[i][j] = sand_type;
	  draw[i][j] = true;
	}
      }
    }
  }

  this->Refresh();
}


void Canvas::Refresh(){
  wxClientDC dc(g_canvas);

  int cx,cy,cw,ch;
  dc.GetClippingBox(&cx,&cy,&cw,&ch);
  for(int y = cy;y<cy+ch; ++y)
    for(int x = cx;x<cx+cw; ++x)
      draw[x][y] = true;

  for(int y=0;y<800;++y){
    for(int x=0;x<1000;++x){
      if (draw[x][y] == false)
	continue;

      dc.SetPen(colors[data[x][y]]);
      dc.DrawPoint(x, y);
      dc.SetPen(wxNullPen);
      draw[x][y] = false;
      continue;
      
      /*
      if (data[x][y] == 0){
	dc.SetPen(*wxBLACK_PEN);
	dc.DrawPoint(x, y);
	dc.SetPen(wxNullPen);
	draw[x][y] = false;
	continue;
      }
      if (data[x][y] == SALT){
	dc.SetPen(*wxWHITE_PEN);
	dc.DrawPoint(x, y);
	dc.SetPen(wxNullPen);
	draw[x][y] = false;
	continue;
      }
      if (data[x][y] == SAND){
	dc.SetPen(wxPen(wxColor(238,204,128), 1, wxSOLID));
	dc.DrawPoint(x, y);
	dc.SetPen(wxNullPen);
	draw[x][y] = false;
	continue;
      }
      if (data[x][y] == WOOD){
	dc.SetPen(wxPen(wxColor(165,42,42), 1, wxSOLID));
	dc.DrawPoint(x, y);
	dc.SetPen(wxNullPen);
	draw[x][y] = false;
	continue;
      }
      if (data[x][y] == PLANT){
	dc.SetPen(wxPen(wxColor(0,255,0), 1, wxSOLID));
	dc.DrawPoint(x, y);
	dc.SetPen(wxNullPen);
	draw[x][y] = false;
	continue;
      }
      if (data[x][y] == WETSAND){
	dc.SetPen(wxPen(wxColor(238-10,204-10,128-10), 1, wxSOLID));
	dc.DrawPoint(x, y);
	dc.SetPen(wxNullPen);
	draw[x][y] = false;
	continue;
      }
      if (data[x][y] == WETWOOD){
	dc.SetPen(wxPen(wxColor(165-10,42-10,42-10), 1, wxSOLID));
	dc.DrawPoint(x, y);
	dc.SetPen(wxNullPen);
	draw[x][y] = false;
	continue;
      }
      if (data[x][y] == WETPLANT){
	dc.SetPen(wxPen(wxColor(0,255-10,0), 1, wxSOLID));
	dc.DrawPoint(x, y);
	dc.SetPen(wxNullPen);
	draw[x][y] = false;
	continue;
      }
      if (data[x][y] == WATER){
	dc.SetPen(wxPen(wxColor(32,32,255), 1, wxSOLID));
	dc.DrawPoint(x, y);
	dc.SetPen(wxNullPen);
	draw[x][y] = false;
	continue;
      }
      if (data[x][y] == SALTWATER){
	dc.SetPen(wxPen(wxColor(2,2,225), 1, wxSOLID));
	dc.DrawPoint(x, y);
	dc.SetPen(wxNullPen);
	draw[x][y] = false;
	continue;
      }
      if (data[x][y] == STONE){
	dc.SetPen(wxPen(wxColor(192,192,192), 1, wxSOLID));
	dc.DrawPoint(x, y);
	dc.SetPen(wxNullPen);
	draw[x][y] = false;
	continue;
      }
      */

    }
  }

}

void Canvas::OnEraseBG(wxEraseEvent& e){
  //Do absolutely nothing, thereby halting this event.
  
  for(int y=0;y<800;++y){
    for(int x=0;x<1000;++x){
      draw[x][y] = true;
    }
  }
   
  this->Refresh();
}

void Canvas::OnMouseLeftDown(wxMouseEvent& event){
  mouseIsDown = true;
  mousex = event.GetX();
  mousey = event.GetY();

  for(int i=mousex-pen_width/2;i<mousex+pen_width/2;++i){
    for(int j=mousey-pen_width/2;j<mousey+pen_width/2;++j){
      if (i > 0 && i < 1000 && j > 0 && j < 800){
	data[i][j] = sand_type;
	draw[i][j] = true;
      }
    }
  }

  g_canvas->Refresh();
}

void Canvas::OnMouseLeftUp(wxMouseEvent& event){
  mouseIsDown = false;
}

void Canvas::OnMouseMove(wxMouseEvent& event){
  if (event.LeftIsDown()){
    mousex = event.GetX();
    mousey = event.GetY();
    mouseIsDown = true;

    for(int i=mousex-pen_width/2;i<mousex+pen_width/2;++i){
      for(int j=mousey-pen_width/2;j<mousey+pen_width/2;++j){
	if (i > 0 && i < 1000 && j > 0 && j < 800){
	  data[i][j] = sand_type;
	  draw[i][j] = true;
	}
      }
    }

    g_canvas->Refresh();
  }
  else
    mouseIsDown = false;
}

void Canvas::OnPaint(wxPaintEvent& event){
  wxPaintDC dc;
  this->Refresh();
}




MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size, 
		     long style) : wxFrame(NULL, -1, title, pos, size, style){
  g_mainFrame = this;
  //this->SetBackgroundStyle(wxBG_STYLE_CUSTOM);
  g_canvas = new Canvas(this, -1, wxDefaultPosition, wxDefaultSize);
  wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
  sizer->Add(g_canvas, 1, wxEXPAND);

  sizer->Add(new wxListBox(this, 1000, wxDefaultPosition, wxDefaultSize, NUMBEROFELEMENTS, names, wxLB_SINGLE), 0, wxEXPAND);
  
  const wxString labels2[5] = {"2", "4", "6", "8", "10"};
  sizer->Add(new wxListBox(this, 1001, wxDefaultPosition, wxDefaultSize, 5, labels2, wxLB_SINGLE), 0, wxEXPAND);
  

  this->SetSizer(sizer);
  //this->SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
}

void MainFrame::OnChoice(wxCommandEvent& event){
  if (event.GetId() == 1000){
    sand_type = (char)event.GetSelection();
  }
  else{
    pen_width = (event.GetSelection()+1)*2;
  }

}


void MainFrame::OnSize(wxSizeEvent& event){
  for(int y=0;y<800;++y){
    for(int x=0;x<1000;++x){
      draw[x][y] = true;
    }
  }
  g_mainFrame->Layout();
}

void MainFrame::OnMove(wxFocusEvent& event){
  for(int y=0;y<800;++y){
    for(int x=0;x<1000;++x){
      draw[x][y] = true;
    }
  }
  if (g_canvas)
    g_canvas->Refresh();
}


/* this is executed upon startup, like 'main()' in non-wxWidgets programs */
bool Sand::OnInit()
{
  wxFrame *frame = new MainFrame("Owen's Reality v1.0", wxDefaultPosition, wxSize(1000,800), wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN);
  frame->Show(TRUE);
  SetTopWindow(frame);
  return true;
}

