contract B2BCCrowdsale is Ownable{
    using SafeMath for uint256;

      // The token being sold
      B2BCToken public b2bcToken;

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

      uint256 internal constant baseExchangeRate =  2000 ;  //2000 B2BC Tokens per 1 ETH
      uint256 internal constant earlyExchangeRate = 2300 ;  //2300 B2BC Tokens per 1 ETH
      uint256 internal constant vipExchangeRate =   2900 ;  //2900 B2BC Tokens per 1 ETH
      uint256 internal constant vcExchangeRate  =   3000 ;  //3000 B2BC Tokens per 1 ETH
      uint8   internal constant  DaysForEarlyDay = 11;
      uint256 internal constant vipThrehold = 1000 * (10**18);
           
      // amount of eth crowded in wei
      uint256 public weiCrowded;
      event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);

      //constructor
      function B2BCCrowdsale() {          
            owner = 0xeedA60D0C81836747f684cE48d53137d08392448;
            b2bcToken = new B2BCToken(owner); 
      }

      function setStartEndTime(uint256 _startTime, uint256 _endTime) onlyOwner{
            require(_startTime >= now);
            require(_endTime >= _startTime);
            startTime = _startTime;
            endTime = _endTime;
      }
      // fallback function can be used to buy tokens
      function () payable {
          buyTokens(msg.sender);
      }

      // low level token purchase function
      function buyTokens(address beneficiary) public payable {
            require(beneficiary != 0x0);
            require(validPurchase());

            uint256 weiAmount = msg.value;
            weiCrowded = weiCrowded.add(weiAmount);

            
            // calculate token amount to be created
            uint256 rRate = rewardRate();
            uint256 rewardB2BC = weiAmount.mul(rRate);
            uint256 baseB2BC = weiAmount.mul(baseExchangeRate);
           
            // the rewardB2BC lock in 3 mounthes
            if(rRate > baseExchangeRate) {
                b2bcToken.mintB2BC(beneficiary, rewardB2BC);  
                TokenPurchase(msg.sender, beneficiary, weiAmount, rewardB2BC);
            } else {
                b2bcToken.mintB2BC(beneficiary, baseB2BC);  
                TokenPurchase(msg.sender, beneficiary, weiAmount, baseB2BC);
            }

            forwardFunds();           
      }

      /**
       * reward rate for purchase
       */
      function rewardRate() internal constant returns (uint256) {
            uint256 rate = baseExchangeRate;
            if (now < startTime) {
                rate = vcExchangeRate;
            } else {
                uint crowdIndex = (now - startTime) / (24 * 60 * 60); 
                if (crowdIndex < DaysForEarlyDay) {
                    rate = earlyExchangeRate;
                } else {
                    rate = baseExchangeRate;
                }

                //vip
                if (msg.value >= vipThrehold) {
                    rate = vipExchangeRate;
                }
            }
            return rate;
      }

      // send ether to the fund collection wallet
      function forwardFunds() internal {
            owner.transfer(msg.value);
      }

      // @return true if the transaction can buy tokens
      function validPurchase() internal constant returns (bool) {
            bool nonZeroPurchase = msg.value != 0;
            bool noEnd = !hasEnded();
            return  nonZeroPurchase && noEnd;
      }

      // @return true if crowdsale event has ended
      function hasEnded() public constant returns (bool) {
            return (now > endTime) || b2bcToken.isSoleout(); 
      }
}
// Contract for B2BC Token sale
function hasEnded() public constant returns (bool) {
      return (now > endTime) || b2bcToken.isSoleout(); 
}

// @return true if crowdsale event has ended