contract ICO is Pausable, WhitelistedCrowdsale {
    using SafeMath for uint256;

    Token public token;

    // June 01, 2018 @ UTC 0:01
    uint256 public startDate;

    // July 05, 2018 on UTC 23:59
    uint256 public endDate;

    uint256 public hardCap;

    // amount of raised money in wei
    uint256 public weiRaised;

    address public wallet;

    mapping(address => uint256) public deposited;

    /**
     * event for token purchase logging
     * @param purchaser who paid for the tokens
     * @param beneficiary who got the tokens
     * @param value weis paid for purchase
     * @param amount amount of tokens purchased
     */
    event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);

    /**
     * @dev _wallet where collect funds during crowdsale
     * @dev _startDate should be 1527811260
     * @dev _endDate should be 1530835140
     * @dev _maxEtherPerInvestor should be 10 ether
     * @dev _hardCap should be 8700 ether
     */
    function ICO(address _token, address _wallet, uint256 _startDate, uint256 _endDate, uint256 _hardCap) public {
        require(_token != address(0) && _wallet != address(0));
        require(_endDate > _startDate);
        require(_hardCap > 0);
        startDate = _startDate;
        endDate = _endDate;
        hardCap = _hardCap;
        token = Token(_token);
        wallet = _wallet;
    }

    function claimFunds() onlyOwner public {
        require(hasEnded());
        wallet.transfer(this.balance);
    }

    function getRate() public view returns (uint256) {
        if (now < startDate || hasEnded()) return 0;

        // Period: from June 01, 2018 @ UTC 0:01 to June 7, 2018 @ UTC 23:59; Price: 1 ETH = 1840 TKP
        if (now >= startDate && now < startDate + 604680) return 1840;
        // Period: from June 08, 2018 @ UTC 0:00 to June 14, 2018 @ UTC 23:59; Price: 1 ETH = 1760 TKP
        if (now >= startDate + 604680 && now < startDate + 1209480) return 1760;
        // Period: from June 15, 2018 @ UTC 0:00 to June 21, 2018 @ UTC 23:59; Price: 1 ETH = 1680 TKP
        if (now >= startDate + 1209480 && now < startDate + 1814280) return 1680;
        // Period: from June 22, 2018 @ UTC 0:00 to June 28, 2018 @ UTC 23:59; Price: 1 ETH = 1648 TKP
        if (now >= startDate + 1814280 && now < startDate + 2419080) return 1648;
        // Period: from June 29, 2018 @ UTC 0:00 to July 5, 2018 @ UTC 23:59; Price: 1 ETH = 1600 TKP
        if (now >= startDate + 2419080) return 1600;
    }

    // fallback function can be used to buy tokens
    function() external payable {
        buyTokens(msg.sender);
    }

    // low level token purchase function
    function buyTokens(address beneficiary) whenNotPaused isWhitelisted(beneficiary) isWhitelisted(msg.sender) public payable {
        require(beneficiary != address(0));
        require(validPurchase());
        require(!hasEnded());

        uint256 weiAmount = msg.value;

        // calculate token amount to be created
        uint256 tokens = weiAmount.mul(getRate());

        // Minimum contribution level in TKP tokens for each investor = 100 TKP
        require(tokens >= 100 * (10 ** 18));

        // update state
        weiRaised = weiRaised.add(weiAmount);

        token.mint(beneficiary, tokens);
        TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
    }

    // @return true if the transaction can buy tokens
    function validPurchase() internal view returns (bool) {
        return now >= startDate && msg.value != 0;
    }

    // @return true if crowdsale event has ended
    function hasEnded() public view returns (bool) {
        return (now > endDate || weiRaised >= hardCap);
    }
}
function buyTokens(address beneficiary) whenNotPaused isWhitelisted(beneficiary) isWhitelisted(msg.sender) public payable {
    require(beneficiary != address(0));
    require(validPurchase());
    require(!hasEnded());

    uint256 weiAmount = msg.value;

    // calculate token amount to be created
    uint256 tokens = weiAmount.mul(getRate());

    // Minimum contribution level in TKP tokens for each investor = 100 TKP
    require(tokens >= 100 * (10 ** 18));

    // update state
    weiRaised = weiRaised.add(weiAmount);

    token.mint(beneficiary, tokens);
    TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
}

// low level token purchase function