int WorldGenerator::genChairsByFurniture( Level& level, Room& room, Level::Furniture& furniture,
                                          short leftIndex, short frontIndex, short rightIndex, short backIndex )
{
    int chairCount = furniture.getType() == Level::Furniture::Desk ? mRand.gen(1, 2) : mRand.gen(1, 8 );
    int gennedChairs = 0;
    int attempts = 0;

    float chairRoll = mRand.genNorm();

    //If we fail the chair roll, don't generate any chairs
    if( chairRoll > mLevelRanges->rooms[ room.type ].furnitureChances[ Level::Furniture::Chair ] ){
        return 0;
    }

    while( gennedChairs < chairCount ){
        attempts++;

        if( attempts > WORLD_GEN_ATTEMPTS ){
            break;
        }

        int side = mRand.gen(0, 4);
        int gX = 0;
        int gZ = 0;
        int yRot = mRand.gen(0, 4);

        switch( side ){
        case 0:
            gX = leftIndex - 1;
            gZ = mRand.gen( frontIndex + 1, backIndex - 1 );
            yRot = 2;
            break;
        case 1:
            gX = mRand.gen( leftIndex + 1, rightIndex - 1 );
            gZ = frontIndex - 1;
            yRot = 1;
            break;
        case 2:
            gX = rightIndex + 1;
            gZ = mRand.gen( frontIndex + 1, backIndex - 1 );
            yRot = 0;
            break;
        case 3:
            gX = mRand.gen( leftIndex + 1, rightIndex - 1 );
            gZ = backIndex + 1;
            yRot = 3;
            break;
        default:
            break;
        }

        //If we are out of bounds of the room, try again
        if( gX < room.left || gX > room.right ||
            gZ < room.top || gZ > room.bottom ){
            continue;
        }

        Level::Furniture furniture;

        furniture.setType( Level::Furniture::Type::Chair );

        //Position the furniture
        furniture.getPosition().x = ( static_cast<float>( gX ) * 0.3f ) + 0.15f;
        furniture.getPosition().z = ( static_cast<float>( gZ ) * 0.3f ) + 0.15f;
        furniture.getPosition().y = 0.0f;

        //Rotate the furniture
        furniture.setYRotation( static_cast<float>( yRot ) * ( 3.14159f / 2.0f ) );

        float left, front, right, back;
        
        //Calculate bounding box
        level.getFurnitureAABoundingSquare( furniture, left, front, right, back );

        //Convert to indices touched
        short iLeft = static_cast<short>( left / 0.3f );
        short iFront = static_cast<short>( front / 0.3f );
        short iRight = static_cast<short>( right / 0.3f );
        short iBack = static_cast<short>( back / 0.3f );

        //Make sure the area we want to set to furniture is clear
        if( !level.isRectOfBlocksOpen(iLeft, iRight, iFront, iBack) ){
            continue;
        }

        ushort addedFurnitureIndex = level.addFurniture( furniture );
        Level::Furniture* addedFurniture = &level.getFurniture( addedFurnitureIndex );

        //Set the blocks in the touched indicies to be furniture blocks
        for(int i = iLeft; i <= iRight; i++){
            for(int j = iFront; j <= iBack; j++){
                level.getBlock( i, j ).setFurniture( addedFurniture );
            }
        }

        if( !pathExistsToDoors( level, room ) ){
            level.removeFurniture( addedFurnitureIndex );

            for(int i = iLeft; i <= iRight; i++){
                for(int j = iFront; j <= iBack; j++){
                    level.getBlock( i, j ).setOpen();
                }
            }

            continue;
        }



        gennedChairs++;
    }

    return gennedChairs;
}
void WorldGenerator::genLevelRoomFurniture( Level& level, Room& room, float blockDimension )
{
    float genFurnitureDensity = mLevelRanges->rooms[ room.type ].furnitureDensity.gen( mRand );
    int furnitureCount = static_cast<int>(static_cast<float>((room.right - room.left) * (room.bottom - room.top)) * genFurnitureDensity);
    int gennedFurnitureBlocks = 0;

    int attempts = 0;
    
    while( gennedFurnitureBlocks < furnitureCount ){
        Level::Furniture furniture;

        float furnitureRoll = mRand.genNorm();
        float check = 0.0f;

        attempts++;

        if( attempts > WORLD_GEN_ATTEMPTS ){
            break;
        }

        //Generate the type of furniture
        for(int i = Level::Furniture::Type::Desk; i < LEVEL_FURNITURE_TYPE_COUNT; i++){
            check += mLevelRanges->rooms[ room.type ].furnitureChances[ i ];

            if( furnitureRoll < check ){
                furniture.setType( (Level::Furniture::Type)(i) );
                break;
            }
        }

        //Gen position
        int gX = mRand.gen( room.left, room.right + 1 );
        int gZ = mRand.gen( room.top, room.bottom + 1 );

        //Gen rotation
        int yRot = mRand.gen( 0, 4 );

        //TODO: Regenerate values against the wall
        if( furniture.getType() == Level::Furniture::Type::Desk ){
            int wall = mRand.gen( 0, 4 );

            int furnWidth = static_cast<int>( ( level.getFurnitureDimensions( Level::Furniture::Type::Desk ).x / 2.0f ) / blockDimension );
            int furnDepth = static_cast<int>( ( level.getFurnitureDimensions( Level::Furniture::Type::Desk ).z / 2.0f ) / blockDimension );

            switch( wall ){
            case 0:
                gZ = room.top + furnDepth;
                gX = mRand.gen( room.left, room.right + 1 );
                yRot = 3;
                break;
            case 1:
                gX = room.left + furnWidth;
                gZ = mRand.gen( room.top, room.bottom + 1 );
                yRot = 0;
                break;
            case 2:
                gZ = room.bottom - furnDepth;
                gX = mRand.gen( room.left, room.right + 1 );
                yRot = 1;
                break;
            case 3:
                gX = room.right - furnWidth;
                gZ = mRand.gen( room.top, room.bottom + 1 );
                yRot = 2;
                break;
            default:
                break;
            }
        }

        //Position the furniture
        furniture.getPosition().x = ( static_cast<float>( gX ) * blockDimension ) + blockDimension / 2.0f;
        furniture.getPosition().z = ( static_cast<float>( gZ ) * blockDimension ) + blockDimension / 2.0f;
        furniture.getPosition().y = 0.0f;

        //Rotate the furniture
        furniture.setYRotation( static_cast<float>( yRot ) * ( 3.14159f / 2.0f ) );

        float left, front, right, back;
        
        //Calculate bounding box
        level.getFurnitureAABoundingSquare( furniture, left, front, right, back );

        //Convert to indices touched
        short iLeft = static_cast<short>( left / blockDimension );
        short iFront = static_cast<short>( front / blockDimension );
        short iRight = static_cast<short>( right / blockDimension );
        short iBack = static_cast<short>( back / blockDimension );

        //Make sure the area we want to set to furniture is clear
        if( !level.isRectOfBlocksOpen(iLeft, iRight, iFront, iBack) ){
            continue;
        }

        ushort addedFurnitureIndex = level.addFurniture( furniture );
        Level::Furniture* addedFurniture = &level.getFurniture( addedFurnitureIndex );

        //Set the blocks in the touched indicies to be furniture blocks
        for(int i = iLeft; i <= iRight; i++){
            for(int j = iFront; j <= iBack; j++){
                level.getBlock( i, j ).setFurniture( addedFurniture );
            }
        }

        //If there isn't a path, undo what we added
        if( !pathExistsToDoors( level, room ) ){
            for(int i = iLeft; i <= iRight; i++){
                for(int j = iFront; j <= iBack; j++){
                    level.getBlock( i, j ).setOpen();
                }
            }

            level.removeFurniture( addedFurnitureIndex );
            continue;
        }

        //Increment by furniture width * height
        gennedFurnitureBlocks += ( ( iRight - iLeft ) + 1 ) * ( ( iBack - iFront ) + 1);

        //Generate a chair if it is a table or desk
        if( furniture.getType() == Level::Furniture::Type::Table ||
            furniture.getType() == Level::Furniture::Type::Desk ){
            gennedFurnitureBlocks += genChairsByFurniture( level, room, furniture, iLeft, iFront, iRight, iBack );
        }
    }
}