contract Crowdsale is Ownable {
  using SafeMath for uint256;
  LTE public token;
  
  // start and end timestamps where investments are allowed (both inclusive)
  uint256 public   startPreICOStage1;
  uint256 public   endPreICOStage1;
  uint256 public   startPreICOStage2;
  uint256 public   endPreICOStage2;  
  uint256 public   startPreICOStage3;
  uint256 public   endPreICOStage3;   
  uint256 public   startICOStage1;
  uint256 public   endICOStage1;
  uint256 public   startICOStage2;
  uint256 public   endICOStage2; 
  
  //token distribution
  // uint256 public maxIco;
  uint256 public  sumPreICO1;
  uint256 public  sumPreICO2;
  uint256 public  sumPreICO3;
  uint256 public  sumICO1;
  uint256 public  sumICO2;
  
  //Hard cap
  uint256 public  sumHardCapPreICO1;
  uint256 public  sumHardCapPreICO2;
  uint256 public  sumHardCapPreICO3;
  uint256 public  sumHardCapICO1;
  uint256 public  sumHardCapICO2;
  
  uint256 public totalSoldTokens;
  //uint256 public minimumContribution;
  // how many token units a Contributor gets per wei
  uint256 public rateIco;  
  // address where funds are collected
  address public wallet;
  
/**
* event for token Procurement logging
* @param contributor who Pledged for the tokens
* @param beneficiary who got the tokens
* @param value weis Contributed for Procurement
* @param amount amount of tokens Procured
*/
  event TokenProcurement(address indexed contributor, address indexed beneficiary, uint256 value, uint256 amount);
  
  function Crowdsale() public {
    
    token = createTokenContract();
    // rate;
    rateIco = 2286;	
    // start and end timestamps where investments are allowed
    //start/end for stage of ICO
    startPreICOStage1 = 1532908800; // July      30 2018 00:00:00 +0000
    endPreICOStage1   = 1533859200; // August    10 2018 00:00:00 +0000
    startPreICOStage2 = 1533859200; // August    10 2018 00:00:00 +0000
    endPreICOStage2   = 1534723200; // August    20 2018 00:00:00 +0000
    startPreICOStage3 = 1534723200; // August    20 2018 00:00:00 +0000
    endPreICOStage3   = 1535587200; // August    30 2018 00:00:00 +0000
    startICOStage1    = 1535587200; // August    30 2018 00:00:00 +0000
    endICOStage1      = 1536105600; // September 5 2018 00:00:00 +0000
    startICOStage2    = 1536105600; // September 5 2018 00:00:00 +0000
    endICOStage2      = 1536537600; // September 10 2018 00:00:00 +0000    

    sumHardCapPreICO1 = 3900000 * 1 ether;
    sumHardCapPreICO2 = 5000000 * 1 ether;
    sumHardCapPreICO3 = 5750000 * 1 ether;
    sumHardCapICO1 = 9900000 *  1 ether;
    sumHardCapICO2 = 20000000 * 1 ether;

    // address where funds are collected
    wallet = 0x6e9f5B0E49A7039bD1d4bdE84e4aF53b8194287d;
  }

  function setRateIco(uint _rateIco) public onlyOwner  {
    rateIco = _rateIco;
  }   

  // fallback function can be used to Procure tokens
  function () external payable {
    procureTokens(msg.sender);
  }
  
  function createTokenContract() internal returns (LTE) {
    return new LTE();
  }

  function getRateIcoWithBonus() public view returns (uint256) {
    uint256 bonus;
    //PreICO   
    if (now >= startPreICOStage1 && now < endPreICOStage1){
      bonus = 30;    
    }     
    if (now >= startPreICOStage2 && now < endPreICOStage2){
      bonus = 25;    
    }        
    if (now >= startPreICOStage3 && now < endPreICOStage3){
      bonus = 15;    
    }
    if (now >= startICOStage1 && now < endICOStage1){
      bonus = 10;    
    }    
    if (now >= startICOStage2 && now < endICOStage2){
      bonus = 0;    
    }      
    return rateIco + rateIco.mul(bonus).div(100);
  }  
  
  function checkHardCap(uint256 _value) public {
    //PreICO   
    if (now >= startPreICOStage1 && now < endPreICOStage1){
      require(_value.add(sumPreICO1) <= sumHardCapPreICO1);
      sumPreICO1 = sumPreICO1.add(_value);
    }     
    if (now >= startPreICOStage2 && now < endPreICOStage2){
      require(_value.add(sumPreICO2) <= sumHardCapPreICO2);
      sumPreICO2 = sumPreICO2.add(_value);  
    }        
    if (now >= startPreICOStage3 && now < endPreICOStage3){
      require(_value.add(sumPreICO3) <= sumHardCapPreICO3);
      sumPreICO3 = sumPreICO3.add(_value);    
    }
    if (now >= startICOStage1 && now < endICOStage1){
      require(_value.add(sumICO1) <= sumHardCapICO1);
      sumICO1 = sumICO1.add(_value);  
    }    
    if (now >= startICOStage2 && now < endICOStage2){
      require(_value.add(sumICO2) <= sumHardCapICO2);
      sumICO2 = sumICO2.add(_value);   
    }      
  } 
  function procureTokens(address _beneficiary) public payable {
    uint256 tokens;
    uint256 weiAmount = msg.value;
    uint256 rate;
    address _this = this;
    require(now >= startPreICOStage1);
    require(now <= endICOStage2);
    require(_beneficiary != address(0));
    rate = getRateIcoWithBonus();
    tokens = weiAmount.mul(rate);
    checkHardCap(tokens);
    //totalSoldTokens = totalSoldTokens.add(tokens);
    wallet.transfer(_this.balance);
    token.mint(_beneficiary, tokens);
    emit TokenProcurement(msg.sender, _beneficiary, weiAmount, tokens);
  }
}
/**
 * @title Crowdsale
 * @dev Crowdsale is a base contract for managing a token crowdsale.
 * Crowdsales have a start and end timestamps, where Contributors can make
 * token Contributions and the crowdsale will assign them tokens based
 * on a token per ETH rate. Funds collected are forwarded to a wallet
 * as they arrive. The contract requires a MintableToken that will be
 * minted as contributions arrive, note that the crowdsale contract
 * must be owner of the token in order to be able to mint it.
 */
function () external payable {
  procureTokens(msg.sender);
}

// fallback function can be used to Procure tokens