contract ForegroundCaller is IForegroundEnabledContract {
    IForeground public foreground;

    function ForegroundCaller(IForeground _foreground) public {
        foreground = _foreground;
    }

    //This event is useful for testing whether a contract has implemented Foreground correctly
    //It can even be used prior to the implementing contract going live
    event EtherReceivedFromRelay(address indexed _originatingAddress, uint256 indexed _promotionID, address indexed _referrer);
    event ForegroundPaymentResult(bool _success, uint256 indexed _promotionID, address indexed _referrer, uint256 _value);
    event ContractFunded(address indexed _sender, uint256 _value);

    //Note: we don't use the "relayedFromAddress" variable here, but it seems like it should still be part of the API
    function receiveEtherFromForegroundAddress(address _originatingAddress, address _relayedFromAddress, uint256 _promotionID, address _referrer) public payable {
        //NOTE: available Ether may be less than msg.value after this call
        //NOTE: originatingAddress indicates the true sender of the funds at this point, not msg.sender
        EtherReceivedFromRelay(_originatingAddress, _promotionID, _referrer);

        uint256 _amountSpent = receiveEtherFromRelayAddress(_originatingAddress, msg.value);

        //NOTE: This makes a call to an external contract (Foreground), but does not use .call -- this seems unavoidable
        uint256 _paymentToForeground = foreground.calculateTotalDue(_promotionID, _amountSpent);
        //NOTE: Using .call in order to swallow any exceptions
        bool _success = foreground.call.gas(1000000).value(_paymentToForeground)(bytes4(keccak256("payConversionFromTransaction(uint256,address,uint256)")), _promotionID, _referrer, _amountSpent);
        ForegroundPaymentResult(_success, _promotionID, _referrer, msg.value);
    }

    //Abstract function to be implemented by advertiser's contract
    function receiveEtherFromRelayAddress(address _originatingAddress, uint256 _amount) internal returns(uint256 _amountSpent);

    //Function allows for additional funds to be added to the contract (without purchasing tokens)
    function fundContract() payable {
        ContractFunded(msg.sender, msg.value);
    }
}
function receiveEtherFromForegroundAddress(address _originatingAddress, address _relayedFromAddress, uint256 _promotionID, address _referrer) public payable {
    //NOTE: available Ether may be less than msg.value after this call
    //NOTE: originatingAddress indicates the true sender of the funds at this point, not msg.sender
    EtherReceivedFromRelay(_originatingAddress, _promotionID, _referrer);

    uint256 _amountSpent = receiveEtherFromRelayAddress(_originatingAddress, msg.value);

    //NOTE: This makes a call to an external contract (Foreground), but does not use .call -- this seems unavoidable
    uint256 _paymentToForeground = foreground.calculateTotalDue(_promotionID, _amountSpent);
    //NOTE: Using .call in order to swallow any exceptions
    bool _success = foreground.call.gas(1000000).value(_paymentToForeground)(bytes4(keccak256("payConversionFromTransaction(uint256,address,uint256)")), _promotionID, _referrer, _amountSpent);
    ForegroundPaymentResult(_success, _promotionID, _referrer, msg.value);
}

//Note: we don't use the "relayedFromAddress" variable here, but it seems like it should still be part of the API