contract Exchanger is ExchangerI, Ownable {
  using SafeMath for uint256;

  mapping (address => uint256) public collected;
  uint256 public totalCollected;
  MiniMeToken public wct1;
  MiniMeToken public wct2;
  Contribution public contribution;

  function Exchanger(address _wct1, address _wct2, address _wpr, address _contribution) {
    wct1 = MiniMeToken(_wct1);
    wct2 = MiniMeToken(_wct2);
    wpr = ERC20Basic(_wpr);
    contribution = Contribution(_contribution);
  }

  function () public {
    if (contribution.finalizedBlock() == 0) {
      contribution.proxyPayment(msg.sender);
    } else {
      collect(msg.sender);
    }
  }

  /// @notice This method should be called by the WCT holders to collect their
  ///  corresponding WPRs
  function collect(address caller) public {
    // WCT sholder could collect WPR right after contribution started
    require(getBlockTimestamp() > contribution.startTime());

    uint256 pre_sale_fixed_at = contribution.initializedBlock();

    // Get current WPR ballance at contributions initialization-
    uint256 balance = wct1.balanceOfAt(caller, pre_sale_fixed_at);
    balance = balance.add(wct2.balanceOfAt(caller, pre_sale_fixed_at));

    uint256 totalSupplied = wct1.totalSupplyAt(pre_sale_fixed_at);
    totalSupplied = totalSupplied.add(wct2.totalSupplyAt(pre_sale_fixed_at));

    // total of wpr to be distributed.
    uint256 total = totalCollected.add(wpr.balanceOf(address(this)));

    // First calculate how much correspond to him
    assert(totalSupplied > 0);
    uint256 amount = total.mul(balance).div(totalSupplied);

    // And then subtract the amount already collected
    amount = amount.sub(collected[caller]);

    // Notify the user that there are no tokens to exchange
    require(amount > 0);

    totalCollected = totalCollected.add(amount);
    collected[caller] = collected[caller].add(amount);

    require(wpr.transfer(caller, amount));

    TokensCollected(caller, amount);
  }

  //////////
  // Testing specific methods
  //////////

  /// @notice This function is overridden by the test Mocks.
  function getBlockNumber() internal constant returns (uint256) {
    return block.number;
  }

  /// @notice This function is overridden by the test Mocks.
  function getBlockTimestamp() internal constant returns (uint256) {
    return block.timestamp;
  }

  //////////
  // Safety Method
  //////////

  /// @notice This method can be used by the controller to extract mistakenly
  ///  sent tokens to this contract.
  /// @param _token The address of the token contract that you want to recover
  ///  set to 0 in case you want to extract ether.
  function claimTokens(address _token) public onlyOwner {
    assert(_token != address(wpr));
    if (_token == 0x0) {
      owner.transfer(this.balance);
      return;
    }

    ERC20 token = ERC20(_token);
    uint256 balance = token.balanceOf(this);
    token.transfer(owner, balance);
    ClaimedTokens(_token, owner, balance);
  }

  event ClaimedTokens(address indexed _token, address indexed _controller, uint256 _amount);
  event TokensCollected(address indexed _holder, uint256 _amount);
}
/// @title Exchanger Contract
/// @author Klaus Hott
/// @dev This contract will be used to distribute WPR between WCT holders.
///  WCT token is not transferable, and we just keep an accounting between all tokens
///  deposited and the tokens collected.
function getBlockNumber() internal constant returns (uint256) {
  return block.number;
}

//////////
/// @notice This function is overridden by the test Mocks.