contract InbestTokenBuybackProcessor  is Ownable {
  InbestDistribution public inbestDistribution;
  InbestToken public inbestToken;
  // Status of admins
  mapping (address => bool) public admins;

  // Modifier to control who executes functions
  modifier onlyOwnerOrAdmin() {
    require(msg.sender == owner || admins[msg.sender]);
    _;
  }

  /**
   * @dev Constructor recibe the inbestDistribution address contract.
   */
  function InbestTokenBuybackProcessor(InbestDistribution _inbestDistribution, InbestToken _inbestToken) public {
    require(_inbestDistribution != address(0));
    inbestDistribution = _inbestDistribution;
    inbestToken = _inbestToken;
  }

  /**
   * For each wallet on _addresses parameter call to transferTokens over the inbestDistribution contract and then send thoes ibst to another wallet.
   */
  function distributeTokensToDestinationWallet(address[] _addresses, address _addressDestination) public onlyOwnerOrAdmin{
    require(_addresses.length > 0);
    uint arrayLength = _addresses.length;
    for (uint i=0; i < arrayLength; i++) {
      address investorAddress = _addresses[i];
      distributeToAddressAndSendToDestination(investorAddress, _addressDestination);
    }
  }

  function distributeToAddressAndSendToDestination(address _investorAddress, address _addressDestination) public onlyOwnerOrAdmin{
    inbestDistribution.transferTokens(_investorAddress);
    uint256 ibstBalance = inbestToken.balanceOf(_investorAddress);
    require (inbestToken.transferFrom(_investorAddress, _addressDestination, ibstBalance));
    TokensRecoveredFromInvestor(_investorAddress,_addressDestination, ibstBalance);
  }

  function inbestDistributionTransferTokens(address _recipient) public onlyOwnerOrAdmin{
    inbestDistribution.transferTokens(_recipient);
  }

  // ERC20 interface for futures implementations.
  function getBalance(address _investorAddress) public view onlyOwnerOrAdmin  returns (uint256){
    return inbestToken.balanceOf(_investorAddress);
  }

  function tokenTransferFrom(address _fromAddress, address _toAddress, uint256 _ibstAmount) public onlyOwnerOrAdmin returns (bool){
    return inbestToken.transferFrom(_fromAddress, _toAddress, _ibstAmount);
  }

  function tokenTransfer(address _to, uint256 _value) public onlyOwnerOrAdmin returns (bool){
    return inbestToken.transfer(_to, _value);
  }

  function approve(address _spender, uint256 _value) public onlyOwnerOrAdmin returns (bool){
    return inbestToken.approve(_spender, _value);
  }

  event TokensRecoveredFromInvestor(address indexed investor, address indexed newDestination, uint256 amount);


  // Admins management
  /**
   * @dev Admin management
   * @param _admin Address of the admin to modify
   * @param _allowed Status of the admin
   */
  function setAdmin(address _admin, bool _allowed) public onlyOwnerOrAdmin {
    require(_admin != address(0));
    admins[_admin] = _allowed;
    SetAdmin(msg.sender,_admin,_allowed);
  }
  // Event fired when admins are modified
  event SetAdmin(address _caller, address _admin, bool _allowed);
}
function getBalance(address _investorAddress) public view onlyOwnerOrAdmin  returns (uint256){
  return inbestToken.balanceOf(_investorAddress);
}

// ERC20 interface for futures implementations.