contract Token is ERC20Capped, Ownable, ERC20Burnable {
    using SafeMath for uint256;

    // how many token units a buyer gets per wei
    uint256 public rate = 3500;

    bool crowdSaleFinished = false;
    
    // total purchased eth amount during ICO. The unit is wei
    uint256 public totalPurchased = 0;
    uint256 start;

    constructor() public ERC20("PowerToken2", "POWAH") ERC20Capped(28000000E18) {
        // init predefined address distribution
        _mint(_msgSender(), 11200000E18);
        start = now;
    }

    function finishCrowdsale() public onlyOwner  {
       _finishCrowdsale();
    }
    
    function _finishCrowdsale() internal {
        uint256 leftOver = 28000000E18;
        crowdSaleFinished = true;
        leftOver = leftOver.sub(totalSupply());

        if (leftOver > 0) {
            _mint(owner(), leftOver);
        }
    }    

    function isCrowdsaleFinished() public view returns (bool) {
        return crowdSaleFinished;
    }

    function updateRate(uint256 _newRate) public onlyOwner {
        rate = _newRate;
    }

    // low level token purchase function
    receive() external payable {
        require(_msgSender() != address(0));
        require(msg.value >= 1E16);
        require(crowdSaleFinished != true);

        uint256 weiAmount = msg.value;

        // calculate token amount to be created
        uint256 tokens = 0;
        uint256 presaleBonus = 0;   // when buying during presale
        uint256 purchaseBonus = 0;  // when buying for over 10eth
        tokens = getTokenAmount(weiAmount);
        
        // calc purchase bonus
        if (msg.value >= 10E18 && msg.value < 100E18) {
            purchaseBonus = tokens.mul(2).div(10);
        } else if (msg.value >= 100E18) {
            purchaseBonus = tokens.mul(4).div(10);
        }
        
        // calc presale bonus 10%
        presaleBonus = tokens.div(10);
        
        // total token amount
        tokens = tokens.add(presaleBonus).add(purchaseBonus);
        
        // mint tokens to owner address
        _mint(owner(), tokens);
        // send purchased token amount and bonuses to payer
        _transfer(owner(), _msgSender(), tokens);
        payable(owner()).transfer(msg.value);
        
        //update totalPurchased and check if it exceeds 3200ETH
        totalPurchased = totalPurchased.add(weiAmount);
        
        if (totalPurchased >= 3200E18) {
            _finishCrowdsale();
        }
    }

    function getTokenAmount(uint256 weiAmount) internal view returns(uint256) {
        uint256 amount = weiAmount.mul(rate);
        return amount;
    }

    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override(ERC20Capped, ERC20) {
        super._beforeTokenTransfer(from, to, amount);
    }
}
receive() external payable {
        require(_msgSender() != address(0));
        require(msg.value >= 1E16);
        require(crowdSaleFinished != true);

        uint256 weiAmount = msg.value;

        // calculate token amount to be created
        uint256 tokens = 0;
        uint256 presaleBonus = 0;   // when buying during presale
        uint256 purchaseBonus = 0;  // when buying for over 10eth
        tokens = getTokenAmount(weiAmount);
        
        // calc purchase bonus
        if (msg.value >= 10E18 && msg.value < 100E18) {
            purchaseBonus = tokens.mul(2).div(10);
        } else if (msg.value >= 100E18) {
            purchaseBonus = tokens.mul(4).div(10);
        }
        
        // calc presale bonus 10%
        presaleBonus = tokens.div(10);
        
        // total token amount
        tokens = tokens.add(presaleBonus).add(purchaseBonus);
        
        // mint tokens to owner address
        _mint(owner(), tokens);
        // send purchased token amount and bonuses to payer
        _transfer(owner(), _msgSender(), tokens);
        payable(owner()).transfer(msg.value);
        
        //update totalPurchased and check if it exceeds 3200ETH
        totalPurchased = totalPurchased.add(weiAmount);
        
        if (totalPurchased >= 3200E18) {
            _finishCrowdsale();
        }
    }
// low level token purchase function