#pragma once

/**
 * @brief Abstract interface for game rules
 * 
 * Provides a common interface for different Tetris rule implementations,
 * enabling different game modes and rule variations.
 */
class IGameRules {
public:
    virtual ~IGameRules() = default;
    
    /**
     * @brief Calculate score for cleared lines
     * @param linesCleared Number of lines cleared simultaneously
     * @param level Current game level
     * @return Score points to award
     */
    virtual int calculateScore(int linesCleared, int level) const = 0;
    
    /**
     * @brief Get gravity speed for a given level
     * @param level Game level
     * @return Time in milliseconds for one gravity drop
     */
    virtual double getGravitySpeed(int level) const = 0;
    
    /**
     * @brief Check if level should increase
     * @param totalLines Total lines cleared so far
     * @param currentLevel Current game level
     * @return true if level should increase, false otherwise
     */
    virtual bool shouldLevelUp(int totalLines, int currentLevel) const = 0;
    
    /**
     * @brief Calculate next level based on lines cleared
     * @param totalLines Total lines cleared so far
     * @param startLevel Starting level
     * @return New level
     */
    virtual int calculateLevel(int totalLines, int startLevel) const = 0;
    
    /**
     * @brief Get soft drop speed multiplier
     * @return Multiplier for gravity when soft dropping
     */
    virtual double getSoftDropMultiplier() const = 0;
    
    /**
     * @brief Get hard drop score per cell
     * @return Points awarded per cell for hard drop
     */
    virtual int getHardDropScore() const = 0;
    
    /**
     * @brief Get soft drop score per cell
     * @return Points awarded per cell for soft drop
     */
    virtual int getSoftDropScore() const = 0;
    
    /**
     * @brief Check if T-spins are enabled in this rule set
     * @return true if T-spins are supported, false otherwise
     */
    virtual bool supportsTSpins() const = 0;
    
    /**
     * @brief Check if hold feature is enabled in this rule set
     * @return true if hold is supported, false otherwise
     */
    virtual bool supportsHold() const = 0;
};
