contract BabyDinosNFTICO is
    Crowdsale,
    CappedCrowdsale,
    TimedCrowdsale,
    Ownable
    {
    using SafeMath for uint256;

    /* Track investor contributions */
    uint256 public investorHardCap = 50; // 10 NFT
    mapping(address => uint256) public contributions;

    constructor(
        address payable _wallet,
        IBabyDinosNFTToken _token,
        uint256 _cap,
        uint256 _openingTime,
        uint256 _closingTime
    )
        public
        Crowdsale(_wallet, _token)
        CappedCrowdsale(_cap)
        TimedCrowdsale(_openingTime, _closingTime)
    {}

    /**
     * @dev Returns the amount contributed so far by a sepecific user.
     * @param _beneficiary Address of contributor
     * @return User contribution so far
     */
    function getUserContribution(address _beneficiary)
        public
        view
        returns (uint256)
    {
        return contributions[_beneficiary];
    }

    /**
     * @dev Extend parent behavior requiring purchase to respect investor min/max funding cap.
     * @param _beneficiary Token purchaser
     */
    function _preValidatePurchase(
        address _beneficiary,
        uint256 mintAmount,
        uint256 weiAmount
    ) internal virtual override onlyWhileOpen {

        // Check how many NFT are minted
        incrementMinted(mintAmount);
        require(currentMinted() <= _cap, "BabyDinosNFTICO: cap exceeded");
        require(
            weiAmount.div(mintAmount) == rate(),
            "BabyDinosNFTICO: Invalid ETH Amount"
        );

        // Validate inputs
        require(weiAmount != 0, "BabyDinosNFTICO: ETH sent 0");
        require(
            _beneficiary != address(0),
            "BabyDinosNFTICO: beneficiary zero address"
        );
        

        // Check max minting limit
        uint256 _existingContribution = contributions[_beneficiary];
        uint256 _newContribution = _existingContribution.add(mintAmount);
        require(
            _newContribution <= investorHardCap,
            "BabyDinosNFTICO: No of Mint MaxCap"
        );
        contributions[_beneficiary] = _newContribution;
    }

    function extendTime(uint256 closingTime) public virtual onlyOwner {
        _extendTime(closingTime);
    }

    /**
     * @dev If goal is Reached then change to change to ICO Stage
     * etc.)
     * @param _beneficiary Address receiving the tokens
     * @param _weiAmount Value in wei involved in the purchase
     */
    function _updatePurchasingState(address _beneficiary, uint256 _weiAmount)
        internal
        virtual
        override
    {    
        super._updatePurchasingState(_beneficiary, _weiAmount);
    }

    /**
     * @dev enables token transfers, called when owner calls finalize()
     */
    function finalization() public onlyOwner {
        token().renounceMinter();
    }
}
function finalization() public onlyOwner {
        token().renounceMinter();
    }
/**
 * @dev enables token transfers, called when owner calls finalize()
 */