contract Crowdsale is Ownable {
  using SafeMath for uint256;
  // The token being sold
  LendConnect public token;
  // start and end timestamps where investments are allowed (both inclusive
  
  uint256 public start_time = 1511377200;//11/22/2017 @ 7:00pm (UTC) or 8:00pm (CET)
  uint256 public phase_1_Time = 1511809200;//11/27/2017 @ 7:00pm (UTC) or 8:00pm (CET)
  uint256 public phase_2_Time = 1512241200;//12/02/2017 @ 7:00pm (UTC) or 8:00pm (CET)
  uint256 public phase_3_Time = 1512673200;//12/07/2017 @ 7:00pm (UTC) or 8:00pm (CET)
  uint256 public phase_4_Time = 1513105200;//12/12/2017 @ 7:00pm (UTC) or 8:00pm (CET)
  uint256 public end_Time = 1513278000;//12/14/2017 @ 7:00pm (UTC) or 8:00pm (CET)
  uint256 public phase_1_remaining_tokens  = 1000000 * (10 ** uint256(18));
  uint256 public phase_2_remaining_tokens  = 1000000 * (10 ** uint256(18));
  uint256 public phase_3_remaining_tokens  = 1000000 * (10 ** uint256(18));
  uint256 public phase_4_remaining_tokens  = 1000000 * (10 ** uint256(18));
  uint256 public phase_5_remaining_tokens  = 1000000 * (10 ** uint256(18));
  mapping(address => uint256) phase_1_balances;
  mapping(address => uint256) phase_2_balances;
  mapping(address => uint256) phase_3_balances;
  mapping(address => uint256) phase_4_balances;
  mapping(address => uint256) phase_5_balances;
  
  
  // address where funds are collected
  address public wallet;
  // how many token units a buyer gets per wei
  uint256 public rate = 730;
  // amount of raised money in wei
  uint256 public weiRaised;
  /**
   * 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);
  // rate change event
  event RateChanged(address indexed owner, uint256 old_rate, uint256 new_rate);
  
  // constructor
  function Crowdsale(address tokenContractAddress, address _walletAddress) public{
    wallet = _walletAddress;
    token = LendConnect(tokenContractAddress);
  }
  // fallback function can be used to buy tokens
  function () payable public{
    buyTokens(msg.sender);
  }
  // low level token purchase function
  function buyTokens(address beneficiary) public payable {
    require(beneficiary != 0x0);
    require(validPurchase());
    uint256 weiAmount = msg.value;
    // calculate token amount to be created
    uint256 tokens = weiAmount.mul(rate);
    // Check is there are enough token available for current phase and per person  
    require(isTokenAvailable(tokens));
    // update state
    weiRaised = weiRaised.add(weiAmount);
    token.transfer(beneficiary, tokens);
    //decrease phase supply and add user phase balance
    updatePhaseSupplyAndBalance(tokens);
    TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
    forwardFunds();
  }
  // check token availibility for current phase and max allowed token balance
  function isTokenAvailable(uint256 _tokens) internal constant returns (bool){
    uint256 current_time = now;
    uint256 total_expected_tokens = 0;
    if(current_time > start_time && current_time < phase_1_Time){
      total_expected_tokens = _tokens + phase_1_balances[msg.sender];
      return total_expected_tokens <= 10000 * (10 ** uint256(18)) &&
        _tokens <= phase_1_remaining_tokens;
    }
    else if(current_time > phase_1_Time && current_time < phase_2_Time){
      total_expected_tokens = _tokens + phase_2_balances[msg.sender];
      return total_expected_tokens <= 2000 * (10 ** uint256(18)) &&
        _tokens <= phase_2_remaining_tokens;
    }
    else if(current_time > phase_2_Time && current_time < phase_3_Time){
      total_expected_tokens = _tokens + phase_3_balances[msg.sender];
      return total_expected_tokens <= 2000 * (10 ** uint256(18)) &&
        _tokens <= phase_3_remaining_tokens;
    }
    else if(current_time > phase_3_Time && current_time < phase_4_Time){
      total_expected_tokens = _tokens + phase_4_balances[msg.sender];
      return total_expected_tokens <= 3500 * (10 ** uint256(18)) &&
        _tokens <= phase_4_remaining_tokens;
    }
    else{
      total_expected_tokens = _tokens + phase_5_balances[msg.sender];
      return total_expected_tokens <= 3500 * (10 ** uint256(18)) &&
        _tokens <= phase_5_remaining_tokens;
    }
  }
  // decrease phase supply and add user phase balance
  function updatePhaseSupplyAndBalance(uint256 _tokens) internal {
    uint256 current_time = now;
    if(current_time > start_time && current_time < phase_1_Time){
      phase_1_balances[msg.sender] = phase_1_balances[msg.sender].add(_tokens);
      phase_1_remaining_tokens = phase_1_remaining_tokens - _tokens;
    }
    else if(current_time > phase_1_Time && current_time < phase_2_Time){
      phase_2_balances[msg.sender] = phase_2_balances[msg.sender].add(_tokens);
      phase_2_remaining_tokens = phase_2_remaining_tokens - _tokens;
    }
    else if(current_time > phase_2_Time && current_time < phase_3_Time){
      phase_3_balances[msg.sender] = phase_3_balances[msg.sender].add(_tokens);
      phase_3_remaining_tokens = phase_3_remaining_tokens - _tokens;
    }
    else if(current_time > phase_3_Time && current_time < phase_4_Time){
      phase_4_balances[msg.sender] = phase_4_balances[msg.sender].add(_tokens);
      phase_4_remaining_tokens = phase_4_remaining_tokens - _tokens;
    }
    else{
      phase_5_balances[msg.sender] = phase_5_balances[msg.sender].add(_tokens);
      phase_5_remaining_tokens = phase_5_remaining_tokens - _tokens;
    }
  }
  // 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 >= start_time && now <= end_Time;
    bool nonZeroPurchase = msg.value != 0;
    return withinPeriod && nonZeroPurchase;
  }
  // @return true if crowdsale event has ended
  function hasEnded() public constant returns (bool) {
    return now > end_Time;
  }
  // function to transfer token back to owner
  function transferBack(uint256 tokens) onlyOwner public returns (bool){
    token.transfer(owner, tokens);
    return true;
  }
  // function to change rate
  function changeRate(uint256 _rate) onlyOwner public returns (bool){
    RateChanged(msg.sender, rate, _rate);
    rate = _rate;
    return true;
  }
  function tokenBalance() constant public returns (uint256){
    return token.balanceOf(this);
  }
}
function changeRate(uint256 _rate) onlyOwner public returns (bool){
  RateChanged(msg.sender, rate, _rate);
  rate = _rate;
  return true;
}

// function to change rate