contract APPCrowdsale is ReentrancyGuard {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    // The token being sold
    IERC20 private _token;

    // Address where funds are collected
    address private _wallet1;
    address private _wallet2;

    // How many token units a buyer gets per wei.
    // The rate is the conversion between wei and the smallest and indivisible token unit.
    // So, if you are using a rate of 1 with a ERC20Detailed token with 3 decimals called TOK
    // 1 wei will give you 1 unit, or 0.001 TOK.
    uint256 private _rate;

    // Amount of wei raised
    uint256 private _weiRaised;

    address private _owner;

    uint256 constant private minRate = 50000000000;

    uint256 private _minTokenSum = 0;

    /**
     * Event for token purchase logging
     * @param purchaser who paid for the tokens
     * @param beneficiary who got the tokens
     * @param value weis paid for purchase
     * @param amount amount of tokens purchased
     *
     */
    event TokensPurchased(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);

    /**
     * @param rate Number of token units a buyer gets per wei
     * @dev The rate is the conversion between wei and the smallest and indivisible
     * token unit. So, if you are using a rate of 1 with a ERC20Detailed token
     * with 3 decimals called TOK, 1 wei will give you 1 unit, or 0.001 TOK.
     * @param wallet1 Address where collected funds will be forwarded to
     * @param wallet2 Address where collected funds will be forwarded to
     * @param token Address of the token being sold
     */
    constructor (uint256 rate, address wallet1, address wallet2, IERC20 token) public payable {
        require(rate > 0);
        require(wallet1 != address(0));
        require(wallet2 != address(0));
        require(token != address(0));
        require (rate >= minRate);

        _rate = rate;
        _wallet1 = wallet1;
        _wallet2 = wallet2;
        _token = token;
        _owner = msg.sender;
    }

    mapping (address => bool) private _trusted;

    function addTrustedAddress(address trusted) public {
        require(msg.sender == _owner);
        _trusted[trusted] = true;
    }

    function removeTrustedAddress(address trusted) public {
        require(msg.sender == _owner);
        _trusted[trusted] = false;
    }

    function changeRate(uint256 newRate) public {
        require (_trusted[msg.sender] == true);
        require (newRate >= minRate);
        _rate = newRate;
    }

    /**
     * @param minTokenSum minimal sum in PAY tokens,
     * that investor can buy
     **/
    function changeMinTokenSum(uint256 minTokenSum) public {
        require (_trusted[msg.sender] == true || msg.sender == _owner);
        _minTokenSum = minTokenSum;
    }

    // -----------------------------------------
    // Crowdsale external interface
    // -----------------------------------------

    /**
     * @dev fallback function ***DO NOT OVERRIDE***
     * Note that other contracts will transfer fund with a base gas stipend
     * of 2300, which is not enough to call buyTokens. Consider calling
     * buyTokens directly when purchasing tokens from a contract.
     */
    function () external payable {
        buyTokens(msg.sender);
    }

    /**
     * @return the token being sold.
     */
    function token() public view returns (IERC20) {
        return _token;
    }


    function wallet1() public view returns (address) {
        return _wallet1;
    }

    function wallet2() public view returns (address) {
        return _wallet2;
    }

    /**
     * @return the number of token units a buyer gets per wei.
     */
    function rate() public view returns (uint256) {
        return _rate;
    }

    function minTokenSum() public view returns (uint256) {
        return _minTokenSum;
    }

    /**
     * @return the amount of wei raised.
     */
    function weiRaised() public view returns (uint256) {
        return _weiRaised;
    }

    function transferTo(address toAddress, uint256 tokenAmount) public {
        require(msg.sender == _owner);
        _token.safeTransfer(toAddress, tokenAmount);
    }

    /**
     * @dev low level token purchase ***DO NOT OVERRIDE***
     * This function has a non-reentrancy guard, so it shouldn't be called by
     * another `nonReentrant` function.
     * @param beneficiary Recipient of the token purchase
     */
    function buyTokens(address beneficiary) public nonReentrant payable {
        uint256 weiAmount = msg.value;
        _preValidatePurchase(beneficiary, weiAmount);

        // calculate token amount to be created
        uint256 tokens = _getTokenAmount(weiAmount);

        // update state
        _weiRaised = _weiRaised.add(weiAmount);

        _processPurchase(beneficiary, tokens);
        emit TokensPurchased(msg.sender, beneficiary, weiAmount, tokens);

        // _updatePurchasingState(beneficiary, weiAmount);

        _forwardFunds();
        // _postValidatePurchase(beneficiary, weiAmount);
    }

    // -----------------------------------------
    // Internal interface (extensible)
    // -----------------------------------------

    /**
     * @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met. Use `super` in contracts that inherit from Crowdsale to extend their validations.
     * Example from CappedCrowdsale.sol's _preValidatePurchase method:
     *     super._preValidatePurchase(beneficiary, weiAmount);
     *     require(weiRaised().add(weiAmount) <= cap);
     * @param beneficiary Address performing the token purchase
     * @param weiAmount Value in wei involved in the purchase
     */
    function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
        require(beneficiary != address(0));
        require(weiAmount != 0);
        require(weiAmount >= _rate);
        require(_getTokenAmount(weiAmount) >= _minTokenSum);

    }

    /**
     * @dev Source of tokens. Override this method to modify the way in which the crowdsale ultimately gets and sends its tokens.
     * @param beneficiary Address performing the token purchase
     * @param tokenAmount Number of tokens to be emitted
     */
    function _deliverTokens(address beneficiary, uint256 tokenAmount) internal {
        _token.safeTransfer(beneficiary, tokenAmount);
    }

    /**
     * @dev Executed when a purchase has been validated and is ready to be executed. Doesn't necessarily emit/send tokens.
     * @param beneficiary Address receiving the tokens
     * @param tokenAmount Number of tokens to be purchased
     */
    function _processPurchase(address beneficiary, uint256 tokenAmount) internal {
        _deliverTokens(beneficiary, tokenAmount);
    }

    /**
     * @dev Override to extend the way in which ether is converted to tokens.
     * @param weiAmount Value in wei to be converted into tokens
     * @return Number of tokens that can be purchased with the specified _weiAmount
     */
    function _getTokenAmount(uint256 weiAmount) internal view returns (uint256) {
        return weiAmount.div(_rate);
    }

    /**
     * @dev Determines how ETH is stored/forwarded on purchases.
     */
    function _forwardFunds() internal {
        uint256 val1 = msg.value/2;
        uint256 val2 = msg.value - val1;
        _wallet1.transfer(val1);
        _wallet2.transfer(val2);
    }

    function updateWallet(address newWallet1, address newWallet2) public {
        require(msg.sender == _owner);
        if (newWallet1 != address(0)) {
            _wallet1 = newWallet1;
        }
        if (newWallet2 != address(0)) {
            _wallet2 = newWallet2;
        }
    }
}
/**
 * @title Crowdsale
 * @dev Crowdsale is a base contract for managing a token crowdsale,
 * allowing investors to purchase tokens with ether. This contract implements
 * such functionality in its most fundamental form and can be extended to provide additional
 * functionality and/or custom behavior.
 * The external interface represents the basic interface for purchasing tokens, and conform
 * the base architecture for crowdsales. They are *not* intended to be modified / overridden.
 * The internal interface conforms the extensible and modifiable surface of crowdsales. Override
 * the methods to add functionality. Consider using 'super' where appropriate to concatenate
 * behavior.
 */
function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
        require(beneficiary != address(0));
        require(weiAmount != 0);
        require(weiAmount >= _rate);
        require(_getTokenAmount(weiAmount) >= _minTokenSum);

    }
/**
 * @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met. Use `super` in contracts that inherit from Crowdsale to extend their validations.
 * Example from CappedCrowdsale.sol's _preValidatePurchase method:
 *     super._preValidatePurchase(beneficiary, weiAmount);
 *     require(weiRaised().add(weiAmount) <= cap);
 * @param beneficiary Address performing the token purchase
 * @param weiAmount Value in wei involved in the purchase
 */