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

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

#define SALTWATER 1
#define WATER 2
#define SALT 3
#define RSAND 4
#define WOOD 5
#define PLANT 6

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;


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();

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

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

  for(int i=100;i<110;++i)
    if (rand() < RAND_MAX/4){
      data[i][j] = SALT;
      draw[i][j] = true;
    }
  for(int i=200;i<210;++i)
    if (rand() < RAND_MAX/4){
      data[i][j] = RSAND;
      draw[i][j] = true;
    }
  for(int i=400;i<410;++i)
    if (rand() < RAND_MAX/4){
      data[i][j] = WATER;
      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 = 2;
      move = -1;
    }

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

      //Water is special. It flows fast.
      if (data[x][y] == WATER || data[x][y] == SALTWATER){
	if (data[x+1][y] == 0 && data[x-1][y] > 0 && data[x-1][y] != WOOD && data[x-1][y] != PLANT){
	  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 (data[x-1][y] == 0 && data[x+1][y] > 0 && data[x+1][y] != WOOD && data[x+1][y] != PLANT){
	  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;
	}
	continue;
      }
    }
  }

  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;

      
      char type = data[x][y];
      //Check for falling through the air.
      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;
	}
	continue;
      }
      //Check for falling downhill
      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]] > density[data[x][y+1]]){
	if ( rand() < ((density[data[x][y]] - density[data[x][y+1]])/(density[data[x][y]] + density[data[x][y+1]]))*RAND_MAX ){
	  char t = data[x][y];
	  data[x][y+1] = data[x][y];
	  data[x][y] = 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]])/(density[data[x][y]] + density[data[x-1][y+1]]))*RAND_MAX ){
	    char t = data[x][y];
	    data[x-1][y+1] = data[x][y];
	    data[x][y] = 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]])/(density[data[x][y]] + density[data[x+1][y+1]]))*RAND_MAX ){
	    char t = data[x][y];
	    data[x+1][y+1] = data[x][y];
	    data[x][y] = t;
	    draw[x][y] = true;
	    draw[x+1][y+1] = true;
	    continue;
	  }
	}
      }





      if (data[x][y] == WOOD){
	//Ashes to ashes, wood to sand.
	if (rand() < 0.01*RAND_MAX){
	  if (rand() < 0.01*RAND_MAX){
	    if (data[x-1][y] != WOOD ||
		data[x-1][y-1] != WOOD ||
		data[x][y-1] != WOOD ||
		data[x+1][y-1] != WOOD ||
		data[x+1][y] != WOOD ||
		data[x+1][y+1] != WOOD ||
		data[x][y+1] != WOOD ||
		data[x-1][y+1] != WOOD){
	      data[x][y] = RSAND;
	      draw[x][y] = true;
	    }
	  }
	}
	continue;
      }

      if (data[x][y] == PLANT){
	//Check for water to grow a plant.
	if (rand() < 0.01*RAND_MAX){
	  if (data[x-1][y] == WATER){
	    data[x-1][y] = PLANT;
	    draw[x-1][y] = true;
	  }
	  else if (data[x-1][y-1] == WATER){
	    data[x-1][y-1] = PLANT;
	    draw[x-1][y-1] = true;
	  }
	  else if (data[x][y-1] == WATER){
	    data[x][y-1] = PLANT;
	    draw[x][y-1] = true;
	  }
	  else if (data[x+1][y-1] == WATER){
	    data[x+1][y-1] = PLANT;
	    draw[x+1][y-1] = true;
	  }
	  else if (data[x+1][y] == WATER){
	    data[x+1][y] = PLANT;
	    draw[x+1][y] = true;
	  }
	  else if (data[x+1][y+1] == WATER){
	    data[x+1][y+1] = PLANT;
	    draw[x+1][y+1] = true;
	  }
	  else if (data[x][y+1] == WATER){
	    data[x][y+1] = PLANT;
	    draw[x][y+1] = true;
	  }
	  else if (data[x-1][y+1] == WATER){
	    data[x-1][y+1] = PLANT;
	    draw[x-1][y+1] = true;
	  }
	}

	if (rand() < 0.1*RAND_MAX){
	  if (data[x-1][y] == SALTWATER){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	  else if (data[x-1][y-1] == SALTWATER){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	  else if (data[x][y-1] == SALTWATER){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	  else if (data[x+1][y-1] == SALTWATER){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	  else if (data[x+1][y] == SALTWATER){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	  else if (data[x+1][y+1] == SALTWATER){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	  else if (data[x][y+1] == SALTWATER){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	  else if (data[x-1][y+1] == SALTWATER){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	}

	if (rand() < 0.01*RAND_MAX){
	if (rand() < 0.1*RAND_MAX){
	  if (data[x-1][y] == WOOD){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	  else if (data[x-1][y-1] == WOOD){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	  else if (data[x][y-1] == WOOD){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	  else if (data[x+1][y-1] == WOOD){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	  else if (data[x+1][y] == WOOD){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	  else if (data[x+1][y+1] == WOOD){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	  else if (data[x][y+1] == WOOD){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	  else if (data[x-1][y+1] == WOOD){
	    data[x][y] = WOOD;
	    draw[x][y] = true;
	  }
	}
	}

	continue;
      }

      if (data[x][y] == RSAND){
	//Check for water to grow a plant.
	if (rand() < 0.01*RAND_MAX){
	  if (rand() < 0.01*RAND_MAX){
	    if (data[x-1][y] == WATER){
	      data[x-1][y] = PLANT;
	      draw[x-1][y] = true;
	    }
	    else if (data[x-1][y-1] == WATER){
	      data[x-1][y-1] = PLANT;
	      draw[x-1][y-1] = true;
	    }
	    else if (data[x][y-1] == WATER){
	      data[x][y-1] = PLANT;
	      draw[x][y-1] = true;
	    }
	    else if (data[x+1][y-1] == WATER){
	      data[x+1][y-1] = PLANT;
	      draw[x+1][y-1] = true;
	    }
	    else if (data[x+1][y] == WATER){
	      data[x+1][y] = PLANT;
	      draw[x+1][y] = true;
	    }
	    else if (data[x+1][y+1] == WATER){
	      data[x+1][y+1] = PLANT;
	      draw[x+1][y+1] = true;
	    }
	    else if (data[x][y+1] == WATER){
	      data[x][y+1] = PLANT;
	      draw[x][y+1] = true;
	    }
	    else if (data[x-1][y+1] == WATER){
	      data[x-1][y+1] = PLANT;
	      draw[x-1][y+1] = true;
	    }
	  }
	}
      }

      //Fall through the air
      if (data[x][y+1] == 0){
	if (rand() < 0.6*RAND_MAX){
	  char t = data[x][y+1];
	  data[x][y+1] = data[x][y];
	  data[x][y] = t;
	  draw[x][y] = true;
	  draw[x][y+1] = true;
	  continue;
	}
	continue;
      }

      //Saltwater moves randomly in water.
      if (data[x][y] == SALTWATER){
	int r = rand();
	if (data[x][y+1] == WATER && r < 0.7*RAND_MAX){
	  data[x][y+1] = SALTWATER;
	  data[x][y] = WATER;
	}
	else if (data[x][y-1] == WATER && r < 0.7*RAND_MAX){
	  data[x][y-1] = SALTWATER;
	  data[x][y] = WATER;
	}
	else if (data[x-1][y] == WATER && r < 0.7*RAND_MAX){
	  data[x-1][y] = SALTWATER;
	  data[x][y] = WATER;
	}
	else if (data[x+1][y] == WATER && r < 0.7*RAND_MAX){
	  data[x+1][y] = SALTWATER;
	  data[x][y] = WATER;
	}
	else if (data[x+1][y+1] == WATER && r < 0.7*RAND_MAX){
	  data[x+1][y+1] = SALTWATER;
	  data[x][y] = WATER;
	}
	else if (data[x+1][y-1] == WATER && r < 0.7*RAND_MAX){
	  data[x+1][y-1] = SALTWATER;
	  data[x][y] = WATER;
	}
	else if (data[x-1][y-1] == WATER && r < 0.7*RAND_MAX){
	  data[x-1][y-1] = SALTWATER;
	  data[x][y] = WATER;
	}
      }

      //Water is special. It flows fast.
      if (data[x][y] == WATER || data[x][y] == SALTWATER){

	if (data[x][y] == WATER){
	  //If salt is touching water, sometimes dissolve.
	  if (data[x+1][y] == SALT){
	    if (rand() < 0.01*RAND_MAX){
	      data[x][y] = SALTWATER;
	      data[x+1][y] = SALTWATER;
	      draw[x][y] = true;
	      draw[x+1][y] = true;
	      continue;
	    }
	  }
	  if (data[x-1][y] == SALT){
	    if (rand() < 0.01*RAND_MAX){
	      data[x][y] = SALTWATER;
	      data[x-1][y] = SALTWATER;
	      draw[x][y] = true;
	      draw[x-1][y] = true;
	      continue;
	    }
	  }
	  if (data[x][y-1] == SALT){
	    if (rand() < 0.01*RAND_MAX){
	      data[x][y] = SALTWATER;
	      data[x][y-1] = SALTWATER;
	      draw[x][y] = true;
	      draw[x][y-1] = true;
	      continue;
	    }
	  }
	  if (data[x][y+1] == SALT){
	    if (rand() < 0.01*RAND_MAX){
	      data[x][y] = SALTWATER;
	      data[x][y+1] = SALTWATER;
	      draw[x][y] = true;
	      draw[x][y+1] = true;
	      continue;
	    }
	  }
	  if (data[x+1][y+1] == SALT){
	    if (rand() < 0.01*RAND_MAX){
	      data[x][y] = SALTWATER;
	      data[x+1][y+1] = SALTWATER;
	      draw[x][y] = true;
	      draw[x+1][y+1] = true;
	      continue;
	    }
	  }
	}

	if (rand() < 0.01*RAND_MAX){
	  if (rand() < 0.01*RAND_MAX){
	    if (rand() < 0.1*RAND_MAX){
	      //Crystallize!
	      if (data[x][y] == SALTWATER &&
		  data[x+1][y] == SALTWATER &&
		  data[x-1][y] == SALTWATER &&
		  data[x][y-1] == SALTWATER &&
		  data[x][y+1] == SALTWATER){
		data[x][y] = SALT;
		data[x+1][y] = SALT;
		data[x][y-1] = SALT;
		data[x-1][y] = WATER;
		data[x][y+1] = WATER;
		data[x+1][y+1] = WATER;
		
		draw[x][y] = true;
		draw[x+1][y] = true;
		draw[x][y-1] = true;
		continue;
	      }
	    }
	  }
	}

	if (data[x+1][y] == 0 && data[x-1][y] > 0 && data[x-1][y] != WOOD && data[x-1][y] != PLANT){
	  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 (data[x-1][y] == 0 && data[x+1][y] > 0 && data[x+1][y] != WOOD && data[x+1][y] != PLANT){
	  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;
	}

	//Check for moving down and left or down and right.
	if (data[x+1][y+1] == 0 && data[x-1][y+1] == 0){
	  if (rand() < 0.5*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{
	    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){
	    data[x+1][y+1] = data[x][y];
	    data[x][y] = 0;
	    draw[x][y] = true;
	    draw[x+1][y+1] = true;
	    continue;
	  }
	  if (data[x-1][y+1] == 0){
	    data[x-1][y+1] = data[x][y];
	    data[x][y] = 0;
	    draw[x][y] = true;
	    draw[x-1][y+1] = true;
	    continue;
	  }
	}

	continue;
      }

      //Float down through water
      if (data[x][y+1] == WATER || data[x][y+1] == SALTWATER){
	if (rand() < .3*RAND_MAX){
	  char t = data[x][y+1];
	  data[x][y+1] = data[x][y];
	  data[x][y] = t;
	  draw[x][y] = true;
	  draw[x][y+1] = true;
	  continue;
	}
      }

      

      
      //If falling on white or red sand, don't move as often.
      if (data[x][y+1] == SALT || data[x][y+1] == RSAND || 
	  data[x+1][y+1] == SALT || data[x+1][y+1] == RSAND ||
	  data[x-1][y+1] == SALT || data[x-1][y+1] == RSAND){
	if (rand() < 0.5*RAND_MAX)
	  continue;
      }
      //If falling on water, don't move as often.
      if ((data[x][y+1] == WATER || data[x][y+1] == SALTWATER) ||
	  (data[x+1][y+1] == WATER || data[x+1][y+1] == SALTWATER) ||
	  (data[x-1][y+1] == WATER || data[x+1][y+1] == SALTWATER)){
	if (rand() < 0.7*RAND_MAX)
	  continue;
      }

      //Cases where there's something directly below us.
      if (data[x][y+1] > 0){
	//Check to see if we can fall downhill
	if (data[x-1][y+1] <= WATER && data[x+1][y+1] <= WATER){
	  if (rand() < 0.5*RAND_MAX){
	    char t = data[x-1][y+1];
	    data[x-1][y+1] = data[x][y];
	    data[x][y] = t;
	    draw[x][y] = true;
	    draw[x-1][y+1] = true;
	    continue;
	  }
	  else{
	    char t = data[x+1][y+1];
	    data[x+1][y+1] = data[x][y];
	    data[x][y] = t;
	    draw[x][y] = true;
	    draw[x+1][y+1] = true;
	    continue;
	  }
	}
	else if (data[x-1][y+1] <= WATER){
	  char t = data[x-1][y+1];
	  data[x-1][y+1] = data[x][y];
	  data[x][y] = t;
	  draw[x][y] = true;
	  draw[x-1][y+1] = true;
	  continue;
	}
	else if (data[x+1][y+1] <= WATER){
	  char t = data[x+1][y+1];
	  data[x+1][y+1] = data[x][y];
	  data[x][y] = t;
	  draw[x][y] = true;
	  draw[x+1][y+1] = true;
	  continue;
	}

	//Check for pressure to move left or right.
	if (data[x-1][y] <= WATER && (data[x+1][y] > SALTWATER && data[x+1][y] != WOOD && data[x+1][y] != PLANT)){
	  char t = data[x-1][y];
	  data[x-1][y] = data[x][y];
	  data[x][y] = t;
	  draw[x][y] = true;
	  draw[x-1][y] = true;
	  continue;
	}
	if (data[x+1][y] <= WATER && (data[x-1][y] > SALTWATER && data[x-1][y] != WOOD && data[x+1][y] != PLANT)){
	  char t = data[x+1][y];
	  data[x+1][y] = data[x][y];
	  data[x][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;
	}
      }
    }
  }

  g_canvas->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;
      
      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] == RSAND){
	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("Brown"), 1, wxSOLID));
	dc.DrawPoint(x, y);
	dc.SetPen(wxNullPen);
	draw[x][y] = false;
	continue;
      }
      if (data[x][y] == PLANT){
	dc.SetPen(wxPen(wxColor("Green"), 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,235), 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);

  const wxString labels[6] = {"Eraser", "Salt Water", "Water", "Salt", "Red Sand", "Wood"};
  sizer->Add(new wxListBox(this, 1000, wxDefaultPosition, wxDefaultSize, 6, labels, 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;
}

