contract BTC20Crowdsale {
  using SafeMath for uint256;
 
  // The token being sold
  BTC20Token public token;

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

  // address where funds are collected
  // address where tokens are deposited and from where we send tokens to buyers
  address public wallet;

  // how many token units a buyer gets per wei
  uint256 public ratePerWei = 50000;

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

  uint256 TOKENS_SOLD;
  uint256 maxTokensToSale = 15000000 * 10 ** 18;
  uint256 minimumContribution = 5 * 10 ** 16; //0.05 is the minimum contribution

  /**
   * 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 BTC20Crowdsale(uint256 _startTime, address _wallet) public 
  {
    startTime = _startTime;   
    endTime = startTime + 14 days;
    
    require(endTime >= startTime);
    require(_wallet != 0x0);

    wallet = _wallet;
    token = createTokenContract(wallet);
    
  }
  // creates the token to be sold.
  function createTokenContract(address wall) internal returns (BTC20Token) {
    return new BTC20Token(wall);
  }


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

  //determine the rate of the token w.r.t. time elapsed
  function determineBonus(uint tokens) internal view returns (uint256 bonus) {
    uint256 timeElapsed = now - startTime;
    uint256 timeElapsedInWeeks = timeElapsed.div(7 days);
    if (timeElapsedInWeeks == 0)
    {
      bonus = tokens.mul(50); //50% bonus
      bonus = bonus.div(100);
    }
    else if (timeElapsedInWeeks == 1)
    {
      bonus = tokens.mul(25); //25% bonus
      bonus = bonus.div(100);
    }
    else
    {
        bonus = 0;   //No tokens to be transferred - ICO time is over
    }
  }

  // low level token purchase function
  // Minimum purchase can be of 1 ETH
  
  function buyTokens(address beneficiary) public payable {
    require(beneficiary != 0x0);
    require(validPurchase());
    require(msg.value>= minimumContribution);
    require(TOKENS_SOLD<maxTokensToSale);
    uint256 weiAmount = msg.value;
    
    // calculate token amount to be created
    
    uint256 tokens = weiAmount.mul(ratePerWei);
    uint256 bonus = determineBonus(tokens);
    tokens = tokens.add(bonus);
    require(TOKENS_SOLD+tokens<=maxTokensToSale);
    
    // update state
    weiRaised = weiRaised.add(weiAmount);

    token.mint(wallet, beneficiary, tokens); 
    TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
    TOKENS_SOLD = TOKENS_SOLD.add(tokens);
    forwardFunds();
  }

  // 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 constant returns (bool) {
    bool withinPeriod = now >= startTime && now <= endTime;
    bool nonZeroPurchase = msg.value != 0;
    return withinPeriod && nonZeroPurchase;
  }

  // @return true if crowdsale event has ended
  function hasEnded() public constant returns (bool) {
    return now > endTime;
  }
  
   
    function changeEndDate(uint256 endTimeUnixTimestamp) public returns(bool) {
        require (msg.sender == wallet);
        endTime = endTimeUnixTimestamp;
    }
    function changeStartDate(uint256 startTimeUnixTimestamp) public returns(bool) {
        require (msg.sender == wallet);
        startTime = startTimeUnixTimestamp;
    }
    function setPriceRate(uint256 newPrice) public returns (bool) {
        require (msg.sender == wallet);
        ratePerWei = newPrice;
    }
    
    function changeMinimumContribution(uint256 minContribution) public returns (bool) {
        require (msg.sender == wallet);
        minimumContribution = minContribution * 10 ** 15;
    }
}
function buyTokens(address beneficiary) public payable {
  require(beneficiary != 0x0);
  require(validPurchase());
  require(msg.value>= minimumContribution);
  require(TOKENS_SOLD<maxTokensToSale);
  uint256 weiAmount = msg.value;
    
  // calculate token amount to be created
    
  uint256 tokens = weiAmount.mul(ratePerWei);
  uint256 bonus = determineBonus(tokens);
  tokens = tokens.add(bonus);
  require(TOKENS_SOLD+tokens<=maxTokensToSale);
    
  // update state
  weiRaised = weiRaised.add(weiAmount);

  token.mint(wallet, beneficiary, tokens); 
  TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
  TOKENS_SOLD = TOKENS_SOLD.add(tokens);
  forwardFunds();
}

// low level token purchase function
// Minimum purchase can be of 1 ETH