void buttonClick()
{
    // Button click

    // --------------------------- Main ---------------------------

    if(selectedScene == scene["main"])
    {
        // Play
        if(selectedScene->button[selectedButton]->getName() == "Play")
        {
            setScene(scene["saves"]);
            loadSaves();
        }

        // Continue
        else if(selectedScene->button[selectedButton]->getName() == "Continue")
        {
            if(selectedSaveSlot != -1 &&
                    !saveSlot[selectedSaveSlot]->is_empty())
            {
                // Continue game
                loadSaves();
                setScene(scene["game"]);
            }
            else
            {
                message.push_back(new PushMessage("No saves!"));
            }
        }
    }

    // --------------------------- Pause ---------------------------

    else if(selectedScene == scene["gamePause"])
    {
        // Exit to main
        if(selectedScene->button[selectedButton]->getName() == "Main")
        {
            // To main
            if(saveSlot[selectedSaveSlot]->saved())
            {
                setScene(scene["main"]);
            }
            else
            {
                setScene(scene["gamePauseExit"]);
            }
        }

        // Save
        else if(selectedScene->button[selectedButton]->getName() == "Save")
        {
            saveSaves("save.txt");
        }
    }

    // --------------------------- Exit ---------------------------

    else if(selectedScene == scene["mainExit"])
    {
        // No
        if(selectedScene->button[selectedButton]->getName() == "No")
        {
            setScene(scene["main"]);
        }

        // Yes
        else if(selectedScene->button[selectedButton]->getName() == "Yes")
        {
            exit(EXIT_SUCCESS);
        }
    }

    // --------------------------- Game exit ---------------------------

    else if(selectedScene == scene["gamePauseExit"])
    {
        // Save and exit
        if(selectedScene->button[selectedButton]->getName() == "Save and exit")
        {
            saveSaves("save.txt");
            setScene(scene["main"]);
        }

        // Exit unsaved
        else if(selectedScene->button[selectedButton]->getName() == "Exit unsaved")
        {
            setScene(scene["main"]);
        }
    }

    // --------------------------- Maps ---------------------------

    else if(selectedScene == scene["saves"])
    {
        if(selectedScene->button[selectedButton]->getName() == "Delete" ||
                selectedScene->button[selectedButton]->getName() == "Cancel")
        {
            // To delete/load save
            deleteSave = !deleteSave;

            // Rename button

            // New button
            Button* newButton =  selectedScene->button[selectedButton];

            if(deleteSave)
            {
                // Set name "Cancel"
                newButton->setName("Cancel");
            }
            else
            {
                // Set name "Delete"
                newButton->setName("Cancel");
            }

            // Set
            selectedScene->button[selectedButton] = newButton;
        }
        else
        {
            // Select GMap
            selectedSaveSlot = selectedButton;

            if(!saveSlot[selectedButton]->is_empty())
            {
                if(deleteSave)
                {
                    // Delete
                    saveSlot[selectedButton] = new SaveSlot(new GMapWorld(biome["forest"], new GMapHome(biome["home"])));

                    // Message
                    message.push_back(new PushMessage("Deleted"));

                    // Button Cancel
                    selectedButton = selectedScene->buttonId["Delete"];
                    buttonClick();

                    // Update saves/buttons
                    saveSaves();
                    loadSaves();
                }
                else
                {
                    // To game
                    setScene(scene["game"]);
                    saveSlot[selectedSaveSlot]->gMap.setSaved(true);
                }
            }
            else
            {
                if(deleteSave)
                {
                    // Message "This is empty slot"
                    message.push_back(new PushMessage("This is empty slot"));
                }
                else
                {
                    // First game

                    // Clear label
                    Label *newLabel = scene["savesNew"]->label[1];
                    newLabel->setText(string());

                    scene["savesNew"]->label[1] = newLabel;

                    // Set scene
                    setScene(scene["savesNew"]);
                }
            }
        }
    }
}
//Main Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
	switch (message)
	{
	case WM_SYSKEYDOWN:
		{
			if (lParam & 1<<29)
			{
				WWDPhysics->m_modifierKeys = VK_LMENU;
			}
			break;
		}
	case WM_SYSKEYUP:
		{
			if (lParam & 1<<29)
			{
				WWDPhysics->m_modifierKeys = VK_LMENU;
			} else
			{
				WWDPhysics->m_modifierKeys = 0;
			}

			break;
		}

	case WM_SIZE:													// Size Action Has Taken Place

		switch (wParam)											// Evaluate Size Action
		{
		case SIZE_MINIMIZED:									// Was Window Minimized?
			return 0;												// Return

		case SIZE_MAXIMIZED:
			{									// Was Window Maximized?
				int Width = LOWORD (lParam);
				int Height = HIWORD (lParam);
				calcSizes(HIWORD (lParam),LOWORD (lParam));

				MoveWindow(hWndList,0,0,listWidth,listHeight,true);
				MoveWindow(blank,listWidth,bAreaHeight,simWidth,simHeight,true);

				if (sOpenGLInitialized)
				{
					WWDPhysics->reshape(simWidth,simHeight);
				}
			}
			return 0;												// Return

			//resize
		case SIZE_RESTORED:// Was Window Restored?
			if(hwnd == hWnd)
			{
				int Width = LOWORD (lParam);
				int Height = HIWORD (lParam);
				calcSizes(HIWORD (lParam),LOWORD (lParam));

				MoveWindow(hWndList,0,0,listWidth,listHeight,true);
				MoveWindow(blank,listWidth,bAreaHeight,simWidth,simHeight,true);

				if (sOpenGLInitialized){
					WWDPhysics->reshape(simWidth,simHeight);
				}
			}
			return 0;												// Return
		}
		break;

	case WM_CREATE:
		{
		}

		return 0;

	case WM_MBUTTONUP:
		{
			int xPos = LOWORD(lParam);
			int yPos = HIWORD(lParam);
			WWDPhysics->mouseFunc(1,1,xPos,yPos);
			POINT p = POINT();
			p.x=xPos; p.y=yPos;
			SetFocus(ChildWindowFromPoint(hwnd,p));
			break;
		}
	case WM_MBUTTONDOWN:
		{
			int xPos = LOWORD(lParam);
			int yPos = HIWORD(lParam);
			WWDPhysics->mouseFunc(1,0,xPos,yPos);
			POINT p = POINT();
			p.x=xPos; p.y=yPos;
			SetFocus(ChildWindowFromPoint(hwnd,p));
			break;
		}

	case WM_LBUTTONUP:
		{
			int xPos = LOWORD(lParam);
			int yPos = HIWORD(lParam);
			WWDPhysics->mouseFunc(0,1,xPos,yPos);
			POINT p = POINT();
			p.x=xPos; p.y=yPos;
			SetFocus(ChildWindowFromPoint(hwnd,p));
			break;
		}
	case 0x020A://WM_MOUSEWHEEL:
		{
			int zDelta = (short)HIWORD(wParam);
			int xPos = LOWORD(lParam);
			int yPos = HIWORD(lParam);
			if (zDelta>0)
				WWDPhysics->zoomIn();
			else
				WWDPhysics->zoomOut();
			break;
		}

	case WM_MOUSEMOVE:
		{
			int xPos = LOWORD(lParam);
			int yPos = HIWORD(lParam);
			WWDPhysics->mouseMotionFunc(xPos,yPos);
			break;
		}
	case WM_RBUTTONUP:
		{
			int xPos = LOWORD(lParam);
			int yPos = HIWORD(lParam);
			WWDPhysics->mouseFunc(2,1,xPos,yPos);
			POINT p = POINT();
			p.x=xPos; p.y=yPos;
			SetFocus(ChildWindowFromPoint(hwnd,p));
			break;
		}
	case WM_RBUTTONDOWN:
		{
			int xPos = LOWORD(lParam);
			int yPos = HIWORD(lParam);
			WWDPhysics->mouseFunc(2,0,xPos,yPos);
			POINT p = POINT();
			p.x=xPos; p.y=yPos;
			SetFocus(ChildWindowFromPoint(hwnd,p));
			break;
		}
	case WM_LBUTTONDOWN:
		{
			int xPos = LOWORD(lParam);
			int yPos = HIWORD(lParam);
			WWDPhysics->mouseFunc(0,0,xPos,yPos);
			POINT p = POINT();
			p.x=xPos; p.y=yPos;
			SetFocus(ChildWindowFromPoint(hwnd,p));
			break;
		}

	case WM_CONTEXTMENU:
		{
			POINT p;
			GetCursorPos(&p);
			ScreenToClient(hWndList,&p);
			int index = SendMessage(hWndList,LB_ITEMFROMPOINT,0, MAKELPARAM(p.x,p.y));

			int noElements = SendMessage(hWndList,LB_GETCOUNT,0,0);
			if(0<=index && index <noElements){
				popupMenuSel=index;

				HMENU popupMenu = CreatePopupMenu();
				InsertMenu(popupMenu,0,MF_BYPOSITION|MF_STRING,IDC_RUN_MBUTTON,"Run");
				InsertMenu(popupMenu,0,MF_BYPOSITION|MF_STRING,IDC_RENAME_MBUTTON,"Rename");
				InsertMenu(popupMenu,0,MF_BYPOSITION|MF_STRING,IDC_DELETE_MBUTTON,"Delete");
#ifdef _DEBUG
				InsertMenu(popupMenu,0,MF_BYPOSITION|MF_STRING,IDC_SHOWDNA_MBUTTON,"Show DNA");
#endif
				GetCursorPos(&p);
				TrackPopupMenu(popupMenu,TPM_TOPALIGN|TPM_LEFTALIGN,p.x,p.y,0,hwnd,NULL);
			}

			break;}

	case WM_CLOSE:
		PostQuitMessage( 0 );
		return 0;

	case WM_DESTROY:
		return 0;

	case WM_KEYUP:
		switch ( wParam )
		{
		case VK_PRIOR:
		case VK_NEXT:
		case VK_END:
		case VK_HOME:
		case VK_LEFT:
		case VK_UP:
		case VK_RIGHT:
		case VK_DOWN:
			{
				if (WWDPhysics)
					WWDPhysics->specialKeyboardUp(wParam,0,0);
				return 0;
			}
		default:
			{
				WWDPhysics->keyboardUpCallback(tolower(wParam),0,0);
			}
			return DefWindowProc( hwnd, message, wParam, lParam );
		}

	case WM_KEYDOWN:
		switch ( wParam )
		{
		case VK_CONTROL:
		case VK_PRIOR:
		case VK_NEXT:
		case VK_END:
		case VK_HOME:
		case VK_LEFT:
		case VK_UP:
		case VK_RIGHT:
		case VK_DOWN:
			{
				if (WWDPhysics)
					WWDPhysics->specialKeyboard(wParam,0,0);
				break;
			}

		case ' ':
			{
				if (WWDPhysics)
					//WWDPhysics->clientResetScene();
						if(saves.size()>0){
							SendMessage(hWnd,WM_COMMAND,MAKEWPARAM(IDC_LISTBOX,LBN_SELCHANGE),0);
						}
						break;
			}
		case 'Q':
		case VK_ESCAPE:
			{
				quitRequest = 1;
				PostQuitMessage(0);
			}
			return 0;
		}
		return 0;

	case WM_CHAR:
		if (!quitRequest)
			WWDPhysics->keyboardCallback(wParam,0,0);
		break;

	case WM_COMMAND:
		switch(LOWORD(wParam)){
		case IDC_VIEW_CHECKBOX:
			{
				HWND check = GetDlgItem(hwnd, IDC_VIEW_CHECKBOX);
				switch (SendMessage(check, BM_GETCHECK, 0,0))
				{
				case BST_CHECKED:
					SendMessage(check, BM_SETCHECK, BST_UNCHECKED,0);
					fixedSteps=false;
#ifdef _DEBUG
					printf("off\n");
#endif
					break;

				case BST_UNCHECKED:
					SendMessage(check, BM_SETCHECK, BST_CHECKED,0);
					fixedSteps=true;
#ifdef _DEBUG
					printf("on\n");
#endif
					break;
				}
			}
			break;

		case IDC_FITNESSTYPE_COMBOBOX:
			switch (HIWORD(wParam)){
			case CBN_SELCHANGE:
				HWND hwndfit = GetDlgItem(hwnd, IDC_FITNESSTYPE_COMBOBOX);
				int index = SendMessage(hwndfit, CB_GETCURSEL,0,0);
				fitnessTest tmptest=(fitnessTest) SendMessage(hwndfit,CB_GETITEMDATA, index,0);
				WWDPhysics->clearFitnessFunctions();
				WWDPhysics->addFitnessFunction(tmptest,1);
				break;
			}

			break;

		case IDC_LISTBOX:
			{
				switch (HIWORD(wParam)){
				case LBN_SELCHANGE:
					{
						HWND hwndList = GetDlgItem(hwnd, IDC_LISTBOX);

						// Get selected index.
						int index = (int)SendMessage(hwndList, LB_GETCURSEL, 0, 0);

						delete WWDPhysics;

						WWDPhysics = new Physics();
						SendMessage(hWnd,WM_COMMAND,MAKEWPARAM(IDC_FITNESSTYPE_COMBOBOX,LBN_SELCHANGE),0);
						readDNA(&saves.at(index)->dna,WWDPhysics);
						WWDPhysics->runSimStartUp();
						WWDPhysics->reshape(simWidth,simHeight);
					}
				}
			}
			break;
		case IDC_RESET_BUTTON:
			{
				if(saves.size()>0){
					SendMessage(hWnd,WM_COMMAND,MAKEWPARAM(IDC_LISTBOX,LBN_SELCHANGE),0);
				}
			}
			break;
		case IDC_RUN_BUTTON:
			{
				HWND hwndList = GetDlgItem(hwnd, IDC_LISTBOX);

				_ASSERTE(hwndList != NULL);

				// Get current selection index in listbox
				int itemIndex = (int) SendMessage(hwndList, LB_GETCURSEL, (WPARAM)0, (LPARAM) 0);
				if (itemIndex == LB_ERR)
				{
					// No selection
					return 0;
				}

				//threads
				SYSTEM_INFO sysinfo;
				GetSystemInfo( &sysinfo );

				int numCores= sysinfo.dwNumberOfProcessors;

				int pop =0;
				HWND hwndPop = GetDlgItem(hwnd, IDC_POP_EDIT);

				_ASSERTE(hwndPop != NULL);

				int length=0;

				length = GetWindowTextLength(hwndPop);

				if(length > 0){
					TCHAR * text = new TCHAR[length + 1];
					GetWindowText(hwndPop,text,length+1);
					for(int i =0; i<length;i++){
						int value = ((int)text[i])-48;
						int res =  (value* pow(10.,length-1-i)+0.5);
						pop+=res;
					}
					delete text;
				}else{
					MessageBox(NULL, "No populastion size selected", TEXT("ERROR"), MB_OK | MB_ICONERROR);
					return 0;
				}
				if(pop<10){
					MessageBox(NULL, "the Populasion size is to small", TEXT("ERROR"), MB_OK | MB_ICONERROR);
					return 0;
				}

				int noG = 0;
				HWND hwndNoG = GetDlgItem(hwnd, IDC_NOG_EDIT);

				_ASSERTE(hwndNoG != NULL);

				length=0;

				length = GetWindowTextLength(hwndNoG);
				if(length > 0){
					TCHAR * text = new TCHAR[length + 1];
					GetWindowText(hwndNoG,text,length+1);
					for(int i =0; i<length;i++){
						int value = ((int)text[i])-48;
						int res =  (value* pow(10.,length-1-i)+0.5);
						noG+=res;
					}
					delete text;
				}else{
					MessageBox(NULL, "No number of generations selected", TEXT("ERROR"), MB_OK | MB_ICONERROR);
					return 0;
				}

				HWND hwndfit = GetDlgItem(hwnd, IDC_FITNESSTYPE_COMBOBOX);
				int index = SendMessage(hwndfit, CB_GETCURSEL,0,0);
				fitnessTest tmptest=(fitnessTest) SendMessage(hwndfit,CB_GETITEMDATA, index,0);

				noGenerations=noG;
				argumentList* aList = new argumentList();
				aList->nC=numCores;
				aList->p=pop;
				aList->nG=noG;
				aList->iI=itemIndex;
				aList->stopSim=&stopSim;
				aList->type=tmptest;
				aList->theResult = new creature();

				proInfo = new progressInfo();

				HANDLE threadHandle = (HANDLE) _beginthreadex(0,0,&runServer,(void*)aList,0,0);

				UINT_PTR time = SetTimer(0,0,10,(TIMERPROC)&update);
				DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_PROGRESS), hwnd, progressControll,(LPARAM)&noG);
				KillTimer(0,time);

				save* tmpCreature =new save();
				tmpCreature->dna= aList->theResult->dna;
				tmpCreature->fitness=aList->theResult->fitness;

				delete proInfo;
				delete aList->theResult;
				delete aList;

				DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_NAMING), hwnd, namingControl,(LPARAM)&tmpCreature->name);

				saves.push_back(tmpCreature);
				SendMessage(hWndList, LB_ADDSTRING, 0, (LPARAM)saves.at(saves.size()-1)->name.c_str());
				SendMessage(hWndList,LB_SETCURSEL,saves.size()-1,0);
				delete WWDPhysics;

				WWDPhysics = new Physics();
				WWDPhysics->addFitnessFunction(tmptest,1);
				readDNA(&saves.at(saves.size()-1)->dna,WWDPhysics);
				WWDPhysics->runSimStartUp();
				WWDPhysics->reshape(simWidth,simHeight);
			}
			break;

		case IDC_RUN_MBUTTON:
			{
				HWND hwndList = GetDlgItem(hwnd, IDC_LISTBOX);
				SendMessage(hwndList,LB_SETCURSEL,popupMenuSel,0);

				SendMessage(hWnd,WM_COMMAND, MAKEWPARAM(IDC_RUN_BUTTON,0),0);
			}

			break;
		case IDC_RENAME_MBUTTON:
			{
				DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_NAMING), hwnd, namingControl,(LPARAM)&saves.at(popupMenuSel)->name);
				HWND hwndList = GetDlgItem(hwnd, IDC_LISTBOX);
				int itemIndex = (int) SendMessage(hwndList, LB_GETCURSEL, (WPARAM)0, (LPARAM) 0);
				for(int i =0; i<saves.size();i++){
					SendMessage(hwndList,LB_DELETESTRING,0,0);
				}
				for(int i =0; i<saves.size();i++){
					SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)saves.at(i)->name.c_str());
				}

				SendMessage(hwndList,LB_SETCURSEL,itemIndex,0);
			}
			break;
		case IDC_DELETE_MBUTTON:
			{
				HWND hwndList = GetDlgItem(hwnd, IDC_LISTBOX);
				int itemIndex = (int) SendMessage(hwndList, LB_GETCURSEL, (WPARAM)0, (LPARAM) 0);

				SendMessage(hwndList,LB_DELETESTRING,popupMenuSel,0);
				delete saves.at(popupMenuSel);
				saves.erase(saves.begin()+popupMenuSel,saves.begin()+popupMenuSel+1);

				if(itemIndex==popupMenuSel){
					if(saves.size() > 0){
						if(itemIndex==saves.size()){
							itemIndex--;
						}
						SendMessage(hwndList,LB_SETCURSEL,itemIndex,0);
						SendMessage(hWnd,WM_COMMAND,MAKEWPARAM(IDC_LISTBOX,LBN_SELCHANGE),0);
					}else{
						delete WWDPhysics;
						WWDPhysics=new Physics();
						WWDPhysics->reshape(simWidth,simHeight);
					}
				}
			}
			break;
		case IDC_SHOWDNA_MBUTTON:
			{
#ifdef _DEBUG
				HWND hwndList = GetDlgItem(hwnd, IDC_LISTBOX);

				printf("DNA of %s\n",saves.at(popupMenuSel)->name.c_str());
				for(int i=0; i<saves.at(popupMenuSel)->dna.size();i++){
					printf("%d, ", saves.at(popupMenuSel)->dna.at(i));
				}
				printf("\n");
#endif
			}
			break;
		case ID_FILE_NEW40002:

			randomCreature();
			while( (WWDPhysics->noBoxes<2) || (!WWDPhysics->runSimStartUp())  ){
				{//deleting
					int itemIndex = (int) SendMessage(hWndList, LB_GETCURSEL, (WPARAM)0, (LPARAM) 0);
					SendMessage(hWndList,LB_DELETESTRING,itemIndex,0);
					delete saves.at(itemIndex);
					saves.erase(saves.begin()+itemIndex,saves.begin()+itemIndex+1);
				}
				randomCreature();
			}
			break;

		case ID_FILE_SAVE40003:

			saveSaves(saves);
			break;

		case ID_FILE_EXIT:
			PostQuitMessage( 0 );

			break;
		case ID_VIDEO_CAPTURE:
			if(VFWInit()){
				captureVideo(hDC);
				MessageBox(hwnd, "Video Captured", TEXT("DONE"), MB_OK | MB_ICONINFORMATION);
			}else{
				MessageBox(hwnd, "Video Capture failed to start\n Try another codec", TEXT("ERROR"), MB_OK | MB_ICONERROR);
			}
			SendMessage(hWnd,WM_COMMAND,MAKEWPARAM(IDC_LISTBOX,LBN_SELCHANGE),0);
			break;
#ifdef _DEBUG
		default:

			printf("");
#endif
		}
		break;

	default:
		return DefWindowProc( hwnd, message, wParam, lParam );
	}
	return 0;
}