contract Crowdsale is Ownable
{
    using SafeMath for uint256;

    // The token being sold
    ILMTToken public token;
    // the account to which all incoming ether will be transferred
    // Flag to track the crowdsale status (Active/InActive)
    bool public crowdSaleOn = false;

    // Current crowdsale sate variables
    uint256 constant totalCap = 33*10**6;  // Max avaialble number of tokens in total including presale (unit token)
    uint256 constant crowdSaleCap = 18*10**6*(1 ether);  // Max avaialble number of tokens for crowdsale 18 M (unit wei)
    uint256 constant bonusPeriod = 11 days; //change to 11 days when deploying
    uint256 constant tokensPerEther = 3300;
    uint256 public startTime; // Crowdsale start time
    uint256 public endTime;  // Crowdsale end time
    uint256 public weiRaised = 0;  // Total amount ether/wei collected
    uint256 public tokensMinted = 0; // Total number of tokens minted/sold so far in this crowdsale
    uint256 public currentRate = 3300;
    //first_owner receives 90% of ico fund in eth, second_owner receives 10%.
    //first_owner keeps 25% of token, second_owner keeps 20% token, 55% token for public sale
    //For transparency this must be hardcoded and uploaded to etherscan.io
    address constant firstOwner = 0x4F70a11fA322F4614C98AD4D6fEAcAdA55Ce32C2;
    address constant secondOwner = 0xDf47E759b98a0d95063F44c09a74E2ea33E9f18F;
    uint8 constant firstOwnerETHPercentage= 90;
    uint8 constant secondOwnerETHPercentage= 10;
    uint8 constant firstOwnerTokenPercentage= 25;
    uint8 constant secondOwnerTokenPercentage= 20;
    uint256 constant minPurchase = (1*1 ether)/10; //0.1 eth minimum

    // Event to be registered when a successful token purchase happens
    event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);

    /** Modifiers to verify the status of the crowdsale*/
    modifier activeCrowdSale() {
        require(crowdSaleOn);
        _;
    }
    modifier inactiveCrowdSale() {
        require(!crowdSaleOn);
        _;
    }

    /**
        @dev constructor. Intializes the token to be traded using this contract
     */
    function Crowdsale() public {
        token = new ILMTToken(firstOwner,firstOwnerTokenPercentage,secondOwner,secondOwnerTokenPercentage, totalCap);
    }

    /**
      @dev function to start the crowdsale. it will be called once for each crowdsale session
      @return A boolean that indicates if the operation is successful
     */
    function startCrowdsale() inactiveCrowdSale onlyOwner public returns (bool) {
        startTime =  uint256(now);
        //endTime = now + 33 days;
        endTime = now + 3*bonusPeriod;
        crowdSaleOn = true;
        weiRaised = 0;
        tokensMinted = 0;
        return true;
    }

    /**
      @dev function to stop crowdsale session.it will be called once for every crowdsale session and it can be called only its owner
      @return A boolean that indicates if the operation is successful
     */
    function endCrowdsale() activeCrowdSale onlyOwner public returns (bool) {
        require(now >= endTime);
        crowdSaleOn = false;
        token.finishMinting();
        return true;
    }

    /**
      @dev function to calculate and return the discounted token rate based on the current timeslot
      @return _discountedRate for the current timeslot
      return rate of Y wei per 1 Token)
      base rate without bonus : 1 ether = 3 300 tokens
      rate changes after 11 days
      the first 11 days: 30% bonus, next 11 days: 15% bonus , last 11 day : 0%
      hardcoded
     */
    function findCurrentRate() constant private returns (uint256 _discountedRate) {

        uint256 elapsedTime = now.sub(startTime);
        uint256 baseRate = (1*1 ether)/tokensPerEther;

        if (elapsedTime <= bonusPeriod){ // x<= 11days
            _discountedRate = baseRate.mul(100).div(130);
        }else{
            if (elapsedTime < 2*bonusPeriod){ //11days < x <= 22 days
              _discountedRate = baseRate.mul(100).div(115);
              }else{
              _discountedRate = baseRate;
            }
        }

    }

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

    /**
      @dev  low level token purchase function
      */
    function buyTokens(address beneficiary) activeCrowdSale public payable {
        require(beneficiary != 0x0);
        require(now >= startTime);
        require(now <= endTime);
        require(msg.value >= minPurchase); //enforce minimum value of a tx

        // amount ether sent to the contract.. normalized to wei
        uint256 weiAmount = msg.value;
        weiRaised = weiRaised.add(weiAmount);


        // Find out Token value in wei ( Y wei per 1 Token)
        uint256 rate = findCurrentRate();
        //uint256 rate = uint256(1 * 1 ether).div(currentRate);
        require(rate > 0);
        //update public variable for viewing only, as requested
        currentRate = (1*1 ether)/rate;
        // Find out the number of tokens for given wei and normalize to ether so that tokens can be minted
        // by token contract
        uint256 numTokens = weiAmount.div(rate);
        require(numTokens > 0);
        require(tokensMinted.add(numTokens.mul(1 ether)) <= crowdSaleCap);
        tokensMinted = tokensMinted.add(numTokens.mul(1 ether));

        // Mint the tokens and trasfer to the buyer
        token.mint(beneficiary, numTokens);
        TokenPurchase(msg.sender, beneficiary, weiAmount, numTokens);
        // Transfer the ether to owners according to their share and close the purchase
        firstOwner.transfer(weiAmount*firstOwnerETHPercentage/100);
        secondOwner.transfer(weiAmount*secondOwnerETHPercentage/100);

    }

    // ETH balance is always expected to be 0 after the crowsale.
    // but in case something went wrong, we use this function to extract the eth.
    // Security idea from kyber.network crowdsale
    // This should never be used
    function emergencyDrain(ERC20 anyToken) inactiveCrowdSale onlyOwner public returns(bool){
        if( this.balance > 0 ) {
            owner.transfer( this.balance );
        }

        if( anyToken != address(0x0) ) {
            assert( anyToken.transfer(owner, anyToken.balanceOf(this)) );
        }

        return true;
    }

}
/**
 * @title Public Token Generation Event for ILMT
 * credit: part of this contract was created from OpenZeppelin Code
 * @dev It allows multiple Capped CrowdSales. i.e. every crowdsale with capped token limit.
 * Simplified the deployment function for owner, just click & start, no configuration parameters
 */
function findCurrentRate() constant private returns (uint256 _discountedRate) {

    uint256 elapsedTime = now.sub(startTime);
    uint256 baseRate = (1*1 ether)/tokensPerEther;

    if (elapsedTime <= bonusPeriod){ // x<= 11days
        _discountedRate = baseRate.mul(100).div(130);
    }else{
        if (elapsedTime < 2*bonusPeriod){ //11days < x <= 22 days
          _discountedRate = baseRate.mul(100).div(115);
          }else{
          _discountedRate = baseRate;
        }
    }

}

/**
 @dev function to calculate and return the discounted token rate based on the current timeslot
 @return _discountedRate for the current timeslot
 return rate of Y wei per 1 Token)
 base rate without bonus : 1 ether = 3 300 tokens
 rate changes after 11 days
 the first 11 days: 30% bonus, next 11 days: 15% bonus , last 11 day : 0%
 hardcoded
 */