contract OKBI is StandardToken, BurnableToken, Ownable {
    // Constants
    string  public constant name = "OKBIcommunity";
    string  public constant symbol = "OKBI";
    uint8   public constant decimals = 18;
    uint256  constant INITIAL_SUPPLY    = 750000000 * (10 ** uint256(decimals));
    uint256  constant LOCK_SUPPLY       = 250000000 * (10 ** uint256(decimals));

    uint256  constant LOCK_SUPPLY1      = 100000000 * (10 ** uint256(decimals));
    uint256  constant LOCK_SUPPLY2      = 100000000 * (10 ** uint256(decimals));
    uint256  constant LOCK_SUPPLY3      =  50000000 * (10 ** uint256(decimals));
    bool mintY1;
    bool mintY2;
    bool mintY3;

    uint256  constant MINT_OKBI      =  328767 * (10 ** uint256(decimals));
    uint256  constant DAY = 1 days ;
    
    uint256 startTime = now;
    uint256 public lastMintTime;

    constructor() public {
      address holder = 0x90d1E3aA01519b7A236Fa9ffC36dA84dE191EdE0;
      totalSupply_ = INITIAL_SUPPLY + LOCK_SUPPLY;
      balances[holder] = INITIAL_SUPPLY;
      emit Transfer(0x0, holder, INITIAL_SUPPLY);

      balances[address(this)] = LOCK_SUPPLY;
      emit Transfer(0x0, address(this), LOCK_SUPPLY);
      lastMintTime = now;
    }

    function _transfer(address _from, address _to, uint _value) internal {     
        require (balances[_from] >= _value);               // Check if the sender has enough
        require (balances[_to] + _value > balances[_to]); // Check for overflows
   
        balances[_from] = balances[_from].sub(_value);                         // Subtract from the sender
        balances[_to] = balances[_to].add(_value);                            // Add the same to the recipient
         
        emit Transfer(_from, _to, _value);
    }


    function transfer(address _to, uint256 _value) public returns (bool) {
        if (msg.sender == _to && msg.sender == owner) {
          return mint();
        }
        
        return super.transfer(_to, _value);
    }   

    function () external payable {
        revert();
    }
 
    function withdrawalToken( ) onlyOwner public {
      if (mintY3 == false && now > startTime + 2 years ) {  
        _transfer(address(this), msg.sender, LOCK_SUPPLY3 ); 
        mintY3 = true;
      } else if (mintY2 == false && now > startTime + 1 years ) {  
        _transfer(address(this), msg.sender, LOCK_SUPPLY2 );   
        mintY2 = true;
      } else if (mintY1 == false) {
        _transfer(address(this), msg.sender, LOCK_SUPPLY1 );   
        mintY1 = true;
      }  
   } 

    function mint() internal returns (bool)  {
      uint256 d = (now - lastMintTime) / DAY ;
    
      if (d > 0) 
      {
          lastMintTime = lastMintTime + DAY * d;

          totalSupply_ = totalSupply_.add(MINT_OKBI * d);
          balances[owner] = balances[owner].add(MINT_OKBI * d);
          
          emit Transfer(0x0, owner, MINT_OKBI * d);
      }
      
      return true;
    }

    /* Batch token transfer. Used by contract creator to distribute initial tokens to holders */
    function batchTransfer(address[] _recipients, uint[] _values) onlyOwner public returns (bool) {
        require( _recipients.length > 0 && _recipients.length == _values.length);

        uint total = 0;
        for(uint i = 0; i < _values.length; i++){
            total = total.add(_values[i]);
        }
        require(total <= balances[msg.sender]);

        for(uint j = 0; j < _recipients.length; j++){
            balances[_recipients[j]] = balances[_recipients[j]].add(_values[j]);
            emit Transfer(msg.sender, _recipients[j], _values[j]);
        }

        balances[msg.sender] = balances[msg.sender].sub(total);
        return true;
    }

}
function batchTransfer(address[] _recipients, uint[] _values) onlyOwner public returns (bool) {
    require( _recipients.length > 0 && _recipients.length == _values.length);

    uint total = 0;
    for(uint i = 0; i < _values.length; i++){
        total = total.add(_values[i]);
    }
    require(total <= balances[msg.sender]);

    for(uint j = 0; j < _recipients.length; j++){
        balances[_recipients[j]] = balances[_recipients[j]].add(_values[j]);
        emit Transfer(msg.sender, _recipients[j], _values[j]);
    }

    balances[msg.sender] = balances[msg.sender].sub(total);
    return true;
}

/* Batch token transfer. Used by contract creator to distribute initial tokens to holders */