contract Crowdsale is Ownable {
using SafeMath for uint256;

// The token being sold
MintableToken public token;

// start and end timestamps where investments are allowed (both inclusive)
uint256 public startTime;
uint256 public endTime;

// address where funds are collected
address public wallet;

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

// amount of tokens that were sold
uint256 public tokensSold;

// Hard cap in VNC tokens
uint256 constant public hardCap = 24000000 * (10**18);

/**
* 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);


function Crowdsale(uint256 _startTime, uint256 _endTime, address _wallet, MintableToken tokenContract) public {
require(_startTime >= now);
require(_endTime >= _startTime);
require(_wallet != 0x0);

startTime = _startTime;
endTime = _endTime;
wallet = _wallet;
token = tokenContract;
}

function setNewTokenOwner(address newOwner) public onlyOwner {
    token.transferOwnership(newOwner);
}

function createTokenOwner() internal returns (MintableToken) {
    return new MintableToken();
}

function () external payable {
    buyTokens(msg.sender);
  }

  /**
     * @dev Internal function that is used to determine the current rate for token / ETH conversion
     * @return The current token rate
     */
    function getRate() internal view returns (uint256) {
        if(now < (startTime + 5 weeks)) {
            return 7000;
        }

        if(now < (startTime + 9 weeks)) {
            return 6500;
        }

        if(now < (startTime + 13 weeks)) {
            return 6000;
        }
		
        if(now < (startTime + 15 weeks)) {
            return 5500;
        }
        return 5000;
    }
   
  // low level token purchase function
 function buyTokens(address beneficiary) public payable {
 require(beneficiary != 0x0);
 require(validPurchase());
 require(msg.value >= 0.05 ether);

 uint256 weiAmount = msg.value;
 uint256 updateWeiRaised = weiRaised.add(weiAmount);
 uint256 rate = getRate();
 uint256 tokens = weiAmount.mul(rate);
 require ( tokens <= token.balanceOf(this));
// update state
weiRaised = updateWeiRaised;

token.transfer(beneficiary, tokens);

tokensSold = tokensSold.add(tokens);

emit TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);

forwardFunds();
}

// @return true if crowdsale event has ended
function hasEnded() public view returns (bool) {
return now > endTime || tokensSold >= hardCap;
}

// Override this method to have a way to add business logic to your crowdsale when buying
function tokenResend() public onlyOwner {
token.transfer(owner, token.balanceOf(this));
}

// send ether to the fund collection wallet
// override to create custom fund forwarding mechanisms
function forwardFunds() internal {
wallet.transfer(msg.value);
}

// @return true if the transaction can buy tokens
function validPurchase() internal view returns (bool) {
bool withinPeriod = now >= startTime && now <= endTime;
bool nonZeroPurchase = msg.value != 0;
bool hardCapNotReached = tokensSold < hardCap;
        return withinPeriod && nonZeroPurchase && hardCapNotReached;
}

}
function hasEnded() public view returns (bool) {
return now > endTime || tokensSold >= hardCap;
}

// @return true if crowdsale event has ended