bool GameState::Update() {
	//Updates the timers
	m_timerGuards += Settings::ms_deltatime;
	m_timerPlayer += Settings::ms_deltatime;
	m_bumpTimer += Settings::ms_deltatime;

	//Updates keypresses. returns true if the game is exiting
	if(UpdateEvents()) {
		return false;
	}

	//Updates the player
	int noise = mp_player->Update(cl, fm, mp_fov);
	if(noise != -1 && m_bumpTimer > 0.91f) {
		sf::Sound* bump = nullptr;
		if(!SoundEntity::IsMuted()) {
			bump = Settings::ms_soundManager.GetSound("../data/sound/FURNITURE.ogg")->CreateSound(mp_player->GetPosition());
			if(bump != nullptr) {
				bump->play();
			}
		}
		m_soundRippleManager.CreateSoundRipple(mp_player->GetPosition(), noise, true, m_spriteManager.Load("Ripple.txt"), bump);
		m_bumpTimer = 0.0f;
	}

	//Update the listener
	Settings::ms_soundManager.Update(mp_player->GetPosition());
	if(mp_player->IsRunning() && m_timerPlayer > 0.5f) {
		m_timerPlayer = 0.0f;
		sf::Sound* footstep = nullptr;
		if(mp_player->IsRightFoot()) {
			if(!SoundEntity::IsMuted()) {
				footstep = Settings::ms_soundManager.GetSound("../data/sound/RUN_1.ogg")->CreateSound(mp_player->GetPosition());
			}
		}
		else {
			if(!SoundEntity::IsMuted()) {
				footstep = Settings::ms_soundManager.GetSound("../data/sound/RUN_2.ogg")->CreateSound(mp_player->GetPosition());
			}
		}
		m_soundRippleManager.CreateSoundRipple(mp_player->GetPosition(), 4, true, m_spriteManager.Load("Ripple.txt"), footstep);
	}

	for(unsigned int i = 0; i < m_guards.size(); i++) {
		//checks to see if a guard is within hearing range of a playercreated sound
		sf::Vector2f pos(m_soundRippleManager.GuardNotice(m_guards.at(i)->GetPosition()));
		if(pos.x > 1.0f && pos.y > 1.0f) {
			m_guards.at(i)->AddWaypointToFront(pos);
		}

		//updates the guard
		m_guards.at(i)->Update(mp_player->GetPosition(), cl, fm);

		//checks to see if a foot step is to be created. Move or change so it is in sync with the walk animation
		if(m_guards.at(i)->IsWalking() && m_timerGuards > 0.5f) {
			AnimatedSprite* footPrint = m_spriteManager.Load("GuardFootStep.txt");
			sf::Sound* sound = nullptr;
			if(m_guards.at(i)->GetFoot() == 0) {
				footPrint->ChangeAnimation("Footstep_left.png");
				if(!SoundEntity::IsMuted())
				{
					sound = Settings::ms_soundManager.GetSound("../data/sound/STEP_1.ogg")->CreateSound((m_guards.at(i)->GetPosition()));
				}
			}
			else {
				footPrint->ChangeAnimation("Footstep_right.png");
				if(!SoundEntity::IsMuted())
				{
					sound = Settings::ms_soundManager.GetSound("../data/sound/STEP_2.ogg")->CreateSound((m_guards.at(i)->GetPosition()));
				}
			}
			mp_guardFootSteps->AddRipple(m_guards.at(i)->GetPosition(), m_guards.at(i)->GetSprite()->getSprite()->getRotation(), footPrint, sound);
		}

		//updates the guards flashlight position and direction
		Vec2f vecG(m_guards.at(i)->GetPosition().x, -m_guards.at(i)->GetPosition().y + mp_view->getSize().y);
		float angle = (static_cast<int>(m_guards.at(i)->GetSprite()->getSprite()->getRotation() - 90) % 360)  * (3.141592 / 180);
		lm->GetLight(m_guards.at(i))->m_directionAngle = -angle;
		lm->GetLight(m_guards.at(i))->SetCenter(vecG);
		lm->GetLight(m_guards.at(i))->CalculateAABB();
	}

	//resets the timer
	if(m_timerGuards > 0.5f) {
		m_timerGuards = 0.0f;
	}

	//Check if door is open
	if(Settings::ms_inputManager.IsDownOnceKeyboard(sf::Keyboard::E) || Settings::ms_inputManager.IsDownOnceKeyboard(sf::Keyboard::Space)) {
		sf::CircleShape* door = cl->Circle_DoorUse(*mp_player->GetSprite());
		if(door != nullptr) {
			if(!dm->OpenDoor(door)) {
				for(int i = 0; i < mp_gui->GetItemCount(); i++) {
					sf::Color color = mp_gui->GetItem(i)->getColor();
					if(dm->OpenDoor(door, color)) {
						mp_gui->RemoveItem(i);
						if(!SoundEntity::IsMuted())
						{
							mp_unlock->play();
							mp_unlock->setPosition(door->getPosition().x, 0, door->getPosition().y);
						}
						break;
					}
				}
			}
			else
			{
				if(dm->GetDoor(door)->IsOpen())
				{
					if(!SoundEntity::IsMuted())
					{
						sf::Sound* mp_closeDoor = Settings::ms_soundManager.GetSound("../data/sound/DOOR_CLOSE.ogg")->CreateSound(door->getPosition());
						m_soundRippleManager.CreateSoundRipple(mp_player->GetPosition(), 1, true, m_spriteManager.Load("Ripple.txt"), mp_closeDoor);
					}
				}
				else
				{
					if(!SoundEntity::IsMuted())
					{
						sf::Sound* mp_openDoor = Settings::ms_soundManager.GetSound("../data/sound/DOOR_OPEN.ogg")->CreateSound(door->getPosition());
						m_soundRippleManager.CreateSoundRipple(mp_player->GetPosition(), 1, true, m_spriteManager.Load("Ripple.txt"), mp_openDoor);
					}
				}
			}
		}
	}

	//check if key is close enough to pick up
	sf::CircleShape* circle_key = cl->Circle_KeyPickup(*mp_player->GetSprite());
	if(circle_key != nullptr) {
		Key* key = km->PickUpKey(circle_key);
		sf::Color color = key->GetPickUpRadius()->getFillColor();
		color.a = 255;
		key->setColor(color);
		mp_gui->AddItem(key);
		if (!SoundEntity::IsMuted())
		{
			mp_keySound->play();
			mp_keySound->setPosition(key->getPosition().x, 0, key->getPosition().y);
		}
	}

	//updates the footsteps and the soundripples
	mp_guardFootSteps->Update();
	m_soundRippleManager.UpdateSounds();

	//updates the light around the player
	Vec2f vec(mp_player->GetPosition().x, -mp_view->getCenter().y + mp_view->getSize().y);
	lm->GetLight(mp_player)->SetCenter(vec);

	//checks if the player has won or lost.
	if(Settings::ms_gameOver && m_gameOverTimer > 3.2f) {
		m_nextState = "GameOverState";
		Settings::ms_gameOver = false;
		return false;
	}
	else if(mp_player->GetPosition().x > Settings::ms_exit.x - 100 && mp_player->GetPosition().x < Settings::ms_exit.x + 100 && mp_player->GetPosition().y > Settings::ms_exit.y - 100 && mp_player->GetPosition().y < Settings::ms_exit.y + 100) {
		m_levelToLoad++;
		m_levelToLoad = m_levelToLoad % 5;
		if(m_levelToLoad == 0) {
			m_nextState = "VictoryState";
			return false;
		}
		else {
			Exit();
			Enter();
		}
	}
	else if(Settings::ms_gameOver) {
		if(m_gameOverTimer > 0.5f && !m_deathSoundPlayed)
		{
			int random = rand()%10;
			if(random == 0)
			{
				mp_jokeDeath->play();
			}
			else
			{
				mp_death->play();
			}
			m_deathSoundPlayed = true;
		}
		m_gameOverTimer += Settings::ms_deltatime;
	}

	if(Settings::ms_inputManager.IsDownOnceKeyboard(sf::Keyboard::F1) && Settings::ms_inputManager.IsDownKeyboard(sf::Keyboard::LControl) && Settings::ms_inputManager.IsDownKeyboard(sf::Keyboard::LShift)) {
		m_levelToLoad = 1;
		Exit();
		Enter();
	}
	else if(Settings::ms_inputManager.IsDownOnceKeyboard(sf::Keyboard::F2) && Settings::ms_inputManager.IsDownKeyboard(sf::Keyboard::LControl) && Settings::ms_inputManager.IsDownKeyboard(sf::Keyboard::LShift)) {
		m_levelToLoad = 2;
		Exit();
		Enter();
	}
	else if(Settings::ms_inputManager.IsDownOnceKeyboard(sf::Keyboard::F3) && Settings::ms_inputManager.IsDownKeyboard(sf::Keyboard::LControl) && Settings::ms_inputManager.IsDownKeyboard(sf::Keyboard::LShift)) {
		m_levelToLoad = 3;
		Exit();
		Enter();
	}
	else if(Settings::ms_inputManager.IsDownOnceKeyboard(sf::Keyboard::F4) && Settings::ms_inputManager.IsDownKeyboard(sf::Keyboard::LControl) && Settings::ms_inputManager.IsDownKeyboard(sf::Keyboard::LShift)) {
		m_levelToLoad = 4;
		Exit();
		Enter();
	}
	else if(Settings::ms_inputManager.IsDownOnceKeyboard(sf::Keyboard::F5) && Settings::ms_inputManager.IsDownKeyboard(sf::Keyboard::LControl) && Settings::ms_inputManager.IsDownKeyboard(sf::Keyboard::LShift)) {
		m_levelToLoad = 0;
		Exit();
		Enter();
	}
	else if(Settings::ms_inputManager.IsDownOnceKeyboard(sf::Keyboard::F11)) {
		Settings::SetFullscreen();
	}
	else if(Settings::ms_inputManager.IsDownOnceKeyboard(sf::Keyboard::F12)) {
		Settings::SetWindowed();
	}
	else if(Settings::ms_inputManager.IsDownOnceKeyboard(sf::Keyboard::Escape)) {
		m_nextState = "StartMenuState";
		return false;
	}

	return true;
}
bool KeyManager::LoadFromFile(std::string filename){
    std::ifstream stream;
    stream.open(filename);
    if(!stream.is_open())
    {
        return false;
    }
    std::string row;
    std::getline(stream, row, '\n');
    if (*(row.end()-1) == '\r')
    {
        row.erase(row.end()-1);
    }
    if (*(row.begin()) == '\xef')
    {
        for(int i =0; i<3; i++)
        {
            row.erase(row.begin());
        }
    }
    while (!stream.eof())
    {
        
        while(row != "\xa7")
        {
            int x, y;
            std::stringstream ss(row);
            ss >> x >> y;
            
            sf::Color* color = new sf::Color;
            int c;
            ss >> c;
            color->r=c;
            ss >> c;
            color->g=c;
            ss >> c;
            color->b=c;
            
            Key* key = new Key(x, y, m_texture, color);
            m_keys.insert(std::make_pair(key->GetPickUpRadius(), key));
            
            ltbl::Light_Point* glow = new ltbl::Light_Point();
            glow->m_center = Vec2f(key->GetPickUpRadius()->getPosition().x, mp_lightSystem->m_viewAABB.GetDims().y - key->GetPickUpRadius()->getPosition().y);
            glow->m_radius = key->GetPickUpRadius()->getRadius();
            glow->m_size = 1.0f;
            glow->m_color.r = static_cast<float>(color->r) / 255.0f;
            glow->m_color.g = static_cast<float>(color->g) / 255.0f;
            glow->m_color.b = static_cast<float>(color->b) / 255.0f;
            glow->m_intensity = 2.0f;
            glow->m_spreadAngle = ltbl::pifTimes2;
            glow->m_softSpreadAngle = 0.0f;
            glow->CalculateAABB();
            
            mp_lightManager->AddLight(glow, key);
            
            //glow->SetAlwaysUpdate(false);
            
            std::getline(stream, row, '\n');
            if (*(row.end()-1) == '\r')
            {
                row.erase(row.end()-1);
            }
        }
        std::getline(stream, row, '\n');
        if (row == "")
        {
            break;
        }
    }
    return true;
}